# indie:lang_version = 5 from math import nan, isnan from indie import indicator, param, color, plot, MainContext, Optional, line_style, Color, Var from indie.algorithms import Atr, PivotHighLow from indie.drawings import LabelAbs, LineSegment, Rectangle, AbsolutePosition, callout_position from indie.color import rgba
# ─── label font-size mapping ────────────────────────────────────────────────── _FONT_TINY = 8 _FONT_SMALL = 10 _FONT_NORMAL = 12 _FONT_LARGE = 16
def _label_font(size_str: str) -> int: if size_str == "Tiny": return _FONT_TINY if size_str == "Small": return _FONT_SMALL if size_str == "Large": return _FONT_LARGE return _FONT_NORMAL
# ─── liquidity line extend (≈4 months in seconds) ──────────────────────────── _LINE_EXTEND_SEC = 10_000_000.0 # ─── fallback bar duration when only 1 bar available ───────────────────────── _BAR_DUR_FALLBACK = 60.0 # ─── pool sizes ─────────────────────────────────────────────────────────────── _OB_POOL = 20 _FVG_POOL = 30
@indicator('SMC Sniper Indicator v5', overlay_main_pane=True)
# ── Market Structure ────────────────────────────────────────────────────────── @param.bool('showStructure', default=True, title='Market Structure - Show BOS / CHoCH') @param.bool('showSwing', default=True, title='Market Structure - Show Swing High/Low') @param.int( 'swingLen', default=5, min=2, max=50, title='Market Structure - Swing Length') @param.str( 'structureText', default='Small', options=['Tiny', 'Small', 'Normal', 'Large'], title='Market Structure - Label Size') @param.bool('showSweep', default=True, title='Market Structure - Show Liquidity Sweeps') @param.bool('showLevels', default=True, title='Market Structure - Extend Swing Liquidity Levels')
# ── Order Blocks ────────────────────────────────────────────────────────────── @param.bool( 'showOB', default=True, title='Order Blocks - Show Order Blocks') @param.int( 'obCount', default=5, min=1, max=20, title='Order Blocks - Recent Order Blocks') @param.int( 'obLookback', default=12, min=2, max=50, title='Order Blocks - Search Candle Lookback') @param.int( 'obExtend', default=30, min=5, max=200, title='Order Blocks - Extend Bars') @param.bool( 'obUseBody', default=False, title='Order Blocks - Use Candle Body') @param.bool( 'showBullOBLabel', default=True, title='Order Blocks - Show Bull OB Label') @param.bool( 'showBearOBLabel', default=True, title='Order Blocks - Show Bear OB Label') @param.color('bullOBColor', default=color.rgba(8, 153, 129, 0.18), title='Order Blocks - Bullish OB Color') @param.color('bearOBColor', default=color.rgba(242, 54, 69, 0.18), title='Order Blocks - Bearish OB Color') @param.color('bullOBLabelColor', default=color.rgba(8, 153, 129, 0.7), title='Order Blocks - Bull OB Label Color') @param.color('bearOBLabelColor', default=color.rgba(242, 54, 69, 0.7), title='Order Blocks - Bear OB Label Color') @param.color('bullOBBorderColor', default=color.rgba(8, 153, 129, 0.65), title='Order Blocks - Bull OB Border Color') @param.color('bearOBBorderColor', default=color.rgba(242, 54, 69, 0.65), title='Order Blocks - Bear OB Border Color')
# ── Fair Value Gaps ─────────────────────────────────────────────────────────── @param.bool( 'showFVG', default=True, title='Fair Value Gaps - Show FVG') @param.int( 'fvgCount', default=8, min=1, max=30, title='Fair Value Gaps - Recent FVGs') @param.int( 'fvgExtend', default=25, min=3, max=200, title='Fair Value Gaps - Extend Bars') @param.float('fvgMinATR', default=0.05, min=0.0, step=0.01, title='Fair Value Gaps - Minimum Gap / ATR') @param.bool( 'showBullFVGLabel', default=True, title='Fair Value Gaps - Show Bull FVG Label') @param.bool( 'showBearFVGLabel', default=True, title='Fair Value Gaps - Show Bear FVG Label') @param.color('bullFVGColor', default=color.rgba(0, 191, 165, 0.16), title='Fair Value Gaps - Bullish FVG Color') @param.color('bearFVGColor', default=color.rgba(255, 82, 82, 0.16), title='Fair Value Gaps - Bearish FVG Color') @param.color('bullFVGLabelColor', default=color.rgba(8, 153, 129, 0.7), title='Fair Value Gaps - Bull FVG Label Color') @param.color('bearFVGLabelColor', default=color.rgba(242, 54, 69, 0.7), title='Fair Value Gaps - Bear FVG Label Color') @param.color('bullFVGBorderColor', default=color.rgba(0, 191, 165, 0.65), title='Fair Value Gaps - Bull FVG Border Color') @param.color('bearFVGBorderColor', default=color.rgba(255, 82, 82, 0.65), title='Fair Value Gaps - Bear FVG Border Color') @param.str('zoneText', default='Small', options=['Tiny', 'Small', 'Normal', 'Large'], title='Order Blocks & FVG - Label Size')
# ── Visibility ──────────────────────────────────────────────────────────────── @param.bool('colorBars', default=False, title='Visibility - Color Trend Candles') @param.bool('showTrend', default=True, title='Visibility - Show Trend Status') @param.bool('showSignals', default=True, title='Visibility - Show Entry Confirmation')
# ── Entry Filters ───────────────────────────────────────────────────────────── @param.bool('requireSweep', default=True, title='Entry Filters - Require Liquidity Sweep') @param.int( 'sweepWindow', default=5, min=1, max=20, title='Entry Filters - Sweep Lookback Bars') @param.bool('requireRetest', default=True, title='Entry Filters - Require OB / FVG Retest') @param.int( 'signalWindow', default=3, min=1, max=10, title='Entry Filters - Signal Window (bars after BOS)') @param.bool('requireCandleConfirm', default=True, title='Entry Filters - Require Candle Confirmation (engulf/close)')
# ── Trend state line ────────────────────────────────────────────────────────── @plot.line('Trend State', color=color.TRANSPARENT)
# ── Entry confirmation markers ──────────────────────────────────────────────── @plot.marker('BUY Confirmation', style=plot.marker_style.CIRCLE, position=plot.marker_position.BELOW, color=color.GREEN, size=3) @plot.marker('SELL Confirmation', style=plot.marker_style.CIRCLE, position=plot.marker_position.ABOVE, color=color.RED, size=3)
# ── Bar coloring ────────────────────────────────────────────────────────────── @plot.bar_color()
class Main(MainContext): def __init__(self, showStructure, showSwing, swingLen, structureText, showSweep, showLevels, showOB, obCount, obLookback, obExtend, obUseBody, showBullOBLabel, showBearOBLabel, bullOBColor, bearOBColor, bullOBLabelColor, bearOBLabelColor, bullOBBorderColor, bearOBBorderColor, showFVG, fvgCount, fvgExtend, fvgMinATR, showBullFVGLabel, showBearFVGLabel, bullFVGColor, bearFVGColor, bullFVGLabelColor, bearFVGLabelColor, bullFVGBorderColor, bearFVGBorderColor, zoneText, colorBars, showTrend, showSignals, requireSweep, sweepWindow, requireRetest, signalWindow, requireCandleConfirm): # swing state self._lastHigh = nan self._lastLow = nan self._lastHighBar = 0 self._lastLowBar = 0 self._prevHigh = nan self._prevLow = nan self._trend = 0
# pool init flag (pre-allocation happens once in first calc) self._poolsReady = False
# ── OB pools — pre-allocated rectangles + labels + parallel state lists self._bullOBRects: list[Rectangle] = [] self._bullOBLabels: list[LabelAbs] = [] self._bullOBTop: list[float] = [] self._bullOBBot: list[float] = [] self._bullOBActive: list[bool] = [] self._bullOBHead = 0 # round-robin write pointer
self._bearOBRects: list[Rectangle] = [] self._bearOBLabels: list[LabelAbs] = [] self._bearOBTop: list[float] = [] self._bearOBBot: list[float] = [] self._bearOBActive: list[bool] = [] self._bearOBHead = 0
# ── FVG pools — pre-allocated rectangles + labels + parallel state lists self._bullFVGRects: list[Rectangle] = [] self._bullFVGLabels: list[LabelAbs] = [] self._bullFVGTop: list[float] = [] self._bullFVGBot: list[float] = [] self._bullFVGActive: list[bool] = [] self._bullFVGHead = 0
self._bearFVGRects: list[Rectangle] = [] self._bearFVGLabels: list[LabelAbs] = [] self._bearFVGTop: list[float] = [] self._bearFVGBot: list[float] = [] self._bearFVGActive: list[bool] = [] self._bearFVGHead = 0
# sweep bar tracking self._lastBullSweepBar = -999 self._lastBearSweepBar = -999
def _hide_ob(self, rect: Rectangle, label: LabelAbs) -> None: rect.bg_color = color.TRANSPARENT rect.line_color = color.TRANSPARENT label.text = '' self.chart.draw(rect) self.chart.draw(label)
def _hide_fvg(self, rect: Rectangle, label: LabelAbs) -> None: rect.bg_color = color.TRANSPARENT rect.line_color = color.TRANSPARENT label.text = '' self.chart.draw(rect) self.chart.draw(label)
def _init_pools(self) -> None: hidden_a = AbsolutePosition(0.0, 0.0) hidden_b = AbsolutePosition(1.0, 0.0) hidden_lbl_pos = AbsolutePosition(0.0, 0.0) i = 0 while i < _OB_POOL: self._bullOBRects.append(Rectangle(hidden_a, hidden_b, bg_color=color.TRANSPARENT, line_color=color.TRANSPARENT, line_width=1)) self._bullOBLabels.append(LabelAbs('', hidden_lbl_pos, font_size=_FONT_TINY, text_color=color.WHITE, bg_color=color.TRANSPARENT, callout_position=callout_position.BOTTOM_RIGHT)) self._bullOBTop.append(0.0) self._bullOBBot.append(0.0) self._bullOBActive.append(False)
self._bearOBRects.append(Rectangle(hidden_a, hidden_b, bg_color=color.TRANSPARENT, line_color=color.TRANSPARENT, line_width=1)) self._bearOBLabels.append(LabelAbs('', hidden_lbl_pos, font_size=_FONT_TINY, text_color=color.WHITE, bg_color=color.TRANSPARENT, callout_position=callout_position.TOP_RIGHT)) self._bearOBTop.append(0.0) self._bearOBBot.append(0.0) self._bearOBActive.append(False) i = i + 1
j = 0 while j < _FVG_POOL: self._bullFVGRects.append(Rectangle(hidden_a, hidden_b, bg_color=color.TRANSPARENT, line_color=color.TRANSPARENT, line_width=1)) self._bullFVGLabels.append(LabelAbs('', hidden_lbl_pos, font_size=_FONT_TINY, text_color=color.WHITE, bg_color=color.TRANSPARENT, callout_position=callout_position.BOTTOM_RIGHT)) self._bullFVGTop.append(0.0) self._bullFVGBot.append(0.0) self._bullFVGActive.append(False)
self._bearFVGRects.append(Rectangle(hidden_a, hidden_b, bg_color=color.TRANSPARENT, line_color=color.TRANSPARENT, line_width=1)) self._bearFVGLabels.append(LabelAbs('', hidden_lbl_pos, font_size=_FONT_TINY, text_color=color.WHITE, bg_color=color.TRANSPARENT, callout_position=callout_position.TOP_RIGHT)) self._bearFVGTop.append(0.0) self._bearFVGBot.append(0.0) self._bearFVGActive.append(False) j = j + 1
def calc(self, showStructure, showSwing, swingLen, structureText, showSweep, showLevels, showOB, obCount, obLookback, obExtend, obUseBody, showBullOBLabel, showBearOBLabel, bullOBColor, bearOBColor, bullOBLabelColor, bearOBLabelColor, bullOBBorderColor, bearOBBorderColor, showFVG, fvgCount, fvgExtend, fvgMinATR, showBullFVGLabel, showBearFVGLabel, bullFVGColor, bearFVGColor, bullFVGLabelColor, bearFVGLabelColor, bullFVGBorderColor, bearFVGBorderColor, zoneText, colorBars, showTrend, showSignals, requireSweep, sweepWindow, requireRetest, signalWindow, requireCandleConfirm):
# ── One-time pool pre-allocation ────────────────────────────────────── if not self._poolsReady: self._init_pools() self._poolsReady = True
# ── Var-backed liquidity lines (rollback-safe) ──────────────────────── high_line_var = Var[Optional[LineSegment]].new(None) low_line_var = Var[Optional[LineSegment]].new(None)
# ── ATR ─────────────────────────────────────────────────────────────── atr_val = Atr.new(14)[0]
# ── Bar duration for extend calculations ────────────────────────────── bar_dur = _BAR_DUR_FALLBACK if self.bar_index > 0: bar_dur = self.time[0] - self.time[1] if bar_dur <= 0.0: bar_dur = _BAR_DUR_FALLBACK ob_extend_sec = float(obExtend) * bar_dur fvg_extend_sec = float(fvgExtend) * bar_dur
# ── Pivot detection ─────────────────────────────────────────────────── ph, _ = PivotHighLow.new(self.high, left_bars=swingLen, right_bars=swingLen) _, pl = PivotHighLow.new(self.low, left_bars=swingLen, right_bars=swingLen) font_sz = _label_font(structureText) zone_font_sz = _label_font(zoneText)
# ── Swing high confirmed ────────────────────────────────────────────── if not isnan(ph[0]): self._prevHigh = self._lastHigh self._lastHigh = self.high[swingLen] self._lastHighBar = self.bar_index - swingLen pivot_time_h = self.time[swingLen]
if showSwing: self.chart.draw(LabelAbs( 'SH', AbsolutePosition(pivot_time_h, self._lastHigh), font_size=_FONT_TINY, text_color=color.WHITE, bg_color=rgba(220, 50, 50, 0.55), callout_position=callout_position.BOTTOM_LEFT, ))
if showLevels: # erase old line if one exists (Var rolls back with chart) if high_line_var.get() is not None: self.chart.erase(high_line_var.get().value()) new_seg = LineSegment( AbsolutePosition(pivot_time_h, self._lastHigh), AbsolutePosition(self.time[0] + _LINE_EXTEND_SEC, self._lastHigh), color=rgba(220, 50, 50, 0.65), line_style=line_style.DASHED, line_width=1, ) high_line_var.set(Optional[LineSegment](new_seg)) self.chart.draw(new_seg)
# ── Swing low confirmed ─────────────────────────────────────────────── if not isnan(pl[0]): self._prevLow = self._lastLow self._lastLow = self.low[swingLen] self._lastLowBar = self.bar_index - swingLen pivot_time_l = self.time[swingLen]
if showSwing: self.chart.draw(LabelAbs( 'SL', AbsolutePosition(pivot_time_l, self._lastLow), font_size=_FONT_TINY, text_color=color.WHITE, bg_color=rgba(50, 180, 50, 0.55), callout_position=callout_position.TOP_LEFT, ))
if showLevels: # erase old line if one exists (Var rolls back with chart) if low_line_var.get() is not None: self.chart.erase(low_line_var.get().value()) new_seg = LineSegment( AbsolutePosition(pivot_time_l, self._lastLow), AbsolutePosition(self.time[0] + _LINE_EXTEND_SEC, self._lastLow), color=rgba(50, 180, 50, 0.65), line_style=line_style.DASHED, line_width=1, ) low_line_var.set(Optional[LineSegment](new_seg)) self.chart.draw(new_seg)
# ── BOS / CHoCH ─────────────────────────────────────────────────────── bull_break = False bear_break = False
if not isnan(self._lastHigh): bull_break = self.close[1] <= self._lastHigh and self.close[0] > self._lastHigh
if not isnan(self._lastLow): bear_break = self.close[1] >= self._lastLow and self.close[0] < self._lastLow
bull_choch = bull_break and self._trend == -1 bear_choch = bear_break and self._trend == 1
if bull_break: self._trend = 1 if bear_break: self._trend = -1
if showStructure and bull_break: lbl_text = 'CHoCH +' if bull_choch else 'BOS +' self.chart.draw(LabelAbs( lbl_text, AbsolutePosition(self.time[0], self.low[0]), font_size=font_sz, text_color=color.WHITE, bg_color=rgba(8, 153, 129, 0.90), callout_position=callout_position.TOP_LEFT, ))
if showStructure and bear_break: lbl_text = 'CHoCH -' if bear_choch else 'BOS -' self.chart.draw(LabelAbs( lbl_text, AbsolutePosition(self.time[0], self.high[0]), font_size=font_sz, text_color=color.WHITE, bg_color=rgba(242, 54, 69, 0.90), callout_position=callout_position.BOTTOM_LEFT, ))
# ── Liquidity sweeps ────────────────────────────────────────────────── if not isnan(self._lastHigh): if self.high[0] > self._lastHigh and self.close[0] < self._lastHigh: self._lastBullSweepBar = self.bar_index if showSweep: self.chart.draw(LabelAbs( 'BSL SWEEP', AbsolutePosition(self.time[0], self.high[0]), font_size=_FONT_TINY, text_color=color.WHITE, bg_color=rgba(255, 152, 0, 1.0), callout_position=callout_position.BOTTOM_LEFT, ))
if not isnan(self._lastLow): if self.low[0] < self._lastLow and self.close[0] > self._lastLow: self._lastBearSweepBar = self.bar_index if showSweep: self.chart.draw(LabelAbs( 'SSL SWEEP', AbsolutePosition(self.time[0], self.low[0]), font_size=_FONT_TINY, text_color=color.WHITE, bg_color=rgba(0, 170, 255, 1.0), callout_position=callout_position.TOP_LEFT, ))
# ── Order Blocks — new OB on break ──────────────────────────────────── ob_right_time = self.time[0] + ob_extend_sec
if showOB and bull_break: found_idx = -1 i = 1 while i <= obLookback: if self.close[i] < self.open[i]: found_idx = i break i = i + 1 if found_idx > 0: ob_top = self.high[found_idx] ob_bottom = self.low[found_idx] if obUseBody: ob_top = max(self.open[found_idx], self.close[found_idx]) ob_bottom = min(self.open[found_idx], self.close[found_idx]) ob_left_time = self.time[found_idx] slot = self._bullOBHead % _OB_POOL rect = self._bullOBRects[slot] rect.point_a = AbsolutePosition(ob_left_time, ob_top) rect.point_b = AbsolutePosition(ob_right_time, ob_bottom) rect.bg_color = bullOBColor rect.line_color = bullOBBorderColor self._bullOBTop[slot] = ob_top self._bullOBBot[slot] = ob_bottom self._bullOBActive[slot] = True self._bullOBHead = self._bullOBHead + 1 self.chart.draw(rect) lbl = self._bullOBLabels[slot] if showBullOBLabel: lbl.text = 'BULL OB' else: lbl.text = '' lbl.position = AbsolutePosition(ob_left_time, ob_top) lbl.font_size = zone_font_sz lbl.bg_color = bullOBLabelColor self.chart.draw(lbl)
if showOB and bear_break: found_idx = -1 i = 1 while i <= obLookback: if self.close[i] > self.open[i]: found_idx = i break i = i + 1 if found_idx > 0: ob_top = self.high[found_idx] ob_bottom = self.low[found_idx] if obUseBody: ob_top = max(self.open[found_idx], self.close[found_idx]) ob_bottom = min(self.open[found_idx], self.close[found_idx]) ob_left_time = self.time[found_idx] slot = self._bearOBHead % _OB_POOL rect = self._bearOBRects[slot] rect.point_a = AbsolutePosition(ob_left_time, ob_top) rect.point_b = AbsolutePosition(ob_right_time, ob_bottom) rect.bg_color = bearOBColor rect.line_color = bearOBBorderColor self._bearOBTop[slot] = ob_top self._bearOBBot[slot] = ob_bottom self._bearOBActive[slot] = True self._bearOBHead = self._bearOBHead + 1 self.chart.draw(rect) lbl = self._bearOBLabels[slot] if showBearOBLabel: lbl.text = 'BEAR OB' else: lbl.text = '' lbl.position = AbsolutePosition(ob_left_time, ob_bottom) lbl.font_size = zone_font_sz lbl.bg_color = bearOBLabelColor self.chart.draw(lbl)
# ── Order Blocks — extend right edge + mitigate (no chart.erase) ───── i = 0 while i < _OB_POOL: if self._bullOBActive[i]: if self.close[0] < self._bullOBBot[i]: # mitigated: hide by making transparent, mark inactive self._bullOBRects[i].bg_color = color.TRANSPARENT self._bullOBRects[i].line_color = color.TRANSPARENT self._bullOBActive[i] = False self.chart.draw(self._bullOBRects[i]) self._bullOBLabels[i].text = '' self.chart.draw(self._bullOBLabels[i]) elif self.is_last_bar or self.is_realtime: self._bullOBRects[i].point_b = AbsolutePosition(ob_right_time, self._bullOBBot[i]) self.chart.draw(self._bullOBRects[i]) i = i + 1
i = 0 while i < _OB_POOL: if self._bearOBActive[i]: if self.close[0] > self._bearOBTop[i]: self._bearOBRects[i].bg_color = color.TRANSPARENT self._bearOBRects[i].line_color = color.TRANSPARENT self._bearOBActive[i] = False self.chart.draw(self._bearOBRects[i]) self._bearOBLabels[i].text = '' self.chart.draw(self._bearOBLabels[i]) elif self.is_last_bar or self.is_realtime: self._bearOBRects[i].point_b = AbsolutePosition(ob_right_time, self._bearOBBot[i]) self.chart.draw(self._bearOBRects[i]) i = i + 1
# ── Fair Value Gaps — detect ────────────────────────────────────────── fvg_right_time = self.time[0] + fvg_extend_sec valid_bull_fvg = False valid_bear_fvg = False
if showFVG and not isnan(atr_val): bull_gap = self.low[0] > self.high[2] bear_gap = self.high[0] < self.low[2] bull_size = self.low[0] - self.high[2] if bull_gap else 0.0 bear_size = self.low[2] - self.high[0] if bear_gap else 0.0
if bull_gap and bull_size >= atr_val * fvgMinATR: valid_bull_fvg = True fvg_top = self.low[0] fvg_bottom = self.high[2] fvg_left_time = self.time[2] slot = self._bullFVGHead % _FVG_POOL rect = self._bullFVGRects[slot] rect.point_a = AbsolutePosition(fvg_left_time, fvg_top) rect.point_b = AbsolutePosition(fvg_right_time, fvg_bottom) rect.bg_color = bullFVGColor rect.line_color = bullFVGBorderColor self._bullFVGTop[slot] = fvg_top self._bullFVGBot[slot] = fvg_bottom self._bullFVGActive[slot] = True self._bullFVGHead = self._bullFVGHead + 1 self.chart.draw(rect) lbl = self._bullFVGLabels[slot] if showBullFVGLabel: lbl.text = 'BULL FVG' else: lbl.text = '' lbl.position = AbsolutePosition(fvg_left_time, fvg_top) lbl.font_size = zone_font_sz lbl.bg_color = bullFVGLabelColor self.chart.draw(lbl)
if bear_gap and bear_size >= atr_val * fvgMinATR: valid_bear_fvg = True fvg_top = self.low[2] fvg_bottom = self.high[0] fvg_left_time = self.time[2] slot = self._bearFVGHead % _FVG_POOL rect = self._bearFVGRects[slot] rect.point_a = AbsolutePosition(fvg_left_time, fvg_top) rect.point_b = AbsolutePosition(fvg_right_time, fvg_bottom) rect.bg_color = bearFVGColor rect.line_color = bearFVGBorderColor self._bearFVGTop[slot] = fvg_top self._bearFVGBot[slot] = fvg_bottom self._bearFVGActive[slot] = True self._bearFVGHead = self._bearFVGHead + 1 self.chart.draw(rect) lbl = self._bearFVGLabels[slot] if showBearFVGLabel: lbl.text = 'BEAR FVG' else: lbl.text = '' lbl.position = AbsolutePosition(fvg_left_time, fvg_bottom) lbl.font_size = zone_font_sz lbl.bg_color = bearFVGLabelColor self.chart.draw(lbl)
# ── Fair Value Gaps — extend right edge + mitigate (no chart.erase) ── i = 0 while i < _FVG_POOL: if self._bullFVGActive[i]: if self.low[0] <= self._bullFVGBot[i]: self._bullFVGRects[i].bg_color = color.TRANSPARENT self._bullFVGRects[i].line_color = color.TRANSPARENT self._bullFVGActive[i] = False self.chart.draw(self._bullFVGRects[i]) self._bullFVGLabels[i].text = '' self.chart.draw(self._bullFVGLabels[i]) elif self.is_last_bar or self.is_realtime: self._bullFVGRects[i].point_b = AbsolutePosition(fvg_right_time, self._bullFVGBot[i]) self.chart.draw(self._bullFVGRects[i]) i = i + 1
i = 0 while i < _FVG_POOL: if self._bearFVGActive[i]: if self.high[0] >= self._bearFVGTop[i]: self._bearFVGRects[i].bg_color = color.TRANSPARENT self._bearFVGRects[i].line_color = color.TRANSPARENT self._bearFVGActive[i] = False self.chart.draw(self._bearFVGRects[i]) self._bearFVGLabels[i].text = '' self.chart.draw(self._bearFVGLabels[i]) elif self.is_last_bar or self.is_realtime: self._bearFVGRects[i].point_b = AbsolutePosition(fvg_right_time, self._bearFVGBot[i]) self.chart.draw(self._bearFVGRects[i]) i = i + 1
# ── Entry confirmation ──────────────────────────────────────────────── bull_confirm_base = bull_break bear_confirm_base = bear_break
# Filter 1: sweep recency if requireSweep: bull_confirm_base = bull_confirm_base and (self.bar_index - self._lastBullSweepBar) <= sweepWindow bear_confirm_base = bear_confirm_base and (self.bar_index - self._lastBearSweepBar) <= sweepWindow
# Filter 2: zone retest bull_retest = False bear_retest = False if requireRetest: k = 0 while k < _OB_POOL: if self._bullOBActive[k]: if self.low[0] <= self._bullOBTop[k] and self.low[0] >= self._bullOBBot[k]: bull_retest = True k = k + 1 k = 0 while k < _FVG_POOL: if self._bullFVGActive[k]: if self.low[0] <= self._bullFVGTop[k] and self.low[0] >= self._bullFVGBot[k]: bull_retest = True k = k + 1 k = 0 while k < _OB_POOL: if self._bearOBActive[k]: if self.high[0] >= self._bearOBBot[k] and self.high[0] <= self._bearOBTop[k]: bear_retest = True k = k + 1 k = 0 while k < _FVG_POOL: if self._bearFVGActive[k]: if self.high[0] >= self._bearFVGBot[k] and self.high[0] <= self._bearFVGTop[k]: bear_retest = True k = k + 1 else: bull_retest = True bear_retest = True if requireRetest: bull_confirm_base = bull_confirm_base and bull_retest bear_confirm_base = bear_confirm_base and bear_retest
# Filter 3: candle confirmation candle_bull_confirm = False candle_bear_confirm = False if requireCandleConfirm: bar_range = self.high[0] - self.low[0] if bar_range > 0.0: candle_bull_confirm = self.close[0] > self.open[0] and (self.close[0] - self.low[0]) / bar_range >= 0.6 candle_bear_confirm = self.close[0] < self.open[0] and (self.high[0] - self.close[0]) / bar_range >= 0.6 else: candle_bull_confirm = True candle_bear_confirm = True else: candle_bull_confirm = True candle_bear_confirm = True bull_confirm_base = bull_confirm_base and candle_bull_confirm bear_confirm_base = bear_confirm_base and candle_bear_confirm
buy_confirm = showSignals and bull_confirm_base sell_confirm = showSignals and bear_confirm_base
buy_val = self.low[0] if buy_confirm else nan sell_val = self.high[0] if sell_confirm else nan
# ── Bar coloring ────────────────────────────────────────────────────── bar_c_bull = colorBars and self._trend == 1 bar_c_bear = colorBars and self._trend == -1
# ── Trend state ─────────────────────────────────────────────────────── trend_val = nan if showTrend: if self._trend == 1: trend_val = 1.0 elif self._trend == -1: trend_val = -1.0 else: trend_val = 0.0
# ── Return all four plot outputs ────────────────────────────────────── if bar_c_bull: return trend_val, plot.Marker(value=buy_val), plot.Marker(value=sell_val), plot.BarColor(color=rgba(8, 153, 129, 0.65)) if bar_c_bear: return trend_val, plot.Marker(value=buy_val), plot.Marker(value=sell_val), plot.BarColor(color=rgba(242, 54, 69, 0.65)) return trend_val, plot.Marker(value=buy_val), plot.Marker(value=sell_val), plot.BarColor()


Be the first to comment
Publish your first comment to unleash the wisdom of crowd.