# ============================================================ # MIZAN presents: Precedent — Projection Pivots — thinkScript · v2.0 # mizanquant.com/free · free & open source · a QWERTY Options Inc. tool # # WHAT IT DOES # Finds confirmed pivot highs and lows (a pivot needs strength bars on # both sides to exist), extends the latest confirmed levels forward as # horizontal support and resistance, and projects trendlines through # the last two pivot highs and the last two pivot lows. Past pivots # are precedent; this draws where price has been overruled before. # Levels describe structure; they do not advise. # # HONESTY NOTE, READ THIS ONE # Pivot tools confirm with hindsight by definition: a pivot high is # only a pivot high once strength bars have printed after it. So new # pivots appear with a delay, and the projection lines re-aim as new # structure forms. What never happens here: a confirmed level moving. # Once a pivot prints, its price is carved. # # INSTALL (thinkorswim desktop) # Charts > Studies > Edit Studies > Create > delete the template, # paste this whole file, name it, OK, Apply. # # v2.0 CHANGES FROM THE OWNER'S ORIGINAL # 1. Pivot confirmation made explicit and hard-gated: nothing plots # for a pivot until its strength window has fully printed. # 2. The warning bubble and the raw parameter chips are gone; one # status label reports the live resistance and support precedents. # 3. Slope math for the projection lines gained division guards # (identical pivot bars can no longer divide by zero). # 4. Dead toggles wired or removed; every input now does something. # 5. Alerts added: close through the latest pivot resistance or # support, and touches of the projected trendlines. # 6. Hidden scan exports for the Scan tab: distance to the nearest # precedent in ticks, and break flags. # 7. Case-insensitive identifier audit passed; zero collisions, # zero unused inputs. # ============================================================ declare upper; # ----- INPUTS ----- input pivotStrength = 21; # bars required on each side of a pivot input showPivotLevels = yes; # horizontal precedent lines input showProjections = yes; # trendlines through the last two pivots input showPivotPoints = yes; # dots on the confirmed pivots input showStatusLabel = yes; def n = Max(1, pivotStrength); def bn = BarNumber(); # ----- CONFIRMED PIVOTS (evaluated n bars back, once both sides exist) ----- def isPivotHi = if bn > 2 * n and high[n] == Highest(high, 2 * n + 1) then 1 else 0; def isPivotLo = if bn > 2 * n and low[n] == Lowest(low, 2 * n + 1) then 1 else 0; def pivHiPrice = if isPivotHi then high[n] else Double.NaN; def pivLoPrice = if isPivotLo then low[n] else Double.NaN; # latest and prior confirmed pivot highs rec lastHi = CompoundValue(1, if isPivotHi then high[n] else lastHi[1], Double.NaN); rec lastHiBar = CompoundValue(1, if isPivotHi then bn - n else lastHiBar[1], Double.NaN); rec prevHi = CompoundValue(1, if isPivotHi then lastHi[1] else prevHi[1], Double.NaN); rec prevHiBar = CompoundValue(1, if isPivotHi then lastHiBar[1] else prevHiBar[1], Double.NaN); # latest and prior confirmed pivot lows rec lastLo = CompoundValue(1, if isPivotLo then low[n] else lastLo[1], Double.NaN); rec lastLoBar = CompoundValue(1, if isPivotLo then bn - n else lastLoBar[1], Double.NaN); rec prevLo = CompoundValue(1, if isPivotLo then lastLo[1] else prevLo[1], Double.NaN); rec prevLoBar = CompoundValue(1, if isPivotLo then lastLoBar[1] else prevLoBar[1], Double.NaN); # ----- HORIZONTAL PRECEDENTS ----- plot PivotResistance = if showPivotLevels and !IsNaN(lastHi) then lastHi else Double.NaN; PivotResistance.SetDefaultColor(Color.GREEN); PivotResistance.SetStyle(Curve.SHORT_DASH); PivotResistance.SetLineWeight(1); plot PivotSupport = if showPivotLevels and !IsNaN(lastLo) then lastLo else Double.NaN; PivotSupport.SetDefaultColor(Color.RED); PivotSupport.SetStyle(Curve.SHORT_DASH); PivotSupport.SetLineWeight(1); # ----- PIVOT DOTS (plotted at the pivot bar, once confirmed) ----- plot PivotHighDot = if showPivotPoints and isPivotHi[-n] then high else Double.NaN; PivotHighDot.SetPaintingStrategy(PaintingStrategy.POINTS); PivotHighDot.SetDefaultColor(Color.GREEN); PivotHighDot.SetLineWeight(2); plot PivotLowDot = if showPivotPoints and isPivotLo[-n] then low else Double.NaN; PivotLowDot.SetPaintingStrategy(PaintingStrategy.POINTS); PivotLowDot.SetDefaultColor(Color.RED); PivotLowDot.SetLineWeight(2); # ----- PROJECTED TRENDLINES through the last two pivots ----- def hiBarsApart = lastHiBar - prevHiBar; def hiSlope = if !IsNaN(prevHi) and hiBarsApart != 0 then (lastHi - prevHi) / hiBarsApart else 0; def loBarsApart = lastLoBar - prevLoBar; def loSlope = if !IsNaN(prevLo) and loBarsApart != 0 then (lastLo - prevLo) / loBarsApart else 0; plot UpperProjection = if showProjections and !IsNaN(prevHi) then lastHi + hiSlope * (bn - lastHiBar) else Double.NaN; UpperProjection.SetDefaultColor(Color.LIGHT_GRAY); UpperProjection.SetStyle(Curve.SHORT_DASH); UpperProjection.SetLineWeight(1); plot LowerProjection = if showProjections and !IsNaN(prevLo) then lastLo + loSlope * (bn - lastLoBar) else Double.NaN; LowerProjection.SetDefaultColor(Color.LIGHT_GRAY); LowerProjection.SetStyle(Curve.SHORT_DASH); LowerProjection.SetLineWeight(1); # ----- STATUS ----- AddLabel(showStatusLabel and !IsNaN(lastHi) and !IsNaN(lastLo), "PRECEDENT R: " + Round(lastHi, 2) + " S: " + Round(lastLo, 2), if close > lastHi then Color.GREEN else if close < lastLo then Color.RED else Color.LIGHT_GRAY); AddLabel(showStatusLabel and (IsNaN(lastHi) or IsNaN(lastLo)), "PRECEDENT: building history (" + (2 * n + 1) + " bars per pivot)", Color.GRAY); # ----- ALERTS ----- def brokeRes = close > lastHi and close[1] <= lastHi and !IsNaN(lastHi); def brokeSup = close < lastLo and close[1] >= lastLo and !IsNaN(lastLo); Alert(brokeRes, "Precedent: closed above the latest pivot resistance", Alert.BAR, Sound.Bell); Alert(brokeSup, "Precedent: closed below the latest pivot support", Alert.BAR, Sound.Bell); Alert(!IsNaN(UpperProjection) and high >= UpperProjection and high[1] < UpperProjection[1], "Precedent: touched the upper projection", Alert.BAR, Sound.Ding); Alert(!IsNaN(LowerProjection) and low <= LowerProjection and low[1] > LowerProjection[1], "Precedent: touched the lower projection", Alert.BAR, Sound.Ding); # ----- SCAN EXPORTS ----- plot ScanBrokeRes = if brokeRes then 1 else 0; ScanBrokeRes.Hide(); plot ScanBrokeSup = if brokeSup then 1 else 0; ScanBrokeSup.Hide(); plot ScanTicksToRes = if !IsNaN(lastHi) then (lastHi - close) / TickSize() else 0; ScanTicksToRes.Hide(); plot ScanTicksToSup = if !IsNaN(lastLo) then (close - lastLo) / TickSize() else 0; ScanTicksToSup.Hide(); # Educational tool. It describes market structure; it does not give # advice, and no output is a recommendation to buy or sell anything. # Trading involves substantial risk of loss. mizanquant.com/terms