Not a member of gistpad yet?
Sign Up,
it unlocks many cool features!
- //@version=5
- indicator("Phidias Master Engine [v9.5 TITAN]", shorttitle="Phidias_v9.5", overlay=true, max_labels_count=500)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 1. GLOBAL INPUTS
- // ═══════════════════════════════════════════════════════════════════════════════
- nq_sym = input.symbol("NQ1!", "NQ Symbol", group="Institutional Sync")
- pl_input = input.float(0, "Current P&L ($)", step=50, group="Preservation Gate")
- stop_pts = input.float(4.0, "Stop Loss (Pts)", group="Risk Audit")
- target_pts = input.float(8.0, "Target (Pts)", group="Risk Audit")
- rr_floor = 1.5
- // Silent Sweep Detection
- grp_sweep = "Sweep Detection (Silent)"
- z_threshold = input.float(2.5, "Z-Score Volume Threshold", minval=0.5, step=0.1, group=grp_sweep)
- touch_zone_ticks = input.int(2, "Touch Zone (ticks from boundary)", minval=0, maxval=10, group=grp_sweep)
- tick_size_input = input.float(0.25, "Tick Size", step=0.25, group=grp_sweep)
- max_tracked = input.int(10, "Max Tracked Boxes", minval=5, maxval=20, group=grp_sweep)
- sweep_stale_bars = input.int(15, "Sweep Stale After (bars)", minval=5, maxval=60, group=grp_sweep)
- sweep_expire_bars = input.int(30, "Sweep Expires After (bars)", minval=10, maxval=120, group=grp_sweep)
- // RSI Settings
- grp_rsi = "RSI Divergence"
- rsi_len = input.int(14, "RSI Length", minval=5, maxval=30, group=grp_rsi)
- rsi_ob = input.float(70.0, "Overbought", minval=60, maxval=90, group=grp_rsi)
- rsi_os = input.float(30.0, "Oversold", minval=10, maxval=40, group=grp_rsi)
- div_lookback = input.int(20, "Divergence Lookback (bars)", minval=5, maxval=30, group=grp_rsi)
- div_confirm = input.int(2, "Divergence Confirm (bars)", minval=1, maxval=5, group=grp_rsi)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 2. CURRENT PRICE DATA
- // ═══════════════════════════════════════════════════════════════════════════════
- mes_c = close
- mes_v = volume
- nq_c = request.security(nq_sym, timeframe.period, close)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 3. LONDON MIDPOINT (08:00 UTC)
- // ═══════════════════════════════════════════════════════════════════════════════
- var float lon_mid = na
- var bool lon_tested = false
- is_lon_start = not na(time(timeframe.period, "0800-0805", "UTC"))
- if is_lon_start
- lon_mid := (high + low) / 2
- lon_tested := false
- if not na(lon_mid) and not lon_tested
- if low <= lon_mid and high >= lon_mid
- lon_tested := true
- // ═══════════════════════════════════════════════════════════════════════════════
- // 4. ZONE MEMORY
- // ═══════════════════════════════════════════════════════════════════════════════
- vol_ma = ta.sma(mes_v, 20)
- atr_val = ta.atr(14)
- atr_ma = ta.sma(atr_val, 20)
- is_climax = mes_v > vol_ma * 1.8 or atr_val > atr_ma * 1.5
- var red_highs = array.new_float(3, na)
- var red_lows = array.new_float(3, na)
- var grn_highs = array.new_float(3, na)
- var grn_lows = array.new_float(3, na)
- var int r_ghosts = 0
- var int g_ghosts = 0
- if is_lon_start
- r_ghosts := 0
- g_ghosts := 0
- if is_climax
- if close < open
- array.unshift(red_highs, high)
- array.unshift(red_lows, low)
- array.pop(red_highs)
- array.pop(red_lows)
- else
- array.unshift(grn_highs, high)
- array.unshift(grn_lows, low)
- array.pop(grn_highs)
- array.pop(grn_lows)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 5. REFINED ZONE ANALYSIS — nearest = immediate structural threat
- // ═══════════════════════════════════════════════════════════════════════════════
- bool in_red = false
- bool in_grn = false
- bool box_broken = false
- string break_type = ""
- float nearest_resistance = na // closest red zone top above price (immediate threat for longs)
- float nearest_support = na // closest green zone bottom below price (immediate threat for shorts)
- for i = 0 to 2
- rh = array.get(red_highs, i)
- rl = array.get(red_lows, i)
- gh = array.get(grn_highs, i)
- gl = array.get(grn_lows, i)
- if not na(rh)
- if mes_c >= rl and mes_c <= rh
- in_red := true
- float red_edge = rh
- if red_edge > mes_c
- if na(nearest_resistance) or (red_edge - mes_c) < (nearest_resistance - mes_c)
- nearest_resistance := red_edge
- if not na(gh)
- if mes_c >= gl and mes_c <= gh
- in_grn := true
- float grn_edge = gl
- if grn_edge < mes_c
- if na(nearest_support) or (mes_c - grn_edge) < (mes_c - nearest_support)
- nearest_support := grn_edge
- if not na(rh) and close < rl
- box_broken := true
- break_type := "SUPPLY"
- if not na(gh) and close > gh
- box_broken := true
- break_type := "DEMAND"
- if not na(rh) and close > rh
- array.set(red_highs, i, na)
- array.set(red_lows, i, na)
- r_ghosts += 1
- if not na(gh) and close < gl
- array.set(grn_highs, i, na)
- array.set(grn_lows, i, na)
- g_ghosts += 1
- // ═══════════════════════════════════════════════════════════════════════════════
- // 6. SILENT SWEEP DETECTION ENGINE
- // ═══════════════════════════════════════════════════════════════════════════════
- float vol_sma_z = ta.sma(volume, 20)
- float vol_std_z = ta.stdev(volume, 20)
- float z_vol = vol_std_z != 0 ? (volume - vol_sma_z) / vol_std_z : 0
- bool high_vol = z_vol >= z_threshold
- bool bullish_candle = close > open
- var float[] s_box_tops = array.new_float(0)
- var float[] s_box_bottoms = array.new_float(0)
- var int[] s_box_dirs = array.new_int(0)
- var int[] s_box_births = array.new_int(0)
- var int[] s_box_touches = array.new_int(0)
- var bool[] s_box_swept = array.new_bool(0)
- if high_vol
- array.push(s_box_tops, high)
- array.push(s_box_bottoms, low)
- array.push(s_box_dirs, bullish_candle ? 1 : -1)
- array.push(s_box_births, bar_index)
- array.push(s_box_touches, 0)
- array.push(s_box_swept, false)
- if array.size(s_box_tops) > max_tracked
- array.shift(s_box_tops)
- array.shift(s_box_bottoms)
- array.shift(s_box_dirs)
- array.shift(s_box_births)
- array.shift(s_box_touches)
- array.shift(s_box_swept)
- var int last_sweep_bar = 0
- var int last_sweep_dir = 0
- var int last_sweep_touches = 0
- var float last_sweep_level = na
- float touch_zone = touch_zone_ticks * tick_size_input
- int n_sboxes = array.size(s_box_tops)
- if n_sboxes > 0
- for i = n_sboxes - 1 to 0
- float b_top = array.get(s_box_tops, i)
- float b_bottom = array.get(s_box_bottoms, i)
- int b_dir = array.get(s_box_dirs, i)
- int b_birth = array.get(s_box_births, i)
- bool b_swept = array.get(s_box_swept, i)
- int b_touch = array.get(s_box_touches, i)
- if bar_index - b_birth > 200 or b_swept
- continue
- if b_dir == 1
- bool near_bottom = low <= (b_bottom + touch_zone) and low >= (b_bottom - touch_zone)
- bool closed_above = close > b_bottom
- bool swept_below = low < (b_bottom - touch_zone)
- if near_bottom and closed_above and not swept_below
- array.set(s_box_touches, i, b_touch + 1)
- if swept_below
- array.set(s_box_swept, i, true)
- last_sweep_bar := bar_index
- last_sweep_dir := 1
- last_sweep_touches := b_touch
- last_sweep_level := b_bottom
- if b_dir == -1
- bool near_top = high >= (b_top - touch_zone) and high <= (b_top + touch_zone)
- bool closed_below = close < b_top
- bool swept_above = high > (b_top + touch_zone)
- if near_top and closed_below and not swept_above
- array.set(s_box_touches, i, b_touch + 1)
- if swept_above
- array.set(s_box_swept, i, true)
- last_sweep_bar := bar_index
- last_sweep_dir := -1
- last_sweep_touches := b_touch
- last_sweep_level := b_top
- int sweep_age = bar_index - last_sweep_bar
- bool sweep_active = last_sweep_bar > 0 and sweep_age <= sweep_expire_bars
- bool sweep_fresh = sweep_active and sweep_age <= sweep_stale_bars
- bool sweep_stale = sweep_active and sweep_age > sweep_stale_bars
- int pending_touches = 0
- int active_boxes = 0
- if array.size(s_box_tops) > 0
- for i = 0 to array.size(s_box_tops) - 1
- if bar_index - array.get(s_box_births, i) <= 200 and not array.get(s_box_swept, i)
- active_boxes += 1
- pending_touches += array.get(s_box_touches, i)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 7. RSI DIVERGENCE ENGINE
- // ═══════════════════════════════════════════════════════════════════════════════
- float rsi_val = ta.rsi(close, rsi_len)
- float price_low_1 = ta.lowest(low, div_lookback)
- float price_low_2 = ta.lowest(low, div_lookback)[div_lookback]
- float price_high_1 = ta.highest(high, div_lookback)
- float price_high_2 = ta.highest(high, div_lookback)[div_lookback]
- float rsi_low_1 = ta.lowest(rsi_val, div_lookback)
- float rsi_low_2 = ta.lowest(rsi_val, div_lookback)[div_lookback]
- float rsi_high_1 = ta.highest(rsi_val, div_lookback)
- float rsi_high_2 = ta.highest(rsi_val, div_lookback)[div_lookback]
- bool raw_bull_div = price_low_1 < price_low_2 and rsi_low_1 > rsi_low_2
- bool raw_bear_div = price_high_1 > price_high_2 and rsi_high_1 < rsi_high_2
- var int bull_div_count = 0
- var int bear_div_count = 0
- if raw_bull_div
- bull_div_count += 1
- else
- bull_div_count := 0
- if raw_bear_div
- bear_div_count += 1
- else
- bear_div_count := 0
- bool bull_div_confirmed = bull_div_count >= div_confirm
- bool bear_div_confirmed = bear_div_count >= div_confirm
- string rsi_state = ""
- color rsi_bg = color.new(#000000, 40)
- color rsi_tc = color.gray
- if bull_div_confirmed and rsi_val < rsi_os
- rsi_state := "OS + BULL DIV"
- rsi_bg := color.new(color.green, 10)
- rsi_tc := color.white
- else if bear_div_confirmed and rsi_val > rsi_ob
- rsi_state := "OB + BEAR DIV"
- rsi_bg := color.new(color.red, 10)
- rsi_tc := color.white
- else if bull_div_confirmed
- rsi_state := "BULL DIV"
- rsi_bg := color.new(color.green, 40)
- rsi_tc := color.green
- else if bear_div_confirmed
- rsi_state := "BEAR DIV"
- rsi_bg := color.new(color.red, 40)
- rsi_tc := color.red
- else if rsi_val > rsi_ob
- rsi_state := "OB " + str.tostring(rsi_val, "#.#")
- rsi_bg := color.new(color.red, 60)
- rsi_tc := color.red
- else if rsi_val < rsi_os
- rsi_state := "OS " + str.tostring(rsi_val, "#.#")
- rsi_bg := color.new(color.green, 60)
- rsi_tc := color.green
- else
- rsi_state := str.tostring(rsi_val, "#.#")
- rsi_bg := color.new(#000000, 40)
- rsi_tc := color.gray
- // ═══════════════════════════════════════════════════════════════════════════════
- // 8. TARGET CALCULATIONS
- // ═══════════════════════════════════════════════════════════════════════════════
- float long_target = mes_c + target_pts
- float short_target = mes_c - target_pts
- float dyn_rr = target_pts / stop_pts
- // ═══════════════════════════════════════════════════════════════════════════════
- // 9. DUAL GATE AUDIT ENGINE — refined proximity
- // ═══════════════════════════════════════════════════════════════════════════════
- bool is_rsw = not na(time(timeframe.period, "1430-1445", "UTC"))
- bool rr_fail = dyn_rr < rr_floor
- bool loss_limit = pl_input <= -500
- bool long_trap = in_red
- bool long_nq_fail = nq_c < nq_c[1] and not box_broken
- bool long_target_blocked = not na(nearest_resistance) and nearest_resistance < long_target
- string long_veto = ""
- if loss_limit
- long_veto := "LOSS"
- else if is_rsw
- long_veto := "RSW"
- else if rr_fail
- long_veto := "R:R"
- else if long_trap
- long_veto := "ZONE"
- else if long_nq_fail
- long_veto := "NQ"
- else if long_target_blocked
- long_veto := "BLOCKED"
- bool long_pass = long_veto == ""
- bool short_trap = in_grn
- bool short_nq_fail = nq_c > nq_c[1] and not box_broken
- bool short_target_blocked = not na(nearest_support) and nearest_support > short_target
- string short_veto = ""
- if loss_limit
- short_veto := "LOSS"
- else if is_rsw
- short_veto := "RSW"
- else if rr_fail
- short_veto := "R:R"
- else if short_trap
- short_veto := "ZONE"
- else if short_nq_fail
- short_veto := "NQ"
- else if short_target_blocked
- short_veto := "BLOCKED"
- bool short_pass = short_veto == ""
- // ═══════════════════════════════════════════════════════════════════════════════
- // 10. SETUP GRADING ENGINE
- // ═══════════════════════════════════════════════════════════════════════════════
- bool sweep_long_aligned = sweep_fresh and last_sweep_dir == 1
- bool sweep_short_aligned = sweep_fresh and last_sweep_dir == -1
- bool rsi_supports_long = bull_div_confirmed or rsi_val < rsi_os
- bool rsi_supports_short = bear_div_confirmed or rsi_val > rsi_ob
- bool rsi_warns_long = bear_div_confirmed
- bool rsi_warns_short = bull_div_confirmed
- bool rsi_neutral = not rsi_supports_long and not rsi_supports_short and not rsi_warns_long and not rsi_warns_short
- string long_grade = "X"
- if not long_pass
- long_grade := "X"
- else if sweep_long_aligned and (rsi_supports_long or (rsi_neutral and not rsi_warns_long))
- long_grade := "A+"
- else if rsi_warns_long
- long_grade := "C"
- else if sweep_long_aligned or rsi_supports_long
- long_grade := "B+"
- else
- long_grade := "B+"
- string short_grade = "X"
- if not short_pass
- short_grade := "X"
- else if sweep_short_aligned and (rsi_supports_short or (rsi_neutral and not rsi_warns_short))
- short_grade := "A+"
- else if rsi_warns_short
- short_grade := "C"
- else if sweep_short_aligned or rsi_supports_short
- short_grade := "B+"
- else
- short_grade := "B+"
- f_grade_bg(string grade) => grade == "A+" ? color.new(#00e676, 15) : grade == "B+" ? color.new(#448aff, 25) : grade == "C" ? color.new(#ffd600, 25) : color.new(#444455, 50)
- f_grade_tc(string grade) => grade == "A+" ? color.white : grade == "B+" ? color.white : grade == "C" ? color.black : color.gray
- // ═══════════════════════════════════════════════════════════════════════════════
- // 11. CANDLE COLOURING
- // ═══════════════════════════════════════════════════════════════════════════════
- color candle_col = na
- if long_pass and not short_pass
- candle_col := color.new(color.green, 60)
- else if short_pass and not long_pass
- candle_col := color.new(color.red, 60)
- else if long_pass and short_pass
- candle_col := color.new(color.yellow, 60)
- else
- candle_col := color.new(color.gray, 80)
- barcolor(candle_col)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 12. VISUALS
- // ═══════════════════════════════════════════════════════════════════════════════
- plot(lon_mid, "London Mid", color=lon_tested ? color.gray : color.aqua, linewidth=2)
- plotshape(box_broken, "Box Break", shape.diamond, location.belowbar, color=break_type == "DEMAND" ? color.green : color.red, size=size.small)
- plot(long_target, "Long Target", color=color.new(color.green, 70), style=plot.style_linebr, linewidth=1)
- plot(short_target, "Short Target", color=color.new(color.red, 70), style=plot.style_linebr, linewidth=1)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 13. GRADED ALERTS
- // ═══════════════════════════════════════════════════════════════════════════════
- var string prev_long_grade = "X"
- var string prev_short_grade = "X"
- bool long_a_plus_new = long_grade == "A+" and prev_long_grade != "A+"
- bool long_b_plus_new = long_grade == "B+" and prev_long_grade == "X"
- bool long_c_new = long_grade == "C" and prev_long_grade == "X"
- bool short_a_plus_new = short_grade == "A+" and prev_short_grade != "A+"
- bool short_b_plus_new = short_grade == "B+" and prev_short_grade == "X"
- bool short_c_new = short_grade == "C" and prev_short_grade == "X"
- bool long_gate_closed = long_grade == "X" and prev_long_grade != "X"
- bool short_gate_closed = short_grade == "X" and prev_short_grade != "X"
- prev_long_grade := long_grade
- prev_short_grade := short_grade
- alertcondition(long_a_plus_new, title="⚡ A+ LONG", message="A+ LONG SETUP — Gate open, sweep aligned, RSI supports.")
- alertcondition(short_a_plus_new, title="⚡ A+ SHORT", message="A+ SHORT SETUP — Gate open, sweep aligned, RSI supports.")
- alertcondition(long_b_plus_new, title="📈 B+ LONG", message="B+ LONG SETUP — Gate open.")
- alertcondition(short_b_plus_new, title="📉 B+ SHORT", message="B+ SHORT SETUP — Gate open.")
- alertcondition(long_c_new, title="⚠️ C LONG", message="C LONG SETUP — RSI divergence warning.")
- alertcondition(short_c_new, title="⚠️ C SHORT", message="C SHORT SETUP — RSI divergence warning.")
- // ═══════════════════════════════════════════════════════════════════════════════
- // 14. UI TABLE
- // ═══════════════════════════════════════════════════════════════════════════════
- var table t = table.new(position.bottom_left, 9, 3, bgcolor=color.new(#000000, 80), border_width=1)
- if barstate.islast
- // Row 0: Headers
- table.cell(t, 0, 0, "SYM", text_color=#888888, text_size=size.tiny)
- table.cell(t, 1, 0, "R:R", text_color=#888888, text_size=size.tiny)
- table.cell(t, 2, 0, "LONG", text_color=#888888, text_size=size.tiny)
- table.cell(t, 3, 0, "SHORT", text_color=#888888, text_size=size.tiny)
- table.cell(t, 4, 0, "ZONE", text_color=#888888, text_size=size.tiny)
- table.cell(t, 5, 0, "GATE", text_color=#888888, text_size=size.tiny)
- table.cell(t, 6, 0, "CANDLE", text_color=#888888, text_size=size.tiny)
- table.cell(t, 7, 0, "SWEEP", text_color=#888888, text_size=size.tiny)
- table.cell(t, 8, 0, "RSI", text_color=#888888, text_size=size.tiny)
- // Row 1: Data
- string candle_status = long_pass and short_pass ? "BOTH" : long_pass ? "GREEN" : short_pass ? "RED" : "DEAD"
- color candle_bg = long_pass and short_pass ? color.yellow : long_pass ? color.green : short_pass ? color.red : color.gray
- // Create GATE status text
- string gate_status = ""
- color gate_bg = color.new(#000000, 40)
- if long_pass and short_pass
- gate_status := "BOTH OPEN"
- gate_bg := color.new(color.yellow, 30)
- else if long_pass
- gate_status := "LONG OPEN"
- gate_bg := color.new(color.green, 30)
- else if short_pass
- gate_status := "SHORT OPEN"
- gate_bg := color.new(color.red, 30)
- else
- // Gate is closed - show the primary veto reason
- if loss_limit
- gate_status := "LOSS LIMIT"
- else if is_rsw
- gate_status := "RSW"
- else if rr_fail
- gate_status := "R:R FAIL"
- else if long_trap or short_trap
- gate_status := "ZONE TRAP"
- else if long_nq_fail or short_nq_fail
- gate_status := "NQ FAIL"
- else if long_target_blocked or short_target_blocked
- gate_status := "BLOCKED"
- else
- gate_status := "CLOSED"
- gate_bg := color.new(color.gray, 30)
- table.cell(t, 0, 1, "MES", text_color=#FF9800, text_size=size.tiny)
- table.cell(t, 1, 1, str.tostring(dyn_rr, "#.#") + "R", bgcolor=dyn_rr < rr_floor ? color.red : color.green, text_color=color.black, text_size=size.tiny)
- table.cell(t, 2, 1, str.tostring(long_target, "#.##"), text_color=color.green, bgcolor=color.new(#000000, 40), text_size=size.tiny)
- table.cell(t, 3, 1, str.tostring(short_target, "#.##"), text_color=color.red, bgcolor=color.new(#000000, 40), text_size=size.tiny)
- string zone_text = in_red ? "RED" : in_grn ? "GREEN" : "CLEAN"
- zone_text += " | G:" + str.tostring(r_ghosts) + "/" + str.tostring(g_ghosts)
- table.cell(t, 4, 1, zone_text, bgcolor=(in_red or in_grn) ? color.new(color.red, 40) : color.new(color.green, 40), text_color=color.white, text_size=size.tiny)
- // GATE cell - PROPERLY POPULATED
- table.cell(t, 5, 1, gate_status, bgcolor=gate_bg, text_color=color.white, text_size=size.tiny)
- // CANDLE cell
- table.cell(t, 6, 1, candle_status, bgcolor=candle_bg, text_color=color.black, text_size=size.tiny)
- // Sweep cell
- string sweep_text = sweep_fresh ? "SWEEP " + (last_sweep_dir == 1 ? "↓ DEMAND" : "↑ SUPPLY") : sweep_stale ? "STALE" : "NO SWEEP"
- color sweep_bg = sweep_fresh ? color.new(color.green, 20) : color.new(#000000, 40)
- table.cell(t, 7, 1, sweep_text, bgcolor=sweep_bg, text_color=color.white, text_size=size.tiny)
- // RSI cell
- table.cell(t, 8, 1, rsi_state, bgcolor=rsi_bg, text_color=rsi_tc, text_size=size.tiny)
- // Row 2: Grades
- table.cell(t, 2, 2, long_grade + " LONG", bgcolor=f_grade_bg(long_grade), text_color=f_grade_tc(long_grade), text_size=size.tiny)
- table.cell(t, 3, 2, short_grade + " SHORT", bgcolor=f_grade_bg(short_grade), text_color=f_grade_tc(short_grade), text_size=size.tiny)
RAW Gist Data
Copied
