Not a member of gistpad yet?
Sign Up,
it unlocks many cool features!
- //@version=5
- indicator("Phidias Master Engine v9.9.4 [Regime-Gated Alerts]", shorttitle="Phidias_v9.9.4", overlay=true, max_labels_count=500, max_boxes_count=500, max_lines_count=500)
- // ═══════════════════════════════════════════════════════════════════════════════
- // ARCHITECTURE v9.9.4
- // • All alerts regime-gated: no standalone grade alerts outside regime context
- // • All four alert types carry full pipe-delimited payload for Gemini ingestion
- // • Type 1: fires on regime entry/flip when aligned FVG is fresh or reacting
- // • Type 2: fires once per regime when price first touches/reacts to aligned FVG
- // • Type 3: fires on regime breakdown to NEUTRAL
- // • Type 4: fires on X→A+/B+ grade transition within active regime + FVG
- // • Dead grade-toggle inputs removed; single regime_alert_on controls all
- // • Birth bar deduplication and reset on mitigation preserved from v9.9.2
- // ═══════════════════════════════════════════════════════════════════════════════
- // ═══════════════════════════════════════════════════════════════════════════════
- // 1. INPUTS
- // ═══════════════════════════════════════════════════════════════════════════════
- nq_sym = input.symbol("NQ1!", "NQ Symbol", group="Institutional Sync")
- rty_sym = input.symbol("RTY1!", "RTY 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
- grp_auction = "Fixed Tick Auction (v9.6)"
- bin_res = input.float(1.0, "Bin Resolution (Points)", step=0.25, group=grp_auction)
- va_perc = input.float(70.0, "Value Area %", minval=10, maxval=100, group=grp_auction) / 100
- max_bins = 300
- grp_sync = "Index Sync (Embedded)"
- sync_corr_len = input.int(30, "Sync Correlation Lookback", minval=10, maxval=100, group=grp_sync)
- sync_dir_len = input.int(5, "Sync Directional Lookback", minval=2, maxval=20, group=grp_sync)
- sync_smooth_len = input.int(5, "Sync Score Smoothing", minval=1, maxval=20, group=grp_sync)
- sync_w_nq = input.float(40.0, "Sync Weight: MES-NQ %", minval=0, maxval=100, group=grp_sync)
- sync_w_rty = input.float(30.0, "Sync Weight: MES-RTY %", minval=0, maxval=100, group=grp_sync)
- sync_w_dir = input.float(30.0, "Sync Weight: Direction %", minval=0, maxval=100, group=grp_sync)
- grp_regime = "Regime Detection & Alerts"
- regime_window = input.int(20, "Regime Lookback (bars)", minval=10, maxval=60, group=grp_regime)
- regime_sync_thresh = input.float(70.0, "Sync Threshold for Regime", minval=50, maxval=95, group=grp_regime)
- regime_bias_thresh = input.float(60.0, "Directional Bias Threshold %", minval=51, maxval=80, group=grp_regime)
- regime_min_bars = input.int(5, "Min Bars to Confirm Regime", minval=2, maxval=20, group=grp_regime)
- regime_alert_on = input.bool(true, "Fire Regime + Grade Alerts", group=grp_regime)
- regime_fvg_proximity = input.int(10, "5M FVG Freshness Window (1M bars)", minval=2, maxval=40, group=grp_regime)
- grp_sweep = "Sweep Detection"
- 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)", 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)
- displacement_pts = input.float(1.0, "Displacement Threshold (Pts)", minval=0.25, step=0.25, group=grp_sweep)
- grp_zones = "Zone Memory"
- zone_expire_bars = input.int(120, "Climax Zone Expires After (bars)", minval=30, maxval=500, group=grp_zones)
- 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)
- grp_mdl = "Market Data Logger"
- sessionStart = input.session("0000-2359", "Trading Session (All Day)", group=grp_mdl)
- london_tz = input.string("Europe/London", "Timezone", group=grp_mdl)
- show_pivots = input.bool(false, "Show Pivot Levels", group=grp_mdl)
- show_vwap = input.bool(false, "Show VWAP Lines", group=grp_mdl)
- show_tick_auction = input.bool(true, "Show Tick Auction POC/VAL/VAH", group=grp_mdl)
- show_ob = input.bool(false, "Show Order Blocks", group=grp_mdl)
- show_fvg = input.bool(false, "Show Fair Value Gaps", group=grp_mdl)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 2. PRICE DATA
- // ═══════════════════════════════════════════════════════════════════════════════
- mes_c = close
- mes_v = volume
- nq_c = request.security(nq_sym, timeframe.period, close)
- rty_c = request.security(rty_sym, timeframe.period, close)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 3. EMBEDDED SYNC SCORE
- // ═══════════════════════════════════════════════════════════════════════════════
- float corr_mes_nq = ta.correlation(mes_c, nq_c, sync_corr_len)
- float corr_mes_rty = ta.correlation(mes_c, rty_c, sync_corr_len)
- float norm_mes_nq = na(corr_mes_nq) ? 50.0 : (corr_mes_nq + 1) / 2 * 100
- float norm_mes_rty = na(corr_mes_rty) ? 50.0 : (corr_mes_rty + 1) / 2 * 100
- f_sync_dir(src, lookback) =>
- diff = src - src[lookback]
- diff > 0 ? 1 : diff < 0 ? -1 : 0
- int sync_mes_dir = f_sync_dir(mes_c, sync_dir_len)
- int sync_nq_dir = f_sync_dir(nq_c, sync_dir_len)
- int sync_rty_dir = f_sync_dir(rty_c, sync_dir_len)
- float sync_dir_score = 50.0
- if sync_mes_dir == 0 and sync_nq_dir == 0 and sync_rty_dir == 0
- sync_dir_score := 50.0
- else if sync_mes_dir == sync_nq_dir and sync_nq_dir == sync_rty_dir and sync_mes_dir != 0
- sync_dir_score := 100.0
- else if sync_mes_dir == sync_nq_dir and sync_mes_dir != 0
- sync_dir_score := 66.0
- else if sync_mes_dir == sync_rty_dir and sync_mes_dir != 0
- sync_dir_score := 66.0
- else if sync_nq_dir == sync_rty_dir and sync_nq_dir != 0
- sync_dir_score := 40.0
- else
- sync_dir_score := 33.0
- float sync_total_w = sync_w_nq + sync_w_rty + sync_w_dir
- float sync_raw = sync_total_w > 0 ? ((norm_mes_nq * sync_w_nq) + (norm_mes_rty * sync_w_rty) + (sync_dir_score * sync_w_dir)) / sync_total_w : 50.0
- sync_raw := math.min(100, math.max(0, sync_raw))
- float sync_score = ta.ema(sync_raw, sync_smooth_len)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 4. 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
- // ═══════════════════════════════════════════════════════════════════════════════
- // 5. 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 red_births = array.new_int(3, 0)
- var grn_births = array.new_int(3, 0)
- 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.unshift(red_births, bar_index)
- array.pop(red_highs)
- array.pop(red_lows)
- array.pop(red_births)
- else
- array.unshift(grn_highs, high)
- array.unshift(grn_lows, low)
- array.unshift(grn_births, bar_index)
- array.pop(grn_highs)
- array.pop(grn_lows)
- array.pop(grn_births)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 6. REFINED ZONE ANALYSIS
- // ═══════════════════════════════════════════════════════════════════════════════
- bool in_red = false
- bool in_grn = false
- bool box_broken = false
- string break_type = ""
- float nearest_resistance = na
- float nearest_support = na
- 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)
- int rb = array.get(red_births, i)
- int gb = array.get(grn_births, i)
- if not na(rh) and rb > 0 and (bar_index - rb) > zone_expire_bars
- array.set(red_highs, i, na)
- array.set(red_lows, i, na)
- rh := na
- rl := na
- if not na(gh) and gb > 0 and (bar_index - gb) > zone_expire_bars
- array.set(grn_highs, i, na)
- array.set(grn_lows, i, na)
- gh := na
- gl := na
- 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"
- array.set(red_highs, i, na)
- array.set(red_lows, i, na)
- if not na(gh) and close > gh
- box_broken := true
- break_type := "DEMAND"
- array.set(grn_highs, i, na)
- array.set(grn_lows, i, na)
- 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
- // ═══════════════════════════════════════════════════════════════════════════════
- // 7. FIXED TICK AUCTION ENGINE
- // ═══════════════════════════════════════════════════════════════════════════════
- var float daily_anchor = na
- var float[] tick_bins = array.new_float(max_bins, 0.0)
- var float tick_poc = na
- var float tick_val = na
- var float tick_vah = na
- if ta.change(time("D"))
- daily_anchor := open
- f_get_idx(price, anchor) =>
- if na(anchor) or price < anchor - (max_bins / 2) * bin_res or price > anchor + (max_bins / 2) * bin_res
- -1
- else
- idx = math.floor((price - anchor) / bin_res) + (max_bins / 2)
- math.min(max_bins - 1, math.max(0, int(idx)))
- if not na(daily_anchor)
- idx = f_get_idx(hlc3, daily_anchor)
- if idx >= 0
- array.set(tick_bins, idx, array.get(tick_bins, idx) + volume)
- bool recalc_tick_va = bar_index % 10 == 0 or ta.change(time("D"))
- if recalc_tick_va and not na(daily_anchor)
- max_vol = 0.0
- poc_idx = 0
- for j = 0 to max_bins - 1
- bv = array.get(tick_bins, j)
- if bv > max_vol
- max_vol := bv
- poc_idx := j
- if max_vol > 0
- total_vol = 0.0
- for j = 0 to max_bins - 1
- total_vol += array.get(tick_bins, j)
- if total_vol > 0
- captured = max_vol
- lo_idx = poc_idx
- hi_idx = poc_idx
- target_vol = total_vol * va_perc
- while captured < target_vol and (lo_idx > 0 or hi_idx < max_bins - 1)
- vol_below = lo_idx > 0 ? array.get(tick_bins, lo_idx - 1) : 0.0
- vol_above = hi_idx < max_bins - 1 ? array.get(tick_bins, hi_idx + 1) : 0.0
- if lo_idx <= 0
- hi_idx += 1
- captured += vol_above
- else if hi_idx >= max_bins - 1
- lo_idx -= 1
- captured += vol_below
- else if vol_below >= vol_above
- lo_idx -= 1
- captured += vol_below
- else
- hi_idx += 1
- captured += vol_above
- tick_poc := daily_anchor + (poc_idx - (max_bins / 2)) * bin_res + (bin_res / 2)
- tick_val := daily_anchor + (lo_idx - (max_bins / 2)) * bin_res
- tick_vah := daily_anchor + (hi_idx + 1 - (max_bins / 2)) * bin_res
- if ta.change(time("D"))
- for j = 0 to max_bins - 1
- array.set(tick_bins, j, 0.0)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 8. 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
- var bool last_sweep_wick = false
- var bool sweep_displaced = false
- var bool sweep_has_fvg = false
- 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
- last_sweep_wick := close > b_bottom
- sweep_displaced := false
- sweep_has_fvg := false
- 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
- last_sweep_wick := close < b_top
- sweep_displaced := false
- sweep_has_fvg := false
- if bar_index == last_sweep_bar + 1 and last_sweep_bar > 0
- if last_sweep_dir == 1
- sweep_displaced := (close - last_sweep_level) >= displacement_pts
- else if last_sweep_dir == -1
- sweep_displaced := (last_sweep_level - close) >= displacement_pts
- 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
- // ═══════════════════════════════════════════════════════════════════════════════
- // 9. 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, "#.#")
- // ═══════════════════════════════════════════════════════════════════════════════
- // 10. MARKET DATA LOGGER: PIVOTS, VWAP, ORDER BLOCKS, FVGs
- // ═══════════════════════════════════════════════════════════════════════════════
- [xHigh, xLow, xClose] = request.security(syminfo.tickerid, "D", [high[1], low[1], close[1]])
- pivot_p = (xHigh + xLow + xClose) / 3
- pivot_r1 = pivot_p + (pivot_p - xLow)
- pivot_s1 = pivot_p - (xHigh - pivot_p)
- pivot_r2 = pivot_p + (xHigh - xLow)
- pivot_s2 = pivot_p - (xHigh - xLow)
- pivot_r3 = xHigh + 2 * (pivot_p - xLow)
- pivot_s3 = xLow - 2 * (xHigh - pivot_p)
- settlement = xClose
- [weekHigh, weekLow, weekClose] = request.security(syminfo.tickerid, "W", [high[1], low[1], close[1]])
- week_pivot = (weekHigh + weekLow + weekClose) / 3
- [monthHigh, monthLow, monthClose] = request.security(syminfo.tickerid, "M", [high[1], low[1], close[1]])
- month_pivot = (monthHigh + monthLow + monthClose) / 3
- // VWAP
- var float vwap_midnight_sum_price_vol = 0.0
- var float vwap_midnight_sum_vol = 0.0
- var float vwap_230pm_sum_price_vol = 0.0
- var float vwap_230pm_sum_vol = 0.0
- is_in_session = not na(time(timeframe.period, sessionStart, london_tz))
- var bool new_session = false
- new_session := is_in_session and not is_in_session[1]
- var float session_midnight_start_time = na
- var float session_230pm_start_time = na
- if new_session and hour(time, london_tz) == 0 and minute(time, london_tz) == 0
- session_midnight_start_time := time
- if is_in_session and hour(time, london_tz) == 14 and minute(time, london_tz) == 30
- session_230pm_start_time := time
- if new_session and hour(time, london_tz) == 0 and minute(time, london_tz) == 0
- vwap_midnight_sum_price_vol := 0.0
- vwap_midnight_sum_vol := 0.0
- if is_in_session and hour(time, london_tz) == 14 and minute(time, london_tz) == 30
- vwap_230pm_sum_price_vol := 0.0
- vwap_230pm_sum_vol := 0.0
- typical_price = hlc3
- if not na(session_midnight_start_time) and time >= session_midnight_start_time
- vwap_midnight_sum_price_vol += typical_price * volume
- vwap_midnight_sum_vol += volume
- if not na(session_230pm_start_time) and time >= session_230pm_start_time
- vwap_230pm_sum_price_vol += typical_price * volume
- vwap_230pm_sum_vol += volume
- vwap_8am = vwap_midnight_sum_vol > 0 ? vwap_midnight_sum_price_vol / vwap_midnight_sum_vol : na
- vwap_230pm = vwap_230pm_sum_vol > 0 ? vwap_230pm_sum_price_vol / vwap_230pm_sum_vol : na
- // Order Blocks (5M)
- var float bull_ob_top = na
- var float bull_ob_bottom = na
- var float bear_ob_top = na
- var float bear_ob_bottom = na
- var int bull_ob_time = na
- var int bear_ob_time = na
- [ob_open_5m, ob_high_5m, ob_low_5m, ob_close_5m] = request.security(syminfo.tickerid, "5", [open, high, low, close])
- bullish_ob = ob_close_5m[2] < ob_open_5m[2] and ob_close_5m[1] > ob_open_5m[1] and (ob_close_5m[1] - ob_open_5m[1]) > math.abs(ob_open_5m[2] - ob_close_5m[2]) * 1.5
- if bullish_ob and not na(ob_low_5m[2])
- bull_ob_bottom := ob_low_5m[2]
- bull_ob_top := ob_high_5m[2]
- bull_ob_time := time
- bearish_ob = ob_close_5m[2] > ob_open_5m[2] and ob_close_5m[1] < ob_open_5m[1] and (ob_open_5m[1] - ob_close_5m[1]) > math.abs(ob_close_5m[2] - ob_open_5m[2]) * 1.5
- if bearish_ob and not na(ob_high_5m[2])
- bear_ob_top := ob_high_5m[2]
- bear_ob_bottom := ob_low_5m[2]
- bear_ob_time := time
- if not na(bull_ob_time)
- bool bull_ob_expired = (time - bull_ob_time) > 120 * 60 * 1000
- bool bull_ob_mitigated = close < bull_ob_bottom
- if bull_ob_expired or bull_ob_mitigated
- bull_ob_top := na
- bull_ob_bottom := na
- if not na(bear_ob_time)
- bool bear_ob_expired = (time - bear_ob_time) > 120 * 60 * 1000
- bool bear_ob_mitigated = close > bear_ob_top
- if bear_ob_expired or bear_ob_mitigated
- bear_ob_top := na
- bear_ob_bottom := na
- // ─────────────────────────────────────────────────────────────────────────────
- // Fair Value Gaps (5M)
- // FIX (from v9.9.2): birth bar stamps only once per unique FVG level.
- // Birth bars reset to 0 on expiry/mitigation.
- // ─────────────────────────────────────────────────────────────────────────────
- var float bull_fvg_top = na
- var float bull_fvg_bottom = na
- var float bear_fvg_top = na
- var float bear_fvg_bottom = na
- var int bull_fvg_time = na
- var int bear_fvg_time = na
- var int bull_fvg_birth_bar = 0
- var int bear_fvg_birth_bar = 0
- bullish_fvg = ob_low_5m[0] > ob_high_5m[2] and ob_low_5m[1] > ob_high_5m[2]
- bool bull_fvg_is_new = bullish_fvg and not na(ob_high_5m[2]) and ob_high_5m[2] != bull_fvg_bottom
- if bull_fvg_is_new
- bull_fvg_bottom := ob_high_5m[2]
- bull_fvg_top := ob_low_5m[0]
- bull_fvg_time := time
- bull_fvg_birth_bar := bar_index
- bearish_fvg = ob_high_5m[0] < ob_low_5m[2] and ob_high_5m[1] < ob_low_5m[2]
- bool bear_fvg_is_new = bearish_fvg and not na(ob_low_5m[2]) and ob_low_5m[2] != bear_fvg_top
- if bear_fvg_is_new
- bear_fvg_top := ob_low_5m[2]
- bear_fvg_bottom := ob_high_5m[0]
- bear_fvg_time := time
- bear_fvg_birth_bar := bar_index
- if not na(bull_fvg_time)
- bool bull_fvg_expired = (time - bull_fvg_time) > 120 * 60 * 1000
- bool bull_fvg_mitigated = close < bull_fvg_bottom
- if bull_fvg_expired or bull_fvg_mitigated
- bull_fvg_top := na
- bull_fvg_bottom := na
- bull_fvg_birth_bar := 0
- if not na(bear_fvg_time)
- bool bear_fvg_expired = (time - bear_fvg_time) > 120 * 60 * 1000
- bool bear_fvg_mitigated = close > bear_fvg_top
- if bear_fvg_expired or bear_fvg_mitigated
- bear_fvg_top := na
- bear_fvg_bottom := na
- bear_fvg_birth_bar := 0
- // ═══════════════════════════════════════════════════════════════════════════════
- // 10b. FVG CONFLUENCE CHECK AT SWEEP LEVEL
- // ═══════════════════════════════════════════════════════════════════════════════
- if sweep_active and not na(last_sweep_level)
- float fvg_tolerance = 2.0
- if last_sweep_dir == 1 and not na(bull_fvg_top) and not na(bull_fvg_bottom)
- if last_sweep_level >= (bull_fvg_bottom - fvg_tolerance) and last_sweep_level <= (bull_fvg_top + fvg_tolerance)
- sweep_has_fvg := true
- if last_sweep_dir == -1 and not na(bear_fvg_top) and not na(bear_fvg_bottom)
- if last_sweep_level >= (bear_fvg_bottom - fvg_tolerance) and last_sweep_level <= (bear_fvg_top + fvg_tolerance)
- sweep_has_fvg := true
- // ═══════════════════════════════════════════════════════════════════════════════
- // 10c. ALERT MESSAGE BUILDER (PAYLOAD FOR ALL ALERT TYPES)
- // ═══════════════════════════════════════════════════════════════════════════════
- encode_distance(level) =>
- if na(level)
- "NA"
- else
- dist = close - level
- dist >= 0 ? "+" + str.tostring(dist, "#.##") : str.tostring(dist, "#.##")
- build_alert_message() =>
- string msg = syminfo.ticker + "|" + str.tostring(time, "#") + "|" + str.tostring(close, "#.##") + "|"
- msg := msg + "DailyP:" + (not na(pivot_p) ? str.tostring(pivot_p, "#.##") : "NA") + "(" + encode_distance(pivot_p) + ")|"
- msg := msg + "DailyR1:" + (not na(pivot_r1) ? str.tostring(pivot_r1, "#.##") : "NA") + "(" + encode_distance(pivot_r1) + ")|"
- msg := msg + "DailyS1:" + (not na(pivot_s1) ? str.tostring(pivot_s1, "#.##") : "NA") + "(" + encode_distance(pivot_s1) + ")|"
- msg := msg + "Settlement:" + (not na(settlement) ? str.tostring(settlement,"#.##") : "NA") + "(" + encode_distance(settlement) + ")|"
- msg := msg + "VWAP_8AM:" + (not na(vwap_8am) ? str.tostring(vwap_8am, "#.##") + "(" + encode_distance(vwap_8am) + ")" : "NA") + "|"
- msg := msg + "POC:" + (not na(tick_poc) ? str.tostring(tick_poc, "#.##") + "(" + encode_distance(tick_poc) + ")" : "NA") + "|"
- msg := msg + "VAH:" + (not na(tick_vah) ? str.tostring(tick_vah, "#.##") + "(" + encode_distance(tick_vah) + ")" : "NA") + "|"
- msg := msg + "VAL:" + (not na(tick_val) ? str.tostring(tick_val, "#.##") + "(" + encode_distance(tick_val) + ")" : "NA") + "|"
- msg := msg + "BullOB:" + (not na(bull_ob_top) ? str.tostring(bull_ob_bottom, "#.##") + "-" + str.tostring(bull_ob_top, "#.##") : "NA") + "|"
- msg := msg + "BearOB:" + (not na(bear_ob_top) ? str.tostring(bear_ob_bottom, "#.##") + "-" + str.tostring(bear_ob_top, "#.##") : "NA") + "|"
- msg := msg + "BullFVG:" + (not na(bull_fvg_top) ? str.tostring(bull_fvg_bottom, "#.##") + "-" + str.tostring(bull_fvg_top, "#.##") : "NA") + "|"
- msg := msg + "BearFVG:" + (not na(bear_fvg_top) ? str.tostring(bear_fvg_bottom, "#.##") + "-" + str.tostring(bear_fvg_top, "#.##") : "NA") + "|"
- msg := msg + "SweepType:" + (sweep_active ? (last_sweep_wick ? "WICK" : "BODY") : "NONE") + "|"
- msg := msg + "Displaced:" + (sweep_displaced ? "YES" : "NO") + "|"
- msg := msg + "FVG_Conf:" + (sweep_has_fvg ? "YES" : "NO") + "|"
- msg := msg + "Sync:" + str.tostring(sync_score, "#.#") + "|"
- msg
- string alert_message = build_alert_message()
- // ═══════════════════════════════════════════════════════════════════════════════
- // 11. TARGET CALCULATIONS & DUAL GATE AUDIT
- // ═══════════════════════════════════════════════════════════════════════════════
- float long_target = mes_c + target_pts
- float short_target = mes_c - target_pts
- float dyn_rr = target_pts / stop_pts
- 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 == ""
- // ═══════════════════════════════════════════════════════════════════════════════
- // 12. 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
- int sweep_quality = 0
- if sweep_active
- if last_sweep_wick
- sweep_quality += 1
- if sweep_displaced
- sweep_quality += 1
- if sweep_has_fvg
- sweep_quality += 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 sweep_quality >= 2 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 sweep_quality >= 2 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
- // ═══════════════════════════════════════════════════════════════════════════════
- // 12b. REGIME DETECTION ENGINE
- // ═══════════════════════════════════════════════════════════════════════════════
- float sync_avg = ta.sma(sync_score, regime_window)
- bool this_bar_long_active = (long_grade == "A+" or long_grade == "B+")
- bool this_bar_short_active = (short_grade == "A+" or short_grade == "B+")
- float long_active_f = this_bar_long_active ? 1.0 : 0.0
- float short_active_f = this_bar_short_active ? 1.0 : 0.0
- float long_pct = ta.sma(long_active_f, regime_window) * 100
- float short_pct = ta.sma(short_active_f, regime_window) * 100
- bool sync_sustained = not na(sync_avg) and sync_avg >= regime_sync_thresh
- bool long_dominates = long_pct >= regime_bias_thresh and long_pct > short_pct
- bool short_dominates = short_pct >= regime_bias_thresh and short_pct > long_pct
- string current_regime = "NEUTRAL"
- if sync_sustained and long_dominates
- current_regime := "BULL"
- else if sync_sustained and short_dominates
- current_regime := "BEAR"
- var string confirmed_regime = "NEUTRAL"
- var int regime_hold_count = 0
- var string prev_raw_regime = "NEUTRAL"
- if current_regime == prev_raw_regime and current_regime != "NEUTRAL"
- regime_hold_count += 1
- else if current_regime != prev_raw_regime
- regime_hold_count := current_regime != "NEUTRAL" ? 1 : 0
- prev_raw_regime := current_regime
- string new_confirmed = confirmed_regime
- if current_regime != "NEUTRAL" and regime_hold_count >= regime_min_bars
- new_confirmed := current_regime
- else if current_regime == "NEUTRAL" and confirmed_regime != "NEUTRAL"
- new_confirmed := "NEUTRAL"
- bool regime_entered = new_confirmed != "NEUTRAL" and confirmed_regime == "NEUTRAL"
- bool regime_exited = new_confirmed == "NEUTRAL" and confirmed_regime != "NEUTRAL"
- bool regime_flipped = new_confirmed != "NEUTRAL" and confirmed_regime != "NEUTRAL" and new_confirmed != confirmed_regime
- string exiting_regime = confirmed_regime
- confirmed_regime := new_confirmed
- // ═══════════════════════════════════════════════════════════════════════════════
- // 12c. FVG INTERACTION HELPERS
- // ═══════════════════════════════════════════════════════════════════════════════
- bool bull_fvg_active = not na(bull_fvg_bottom) and not na(bull_fvg_top)
- bool bear_fvg_active = not na(bear_fvg_bottom) and not na(bear_fvg_top)
- bool price_in_bull_fvg = bull_fvg_active and close >= bull_fvg_bottom and close <= bull_fvg_top
- bool price_in_bear_fvg = bear_fvg_active and close >= bear_fvg_bottom and close <= bear_fvg_top
- bool bull_fvg_wick_overlap = bull_fvg_active and low <= bull_fvg_top and high >= bull_fvg_bottom
- bool bear_fvg_wick_overlap = bear_fvg_active and low <= bear_fvg_top and high >= bear_fvg_bottom
- bool bull_fvg_reaction_now = price_in_bull_fvg or (bull_fvg_wick_overlap and close > open)
- bool bear_fvg_reaction_now = price_in_bear_fvg or (bear_fvg_wick_overlap and close < open)
- int bull_fvg_age = bull_fvg_active ? bar_index - bull_fvg_birth_bar : 9999
- int bear_fvg_age = bear_fvg_active ? bar_index - bear_fvg_birth_bar : 9999
- bool bull_fvg_fresh = bull_fvg_age <= int(regime_fvg_proximity * 1.5)
- bool bear_fvg_fresh = bear_fvg_age <= int(regime_fvg_proximity * 1.5)
- var bool bull_fvg_touched_this_regime = false
- var bool bear_fvg_touched_this_regime = false
- if regime_entered or regime_flipped or regime_exited or confirmed_regime == "NEUTRAL"
- bull_fvg_touched_this_regime := false
- bear_fvg_touched_this_regime := false
- // ═══════════════════════════════════════════════════════════════════════════════
- // 12d. REGIME ALERTS (ALL TYPES CARRY FULL PAYLOAD)
- // ═══════════════════════════════════════════════════════════════════════════════
- // TYPE 1 — Transition alerts (entry / flip) + full payload
- if regime_alert_on and (regime_entered or regime_flipped)
- string regime_dir = confirmed_regime
- bool should_fire = false
- string reason = ""
- string fvg_detail = ""
- string tag = ""
- if regime_dir == "BULL" and bull_fvg_active
- if bull_fvg_reaction_now
- should_fire := true
- reason := "PRICE INTERACTING / REJECTING BULL FVG NOW"
- tag := "[FVG REACTION @ SHIFT]"
- fvg_detail := "Bull FVG " + str.tostring(bull_fvg_bottom, "#.##") + "–" +
- str.tostring(bull_fvg_top, "#.##") + " (age " +
- str.tostring(bull_fvg_age) + " bars)"
- else if bull_fvg_fresh
- should_fire := true
- reason := "FRESH BULL FVG PRESENT AT REGIME SHIFT"
- tag := "[FRESH FVG @ SHIFT]"
- fvg_detail := "Bull FVG " + str.tostring(bull_fvg_bottom, "#.##") + "–" +
- str.tostring(bull_fvg_top, "#.##") + " (age " +
- str.tostring(bull_fvg_age) + " bars)"
- else if regime_dir == "BEAR" and bear_fvg_active
- if bear_fvg_reaction_now
- should_fire := true
- reason := "PRICE INTERACTING / REJECTING BEAR FVG NOW"
- tag := "[FVG REACTION @ SHIFT]"
- fvg_detail := "Bear FVG " + str.tostring(bear_fvg_bottom, "#.##") + "–" +
- str.tostring(bear_fvg_top, "#.##") + " (age " +
- str.tostring(bear_fvg_age) + " bars)"
- else if bear_fvg_fresh
- should_fire := true
- reason := "FRESH BEAR FVG PRESENT AT REGIME SHIFT"
- tag := "[FRESH FVG @ SHIFT]"
- fvg_detail := "Bear FVG " + str.tostring(bear_fvg_bottom, "#.##") + "–" +
- str.tostring(bear_fvg_top, "#.##") + " (age " +
- str.tostring(bear_fvg_age) + " bars)"
- if should_fire
- string transition_type = regime_flipped ? "FLIP" : "ENTRY"
- string msg = "REGIME " + transition_type + ": " + regime_dir + " " + tag + "\n" +
- reason + "\n" +
- fvg_detail + "\n" +
- "Sync avg: " + str.tostring(sync_avg, "#.#") + " | " +
- "Bias L:" + str.tostring(long_pct, "#.#") + "% S:" +
- str.tostring(short_pct, "#.#") + "%\n" +
- alert_message
- alert(msg, alert.freq_once_per_bar)
- // TYPE 2 — Ongoing regime: first FVG touch / reaction + full payload
- bool new_bull_interaction = confirmed_regime == "BULL" and not bull_fvg_touched_this_regime and bull_fvg_reaction_now
- bool new_bear_interaction = confirmed_regime == "BEAR" and not bear_fvg_touched_this_regime and bear_fvg_reaction_now
- if new_bull_interaction and regime_alert_on
- bull_fvg_touched_this_regime := true
- string bull_msg = "BULL REGIME ACTIVE + 5M FVG TOUCH / REACTION\n" +
- "FVG: " + str.tostring(bull_fvg_bottom, "#.##") + "–" +
- str.tostring(bull_fvg_top, "#.##") +
- " | Age: " + str.tostring(bull_fvg_age) + " bars" +
- " | Sync: " + str.tostring(sync_score, "#.#") + "%\n" +
- alert_message
- alert(bull_msg, alert.freq_once_per_bar_close)
- if new_bear_interaction and regime_alert_on
- bear_fvg_touched_this_regime := true
- string bear_msg = "BEAR REGIME ACTIVE + 5M FVG TOUCH / REACTION\n" +
- "FVG: " + str.tostring(bear_fvg_bottom, "#.##") + "–" +
- str.tostring(bear_fvg_top, "#.##") +
- " | Age: " + str.tostring(bear_fvg_age) + " bars" +
- " | Sync: " + str.tostring(sync_score, "#.#") + "%\n" +
- alert_message
- alert(bear_msg, alert.freq_once_per_bar_close)
- // TYPE 3 — Regime breakdown + full payload
- if regime_alert_on and regime_exited
- alert("REGIME BREAKDOWN | Was: " + exiting_regime +
- " | Sync avg dropped below " + str.tostring(regime_sync_thresh, "#") +
- " or bias lost | Now NEUTRAL\n" +
- alert_message, alert.freq_once_per_bar)
- // ═══════════════════════════════════════════════════════════════════════════════
- // 13. CANDLE COLOURING & VISUALS
- // ═══════════════════════════════════════════════════════════════════════════════
- 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)
- plot(lon_mid, title="London Mid", color=lon_tested ? color.gray : color.aqua, linewidth=2)
- plot(long_target, title="Long Target", color=color.new(color.green, 70), style=plot.style_linebr, linewidth=1)
- plot(short_target, title="Short Target", color=color.new(color.red, 70), style=plot.style_linebr, linewidth=1)
- plot(show_pivots ? pivot_p : na, title="Daily Pivot", color=color.yellow, linewidth=1)
- plot(show_vwap and not na(vwap_8am) ? vwap_8am : na, title="VWAP 8AM", color=color.blue, linewidth=2)
- plot(show_tick_auction and not na(tick_poc) ? tick_poc : na, title="Tick Auction POC", color=color.orange, linewidth=2, style=plot.style_linebr)
- plot(show_tick_auction and not na(tick_vah) ? tick_vah : na, title="Tick Auction VAH", color=color.new(color.red, 50), linewidth=1, style=plot.style_linebr)
- plot(show_tick_auction and not na(tick_val) ? tick_val : na, title="Tick Auction VAL", color=color.new(color.green, 50), linewidth=1, style=plot.style_linebr)
- if show_ob and not na(bull_ob_top) and not na(bull_ob_bottom)
- box.new(left=bar_index - 50, top=bull_ob_top, right=bar_index, bottom=bull_ob_bottom, border_color=color.green, bgcolor=color.new(color.green, 90))
- // ═══════════════════════════════════════════════════════════════════════════════
- // 14. REGIME-GATED GRADE ALERTS — TYPE 4 (FVG REQUIRED + FULL PAYLOAD)
- // ═══════════════════════════════════════════════════════════════════════════════
- var string prev_long_grade = "X"
- var string prev_short_grade = "X"
- var int conflict_cooldown = 0
- var int alert_cooldown = 0
- bool dual_signal = long_grade != "X" and short_grade != "X"
- if dual_signal
- conflict_cooldown := 5
- if conflict_cooldown > 0 and not dual_signal
- conflict_cooldown -= 1
- if alert_cooldown > 0
- alert_cooldown -= 1
- bool alerts_allowed = not dual_signal and conflict_cooldown == 0 and alert_cooldown == 0
- // Gate: regime must be active + aligned FVG interaction required
- bool regime_bull_fvg = confirmed_regime == "BULL" and bull_fvg_reaction_now
- bool regime_bear_fvg = confirmed_regime == "BEAR" and bear_fvg_reaction_now
- bool long_grade_valid = (long_grade == "A+" or long_grade == "B+")
- bool short_grade_valid = (short_grade == "A+" or short_grade == "B+")
- bool long_alert_new = long_grade_valid and prev_long_grade == "X" and alerts_allowed and regime_bull_fvg
- bool short_alert_new = short_grade_valid and prev_short_grade == "X" and alerts_allowed and regime_bear_fvg
- if long_alert_new and regime_alert_on
- alert(long_grade + " LONG | BULL REGIME + FVG | " + alert_message, alert.freq_once_per_bar)
- alert_cooldown := 3
- if short_alert_new and regime_alert_on
- alert(short_grade + " SHORT | BEAR REGIME + FVG | " + alert_message, alert.freq_once_per_bar)
- alert_cooldown := 3
- prev_long_grade := long_grade
- prev_short_grade := short_grade
- // ═══════════════════════════════════════════════════════════════════════════════
- // 15. MASTER DASHBOARD UI
- // ═══════════════════════════════════════════════════════════════════════════════
- var table phidias_tbl = table.new(position.top_left, columns=2, rows=8,
- bgcolor=color.new(color.black, 15),
- border_color=color.new(color.gray, 50),
- border_width=1)
- if barstate.islast
- table.cell(phidias_tbl, 0, 0, "PHIDIAS ENGINE v9.9.4",
- text_color=color.white, text_size=size.small, text_halign=text.align_center)
- table.merge_cells(phidias_tbl, 0, 0, 1, 0)
- color regime_col = confirmed_regime == "BULL" ? color.new(color.green, 20) :
- confirmed_regime == "BEAR" ? color.new(color.red, 20) :
- color.new(color.gray, 50)
- table.cell(phidias_tbl, 0, 1, "REGIME:",
- text_color=color.white, text_halign=text.align_left)
- table.cell(phidias_tbl, 1, 1, confirmed_regime,
- bgcolor=regime_col, text_color=color.white, text_halign=text.align_center)
- color sync_col = sync_score > 75 ? color.green :
- sync_score > 60 ? color.orange : color.red
- table.cell(phidias_tbl, 0, 2, "INST. SYNC:",
- text_color=color.white, text_halign=text.align_left)
- table.cell(phidias_tbl, 1, 2, str.tostring(sync_score, "#.#") + "%",
- text_color=sync_col, text_halign=text.align_center)
- table.cell(phidias_tbl, 0, 3, "LONG GRADE:",
- text_color=color.white, text_halign=text.align_left)
- table.cell(phidias_tbl, 1, 3, long_grade,
- bgcolor=f_grade_bg(long_grade), text_color=f_grade_tc(long_grade), text_halign=text.align_center)
- table.cell(phidias_tbl, 0, 4, "SHORT GRADE:",
- text_color=color.white, text_halign=text.align_left)
- table.cell(phidias_tbl, 1, 4, short_grade,
- bgcolor=f_grade_bg(short_grade), text_color=f_grade_tc(short_grade), text_halign=text.align_center)
- table.cell(phidias_tbl, 0, 5, "LONG VETO:",
- text_color=color.white, text_halign=text.align_left)
- table.cell(phidias_tbl, 1, 5, long_pass ? "PASS" : long_veto,
- bgcolor=long_pass ? color.new(color.green, 70) : color.new(color.red, 70),
- text_halign=text.align_center)
- table.cell(phidias_tbl, 0, 6, "SHORT VETO:",
- text_color=color.white, text_halign=text.align_left)
- table.cell(phidias_tbl, 1, 6, short_pass ? "PASS" : short_veto,
- bgcolor=short_pass ? color.new(color.green, 70) : color.new(color.red, 70),
- text_halign=text.align_center)
- string fvg_status = bull_fvg_active or bear_fvg_active ? "[5M FVG ACTIVE]" : "[NO ACTIVE 5M FVG]"
- table.cell(phidias_tbl, 0, 7, fvg_status,
- text_color=color.gray, text_size=size.tiny, text_halign=text.align_center)
- table.merge_cells(phidias_tbl, 0, 7, 1, 7)
RAW Gist Data
Copied
