Last active
May 14, 2026 17:50
-
-
Save Jordan-Hall/3aa2e9a9f26835998de544ff9adc926b to your computer and use it in GitHub Desktop.
Trading View Pinescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //@version=6 | |
| indicator("XAUUSD Pro Scalper v5 - Fixed (Pine v6)", overlay=true, max_boxes_count=120, max_labels_count=200, max_lines_count=80) | |
| // ============================================================================ | |
| // INPUTS | |
| // ============================================================================ | |
| grpData = "Data Sources" | |
| dxySymbol = input.symbol("TVC:DXY", "DXY Symbol", group=grpData) | |
| dxyTf = input.timeframe("5", "DXY Timeframe", group=grpData) | |
| grpMode = "Mode & Filters" | |
| mode = input.string("Normal", "Mode", options=["Fast", "Normal", "Strict"], group=grpMode) | |
| pauseTrading = input.bool(false, "Pause / News Mode", group=grpMode) | |
| grpDisplay = "Display" | |
| showDashboard = input.bool(true, "Show Dashboard", group=grpDisplay) | |
| showLiveAdvice = input.bool(true, "Show Live Advice", group=grpDisplay) | |
| showLivePlan = input.bool(true, "Show Live Entry / SL / TP", group=grpDisplay) | |
| showXZones = input.bool(true, "Show Best xZones", group=grpDisplay) | |
| showSessionLevels = input.bool(true, "Show Session Levels", group=grpDisplay) | |
| showPdhPdl = input.bool(true, "Show PDH / PDL", group=grpDisplay) | |
| showSR = input.bool(true, "Show Support / Resistance", group=grpDisplay) | |
| showBeNote = input.bool(true, "Show 'Move SL to BE at TP1' note", group=grpDisplay) | |
| showHistorical = input.bool(true, "Plot historical BUY/SELL triangles", group=grpDisplay) | |
| colorBlindMode = input.bool(true, "Colorblind-safe palette (blue/orange, high contrast)", group=grpDisplay, | |
| tooltip="Replaces red/green with blue (BUY) and orange (SELL). Distinguishable for deuteranopia, protanopia, and tritanopia, with extra contrast for dark-mode use.") | |
| // ----- High-contrast palette (deuteranopia/protanopia safe by default) ----- | |
| cBuy = colorBlindMode ? color.rgb(79, 195, 247) : color.green // light blue | |
| cSell = colorBlindMode ? color.rgb(255, 167, 38) : color.red // amber/orange | |
| cBuyOb = colorBlindMode ? color.rgb(38, 198, 218) : color.blue // cyan | |
| cSellOb = colorBlindMode ? color.rgb(255, 112, 67) : color.orange // deep orange | |
| cBuySwing = colorBlindMode ? color.rgb(129, 212, 250) : color.lime // pale blue | |
| cSellSwing = colorBlindMode ? color.rgb(255, 138, 101) : color.maroon // pale orange | |
| cWarn = color.rgb(255, 213, 79) // gold (always readable) | |
| cTextHi = color.white | |
| cTextDim = color.rgb(200, 210, 220) | |
| grpZones = "xZones" | |
| maxZonesEachSide = input.int(4, "Best xZones Per Side", minval=1, maxval=10, group=grpZones) | |
| zoneProjection = input.int(24, "xZone Projection Bars", minval=5, maxval=120, group=grpZones) | |
| zoneExpiry = input.int(120, "xZone Expiry Bars", minval=10, maxval=500, group=grpZones) | |
| removeZoneAfterTouch = input.bool(false, "Remove xZone After First Touch", group=grpZones) | |
| removeZoneAfterMitigation = input.bool(true, "Remove xZone After Mitigation", group=grpZones) | |
| hideFarZones = input.bool(true, "Hide Very Far Zones", group=grpZones) | |
| maxZoneDistanceAtr = input.float(8.0, "Max Zone Distance ATR", minval=1.0, maxval=30.0, group=grpZones) | |
| duplicateAtr = input.float(0.15, "Duplicate Zone Tolerance ATR", minval=0.05, maxval=1.0, group=grpZones) | |
| grpSession = "Sessions" | |
| asiaSession = input.session("0000-0700", "Asia", group=grpSession) | |
| londonSession = input.session("0700-1200", "London", group=grpSession) | |
| nySession = input.session("1330-2100", "New York", group=grpSession) | |
| killzoneLondon = input.session("0700-1000", "London Killzone", group=grpSession) | |
| killzoneNY = input.session("1330-1600", "NY Killzone", group=grpSession) | |
| grpTech = "Indicators" | |
| emaFastLen = input.int(20, "EMA Fast", group=grpTech) | |
| emaSlowLen = input.int(50, "EMA Slow", group=grpTech) | |
| atrLen = input.int(14, "ATR", group=grpTech) | |
| atrAvgLen = input.int(50, "ATR Average", group=grpTech) | |
| swingLen = input.int(10, "Swing Strength", minval=3, maxval=60, group=grpTech) | |
| srLen = input.int(12, "S/R Strength", minval=3, maxval=80, group=grpTech) | |
| grpScore = "Score Weights" | |
| wGoldTrend = input.int(20, "Gold Trend (vwap+ema)", minval=0, maxval=50, group=grpScore) | |
| wHtfTrend = input.int(15, "HTF Trend", minval=0, maxval=50, group=grpScore) | |
| wDxy = input.int(25, "DXY Aligned", minval=0, maxval=50, group=grpScore) | |
| wDxyReject = input.int(20, "DXY Reject Sweep", minval=0, maxval=50, group=grpScore) | |
| wZone = input.int(20, "Near Zone / Level", minval=0, maxval=50, group=grpScore) | |
| wSweep = input.int(20, "Liquidity Sweep", minval=0, maxval=50, group=grpScore) | |
| wVwap = input.int(10, "VWAP Side", minval=0, maxval=30, group=grpScore) | |
| wRejCandle = input.int(10, "Rejection Candle", minval=0, maxval=30, group=grpScore) | |
| wSession = input.int(10, "Killzone / Session", minval=0, maxval=30, group=grpScore) | |
| pChop = input.int(25, "Chop Penalty", minval=0, maxval=50, group=grpScore) | |
| pBigCandle = input.int(15, "Big Candle Penalty", minval=0, maxval=50, group=grpScore) | |
| grpConfirm = "Confirmation" | |
| confirmPctBase = input.int(75, "BUY/SELL Confirm % (Normal)", minval=50, maxval=95, group=grpConfirm) | |
| watchOffset = input.int(15, "WATCH Offset %", minval=5, maxval=30, group=grpConfirm) | |
| minRiskPoints = input.float(2.0, "Min Risk (price units)", minval=0.1, maxval=20.0, group=grpConfirm, | |
| tooltip="Reject signals where risk < this (in $ for XAUUSD).") | |
| grpRisk = "Risk / Targets" | |
| obImpulseAtr = input.float(0.75, "OB Impulse ATR", minval=0.2, maxval=3.0, group=grpRisk) | |
| swingZoneAtr = input.float(0.35, "Swing xZone ATR Width", minval=0.05, maxval=2.0, group=grpRisk) | |
| slBufferAtr = input.float(0.25, "SL Buffer ATR", minval=0.05, maxval=1.5, group=grpRisk) | |
| fallbackStopAtr = input.float(1.0, "Fallback Stop ATR", minval=0.3, maxval=3.0, group=grpRisk) | |
| tp1R = input.float(1.2, "TP1 R", minval=0.5, maxval=5.0, group=grpRisk) | |
| tp2R = input.float(2.0, "TP2 R", minval=1.0, maxval=8.0, group=grpRisk) | |
| structuralClampOnlyBeyond1R = input.bool(true, "Clamp TP to structure only if structure > 1R", group=grpRisk, | |
| tooltip="Prevents tiny TPs when VWAP/PDH sits very close to entry.") | |
| // Mode-driven tuning | |
| confirmPct = mode == "Fast" ? confirmPctBase - 10 : mode == "Strict" ? confirmPctBase + 5 : confirmPctBase | |
| fvgAtrMult = mode == "Fast" ? 0.08 : mode == "Normal" ? 0.14 : 0.22 | |
| obImpulseAtrM = mode == "Strict" ? obImpulseAtr * 1.3 : obImpulseAtr | |
| // ============================================================================ | |
| // CORE | |
| // ============================================================================ | |
| emaFast = ta.ema(close, emaFastLen) | |
| emaSlow = ta.ema(close, emaSlowLen) | |
| vwapValue = ta.vwap(hlc3) | |
| atr = ta.atr(atrLen) | |
| atrAvg = ta.sma(atr, atrAvgLen) | |
| plot(emaFast, "EMA Fast", color=color.aqua) | |
| plot(emaSlow, "EMA Slow", color=color.orange) | |
| plot(vwapValue, "VWAP", linewidth=2, color=color.yellow) | |
| pdh = request.security(syminfo.tickerid, "D", high[1], lookahead=barmerge.lookahead_off) | |
| pdl = request.security(syminfo.tickerid, "D", low[1], lookahead=barmerge.lookahead_off) | |
| plot(showPdhPdl ? pdh : na, "PDH", style=plot.style_linebr, linewidth=2, color=color.new(cSell, 30)) | |
| plot(showPdhPdl ? pdl : na, "PDL", style=plot.style_linebr, linewidth=2, color=color.new(cBuy, 30)) | |
| newDay = ta.change(time("D")) != 0 | |
| // ============================================================================ | |
| // SESSIONS (with prev-day NY persistence) | |
| // ============================================================================ | |
| inAsia = not na(time(timeframe.period, asiaSession)) | |
| inLondon = not na(time(timeframe.period, londonSession)) | |
| inNY = not na(time(timeframe.period, nySession)) | |
| inLondonKZ = not na(time(timeframe.period, killzoneLondon)) | |
| inNYKZ = not na(time(timeframe.period, killzoneNY)) | |
| inKillzone = inLondonKZ or inNYKZ | |
| var float asiaHigh = na | |
| var float asiaLow = na | |
| var float londonHigh = na | |
| var float londonLow = na | |
| var float nyHigh = na | |
| var float nyLow = na | |
| var float prevNyHigh = na | |
| var float prevNyLow = na | |
| if newDay | |
| prevNyHigh := nyHigh | |
| prevNyLow := nyLow | |
| asiaHigh := na | |
| asiaLow := na | |
| londonHigh := na | |
| londonLow := na | |
| nyHigh := na | |
| nyLow := na | |
| if inAsia | |
| asiaHigh := na(asiaHigh) ? high : math.max(asiaHigh, high) | |
| asiaLow := na(asiaLow) ? low : math.min(asiaLow, low) | |
| if inLondon | |
| londonHigh := na(londonHigh) ? high : math.max(londonHigh, high) | |
| londonLow := na(londonLow) ? low : math.min(londonLow, low) | |
| if inNY | |
| nyHigh := na(nyHigh) ? high : math.max(nyHigh, high) | |
| nyLow := na(nyLow) ? low : math.min(nyLow, low) | |
| plot(showSessionLevels ? asiaHigh : na, "Asia High", style=plot.style_linebr, color=color.new(color.purple, 30)) | |
| plot(showSessionLevels ? asiaLow : na, "Asia Low", style=plot.style_linebr, color=color.new(color.purple, 30)) | |
| plot(showSessionLevels ? londonHigh : na, "London High", style=plot.style_linebr, color=color.new(color.blue, 30)) | |
| plot(showSessionLevels ? londonLow : na, "London Low", style=plot.style_linebr, color=color.new(color.blue, 30)) | |
| plot(showSessionLevels ? prevNyHigh : na, "Prev NY High", style=plot.style_linebr, color=color.new(color.fuchsia, 40)) | |
| plot(showSessionLevels ? prevNyLow : na, "Prev NY Low", style=plot.style_linebr, color=color.new(color.fuchsia, 40)) | |
| // ============================================================================ | |
| // DXY (ignore_invalid_symbol + explicit lookahead) | |
| // ============================================================================ | |
| dxyClose = request.security(dxySymbol, dxyTf, close, lookahead=barmerge.lookahead_off, ignore_invalid_symbol=true) | |
| dxyHigh = request.security(dxySymbol, dxyTf, high, lookahead=barmerge.lookahead_off, ignore_invalid_symbol=true) | |
| dxyLow = request.security(dxySymbol, dxyTf, low, lookahead=barmerge.lookahead_off, ignore_invalid_symbol=true) | |
| dxyEma20 = request.security(dxySymbol, dxyTf, ta.ema(close, 20), lookahead=barmerge.lookahead_off, ignore_invalid_symbol=true) | |
| dxyEma50 = request.security(dxySymbol, dxyTf, ta.ema(close, 50), lookahead=barmerge.lookahead_off, ignore_invalid_symbol=true) | |
| dxyPrevHigh = request.security(dxySymbol, dxyTf, ta.highest(high[1], 12), lookahead=barmerge.lookahead_off, ignore_invalid_symbol=true) | |
| dxyPrevLow = request.security(dxySymbol, dxyTf, ta.lowest(low[1], 12), lookahead=barmerge.lookahead_off, ignore_invalid_symbol=true) | |
| dxyOk = not na(dxyClose) | |
| dxyBull = dxyOk and dxyClose > dxyEma20 and dxyEma20 > dxyEma50 | |
| dxyBear = dxyOk and dxyClose < dxyEma20 and dxyEma20 < dxyEma50 | |
| dxyFlat = dxyOk and not dxyBull and not dxyBear | |
| dxyRejectHigh = dxyOk and dxyHigh > dxyPrevHigh and dxyClose < dxyPrevHigh | |
| dxyReclaimLow = dxyOk and dxyLow < dxyPrevLow and dxyClose > dxyPrevLow | |
| // Stabilized DXY for exit logic (won't flip exits on a single bar) | |
| dxyBullStable = dxyBull and dxyBull[1] | |
| dxyBearStable = dxyBear and dxyBear[1] | |
| // ============================================================================ | |
| // HTF | |
| // ============================================================================ | |
| tfSeconds = timeframe.in_seconds(timeframe.period) | |
| tfMinutes = na(tfSeconds) ? 5.0 : tfSeconds / 60.0 | |
| htfTf = tfMinutes <= 3 ? "5" : tfMinutes <= 5 ? "15" : tfMinutes <= 15 ? "60" : "240" | |
| htfClose = request.security(syminfo.tickerid, htfTf, close, lookahead=barmerge.lookahead_off) | |
| htfEmaFast = request.security(syminfo.tickerid, htfTf, ta.ema(close, emaFastLen), lookahead=barmerge.lookahead_off) | |
| htfEmaSlow = request.security(syminfo.tickerid, htfTf, ta.ema(close, emaSlowLen), lookahead=barmerge.lookahead_off) | |
| htfVwap = request.security(syminfo.tickerid, htfTf, ta.vwap(hlc3), lookahead=barmerge.lookahead_off) | |
| htfBull = htfClose > htfVwap and htfEmaFast > htfEmaSlow | |
| htfBear = htfClose < htfVwap and htfEmaFast < htfEmaSlow | |
| htfRange = not htfBull and not htfBear | |
| goldBull = close > vwapValue and emaFast > emaSlow | |
| goldBear = close < vwapValue and emaFast < emaSlow | |
| emaCompression = math.abs(emaFast - emaSlow) <= atr * 0.18 and math.abs(close - vwapValue) <= atr * 0.25 | |
| atrLow = atr < atrAvg * 0.65 | |
| bigCandle = math.abs(close - open) > atr * 1.8 | |
| chop = emaCompression or atrLow | |
| sessionOk = inKillzone or (mode == "Fast" and (inLondon or inNY)) | |
| // ============================================================================ | |
| // SWEEPS (now incl. prev-day NY) | |
| // ============================================================================ | |
| sweepAsiaLow = not na(asiaLow) and low < asiaLow and close > asiaLow | |
| sweepAsiaHigh = not na(asiaHigh) and high > asiaHigh and close < asiaHigh | |
| sweepLondonLow = not na(londonLow) and low < londonLow and close > londonLow | |
| sweepLondonHigh = not na(londonHigh) and high > londonHigh and close < londonHigh | |
| sweepPdl = low < pdl and close > pdl | |
| sweepPdh = high > pdh and close < pdh | |
| sweepPrevNyLow = not na(prevNyLow) and low < prevNyLow and close > prevNyLow | |
| sweepPrevNyHigh = not na(prevNyHigh) and high > prevNyHigh and close < prevNyHigh | |
| buySweep = sweepAsiaLow or sweepLondonLow or sweepPdl or sweepPrevNyLow | |
| sellSweep = sweepAsiaHigh or sweepLondonHigh or sweepPdh or sweepPrevNyHigh | |
| bullFvg = low > high[2] and low - high[2] >= atr * fvgAtrMult | |
| bearFvg = high < low[2] and low[2] - high >= atr * fvgAtrMult | |
| bullImpulse = close > open and close - open >= atr * obImpulseAtrM and close > emaFast and close > vwapValue | |
| bearImpulse = close < open and open - close >= atr * obImpulseAtrM and close < emaFast and close < vwapValue | |
| bullOb = bullImpulse and close[1] < open[1] | |
| bearOb = bearImpulse and close[1] > open[1] | |
| swingLow = ta.pivotlow(low, swingLen, swingLen) | |
| swingHigh = ta.pivothigh(high, swingLen, swingLen) | |
| srLow = ta.pivotlow(low, srLen, srLen) | |
| srHigh = ta.pivothigh(high, srLen, srLen) | |
| // ============================================================================ | |
| // ZONE ARRAYS (Pine v6 generic syntax) | |
| // ============================================================================ | |
| var buyBoxes = array.new<box>() | |
| var buyLabels = array.new<label>() | |
| var buyTops = array.new<float>() | |
| var buyBottoms = array.new<float>() | |
| var buyTypes = array.new<string>() | |
| var buyBorns = array.new<int>() | |
| var buyTouched = array.new<bool>() | |
| var sellBoxes = array.new<box>() | |
| var sellLabels = array.new<label>() | |
| var sellTops = array.new<float>() | |
| var sellBottoms = array.new<float>() | |
| var sellTypes = array.new<string>() | |
| var sellBorns = array.new<int>() | |
| var sellTouched = array.new<bool>() | |
| // ----- Zone add helpers (fixes the sequential-overwrite bug: | |
| // each detection now adds its OWN zone instead of clobbering the last) | |
| addBuyZone(float top, float bottom, string ztype) => | |
| mid = (top + bottom) / 2 | |
| far = hideFarZones and math.abs(close - mid) > atr * maxZoneDistanceAtr | |
| bool duplicate = false | |
| if array.size(buyTops) > 0 | |
| for i = 0 to array.size(buyTops) - 1 | |
| oldMid = (array.get(buyTops, i) + array.get(buyBottoms, i)) / 2 | |
| if math.abs(oldMid - mid) <= atr * duplicateAtr | |
| duplicate := true | |
| canAdd = not far and not duplicate and showXZones | |
| if canAdd | |
| zColor = str.contains(ztype, "OB") ? cBuyOb : str.contains(ztype, "Swing") ? cBuySwing : cBuy | |
| bx = box.new(bar_index - 2, top, bar_index + zoneProjection, bottom, | |
| bgcolor=color.new(zColor, 84), border_color=color.new(zColor, 15), border_width=2) | |
| lb = label.new(bar_index + 1, mid, ztype, style=label.style_label_left, | |
| textcolor=color.white, color=color.new(zColor, 10)) | |
| array.push(buyBoxes, bx) | |
| array.push(buyLabels, lb) | |
| array.push(buyTops, top) | |
| array.push(buyBottoms, bottom) | |
| array.push(buyTypes, ztype) | |
| array.push(buyBorns, bar_index) | |
| array.push(buyTouched, false) | |
| canAdd | |
| addSellZone(float top, float bottom, string ztype) => | |
| mid = (top + bottom) / 2 | |
| far = hideFarZones and math.abs(close - mid) > atr * maxZoneDistanceAtr | |
| bool duplicate = false | |
| if array.size(sellTops) > 0 | |
| for i = 0 to array.size(sellTops) - 1 | |
| oldMid = (array.get(sellTops, i) + array.get(sellBottoms, i)) / 2 | |
| if math.abs(oldMid - mid) <= atr * duplicateAtr | |
| duplicate := true | |
| canAdd = not far and not duplicate and showXZones | |
| if canAdd | |
| zColor = str.contains(ztype, "OB") ? cSellOb : str.contains(ztype, "Swing") ? cSellSwing : cSell | |
| bx = box.new(bar_index - 2, top, bar_index + zoneProjection, bottom, | |
| bgcolor=color.new(zColor, 84), border_color=color.new(zColor, 15), border_width=2) | |
| lb = label.new(bar_index + 1, mid, ztype, style=label.style_label_left, | |
| textcolor=color.white, color=color.new(zColor, 10)) | |
| array.push(sellBoxes, bx) | |
| array.push(sellLabels, lb) | |
| array.push(sellTops, top) | |
| array.push(sellBottoms, bottom) | |
| array.push(sellTypes, ztype) | |
| array.push(sellBorns, bar_index) | |
| array.push(sellTouched, false) | |
| canAdd | |
| // ----- Detection: every type independently (NOT cascading) | |
| if bullFvg | |
| addBuyZone(low, high[2], "BUY xZone FVG") | |
| if bullOb | |
| addBuyZone(high[1], low[1], "BUY xZone OB") | |
| if not na(swingLow) | |
| addBuyZone(swingLow + atr * swingZoneAtr, swingLow - atr * swingZoneAtr, "BUY xZone Swing (confirmed)") | |
| if bearFvg | |
| addSellZone(low[2], high, "SELL xZone FVG") | |
| if bearOb | |
| addSellZone(high[1], low[1], "SELL xZone OB") | |
| if not na(swingHigh) | |
| addSellZone(swingHigh + atr * swingZoneAtr, swingHigh - atr * swingZoneAtr, "SELL xZone Swing (confirmed)") | |
| // ----- Better eviction: combined distance + age score | |
| while array.size(buyBoxes) > maxZonesEachSide | |
| worstIndex = 0 | |
| worstScore = -1.0 | |
| for i = 0 to array.size(buyBoxes) - 1 | |
| mid = (array.get(buyTops, i) + array.get(buyBottoms, i)) / 2 | |
| dist = math.abs(close - mid) / math.max(atr, syminfo.mintick) | |
| age = (bar_index - array.get(buyBorns, i)) / math.max(1, zoneExpiry) | |
| sc = dist * 0.6 + age * 0.4 | |
| if sc > worstScore | |
| worstScore := sc | |
| worstIndex := i | |
| box.delete(array.get(buyBoxes, worstIndex)) | |
| label.delete(array.get(buyLabels, worstIndex)) | |
| array.remove(buyBoxes, worstIndex) | |
| array.remove(buyLabels, worstIndex) | |
| array.remove(buyTops, worstIndex) | |
| array.remove(buyBottoms, worstIndex) | |
| array.remove(buyTypes, worstIndex) | |
| array.remove(buyBorns, worstIndex) | |
| array.remove(buyTouched, worstIndex) | |
| while array.size(sellBoxes) > maxZonesEachSide | |
| worstIndex = 0 | |
| worstScore = -1.0 | |
| for i = 0 to array.size(sellBoxes) - 1 | |
| mid = (array.get(sellTops, i) + array.get(sellBottoms, i)) / 2 | |
| dist = math.abs(close - mid) / math.max(atr, syminfo.mintick) | |
| age = (bar_index - array.get(sellBorns, i)) / math.max(1, zoneExpiry) | |
| sc = dist * 0.6 + age * 0.4 | |
| if sc > worstScore | |
| worstScore := sc | |
| worstIndex := i | |
| box.delete(array.get(sellBoxes, worstIndex)) | |
| label.delete(array.get(sellLabels, worstIndex)) | |
| array.remove(sellBoxes, worstIndex) | |
| array.remove(sellLabels, worstIndex) | |
| array.remove(sellTops, worstIndex) | |
| array.remove(sellBottoms, worstIndex) | |
| array.remove(sellTypes, worstIndex) | |
| array.remove(sellBorns, worstIndex) | |
| array.remove(sellTouched, worstIndex) | |
| // ----- Zone maintenance / cleanup | |
| if array.size(buyBoxes) > 0 | |
| for i = array.size(buyBoxes) - 1 to 0 | |
| bx = array.get(buyBoxes, i) | |
| lb = array.get(buyLabels, i) | |
| top = array.get(buyTops, i) | |
| bottom = array.get(buyBottoms, i) | |
| mid = (top + bottom) / 2 | |
| born = array.get(buyBorns, i) | |
| touchedNow = low <= top and high >= bottom | |
| touchedEver = array.get(buyTouched, i) or touchedNow | |
| array.set(buyTouched, i, touchedEver) | |
| invalid = close < bottom | |
| expired = bar_index - born > zoneExpiry | |
| mitigated = touchedEver and close > top | |
| far = hideFarZones and math.abs(close - mid) > atr * maxZoneDistanceAtr | |
| remove = invalid or expired or (removeZoneAfterTouch and touchedNow) or (removeZoneAfterMitigation and mitigated) or far | |
| if remove | |
| box.delete(bx) | |
| label.delete(lb) | |
| array.remove(buyBoxes, i) | |
| array.remove(buyLabels, i) | |
| array.remove(buyTops, i) | |
| array.remove(buyBottoms, i) | |
| array.remove(buyTypes, i) | |
| array.remove(buyBorns, i) | |
| array.remove(buyTouched, i) | |
| else | |
| box.set_right(bx, bar_index + zoneProjection) | |
| label.set_x(lb, bar_index + 1) | |
| label.set_y(lb, mid) | |
| if array.size(sellBoxes) > 0 | |
| for i = array.size(sellBoxes) - 1 to 0 | |
| bx = array.get(sellBoxes, i) | |
| lb = array.get(sellLabels, i) | |
| top = array.get(sellTops, i) | |
| bottom = array.get(sellBottoms, i) | |
| mid = (top + bottom) / 2 | |
| born = array.get(sellBorns, i) | |
| touchedNow = high >= bottom and low <= top | |
| touchedEver = array.get(sellTouched, i) or touchedNow | |
| array.set(sellTouched, i, touchedEver) | |
| invalid = close > top | |
| expired = bar_index - born > zoneExpiry | |
| mitigated = touchedEver and close < bottom | |
| far = hideFarZones and math.abs(close - mid) > atr * maxZoneDistanceAtr | |
| remove = invalid or expired or (removeZoneAfterTouch and touchedNow) or (removeZoneAfterMitigation and mitigated) or far | |
| if remove | |
| box.delete(bx) | |
| label.delete(lb) | |
| array.remove(sellBoxes, i) | |
| array.remove(sellLabels, i) | |
| array.remove(sellTops, i) | |
| array.remove(sellBottoms, i) | |
| array.remove(sellTypes, i) | |
| array.remove(sellBorns, i) | |
| array.remove(sellTouched, i) | |
| else | |
| box.set_right(bx, bar_index + zoneProjection) | |
| label.set_x(lb, bar_index + 1) | |
| label.set_y(lb, mid) | |
| // ============================================================================ | |
| // SUPPORT / RESISTANCE | |
| // ============================================================================ | |
| var line supportLine = na | |
| var line resistanceLine = na | |
| var label supportLabel = na | |
| var label resistanceLabel= na | |
| var float supportLevel = na | |
| var float resistanceLevel= na | |
| if showSR and not na(srLow) | |
| line.delete(supportLine) | |
| label.delete(supportLabel) | |
| supportLevel := srLow | |
| supportLine := line.new(bar_index - srLen, supportLevel, bar_index + zoneProjection, supportLevel, | |
| extend=extend.right, color=color.new(cBuy, 10), width=2) | |
| supportLabel := label.new(bar_index + 1, supportLevel, "Support", | |
| style=label.style_label_left, textcolor=color.white, color=color.new(cBuy, 25)) | |
| if showSR and not na(srHigh) | |
| line.delete(resistanceLine) | |
| label.delete(resistanceLabel) | |
| resistanceLevel := srHigh | |
| resistanceLine := line.new(bar_index - srLen, resistanceLevel, bar_index + zoneProjection, resistanceLevel, | |
| extend=extend.right, color=color.new(cSell, 10), width=2) | |
| resistanceLabel := label.new(bar_index + 1, resistanceLevel, "Resistance", | |
| style=label.style_label_left, textcolor=color.white, color=color.new(cSell, 25)) | |
| if not na(supportLine) | |
| if close < supportLevel - atr * 0.15 | |
| line.delete(supportLine) | |
| label.delete(supportLabel) | |
| supportLine := na | |
| supportLabel := na | |
| supportLevel := na | |
| else | |
| label.set_x(supportLabel, bar_index + 1) | |
| label.set_y(supportLabel, supportLevel) | |
| if not na(resistanceLine) | |
| if close > resistanceLevel + atr * 0.15 | |
| line.delete(resistanceLine) | |
| label.delete(resistanceLabel) | |
| resistanceLine := na | |
| resistanceLabel := na | |
| resistanceLevel := na | |
| else | |
| label.set_x(resistanceLabel, bar_index + 1) | |
| label.set_y(resistanceLabel, resistanceLevel) | |
| // ============================================================================ | |
| // ACTIVE ZONE LOOKUP | |
| // ============================================================================ | |
| bool nearBuyZone = false | |
| bool nearSellZone = false | |
| float activeBuyTop = na | |
| float activeBuyBottom = na | |
| string activeBuyType = "Clear" | |
| float activeSellTop = na | |
| float activeSellBottom = na | |
| string activeSellType = "Clear" | |
| if array.size(buyBoxes) > 0 | |
| bestDist = 1e10 | |
| for i = 0 to array.size(buyBoxes) - 1 | |
| top = array.get(buyTops, i) | |
| bottom = array.get(buyBottoms, i) | |
| touching = low <= top and high >= bottom | |
| d = math.abs(close - ((top + bottom) / 2)) | |
| if touching | |
| nearBuyZone := true | |
| if d < bestDist | |
| bestDist := d | |
| activeBuyTop := top | |
| activeBuyBottom := bottom | |
| activeBuyType := array.get(buyTypes, i) | |
| if array.size(sellBoxes) > 0 | |
| bestDist = 1e10 | |
| for i = 0 to array.size(sellBoxes) - 1 | |
| top = array.get(sellTops, i) | |
| bottom = array.get(sellBottoms, i) | |
| touching = high >= bottom and low <= top | |
| d = math.abs(close - ((top + bottom) / 2)) | |
| if touching | |
| nearSellZone := true | |
| if d < bestDist | |
| bestDist := d | |
| activeSellTop := top | |
| activeSellBottom := bottom | |
| activeSellType := array.get(sellTypes, i) | |
| nearSupport = not na(supportLevel) and math.abs(close - supportLevel) <= atr * 0.35 | |
| nearResistance = not na(resistanceLevel) and math.abs(close - resistanceLevel) <= atr * 0.35 | |
| atPdl = low <= pdl and close >= pdl | |
| atPdh = high >= pdh and close <= pdh | |
| bullRejection = close > open and close > emaFast | |
| bearRejection = close < open and close < emaFast | |
| // ============================================================================ | |
| // SCORING (all weights configurable) | |
| // ============================================================================ | |
| buyScore = 0 | |
| buyScore += goldBull ? wGoldTrend : 0 | |
| buyScore += htfBull ? wHtfTrend : (htfRange and mode == "Fast" ? math.round(wHtfTrend * 0.33) : 0) | |
| buyScore += dxyBear ? wDxy : (dxyRejectHigh ? wDxyReject : (dxyFlat and mode == "Fast" ? 8 : 0)) | |
| buyScore += (nearBuyZone or atPdl or nearSupport) ? wZone : 0 | |
| buyScore += buySweep ? wSweep : 0 | |
| buyScore += close > vwapValue ? wVwap : 0 | |
| buyScore += bullRejection ? wRejCandle : 0 | |
| buyScore += sessionOk ? wSession : 0 | |
| buyScore -= chop ? pChop : 0 | |
| buyScore -= bigCandle ? pBigCandle : 0 | |
| buyScore -= dxyBull ? wDxy : 0 | |
| buyScore -= pauseTrading ? 100 : 0 | |
| sellScore = 0 | |
| sellScore += goldBear ? wGoldTrend : 0 | |
| sellScore += htfBear ? wHtfTrend : (htfRange and mode == "Fast" ? math.round(wHtfTrend * 0.33) : 0) | |
| sellScore += dxyBull ? wDxy : (dxyReclaimLow ? wDxyReject : (dxyFlat and mode == "Fast" ? 8 : 0)) | |
| sellScore += (nearSellZone or atPdh or nearResistance) ? wZone : 0 | |
| sellScore += sellSweep ? wSweep : 0 | |
| sellScore += close < vwapValue ? wVwap : 0 | |
| sellScore += bearRejection ? wRejCandle : 0 | |
| sellScore += sessionOk ? wSession : 0 | |
| sellScore -= chop ? pChop : 0 | |
| sellScore -= bigCandle ? pBigCandle : 0 | |
| sellScore -= dxyBear ? wDxy : 0 | |
| sellScore -= pauseTrading ? 100 : 0 | |
| buyPct = math.max(0, math.min(buyScore, 100)) | |
| sellPct = math.max(0, math.min(sellScore, 100)) | |
| // Diagnostic: lifetime max of each side, so user can verify both directions fire | |
| var int maxBuyPctEver = 0 | |
| var int maxSellPctEver = 0 | |
| maxBuyPctEver := math.max(maxBuyPctEver, buyPct) | |
| maxSellPctEver := math.max(maxSellPctEver, sellPct) | |
| buyWatch = buyPct >= confirmPct - watchOffset and buyPct < confirmPct and not pauseTrading | |
| sellWatch = sellPct >= confirmPct - watchOffset and sellPct < confirmPct and not pauseTrading | |
| buyConfirmed = barstate.isconfirmed and buyPct >= confirmPct and not pauseTrading | |
| sellConfirmed= barstate.isconfirmed and sellPct >= confirmPct and not pauseTrading | |
| // ============================================================================ | |
| // PLAN (entry / SL / TP) with non-destructive structural clamping | |
| // ============================================================================ | |
| buyEntry = nearBuyZone ? activeBuyTop : close | |
| buyStop = nearBuyZone ? (activeBuyBottom - atr * slBufferAtr) : (buySweep ? (low - atr * slBufferAtr) : (close - atr * fallbackStopAtr)) | |
| buyRisk = buyEntry - buyStop | |
| sellEntry = nearSellZone ? activeSellBottom : close | |
| sellStop = nearSellZone ? (activeSellTop + atr * slBufferAtr) : (sellSweep ? (high + atr * slBufferAtr) : (close + atr * fallbackStopAtr)) | |
| sellRisk = sellStop - sellEntry | |
| float buyTp1 = na | |
| float buyTp2 = na | |
| float sellTp1 = na | |
| float sellTp2 = na | |
| if buyRisk > syminfo.mintick | |
| buyTp1 := buyEntry + buyRisk * tp1R | |
| buyTp2 := buyEntry + buyRisk * tp2R | |
| structThr = structuralClampOnlyBeyond1R ? (buyEntry + buyRisk) : buyEntry | |
| if not na(vwapValue) and vwapValue > structThr and vwapValue < buyTp1 | |
| buyTp1 := vwapValue | |
| if not na(asiaHigh) and asiaHigh > structThr and asiaHigh < buyTp2 | |
| buyTp2 := asiaHigh | |
| if not na(londonHigh) and londonHigh > structThr and londonHigh < buyTp2 | |
| buyTp2 := londonHigh | |
| if pdh > structThr and pdh < buyTp2 | |
| buyTp2 := pdh | |
| if sellRisk > syminfo.mintick | |
| sellTp1 := sellEntry - sellRisk * tp1R | |
| sellTp2 := sellEntry - sellRisk * tp2R | |
| structThr = structuralClampOnlyBeyond1R ? (sellEntry - sellRisk) : sellEntry | |
| if not na(vwapValue) and vwapValue < structThr and vwapValue > sellTp1 | |
| sellTp1 := vwapValue | |
| if not na(asiaLow) and asiaLow < structThr and asiaLow > sellTp2 | |
| sellTp2 := asiaLow | |
| if not na(londonLow) and londonLow < structThr and londonLow > sellTp2 | |
| sellTp2 := londonLow | |
| if pdl < structThr and pdl > sellTp2 | |
| sellTp2 := pdl | |
| // Reject signals with risk smaller than minRiskPoints | |
| buyRiskOk = buyRisk >= minRiskPoints | |
| sellRiskOk = sellRisk >= minRiskPoints | |
| // ============================================================================ | |
| // TRADE LOCKING | |
| // ============================================================================ | |
| var int tradeSide = 0 | |
| var int tradeBar = na | |
| var float lockedEntry = na | |
| var float lockedStop = na | |
| var float lockedTp1 = na | |
| var float lockedTp2 = na | |
| var int lockedPct = na | |
| var string lockedReason = "Clear" | |
| newBuyTrade = buyConfirmed and buyRiskOk and tradeSide != 1 | |
| newSellTrade = sellConfirmed and sellRiskOk and tradeSide != -1 | |
| if newBuyTrade | |
| tradeSide := 1 | |
| tradeBar := bar_index | |
| lockedEntry := buyEntry | |
| lockedStop := buyStop | |
| lockedTp1 := buyTp1 | |
| lockedTp2 := buyTp2 | |
| lockedPct := buyPct | |
| lockedReason := nearBuyZone ? activeBuyType : (buySweep ? "Liquidity Sweep" : (atPdl ? "PDL" : (nearSupport ? "Support" : "Momentum"))) | |
| if newSellTrade | |
| tradeSide := -1 | |
| tradeBar := bar_index | |
| lockedEntry := sellEntry | |
| lockedStop := sellStop | |
| lockedTp1 := sellTp1 | |
| lockedTp2 := sellTp2 | |
| lockedPct := sellPct | |
| lockedReason := nearSellZone ? activeSellType : (sellSweep ? "Liquidity Sweep" : (atPdh ? "PDH" : (nearResistance ? "Resistance" : "Momentum"))) | |
| // ----- Less twitchy exits: require VWAP *and* EMA breach (was 'or'), | |
| // and stable DXY flip across two bars instead of one | |
| exitBuy = tradeSide == 1 and bar_index > tradeBar and (sellPct >= confirmPct or (close < vwapValue and close < emaFast) or dxyBullStable) | |
| exitSell = tradeSide == -1 and bar_index > tradeBar and (buyPct >= confirmPct or (close > vwapValue and close > emaFast) or dxyBearStable) | |
| if exitBuy or exitSell | |
| tradeSide := 0 | |
| // ============================================================================ | |
| // ADVICE | |
| // ============================================================================ | |
| advice = exitBuy ? "EXIT BUY" : exitSell ? "EXIT SELL" : | |
| newBuyTrade ? "BUY NOW" : newSellTrade ? "SELL NOW" : | |
| buyWatch ? "BUY WATCH" : sellWatch ? "SELL WATCH" : | |
| tradeSide == 1 ? "HOLD BUY" : tradeSide == -1 ? "HOLD SELL" : | |
| pauseTrading ? "PAUSED" : | |
| buyPct > sellPct and buyPct >= 50 ? "BUY BIAS" : | |
| sellPct > buyPct and sellPct >= 50 ? "SELL BIAS" : "WAIT" | |
| adviceColor = str.contains(advice, "BUY") ? cBuy : str.contains(advice, "SELL") ? cSell : | |
| str.contains(advice, "EXIT") ? cWarn : color.gray | |
| advicePct = str.contains(advice, "BUY") ? buyPct : str.contains(advice, "SELL") ? sellPct : math.max(buyPct, sellPct) | |
| planSide = tradeSide != 0 ? tradeSide : (str.contains(advice, "BUY") ? 1 : (str.contains(advice, "SELL") ? -1 : 0)) | |
| planEntry = tradeSide != 0 ? lockedEntry : (planSide == 1 ? buyEntry : (planSide == -1 ? sellEntry : na)) | |
| planStop = tradeSide != 0 ? lockedStop : (planSide == 1 ? buyStop : (planSide == -1 ? sellStop : na)) | |
| planTp1 = tradeSide != 0 ? lockedTp1 : (planSide == 1 ? buyTp1 : (planSide == -1 ? sellTp1 : na)) | |
| planTp2 = tradeSide != 0 ? lockedTp2 : (planSide == 1 ? buyTp2 : (planSide == -1 ? sellTp2 : na)) | |
| planPct = tradeSide != 0 ? lockedPct : (planSide == 1 ? buyPct : (planSide == -1 ? sellPct : na)) | |
| // R:R for display | |
| float planRR = na | |
| if planSide == 1 and not na(planEntry) and not na(planStop) and not na(planTp2) | |
| rk = planEntry - planStop | |
| rw = planTp2 - planEntry | |
| if rk > 0 | |
| planRR := rw / rk | |
| if planSide == -1 and not na(planEntry) and not na(planStop) and not na(planTp2) | |
| rk = planStop - planEntry | |
| rw = planEntry - planTp2 | |
| if rk > 0 | |
| planRR := rw / rk | |
| // ============================================================================ | |
| // LIVE PLAN RENDERING | |
| // ============================================================================ | |
| var label adviceLabel = na | |
| var line entryLine = na | |
| var line stopLine = na | |
| var line tp1Line = na | |
| var line tp2Line = na | |
| var label entryLabel = na | |
| var label stopLabel = na | |
| var label tp1Label = na | |
| var label tp2Label = na | |
| var label beNoteLabel = na | |
| if barstate.islast | |
| label.delete(adviceLabel) | |
| line.delete(entryLine) | |
| line.delete(stopLine) | |
| line.delete(tp1Line) | |
| line.delete(tp2Line) | |
| label.delete(entryLabel) | |
| label.delete(stopLabel) | |
| label.delete(tp1Label) | |
| label.delete(tp2Label) | |
| label.delete(beNoteLabel) | |
| if showLiveAdvice | |
| adviceY = planSide == 1 ? low - atr * 0.6 : high + atr * 0.6 | |
| adviceStyle = planSide == 1 ? label.style_label_up : label.style_label_down | |
| adviceLabel := label.new(bar_index, adviceY, advice + " " + str.tostring(advicePct) + "%", | |
| style=adviceStyle, textcolor=color.white, color=color.new(adviceColor, 0)) | |
| if showLivePlan and planSide != 0 and not na(planEntry) and not na(planStop) and not na(planTp1) and not na(planTp2) | |
| planColor = planSide == 1 ? cBuy : cSell | |
| stopColor = planSide == 1 ? cSell : cBuy | |
| planText = (planSide == 1 ? "BUY " : "SELL ") + str.tostring(planPct) + "%" | |
| rrText = na(planRR) ? "" : " (" + str.tostring(planRR, "#.##") + "R)" | |
| entryLine := line.new(bar_index, planEntry, bar_index + zoneProjection, planEntry, width=2, color=color.new(planColor, 0)) | |
| stopLine := line.new(bar_index, planStop, bar_index + zoneProjection, planStop, width=2, color=color.new(stopColor, 0)) | |
| tp1Line := line.new(bar_index, planTp1, bar_index + zoneProjection, planTp1, width=2, color=color.new(planColor, 25)) | |
| tp2Line := line.new(bar_index, planTp2, bar_index + zoneProjection, planTp2, width=2, color=color.new(planColor, 45)) | |
| entryLabel := label.new(bar_index + zoneProjection, planEntry, planText + " ENTRY" + rrText, style=label.style_label_left, textcolor=color.white, color=color.new(planColor, 0)) | |
| stopLabel := label.new(bar_index + zoneProjection, planStop, "SL", style=label.style_label_left, textcolor=color.white, color=color.new(stopColor, 0)) | |
| tp1Label := label.new(bar_index + zoneProjection, planTp1, "TP1", style=label.style_label_left, textcolor=color.white, color=color.new(planColor, 25)) | |
| tp2Label := label.new(bar_index + zoneProjection, planTp2, "TP2", style=label.style_label_left, textcolor=color.white, color=color.new(planColor, 45)) | |
| if showBeNote | |
| beY = (planTp1 + planEntry) / 2 | |
| beNoteLabel := label.new(bar_index + zoneProjection, beY, "→ Move SL to BE @ TP1", | |
| style=label.style_label_left, textcolor=color.white, color=color.new(color.gray, 20), size=size.small) | |
| // ============================================================================ | |
| // HISTORICAL SIGNAL MARKERS (so you can SEE every past trigger, not just live) | |
| // ============================================================================ | |
| plotshape(showHistorical and newBuyTrade, "BUY NOW", shape.triangleup, location.belowbar, color.new(cBuy, 0), size=size.small, text="BUY", textcolor=color.white) | |
| plotshape(showHistorical and newSellTrade, "SELL NOW", shape.triangledown, location.abovebar, color.new(cSell, 0), size=size.small, text="SELL", textcolor=color.white) | |
| plotshape(showHistorical and buyWatch, "BUY WATCH", shape.circle, location.belowbar, color.new(cBuy, 50), size=size.tiny) | |
| plotshape(showHistorical and sellWatch, "SELL WATCH", shape.circle, location.abovebar, color.new(cSell, 50), size=size.tiny) | |
| plotshape(showHistorical and exitBuy, "EXIT BUY", shape.xcross, location.abovebar, color.new(cWarn, 0), size=size.tiny) | |
| plotshape(showHistorical and exitSell, "EXIT SELL", shape.xcross, location.belowbar, color.new(cWarn, 0), size=size.tiny) | |
| // ============================================================================ | |
| // DASHBOARD (compact 7-row layout) | |
| // ============================================================================ | |
| zoneText = nearBuyZone ? activeBuyType : (nearSellZone ? activeSellType : | |
| (buySweep ? "Buy Sweep" : (sellSweep ? "Sell Sweep" : | |
| (atPdl ? "PDL" : (atPdh ? "PDH" : | |
| (nearSupport ? "Support" : (nearResistance ? "Resistance" : "Clear"))))))) | |
| sessionText = inLondonKZ ? "Lon KZ" : (inNYKZ ? "NY KZ" : | |
| (inAsia ? "Asia" : (inLondon ? "London" : (inNY ? "NY" : "Off")))) | |
| filterText = pauseTrading ? "Paused" : (chop ? "Chop" : | |
| (bigCandle ? "Extd" : (sessionOk ? "OK" : "Weak"))) | |
| // Friendly HTF label (60→1h, 240→4h) | |
| htfDisplay = htfTf == "60" ? "1h" : htfTf == "240" ? "4h" : htfTf + "m" | |
| // Compact merged strings | |
| goldShort = goldBull ? "Bull" : (goldBear ? "Bear" : "Rng") | |
| htfShort = htfBull ? "Bull" : (htfBear ? "Bear" : "Rng") | |
| dxyShort = not dxyOk ? "$?" : (dxyBull ? "$+" : (dxyBear ? "$-" : "$=")) | |
| trendCell = goldShort + " / " + htfShort + " " + htfDisplay + " / " + dxyShort | |
| sessCell = sessionText + " · " + filterText | |
| zoneCell = zoneText + " (" + str.tostring(array.size(buyBoxes)) + "B/" + str.tostring(array.size(sellBoxes)) + "S)" | |
| scoreCell = str.tostring(buyPct) + "% ▲ / " + str.tostring(sellPct) + "% ▼" | |
| peakCell = str.tostring(maxBuyPctEver) + "% ▲ / " + str.tostring(maxSellPctEver) + "% ▼" | |
| adviceArrow = str.contains(advice, "BUY") ? "▲ " : str.contains(advice, "SELL") ? "▼ " : str.contains(advice, "EXIT") ? "✕ " : "• " | |
| adviceCell = adviceArrow + advice + " " + str.tostring(advicePct) + "%" | |
| planCell = (na(planRR) ? "—" : str.tostring(planRR, "#.##") + "R") + " · " + (tradeSide == 1 ? "▲ Long" : (tradeSide == -1 ? "▼ Short" : "• Flat")) + (lockedReason != "Clear" and tradeSide != 0 ? " (" + lockedReason + ")" : "") | |
| // Dominance tint for the scores cell — strong enough alpha to be visible in dark mode | |
| scoreBg = buyPct > sellPct ? color.new(cBuy, 55) : (sellPct > buyPct ? color.new(cSell, 55) : color.new(color.gray, 70)) | |
| adviceBg = color.new(adviceColor, 30) | |
| planTextColor = tradeSide == 1 ? cBuy : (tradeSide == -1 ? cSell : cTextDim) | |
| var table dash = table.new(position.top_right, 2, 7, border_width=1, frame_color=color.new(color.gray, 40), frame_width=1) | |
| if barstate.islast and showDashboard | |
| // Advice (most important — biggest text, strongest highlight) | |
| table.cell(dash, 0, 0, "Advice", text_color=cTextDim, text_size=size.small, text_halign=text.align_left) | |
| table.cell(dash, 1, 0, adviceCell, text_color=cTextHi, text_size=size.normal, text_halign=text.align_right, bgcolor=adviceBg) | |
| // Plan (R:R + position) | |
| table.cell(dash, 0, 1, "Plan", text_color=cTextDim, text_size=size.small, text_halign=text.align_left) | |
| table.cell(dash, 1, 1, planCell, text_color=planTextColor, text_size=size.small, text_halign=text.align_right) | |
| // Scores (live) | |
| table.cell(dash, 0, 2, "Scores", text_color=cTextDim, text_size=size.small, text_halign=text.align_left) | |
| table.cell(dash, 1, 2, scoreCell, text_color=cTextHi, text_size=size.small, text_halign=text.align_right, bgcolor=scoreBg) | |
| // Peak (lifetime) | |
| table.cell(dash, 0, 3, "Peak", text_color=cTextDim, text_size=size.small, text_halign=text.align_left) | |
| table.cell(dash, 1, 3, peakCell, text_color=cTextHi, text_size=size.small, text_halign=text.align_right) | |
| // Zone + counts | |
| table.cell(dash, 0, 4, "Zone", text_color=cTextDim, text_size=size.small, text_halign=text.align_left) | |
| table.cell(dash, 1, 4, zoneCell, text_color=cTextHi, text_size=size.small, text_halign=text.align_right) | |
| // Trend (Gold/HTF/DXY) | |
| table.cell(dash, 0, 5, "Trend", text_color=cTextDim, text_size=size.small, text_halign=text.align_left) | |
| table.cell(dash, 1, 5, trendCell, text_color=cTextHi, text_size=size.small, text_halign=text.align_right) | |
| // Session + filter | |
| table.cell(dash, 0, 6, "Session", text_color=cTextDim, text_size=size.small, text_halign=text.align_left) | |
| table.cell(dash, 1, 6, sessCell, text_color=cTextHi, text_size=size.small, text_halign=text.align_right) | |
| // ============================================================================ | |
| // ALERTS | |
| // ============================================================================ | |
| alertcondition(buyWatch, "XAUUSD BUY WATCH", "BUY WATCH forming.") | |
| alertcondition(sellWatch, "XAUUSD SELL WATCH", "SELL WATCH forming.") | |
| alertcondition(newBuyTrade, "XAUUSD BUY NOW", "Confirmed BUY NOW.") | |
| alertcondition(newSellTrade,"XAUUSD SELL NOW", "Confirmed SELL NOW.") | |
| alertcondition(exitBuy, "XAUUSD EXIT BUY", "Exit BUY: conditions changed.") | |
| alertcondition(exitSell, "XAUUSD EXIT SELL", "Exit SELL: conditions changed.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment