TTM Squeeze Pro.pine
Copy
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © tamth_
//@version=6
indicator('TTM Squeeze Pro', overlay = false, precision = 2)
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
// Colors
AQUA_COLOR = color.aqua
BLUE_COLOR = #2962ff
RED_COLOR = color.red
YELLOW_COLOR = color.yellow
ORANGE_COLOR = color.orange
GREEN_COLOR = color.green
BLACK_COLOR = color.black
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Settings
//-----------------------------------------------------------------------------
sqzGroup = "Squeeze"
length = input.int(20, "TTM Squeeze Length", group = sqzGroup)
// Bollinger Bands
BB_mult = input.float(2.0, "Bollinger Band STD Multiplier", group = sqzGroup)
// Keltner Channels
KC_mult_high = input.float(1.0, "Keltner Channel #1", group = sqzGroup)
KC_mult_mid = input.float(1.5, "Keltner Channel #2", group = sqzGroup)
KC_mult_low = input.float(2.0, "Keltner Channel #3", group = sqzGroup)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Calculations
//-----------------------------------------------------------------------------
BB_basis = ta.sma(close, length)
dev = BB_mult * ta.stdev(close, length)
BB_upper = BB_basis + dev
BB_lower = BB_basis - dev
KC_basis = ta.sma(close, length)
devKC = ta.sma(ta.tr, length)
KC_upper_high = KC_basis + devKC * KC_mult_high
KC_lower_high = KC_basis - devKC * KC_mult_high
KC_upper_mid = KC_basis + devKC * KC_mult_mid
KC_lower_mid = KC_basis - devKC * KC_mult_mid
KC_upper_low = KC_basis + devKC * KC_mult_low
KC_lower_low = KC_basis - devKC * KC_mult_low
// Squeeze Conditions
NoSqz = BB_lower < KC_lower_low or BB_upper > KC_upper_low //NO SQUEEZE: GREEN
LowSqz = BB_lower >= KC_lower_low or BB_upper <= KC_upper_low //LOW COMPRESSION: BLACK
MidSqz = BB_lower >= KC_lower_mid or BB_upper <= KC_upper_mid //MID COMPRESSION: RED
HighSqz = BB_lower >= KC_lower_high or BB_upper <= KC_upper_high //HIGH COMPRESSION: ORANGE
// Momentum Oscillator
mom = ta.linreg(close - math.avg(math.avg(ta.highest(high, length), ta.lowest(low, length)), ta.sma(close, length)), length, 0)
// Momentum Histogram Colors
iff_1 = mom > nz(mom[1]) ? AQUA_COLOR : BLUE_COLOR
iff_2 = mom < nz(mom[1]) ? RED_COLOR : YELLOW_COLOR
mom_color = mom > 0 ? iff_1 : iff_2
// Squeeze Dots Colors
sq_color = HighSqz ? ORANGE_COLOR : MidSqz ? RED_COLOR : LowSqz ? BLACK_COLOR : GREEN_COLOR
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Render
//-----------------------------------------------------------------------------
plot(mom, title = 'Momentum', color = mom_color, style = plot.style_columns, linewidth = 2)
plot(0, title = 'Squeeze', color = sq_color, style = plot.style_circles, linewidth = 3)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Signals
//-----------------------------------------------------------------------------
// Settings
//-----------------------------------------------------------------------------
string sigGroup = "Signals"
bool sigarrows = input.bool(true, title = "Show", group = sigGroup)
string sigt = input.string("+/-", title = "Signal Type", options = ["Current Momentum", "Sum of Change", "+/-", "Rising/Falling", "Crossed Zero", "Basis Line Momentum", "Divergence", "Combo"], group = sigGroup)
string custsqz = input.string("Default", title = "Squeeze Signal Length", options = ["Default", "End of Early Signal", "End of Squeeze", "Custom"], group = sigGroup)
int sqzsig = input.int(8, title = "Custom Squeeze Signal Duration", group = sigGroup)
int sumofc = input.int(20, title = "Sum of Change Length", group = sigGroup)
int entrysmooth = input.int(7, title = "Early Entry Smoothing Period", group = sigGroup)
int exitsmooth = input.int(9, title = "Early Exit Smoothing Period", group = sigGroup)
//-----------------------------------------------------------------------------
// Values
//-----------------------------------------------------------------------------
// Squeeze Variables
float sqz = ta.linreg(close - math.avg(math.avg(ta.highest(high, 20), ta.lowest(low, 20)), ta.ema(close, 20)), 20, 0)
float momo = ta.linreg((sqz - sqz[1]), exitsmooth, 0)
// Basis Line
float basis = ta.sma(close,20)
// Bollinger Bands
float upperbb = basis + dev
float lowerbb = basis - dev
// Keltner Channels Range
float kcrange = ta.sma(ta.tr, 20)
// Keltner Channels High
float kcuph = basis + kcrange * KC_mult_high
float kcdnh = basis - kcrange * KC_mult_high
// Keltner Channels Mid
float kcupm = basis + kcrange * KC_mult_mid
float kcdnm = basis - kcrange * KC_mult_mid
// Keltner Channels Low
float kcupl = basis + kcrange * KC_mult_low
float kcdnl = basis - kcrange * KC_mult_low
// Early Signal Variables
float bkhigh = upperbb - kcuph
float bkmid = upperbb - kcupm
float bklow = upperbb - kcupl
float bkhema = ta.ema(bkhigh,entrysmooth)
float bkmema = ta.ema(bkmid,entrysmooth)
float bklema = ta.ema(bklow,entrysmooth)
// Each Squeeze Type
bool lowsqz = upperbb < kcupl and lowerbb > kcdnl
bool midsqz = upperbb < kcupm and lowerbb > kcdnm
bool highsqz = upperbb < kcuph and lowerbb > kcdnh
// BB and KC Signal Formulas
bool ksm = close < kcdnm or close > kcupm
bool ksh = close < kcdnh or close > kcuph
bool ksl = close < kcdnl or close > kcupl
bool bbsmh = close < lowerbb or close > upperbb
// Early Entry Candle Conditions
bool earlyentrymid = bkmid > bkmema and bkmid <=0
bool earlyentryhigh = bkhigh > bkhema and bkhigh <=0
bool earlyentrylow = bklow > bklema and bklow <=0
bool endofmid = ta.barssince(earlyentrymid) == 1
bool endofhigh = ta.barssince(earlyentryhigh) == 1
bool endoflow = ta.barssince(earlyentrylow) == 1
// Individual KC Formulas
barssinceKsl = ta.barssince(ksl)
barssinceKsm = ta.barssince(ksm)
barssinceKsh = ta.barssince(ksh)
bool kcllong = ksl and lowsqz[1] and close > basis and (barssinceKsl[1] > 20)
bool kclshort = ksl and lowsqz[1] and close < basis and (barssinceKsl[1] > 20)
bool kcmlong = ksm and midsqz[1] and close > basis and (barssinceKsm[1] > 20)
bool kcmshort = ksm and midsqz[1] and close < basis and (barssinceKsm[1] > 20)
bool kchlong = ksh and highsqz[1] and close > basis and (barssinceKsh[1] > 20)
bool kchshort = ksh and highsqz[1] and close < basis and (barssinceKsh[1] > 20)
// Individual BB Formulas
barssinceBbSmh = ta.barssince(bbsmh)
bool bbllong = bbsmh and lowsqz[1] and close > basis and (barssinceBbSmh[1] > 20)
bool bblshort = bbsmh and lowsqz[1] and close < basis and (barssinceBbSmh[1] > 20)
bool bbmlong = bbsmh and midsqz[1] and close > basis and (barssinceBbSmh[1] > 20)
bool bbmshort = bbsmh and midsqz[1] and close < basis and (barssinceBbSmh[1] > 20)
bool bbhlong = bbsmh and highsqz[1] and close > basis and (barssinceBbSmh[1] > 20)
bool bbhshort = bbsmh and highsqz[1] and close < basis and (barssinceBbSmh[1] > 20)
// Signal Types
bool cmom = sigt == "Current Momentum"
bool soc = sigt == "Sum of Change"
bool momom = sigt == "+/-"
bool rf = sigt == "Rising/Falling"
bool czero = sigt == "Crossed Zero"
bool blma = sigt == "Basis Line Momentum"
bool diverg = sigt == "Divergence"
bool combo = sigt == "Combo"
// Signal Durations
bool sigreg = custsqz == "Default"
bool sigeoe = custsqz == "End of Early Signal"
bool sigeos = custsqz == "End of Squeeze"
bool sigcus = custsqz == "Custom"
// Sum of Change
float change = math.sum((sqz-sqz[1]),sumofc)
bool changel = change > 0
bool changes = change < 0
// Basis Line Filter
bool bbmal = close >= basis
bool bbmas = close < basis
// Basic Signal Conditions
bool sc1 = sqz > 0
bool sc2 = sqz < 0
// Rising/Falling Conditions
bool sqzlongreg = sqz > sqz[1] and sqz[1] > sqz[2] and sqz[2] > sqz[3] and sqz[3] > sqz[4] and sqz[4] > sqz[5] and sqz[5] > sqz[6]
bool sqzshortreg = sqz < sqz[1] and sqz[1] < sqz[2] and sqz[2] < sqz[3] and sqz[3] < sqz[4] and sqz[4] < sqz[5] and sqz[5] < sqz[6]
// Zero Line Conditions
bool sqzzerolong = sqz > 0 and sqz[6] < 0
bool sqzzeroshort= sqz < 0 and sqz[6] > 0
// Divergence Formula
ftf(_src) => _src[4] < _src[2] and _src[3] < _src[2] and _src[2] > _src[1] and _src[2] > _src[0]
fbf(_src) => _src[4] > _src[2] and _src[3] > _src[2] and _src[2] < _src[1] and _src[2] < _src[0]
ffract(_src) => ftf(_src) ? 1 : fbf(_src) ? -1 : 0
// Divergence Variables
float fractaltop = ffract(sqz) > 0 ? sqz[2] : na
float fractalbot = ffract(sqz) < 0 ? sqz[2] : na
float high_prev = ta.valuewhen(not na(fractaltop), sqz[2], 1)
float high_price = ta.valuewhen(not na(fractaltop), high[2], 1)
float low_prev = ta.valuewhen(not na(fractalbot), sqz[2], 1)
float low_price = ta.valuewhen(not na(fractalbot), low[2], 1)
bool regbeardiv = not na(fractaltop) and high[2] > high_price and sqz[2] < high_prev
bool regbulldiv = not na(fractalbot) and low[2] < low_price and sqz[2] > low_prev
// Current Momentum
bool cmolong = sqz > sqz[1]
bool cmoshort = sqz <= sqz[1]
// False Signals
bool lsf = lowsqz == false
bool msf = midsqz == false
bool hsf = highsqz == false
// End of Early Signal
bool eoel = sigeoe ? endoflow : false
bool eoem = sigeoe ? endofmid : false
bool eoeh = sigeoe ? endofhigh : false
barssinceLsf = ta.barssince(lsf)
barssinceMsf = ta.barssince(msf)
barssinceHsf = ta.barssince(hsf)
barssinceLowSqz = ta.barssince(lowsqz)
barssinceMidSqz = ta.barssince(midsqz)
barssinceHighSqz = ta.barssince(highsqz)
// Dot Count Regular
bool llDef = sigreg ? lowsqz and (barssinceLsf == 6) : false
bool mlDef = sigreg ? midsqz and (barssinceMsf == 6) : false
bool hlDef = sigreg ? highsqz and (barssinceHsf == 6) : false
// End Of Squeeze
bool eol = sigeos ? lsf and (barssinceLowSqz == 1) : false
bool eom = sigeos ? msf and (barssinceMidSqz == 1) : false
bool eoh = sigeos ? hsf and (barssinceHighSqz == 1) : false
// Custom Squeeze
bool custl = sigcus ? lowsqz and (barssinceLsf == sqzsig) : false
bool custm = sigcus ? midsqz and (barssinceMsf == sqzsig) : false
bool custh = sigcus ? highsqz and (barssinceHsf == sqzsig) : false
// Dot Count Signals
bool squeezesignall = eoel or llDef or eol or custl
bool squeezesignalm = eoem or mlDef or eom or custm
bool squeezesignalh = eoeh or hlDef or eoh or custh
// Sum of Change Formulas
bool llchg = squeezesignall and changel
bool lschg = squeezesignall and changes
bool mlchg = squeezesignalm and changel
bool mschg = squeezesignalm and changes
bool hlchg = squeezesignalh and changel
bool hschg = squeezesignalh and changes
// Basic Signal Formulas
bool llbsc = squeezesignall and sc1
bool lsbsc = squeezesignall and sc2
bool mlbsc = squeezesignalm and sc1
bool msbsc = squeezesignalm and sc2
bool hlbsc = squeezesignalh and sc1
bool hsbsc = squeezesignalh and sc2
// Rising/Falling Signal Formulas
bool llrf = squeezesignall and sqzlongreg
bool lsrf = squeezesignall and sqzshortreg
bool mlrf = squeezesignalm and sqzlongreg
bool msrf = squeezesignalm and sqzshortreg
bool hlrf = squeezesignalh and sqzlongreg
bool hsrf = squeezesignalh and sqzshortreg
// Zero Line Signal Formulas
bool llz = squeezesignall and sqzzerolong
bool lsz = squeezesignall and sqzzeroshort
bool mlz = squeezesignalm and sqzzerolong
bool msz = squeezesignalm and sqzzeroshort
bool hlz = squeezesignalh and sqzzerolong
bool hsz = squeezesignalh and sqzzeroshort
// Basis Line Signal Formulas
bool llbl = squeezesignall and bbmal
bool lsbl = squeezesignall and bbmas
bool mlbl = squeezesignalm and bbmal
bool msbl = squeezesignalm and bbmas
bool hlbl = squeezesignalh and bbmal
bool hsbl = squeezesignalh and bbmas
// Divergence Signal Formulas
bool lldv = squeezesignall and regbulldiv
bool lsdv = squeezesignall and regbeardiv
bool mldv = squeezesignalm and regbulldiv
bool msdv = squeezesignalm and regbeardiv
bool hldv = squeezesignalh and regbulldiv
bool hsdv = squeezesignalh and regbeardiv
// Current Momentum Signal Formulas
bool llcm = squeezesignall and cmolong
bool lscm = squeezesignall and cmoshort
bool mlcm = squeezesignalm and cmolong
bool mscm = squeezesignalm and cmoshort
bool hlcm = squeezesignalh and cmolong
bool hscm = squeezesignalh and cmoshort
// Combo Scoring
int basicscore = sc1 ? 6 : -6
int rfscore = sqzlongreg ? 3 : sqzshortreg ? -3 : 0
int zlscore = sqzzerolong ? 4 : sqzzeroshort ? -4 : 0
int bbmascore = bbmal ? 3 : bbmas ? -3 : 0
int divscore = regbulldiv ? 3 : regbeardiv ? -3 : 0
int sumscore = changel ? 4 : -4
int currentmo = cmolong ? 3 : -3
int comboscore = basicscore + rfscore + zlscore + bbmascore + divscore + sumscore + currentmo
bool longcombo = comboscore > 0
bool shortcombo = comboscore < 0
// Combo Signal Formulas
bool llcombo = squeezesignall and longcombo
bool lscombo = squeezesignall and shortcombo
bool mlcombo = squeezesignalm and longcombo
bool mscombo = squeezesignalm and shortcombo
bool hlcombo = squeezesignalh and longcombo
bool hscombo = squeezesignalh and shortcombo
// Final Signals
bool longlow = (soc and llchg) or (momom and llbsc) or (rf and llrf) or (czero and llz) or (blma and llbl) or (diverg and lldv) or (llcm and cmom) or (combo and llcombo)
bool shortlow = (soc and lschg) or (momom and lsbsc) or (rf and lsrf) or (czero and lsz) or (blma and lsbl) or (diverg and lsdv) or (lscm and cmom) or (combo and lscombo)
bool longmid = (soc and mlchg) or (momom and mlbsc) or (rf and mlrf) or (czero and mlz) or (blma and mlbl) or (diverg and mldv) or (mlcm and cmom) or (combo and mlcombo)
bool shortmid = (soc and mschg) or (momom and msbsc) or (rf and msrf) or (czero and msz) or (blma and msbl) or (diverg and msdv) or (mscm and cmom) or (combo and mscombo)
bool longhigh = (soc and hlchg) or (momom and hlbsc) or (rf and hlrf) or (czero and hlz) or (blma and hlbl) or (diverg and hldv) or (hlcm and cmom) or (combo and hlcombo)
bool shorthigh = (soc and hschg) or (momom and hsbsc) or (rf and hsrf) or (czero and hsz) or (blma and hsbl) or (diverg and hsdv) or (hscm and cmom) or (combo and hscombo)
//-----------------------------------------------------------------------------
// Render
//-----------------------------------------------------------------------------
plotshape(sigarrows ? (longhigh ? false : longmid ? false : longlow ? longlow : false) : false, color = BLACK_COLOR, style = shape.arrowup, location = location.belowbar, size = size.small, title = "Low Squeeze Signal - Long", force_overlay = true)
plotshape(sigarrows ? (shorthigh ? false : shortmid ? false : shortlow ? shortlow : false) : false, color = BLACK_COLOR, style = shape.arrowdown, location = location.abovebar, size = size.small, title = "Low Squeeze Signal - Short", force_overlay = true)
plotshape(sigarrows ? (longhigh ? false : longmid ? longmid : false) : false, color = RED_COLOR, style = shape.arrowup, location = location.belowbar, size = size.small, title = "Mid Squeeze Signal - Long", force_overlay = true)
plotshape(sigarrows ? (shorthigh ? false : shortmid ? shortmid : false) : false, color = RED_COLOR, style = shape.arrowdown, location = location.abovebar, size = size.small, title = "Mid Squeeze Signal - Short", force_overlay = true)
plotshape(sigarrows ? (longhigh ? longhigh : false) : false, color = ORANGE_COLOR, style = shape.arrowup, location = location.belowbar, size = size.small, title = "High Squeeze Signal - Long", force_overlay = true)
plotshape(sigarrows ? (shorthigh ? shorthigh : false) : false, color = ORANGE_COLOR, style = shape.arrowdown, location = location.abovebar, size = size.small, title = "High Squeeze Signal - Short", force_overlay = true)
//------------------------------------------------------------------------------
Show all 329 lines