GEX + EFP Basis Matrix v29 · ซอร์สโค้ด
Pine Script ต้นฉบับ
ไฟล์นี้ถูกคัดลอกจากต้นฉบับใน G:\Trader\PineSCript\ ตอนสร้างเว็บ
จึงเป็นโค้ดชุดเดียวกับที่ทำงานอยู่บนชาร์ตจริง ณ วันที่ปรับปรุง
Pine Script ยังไม่มีไวยากรณ์เฉพาะสำหรับตัวไฮไลต์ที่ใช้ จึงไฮไลต์ด้วยไวยากรณ์ TypeScript ซึ่งใกล้เคียงกันพอที่จะอ่านง่าย
ตัวเลขบรรทัดตรงกับไฟล์จริง ใช้อ้างอิงในบทเรียนได้ เช่น gex-v29.pine:120
สารบัญส่วนของโค้ด (29)
- 134 §1 INPUTS
- 452 §2 TYPES + FUNCTIONS
- 577 §3 RS DATA FETCH (7 calls — _efp_fut_h4 H4 restored in v21 revised)
- 595 §4 BASIS ENGINE + COMEX CIRCUIT BREAKER TIERS
- 729 §5 SPOTEX LEVELS
- 757 §6 GEX PHYSICS ENGINE + VWAP (London daily-reset fix) + ALMA
- 855 §5b DUAL-SYSTEM SD LEVELS
- 896 §7 GVZ VOLATILITY REGIME
- 912 §8 DXY MACRO FILTER [v19 fix: fully implemented — was stub in v18]
- 930 §9 MLMI COMPUTATION (k=987, momentumWindow=10, session-aware decay)
- 967 §10 SMI COMPUTATION (K=10, D=3, EMA=3 — OB=+40, OS=-40)
- 986 §11 QUANTALGO VOLUME INTELLIGENCE
- 1081 §11b BUBBLE CONTEXT — LTF INTRABAR POSITION → AMT EVENT CLASSIFIER [v26]
- 1213 §12 AMT PATTERN ENGINE — SOVEREIGN §24b ADAPTED
- 1364 §13 CONFLUENCE CHECKS
- 1387 §14 SQUEEZE + BUBBLE PROXIMITY
- 1429 §15 REGIME FSM [v19: ATR-based breakout fallback]
- 1459 §16 REGIME CONFIDENCE SCORE [v19: CB tier penalty added]
- 1511 §FRZ FROZEN ZONE DISPLAY — ported from QC_BasisMatrix v8.4 §13
- 1589 §14b SQUEEZE LABELS [v22 new] — label.new() → 0 plot-budget units
- 1667 §16c EXPANSION SCORE + MR-INTO-TREND [v27] — DISPLAY-ONLY (label → 0 budget)
- 1748 §17 SIGNAL LOGIC — Priority Gate C/D > A/B > E/F (+MLMI/SMI+DXY gates)
- 1848 §K K-MEANS CLUSTER VP (unchanged from v18)
- 1859 §18 CHART LINES + LABELS + CVP (barstate.islast)
- 2176 §19 CHART PLOTS + SIGNALS
- 2230 §19b NO-VOLUME WARNING TABLE
- 2246 §20 ALERTS (all const string — CE10123 compliant)
- 2285 §19 REGIME MATRIX + Γ-PROXY [v28] — DISPLAY-ONLY (one table → 0 plot-budget)
- 2438 §19c DEEP-FIB PREMIUM / DISCOUNT [v29] — box/line/label only → 0 plot-budget
//@version=6
// ╔═══════════════════════════════════════════════════════════════════════════════════╗
// ║ Gex and EFP Basis Matrix | GEX+ALMA+AMT Sovereign+MLMI+SMI+g3+YZsqz | XAUUSD ║
// ║ Pine Script v6 | CE:0 RE:0 CW:0 | BUDGET: 19/64u declared ~64/64u total ║
// ║ Production Grade: CME/COMEX + LBMA Gold Desk Standard ║
// ╚═══════════════════════════════════════════════════════════════════════════════════╝
//
// CHANGES v28 → v29 (all DISPLAY-ONLY · 0 plot-budget · file stays 63/64)
// ─────────────────────────────────────────────────────────────────────────────────
// [v29-1] §19 ACTION AUTO-FLIP on Γ conflict — the headline verb now FLIPS
// (FOLLOW↔FADE/RANGE, MR-FADE↔FOLLOW/BREAK) + route + colour when
// the Γ-proxy strongly overrides the direction cell (|Γ-score| ≥
// i_rm_gth), with i_rm_hyst-bar hysteresis to kill flicker. Toggle
// i_rm_autoflip (default ON). OFF = v28 (headline stays, ⚠ tag only).
// Same info — removes the mis-read that "FOLLOW + Γ⚠fade-risk" caused.
// [v29-2] §19 ADX/DI rows (i_rm_adx, default OFF) — ta.dmi → 2 table rows (ADX strength
// + DI± direction). ⚠ read WITH DI, never a lone gate (ER lesson).
// [v29-3] §19c DEEP-FIB PREMIUM/DISCOUNT (i_rm_fib, default OFF) — swing range split into
// PREMIUM(upper/sell) / DISCOUNT(lower/buy) + deep 0.705–0.886 zones
// (Kmer 'trade from discount'). box/line/label only. Isolated block.
// All three: own toggles, own prefixes, NO existing logic touched,
// NO plot/fill/alert added → no RE10140 risk.
//
// CHANGES v27 → v28
// ─────────────────────────────────────────────────────────────────────────────────
// [v28-1] §19 REGIME MATRIX + Γ-PROXY — NEW, group ⑳. DISPLAY-ONLY (one table → 0
// plot-budget; file stays 63/64). Unifies Direction × Volatility
// into the 6-regime matrix (Bull/Sideways/Bear × Quiet/Volatile)
// with a per-cell prescription (follow full / ×0.6 / MR-fade @VA /
// STAND ASIDE / preserve ×0.5) + EA routing. Direction = close vs
// EMA200 baseline + slope; Volatility = YZ ratio expansion / GVZ
// elevated-extreme. Plus a POS/NEG-GAMMA PROXY (NOT real dealer
// gamma — gold has no options chain; a vol-behaviour footprint):
// 5 orthogonal votes → signed Γ-score →
// VarianceRatio VR(k) (replaces Hurst) · RV−GVZ (realized vs
// implied) · YZ fast/slow · trend-efficiency ER · vs g1 flip.
// pos-Γ = vol dampening → fade/failed BO; neg-Γ = amplifying →
// follow/trend. Γ tag flags fade-vs-trend conflict on the action.
// Black table bg (default), adjustable size + position (default
// Top Left). Toggle i_rm_on. NOT entry — no gate/conf_score touched
// (port to gate → walk-forward OOS first). M5 defaults.
//
// CHANGES v26 → v27
// ─────────────────────────────────────────────────────────────────────────────────
// [v27-1] §16c EXPANSION SCORE + MR-INTO-TREND — NEW, group ⑲. DISPLAY-ONLY.
// Two reads from the "3 primitives" framework, as labels only:
// • EXPANSION = breakout trigger — bar range ≥ i_exp_thr × the
// i_exp_len-bar average range → "EXP▲/▼ N×" marker (dir by
// candle). The volatility-expansion counterpart to the ⑰ squeeze
// (compression) detector.
// • MR-INTO-TREND = buy-the-dip WITH the trend — inside regime ±1,
// price retests the g1 flip level (broken resistance→support in an
// uptrend / support→resistance in a downtrend) → "MR→trend BUY/
// SELL" label + pullback-depth% in tooltip (deeper = higher prob).
// The systematic answer to "never fade AGAINST the trend": this
// fades TOWARD it.
// Uses only label.new (0 plot-budget — file is at 63/64). Dedup via
// i_dedup; expansion fires on fresh onset only. Toggles: i_xmt_on +
// i_exp_lbl / i_mrt_lbl. NOT an entry — no gate/conf_score touched
// (any port to entry logic → walk-forward OOS first). M5 defaults.
//
// CHANGES v25 → v26
// ─────────────────────────────────────────────────────────────────────────────────
// [v26-1] §11b BUBBLE CONTEXT ENGINE (LTF Position → AMT event) — NEW, group ⑬b.
// Upgrades the ⑫ volume bubbles: previously they only reported
// size + BUY/SELL side. Now, on each classified bubble bar, the
// engine pulls lower-TF intrabar bars (request.security_lower_tf),
// bins them into the candle's high→low range, finds the volume POC
// (the intrabar cluster), reads the net delta AT that cluster, and
// combines {candle direction × cluster side × cluster position} to
// NAME the event exactly per the AMT reference cards:
// Bullish candle → cluster TOP+sell = rejection · TOP+buy =
// abs-contrarian (both bearish/red) · MID buy = acceptance buy ·
// BOT sell = abs-continue (both bullish/green).
// Bearish candle = mirror image.
// Draws: (a) a position DOT at the true cluster price (colored by
// cluster side buy/sell), (b) a CONTEXT LABEL naming the pattern,
// colored by OUTCOME (green=bullish, red=bearish), placed below the
// low (bullish outcome) / above the high (bearish outcome).
// Toggles: master (i_bctx_on), labels (i_bctx_lbl), dot (i_bctx_dot),
// LTF res (i_bctx_ltf, def "1"), bins (20), top/bot zone (.66/.34),
// size gate (Medium+), colors, size, side-arrow. M5 defaults.
// + 2 alerts (reversal UP / DOWN). DISPLAY-ONLY: touches no gate /
// conf_score / entry logic (any port to entry → walk-forward OOS).
// Proxy caveat: LTF wick-weighted delta = eyes, not a validated edge.
//
// CHANGES v24 → v25
// ─────────────────────────────────────────────────────────────────────────────────
// [v25-1] §12 AMT ACCEPTANCE LABELS: "Accept Buy" / "Accept Sell" text labels added
// alongside the existing "●" dot for ACCEPTANCE BUY/SELL patterns.
// Text uses size.tiny (matches normal chart labels). Dot (●) at
// _emj_sz_resolved unchanged. Text label added to _amt_lbs array
// (cap 400 preserved).
// [v25-2] INPUT DEFAULTS updated to match preferred configuration:
// EFP Basis Mode: SESSION (was ORIGINAL)
// PBV L1: 1.71% (was 2.150%), PBV L2: 2.1278% (was 3.414%),
// PBV L3: 3.618% (was 3.730%)
// Explosion (g3): 5.0 (was 4.236)
// CB Signal Gate: true (was false)
// Show gFlip g1 Labels: false (was true)
// Show SpotEx ATM: false (was true)
// Show Gamma Wall Labels: false (was true)
// Show Explosion Labels: false (was true)
// Show PHI System: false (was true)
// Show EM +/-2sigma: true (was false)
// ALMA L1/L2/L3 Width: 1 (was 2)
// QA Small Percentile: 90 (was 75), Medium Percentile: 93 (was 90)
// Show Small Clusters: false (was true)
//
// CHANGES v23 → v24 (prior changelog preserved)
// ─────────────────────────────────────────────────────────────────────────────────
// [v23-1] §14 : Squeeze false-positive filters added (2-layer)
// Filter 1: Min Compression Duration — sqz_dur[1] >= i_sqz_min_dur
// Filter 2: YZ Ratio Expansion Confirmation — _yz_ratio > _yz_ratio[1]
// [v23-2] §17 : alert titles/messages updated
// CHANGES v23 → v24 : max_boxes_count=500, MLMI array cap (preserved)
// CHANGES v22 → v23 : Squeeze false-positive filters (preserved)
// CHANGES v21 → v22 : YZ-based Squeeze Detector + 2 alerts (preserved)
// CHANGES v18 → v21 : table fix, London VWAP reset, basis_cv abs, DXY filter,
// cond_I/J dedup, GOFO input, COMEX CB tiers, ATR fallback,
// Globex open, conf_score CB penalty (all preserved)
// ─────────────────────────────────────────────────────────────────────────────────
indicator(
title = "Gex and EFP Basis Matrix v29 | GEX+ALMA+AMT Sovereign+MLMI+SMI+g3+YZsqz+BubbleCtx+ExpMRT+RegimeMatrix | XAUUSD",
shorttitle = "GEX+EFP Matrix v29",
overlay = true,
max_lines_count = 500,
max_labels_count = 500,
max_boxes_count = 500,
max_bars_back = 2000)
// ═══════════════════════════════════════════════════════════════════════════════
// §1 INPUTS
// ═══════════════════════════════════════════════════════════════════════════════
const string G_FEED = "① BASIS MATRIX"
string i_efp_mode = input.string("SESSION","EFP Basis Mode",options=["ORIGINAL","SESSION","1-MINUTE"],group=G_FEED)
string i_fut_sym = input.symbol("COMEX:GC1!","Futures Ticker (COMEX)",group=G_FEED)
string i_gvz_sym = input.symbol("CBOE:GVZ", "GVZ Vol Index (CBOE)", group=G_FEED)
int i_basis_len = input.int(200, "Basis SMA Length",group=G_FEED,minval=20)
float i_block = input.float(25.0,"COMEX Strike Block ($)",group=G_FEED,step=5.0)
float i_sd_mult = input.float(1.618,"SD Level phi (sigma)",group=G_FEED,step=0.001)
float i_pbv_1 = input.float(1.71, "PBV L1 % (1.71)", group=G_FEED,step=0.001)
float i_pbv_2 = input.float(2.1278,"PBV L2 % (2.1278)",group=G_FEED,step=0.001)
float i_pbv_3 = input.float(3.618, "PBV L3 % (3.618)", group=G_FEED,step=0.001)
float i_gofo_rate = input.float(4.20,"GOFO Rate % (1-month)",group=G_FEED,step=0.05,minval=0.0,maxval=20.0,tooltip="1-month Gold Forward Offered Rate. Update daily from LBMA GOFO page.")
const string G_GEX = "② GEX PHYSICS (Yang-Zhang)"
int i_vol_lb = input.int(600, "YZ Lookback (bars)",group=G_GEX,minval=50)
float i_vol_mult = input.float(5.0,"Implied Vol Multiplier",group=G_GEX,step=0.1)
string i_sigma_mode= input.string("FIBONACCI","sigma Level Mode",group=G_GEX,options=["FIBONACCI","GAUSSIAN"])
float i_g1 = input.float(1.618,"Zero Gamma Flip",group=G_GEX,step=0.001)
float i_g2 = input.float(3.236,"Gamma Wall",group=G_GEX,step=0.001)
float i_g3 = input.float(5.0, "Explosion",group=G_GEX,step=0.001)
float i_sig_floor = input.float(2.0, "Sigma Floor (xATR14)",group=G_GEX,step=0.1)
const string G_VOL = "③ GVZ REGIME FILTER"
bool i_gvz_en = input.bool(true, "Enable GVZ Filter",group=G_VOL)
float i_gvz_norm = input.float(24.0,"GVZ Normal Threshold",group=G_VOL,step=1.0)
float i_gvz_elev = input.float(32.0,"GVZ Elevated Threshold",group=G_VOL,step=1.0)
float i_gvz_ext = input.float(42.0,"GVZ Extreme Threshold",group=G_VOL,step=1.0)
const string G_DXY = "④ DXY MACRO FILTER"
bool i_dxy_en = input.bool(true,"Enable DXY Filter",group=G_DXY)
int i_dxy_roc = input.int(5,"DXY ROC Period (bars)",group=G_DXY,minval=2,maxval=20)
float i_dxy_thr = input.float(0.3,"DXY ROC Threshold (%)",group=G_DXY,step=0.1)
const string G_CB = "⑤ COMEX CIRCUIT BREAKER (Awareness)"
bool i_show_cb = input.bool(true, "Show CB Tier Lines",group=G_CB,tooltip="COMEX Globex rule 589: ±3/±6/±9% from prior settle triggers halts. Displayed as awareness only — does NOT block signals unless CB Gate enabled.")
bool i_cb_gate = input.bool(true, "Enable CB Signal Gate (blocks MR inside ±3%)",group=G_CB,tooltip="When enabled, MR signals are blocked if price is within the ±3% CB tier band. Recommended: OFF for scalping, ON for swing.")
color i_cb_t1_col = input.color(color.new(#FF9800,40),"CB Tier 1 (±3%) Color",group=G_CB)
color i_cb_t2_col = input.color(color.new(#FF1744,40),"CB Tier 2 (±6%) Color",group=G_CB)
color i_cb_t3_col = input.color(color.new(#D500F9,35),"CB Tier 3 (±9%) Color",group=G_CB)
const string G_EXEC = "⑥ EXECUTION"
float i_tol = input.float(3.0,"Zone Tolerance ($)",group=G_EXEC,step=0.5)
float i_body_min = input.float(0.40,"Min Candle Body Ratio",group=G_EXEC,step=0.05)
int i_evt_win = input.int(5,"Event Window (bars)",group=G_EXEC,minval=1,maxval=20)
float i_prox_mult = input.float(1.5,"Bubble Proximity Mult",group=G_EXEC,step=0.1)
int i_dedup = input.int(5,"Dedup Window (bars)",group=G_EXEC,minval=1,maxval=20)
bool i_prio_gate = input.bool(true,"Signal Priority Gate C/D>A/B>E/F",group=G_EXEC)
int i_out_bars = input.int(2,"Regime Hysteresis (bars)",group=G_EXEC,minval=1,maxval=5)
int i_n_str = input.int(2,"N Strikes to show",group=G_EXEC,minval=1,maxval=4)
bool i_sess_filt = input.bool(true,"No MR 00-02:59 UTC",group=G_EXEC)
const string G_VIS = "⑦ VISUALIZATION"
bool i_show_map = input.bool(true, "Show Regime Heatmap",group=G_VIS)
bool i_show_g1 = input.bool(false,"Show gFlip g1 Labels",group=G_VIS)
bool i_show_atm = input.bool(false,"Show SpotEx ATM",group=G_VIS)
bool i_show_vwap = input.bool(true, "Show VWAP Label",group=G_VIS)
bool i_show_dvwap = input.bool(false,"Show Daily VWAP (secondary)",group=G_VIS)
bool i_rich_lbl = input.bool(true, "Rich Strike Labels",group=G_VIS)
bool i_show_g2 = input.bool(false,"Show Gamma Wall Labels (2x)",group=G_VIS)
bool i_show_g3 = input.bool(false,"Show Explosion Labels (3x)",group=G_VIS)
bool i_show_sd = input.bool(true, "Show SD/PBV Levels",group=G_VIS)
bool i_show_phi = input.bool(false," Show PHI System (1.618sigma)",group=G_VIS)
bool i_show_delta_sys = input.bool(true," Show DELTA System (25D/15D/5D)",group=G_VIS)
string i_sd_signal = input.string("DELTA"," Signal Source (cond_C/D)",group=G_VIS,options=["PHI","DELTA"])
bool i_show_str = input.bool(true, "Show SpotEx Strikes",group=G_VIS)
bool i_show_em = input.bool(true, "Show Expected Move +/-1sigma",group=G_VIS)
bool i_show_em2 = input.bool(true, "Show Expected Move +/-2sigma",group=G_VIS)
bool i_show_rr = input.bool(true, "Show Risk Reversal Label",group=G_VIS)
bool i_show_vpin = input.bool(true, "Show VPIN Proxy Label",group=G_VIS)
color i_c_g1 = input.color(color.new(color.gray,40),"gFlip color",group=G_VIS)
color i_c_g2u = input.color(color.new(#FF1744,0),"Wall+2x",group=G_VIS)
color i_c_g2d = input.color(color.new(#00E676,0),"Wall-2x",group=G_VIS)
color i_c_g3 = input.color(color.new(#D500F9,0),"Explosion 3x",group=G_VIS)
color i_c_sd = input.color(color.new(#FF9800,40),"SD Level",group=G_VIS)
color i_c_pbv = input.color(color.new(#CE93D8,40),"PBV Level",group=G_VIS)
color i_c_buy = input.color(#00E676,"BUY Signal",group=G_VIS)
color i_c_sell = input.color(#FF1744,"SELL Signal",group=G_VIS)
const string G_STR_COL = "⑦ VISUALIZATION — SPOTEX COLORS"
color i_cc_line = input.color(color.new(#00BCD4,50),"Call Line",group=G_STR_COL)
color i_cp_line = input.color(color.new(#00BCD4,50),"Put Line",group=G_STR_COL)
color i_c_blk_ln = input.color(color.new(#FF1744,35),"Blocked Line",group=G_STR_COL)
color i_cc_bg_norm = input.color(color.new(#FF9800,50),"Call Label BG (Normal)",group=G_STR_COL)
color i_cc_bg_med = input.color(color.new(#FF9800,20),"Call Label BG (Med)",group=G_STR_COL)
color i_cc_bg_str = input.color(color.new(#FF1744,10),"Call Label BG (Strong)",group=G_STR_COL)
color i_cp_bg_norm = input.color(color.new(#B0BEC5,50),"Put Label BG (Normal)",group=G_STR_COL)
color i_cp_bg_med = input.color(color.new(#00BCD4,20),"Put Label BG (Med)",group=G_STR_COL)
color i_cp_bg_str = input.color(color.new(#00E676,10),"Put Label BG (Strong)",group=G_STR_COL)
color i_c_blk_bg = input.color(color.new(#FF1744,40),"Blocked Label BG",group=G_STR_COL)
color i_cc_txt_norm= input.color(#607D8B,"Call Text (Normal)",group=G_STR_COL)
color i_cc_txt_med = input.color(#FF9800,"Call Text (Med)",group=G_STR_COL)
color i_cc_txt_str = input.color(#FF1744,"Call Text (Strong)",group=G_STR_COL)
color i_cp_txt_norm= input.color(#607D8B,"Put Text (Normal)",group=G_STR_COL)
color i_cp_txt_med = input.color(#00BCD4,"Put Text (Med)",group=G_STR_COL)
color i_cp_txt_str = input.color(#00E676,"Put Text (Strong)",group=G_STR_COL)
color i_c_blk_txt = input.color(#FF1744,"Blocked Text",group=G_STR_COL)
const string G_STYL = "⑧ LINE STYLE — PHI System"
color i_phi_col = input.color(color.new(#FF9800,25),"PHI Line Color",group=G_STYL)
int i_phi_width = input.int(1,"PHI Line Width (1-4)",group=G_STYL,minval=1,maxval=4)
string i_phi_style = input.string("Dotted","PHI Line Style",group=G_STYL,options=["Solid","Dashed","Dotted"])
int i_phi_lbl_tr= input.int(75,"PHI Label Transparency",group=G_STYL,minval=0,maxval=100)
const string G_STYL2 = "⑧ LINE STYLE — DELTA System"
float i_delta_dte = input.float(1.0," DELTA DTE (days)",group=G_STYL2,step=0.25,minval=0.1,maxval=5.0)
float i_skew_15d_p = input.float(1.29,"15D Put Skew x",group=G_STYL2,step=0.01,minval=0.8,maxval=2.0)
float i_skew_15d_c = input.float(1.27,"15D Call Skew x",group=G_STYL2,step=0.01,minval=0.8,maxval=2.0)
float i_skew_5d_p = input.float(1.21," 5D Put Skew x",group=G_STYL2,step=0.01,minval=0.8,maxval=2.0)
float i_skew_5d_c = input.float(1.23," 5D Call Skew x",group=G_STYL2,step=0.01,minval=0.8,maxval=2.0)
color i_d25_col = input.color(color.new(#FF6F00,5), "25D Color",group=G_STYL2)
int i_d25_width = input.int(1,"25D Width (1-4)",group=G_STYL2,minval=1,maxval=4)
string i_d25_style = input.string("Dotted","25D Style",group=G_STYL2,options=["Solid","Dashed","Dotted"])
int i_d25_lbl_tr = input.int(50,"25D Label Transparency",group=G_STYL2,minval=0,maxval=100)
color i_d15_col = input.color(color.new(#FFA726,35),"15D Color",group=G_STYL2)
int i_d15_width = input.int(1,"15D Width (1-4)",group=G_STYL2,minval=1,maxval=4)
string i_d15_style = input.string("Dotted","15D Style",group=G_STYL2,options=["Solid","Dashed","Dotted"])
int i_d15_lbl_tr = input.int(65,"15D Label Transparency",group=G_STYL2,minval=0,maxval=100)
color i_d5_col = input.color(color.new(#90A4AE,55)," 5D Color",group=G_STYL2)
int i_d5_width = input.int(1," 5D Width (1-4)",group=G_STYL2,minval=1,maxval=4)
string i_d5_style = input.string("Dotted"," 5D Style",group=G_STYL2,options=["Solid","Dashed","Dotted"])
int i_d5_lbl_tr = input.int(75," 5D Label Transparency",group=G_STYL2,minval=0,maxval=100)
string i_sd_lbl_sz = input.string("Tiny","SD/Delta Label Size",group=G_STYL2,options=["Tiny","Small","Normal"])
color i_d35_col = input.color(color.new(#FF5722,50),"35D Color",group=G_STYL2)
color i_d45_col = input.color(color.new(#E64A19,50),"45D Color",group=G_STYL2)
bool i_show_fill = input.bool(true,"Show Delta Zone Fills",group=G_STYL2)
color i_fill_5_15 = input.color(color.new(#90A4AE,90),"Fill 5D-15D", group=G_STYL2)
color i_fill_15_25 = input.color(color.new(#FFA726,90),"Fill 15D-25D",group=G_STYL2)
color i_fill_25_35 = input.color(color.new(#FF6F00,90),"Fill 25D-35D",group=G_STYL2)
color i_fill_35_45 = input.color(color.new(#FF1744,90),"Fill 35D-45D",group=G_STYL2)
const string G_BAND = "⑨ GEX BANDS — Continuous History"
bool i_show_g1_band = input.bool(true,"Show gFlip g1 Band (+/-1.618sigma)",group=G_BAND)
color i_band_g1_col = input.color(color.new(#00BCD4,20),"g1 Band Color",group=G_BAND)
int i_band_g1_w = input.int(1,"g1 Width (1-4)",group=G_BAND,minval=1,maxval=4)
bool i_show_g2_band = input.bool(true,"Show gWall g2 Band (+/-3.414sigma)",group=G_BAND)
color i_band_g2u_col = input.color(color.new(#FF1744,30),"g2+ Call Wall Color",group=G_BAND)
color i_band_g2d_col = input.color(color.new(#00E676,30),"g2- Put Wall Color", group=G_BAND)
int i_band_g2_w = input.int(1,"g2 Width (1-4)",group=G_BAND,minval=1,maxval=4)
bool i_show_g3_band = input.bool(true,"Show gExp g3 Band (+/-5sigma)",group=G_BAND)
color i_band_g3_col = input.color(color.new(#D500F9,40),"g3 Explosion Color",group=G_BAND)
int i_band_g3_w = input.int(1,"g3 Width (1-4)",group=G_BAND,minval=1,maxval=4)
string i_band_g1_sty = input.string("Dotted","g1 Band Style",group=G_BAND,options=["Solid","Dashed","Dotted"])
string i_band_g2_sty = input.string("Dotted","g2 Band Style",group=G_BAND,options=["Solid","Dashed","Dotted"])
string i_band_g3_sty = input.string("Dotted","g3 Band Style",group=G_BAND,options=["Solid","Dashed","Dotted"])
const string G_CVP = "⑩ K-MEANS CLUSTER VP"
bool i_show_cvp = input.bool(true, "Show K-Means Cluster VP",group=G_CVP)
int i_cvp_lb = input.int(377, "Lookback Period (bars)",group=G_CVP,minval=50,maxval=2000)
int i_n_clusters = input.int(5, "Number of Clusters",group=G_CVP,minval=2,maxval=10)
int i_km_iter = input.int(50, "K-Means Iterations",group=G_CVP,minval=10,maxval=200)
color i_cvp_col = input.color(color.new(#FFD700,30),"Cluster Line Color",group=G_CVP)
bool i_cvp_label = input.bool(true,"Show Cluster Labels",group=G_CVP)
bool i_cvp_dots = input.bool(true,"Highlight Price at Cluster Level",group=G_CVP)
int i_cvp_ext = input.int(50,"Cluster Line Extension (bars)",group=G_CVP,minval=10,maxval=500)
int i_cvp_line_w = input.int(1,"Cluster Line Width (1-4)",group=G_CVP,minval=1,maxval=4)
string i_cvp_poc_sty= input.string("Dotted","POC Line Style",group=G_CVP,options=["Solid","Dashed","Dotted"])
string i_cvp_clus_sty=input.string("Dotted","Cluster Line Style",group=G_CVP,options=["Solid","Dashed","Dotted"])
string i_cvp_lbl_sz = input.string("Tiny","Cluster Label Size",group=G_CVP,options=["Tiny","Small","Normal"])
string i_cvp_dot_sz2= input.string("small","CVP Dot Size (near cluster)",group=G_CVP,options=["tiny","small","normal"])
color i_cvp_poc_col= input.color(color.new(#FF6F00,0),"POC Star Color",group=G_CVP)
const string G_ALMA = "⑪ ALMA MOVING AVERAGES"
bool i_show_alma = input.bool(true,"Show ALMA Lines",group=G_ALMA)
int i_al1_len = input.int(59, "L1 Length (Fast)",group=G_ALMA,minval=2)
float i_al1_offset = input.float(0.85,"L1 Offset (0-1)",group=G_ALMA,step=0.01,minval=0.0,maxval=1.0)
float i_al1_sigma = input.float(6.0, "L1 Sigma",group=G_ALMA,step=0.5,minval=1.0)
color i_al1_col = input.color(color.new(#00FF88,0),"L1 Color (Fast)",group=G_ALMA)
int i_al1_w = input.int(1,"L1 Width (1-4)",group=G_ALMA,minval=1,maxval=4)
int i_al2_len = input.int(125, "L2 Length (Medium)",group=G_ALMA,minval=2)
float i_al2_offset = input.float(0.85,"L2 Offset",group=G_ALMA,step=0.01,minval=0.0,maxval=1.0)
float i_al2_sigma = input.float(6.0, "L2 Sigma",group=G_ALMA,step=0.5,minval=1.0)
color i_al2_col = input.color(color.new(#FFCC00,0),"L2 Color (Med)",group=G_ALMA)
int i_al2_w = input.int(1,"L2 Width (1-4)",group=G_ALMA,minval=1,maxval=4)
int i_al3_len = input.int(215, "L3 Length (Slow)",group=G_ALMA,minval=2)
float i_al3_offset = input.float(0.85,"L3 Offset",group=G_ALMA,step=0.01,minval=0.0,maxval=1.0)
float i_al3_sigma = input.float(6.0, "L3 Sigma",group=G_ALMA,step=0.5,minval=1.0)
color i_al3_col = input.color(color.new(#FF0044,0),"L3 Color (Slow)",group=G_ALMA)
int i_al3_w = input.int(1,"L3 Width (1-4)",group=G_ALMA,minval=1,maxval=4)
const string G_QA = "⑫ VOLUME INTELLIGENCE (QuantAlgo Consensus)"
int i_qa_short = input.int(20, "Short Window",group=G_QA,minval=5,maxval=100)
int i_qa_mid = input.int(50, "Medium Window",group=G_QA,minval=10,maxval=300)
int i_qa_long = input.int(100, "Long Window",group=G_QA,minval=20,maxval=500)
float i_qa_sm_pct = input.float(90.0,"Small Percentile",group=G_QA,step=1.0,minval=50.0,maxval=95.0)
float i_qa_md_pct = input.float(93.0,"Medium Percentile",group=G_QA,step=1.0,minval=60.0,maxval=98.0)
float i_qa_bg_pct = input.float(97.0,"Big Percentile",group=G_QA,step=1.0,minval=70.0,maxval=99.9)
bool i_qa_show_sm = input.bool(false,"Show Small Clusters",group=G_QA)
bool i_qa_show_md = input.bool(true,"Show Medium Clusters",group=G_QA)
bool i_qa_show_bg = input.bool(true,"Show Big Clusters",group=G_QA)
color i_qa_c_buy = input.color(color.new(#00E676,20),"Bubble BUY Color",group=G_QA)
color i_qa_c_sell = input.color(color.new(#FF1744,20),"Bubble SELL Color",group=G_QA)
color i_qa_c_mix = input.color(color.new(#FFD700,30),"Bubble MIXED Color",group=G_QA)
bool i_qa_show_lbl= input.bool(true, "Show Numbers in Bubbles",group=G_QA,tooltip="Text inside each bubble: Volume / Delta / Ratio")
string i_qa_lbl_cnt= input.string("Volume","Bubble Text",group=G_QA,options=["Volume","Delta","Ratio","Vol+Delta","Vol+Ratio"],tooltip="Volume: raw bar vol\nDelta: net buy-sell (proxy)\nRatio: x SMA50\nVol+Delta / Vol+Ratio: two lines")
const string G_AMT = "⑬ AMT PATTERN ENGINE (Sovereign 24b)"
bool i_show_amt = input.bool(true,"Show AMT Patterns",group=G_AMT)
bool i_amt_rej = input.bool(true," Show Rejection (reversal wick)",group=G_AMT)
bool i_amt_abs = input.bool(true," Show Absorption (continuation)",group=G_AMT)
bool i_amt_ctr = input.bool(true," Show Contrarian (exhaustion warn)",group=G_AMT)
bool i_amt_acc = input.bool(true," Show Acceptance (balanced)",group=G_AMT)
bool i_amt_ice = input.bool(true," Show Iceberg at GEX zones (signal)",group=G_AMT)
bool i_ice_strikes= input.bool(true," Show Iceberg warning at SpotEx",group=G_AMT)
float i_amt_wick_rej=input.float(0.40,"Rejection Wick % (of range)",group=G_AMT,step=0.05,minval=0.20,maxval=0.80)
float i_amt_vol_dom =input.float(1.50,"Absorption Dominance Ratio",group=G_AMT,step=0.10,minval=1.10,maxval=3.00)
float i_ice_mass = input.float(1.8,"Iceberg Mass Threshold (xSMA50)",group=G_AMT,step=0.1,minval=1.2,maxval=3.0)
color i_amt_rej_col= input.color(color.new(#9C27B0,0),"Rejection Color",group=G_AMT)
color i_amt_abs_col= input.color(color.new(#00BCD4,0),"Absorption Color",group=G_AMT)
color i_amt_ice_col= input.color(color.new(#FFD700,0),"Iceberg Color",group=G_AMT)
string i_amt_emj_sz= input.string("Large","AMT Symbol Size (Rejection/Absorption/Iceberg)",group=G_AMT,options=["Small","Normal","Large","Huge"],tooltip="Size of emoji symbols on chart: Rejection / Absorption / Iceberg")
// [v26] BUBBLE CONTEXT — Lower-TF intrabar POSITION → AMT event classifier
const string G_BCTX = "⑬b BUBBLE CONTEXT (LTF Position Engine)"
bool i_bctx_on = input.bool(true, "Enable Bubble Context (LTF position → pattern)", group=G_BCTX, tooltip="Upgrades the ⑫ volume bubbles: pulls lower-TF intrabar data to find WHERE inside the current candle the volume/delta cluster sits, then names the AMT event.\n\nBullish candle → cluster at BOTTOM (sellers absorbed)=abs-continue · MID buy=acceptance buy · TOP buy=abs-contrarian · TOP sell=rejection.\nBearish candle = mirror image.")
bool i_bctx_lbl = input.bool(true, " Show Context Labels (abs-continue / acceptance / rejection …)", group=G_BCTX)
bool i_bctx_dot = input.bool(true, " Show Position Dot (bubble at LTF cluster, colored by side)", group=G_BCTX)
string i_bctx_ltf = input.timeframe("1", "LTF Resolution (intrabar)", group=G_BCTX, tooltip="Lower timeframe used to locate the intrabar cluster. MUST be ≤ chart TF.\nM5 chart: 1 = 5 intrabars · 15S = 20 (finer, needs seconds data) · 5S = 60.")
int i_bctx_bins = input.int(20, "Position Bins (vertical resolution)", group=G_BCTX, minval=4, maxval=50, tooltip="The candle's high→low range is split into this many horizontal price bins; the bin holding the most LTF volume = the cluster (mini volume-profile POC).")
float i_bctx_top = input.float(0.66, "Top Zone Threshold (frac of range)", group=G_BCTX, minval=0.50, maxval=0.90, step=0.01, tooltip="Cluster fraction ≥ this = TOP zone (upper wick / distribution).")
float i_bctx_bot = input.float(0.34, "Bottom Zone Threshold (frac of range)", group=G_BCTX, minval=0.10, maxval=0.50, step=0.01, tooltip="Cluster fraction ≤ this = BOTTOM zone (lower wick / accumulation).")
string i_bctx_gate = input.string("Medium+", "Min Bubble Size to Classify", group=G_BCTX, options=["Small+","Medium+","Big only"], tooltip="Only classify bars where a ⑫ volume bubble of at least this tier is visible.")
color i_bctx_up = input.color(color.new(#00E676,0), "Bullish-Outcome Label Color", group=G_BCTX, tooltip="Color for abs-continue / acceptance on a bullish candle, and rejection / abs-contrarian on a bearish candle.")
color i_bctx_dn = input.color(color.new(#FF1744,0), "Bearish-Outcome Label Color", group=G_BCTX)
string i_bctx_sz = input.string("Small","Context Label Size",group=G_BCTX,options=["Tiny","Small","Normal","Large"])
bool i_bctx_arrow= input.bool(true, " Prefix side arrow on label (▲buy / ▼sell)", group=G_BCTX)
const string G_MOM = "⑭ MOMENTUM — MLMI + SMI"
int i_mlmi_k = input.int(987, "MLMI Neighbors (k)",group=G_MOM,minval=10,maxval=2000)
int i_mlmi_mw = input.int(10, "MLMI Momentum Window",group=G_MOM,minval=5,maxval=50)
int i_mlmi_cap = input.int(2500,"MLMI Max Stored Trades (perf cap)",group=G_MOM,minval=987,maxval=10000,tooltip="[v24] Bounds the kNN trade memory so the array cannot grow unbounded → kills execution-timeout / array-size RE on deep history.\nKeeps the most-recent N crossover trades. Must be >= k (987). 2500 >> k so prediction is functionally unchanged.")
bool i_mlmi_gate = input.bool(true,"Enable MLMI/SMI Signal Gate",group=G_MOM)
int i_mlmi_d_lon = input.int(8, "MLMI Decay LON+NY (bars)",group=G_MOM,minval=3,maxval=20)
int i_mlmi_d_asia= input.int(5, "MLMI Decay ASIA (bars)",group=G_MOM,minval=2,maxval=15)
int i_mlmi_expire= input.int(21, "MLMI Expire (bars)",group=G_MOM,minval=5,maxval=50)
int i_smi_k = input.int(10, "SMI %K Length",group=G_MOM,minval=1,maxval=50)
int i_smi_d = input.int(3, "SMI %D Length",group=G_MOM,minval=1,maxval=20)
int i_smi_ema = input.int(3, "SMI EMA Length",group=G_MOM,minval=1,maxval=20)
float i_smi_ob = input.float(40.0, "SMI Overbought Level",group=G_MOM,step=1.0)
float i_smi_os = input.float(-40.0,"SMI Oversold Level",group=G_MOM,step=1.0)
const string G_EMAV = "⑮ EXPECTED MOVE — Annualized Vol"
bool i_show_em3 = input.bool(true,"Show EM +/-3sigma Band (99.7%)",group=G_EMAV)
color i_c_em3 = input.color(color.new(#FF1744,30),"EM +/-3sigma Color",group=G_EMAV)
bool i_show_em_lbl= input.bool(true,"Show EM Probability Labels",group=G_EMAV)
bool i_show_yz_av = input.bool(true,"Show YZ Realized Vol Band",group=G_EMAV)
const string G_QBLK = "⑯ EFP + Q-BLOCK GRID"
bool i_show_qblk = input.bool(true,"Show Q-Block Grid Lines",group=G_QBLK)
bool i_show_basis = input.bool(true,"Show EFP Basis Labels on Chart",group=G_QBLK)
color i_qblk_w0_col= input.color(color.new(#607D8B,30),"W0 ATM Color",group=G_QBLK)
color i_qblk_wu_col= input.color(color.new(#FF1744,40),"W+1/+2 Call Color",group=G_QBLK)
color i_qblk_wd_col= input.color(color.new(#00E676,40),"W-1/-2 Put Color",group=G_QBLK)
int i_qblk_w = input.int(1,"Q-Block Line Width",group=G_QBLK,minval=1,maxval=3)
const string G_SQZ = "⑰ SQUEEZE DETECTOR (Yang-Zhang)"
bool i_sqz_en = input.bool(true, "Enable Squeeze Labels", group=G_SQZ)
int i_sqz_yz_fast = input.int(20, "YZ Fast Window (bars)", group=G_SQZ, minval=5, maxval=100, tooltip="Short-window realized vol — responds quickly to compression onset")
int i_sqz_yz_slow = input.int(100, "YZ Slow Window (bars)", group=G_SQZ, minval=20, maxval=500, tooltip="Long-window structural baseline vol — sets the compression floor")
float i_sqz_ratio = input.float(0.7, "Compression Ratio Threshold", group=G_SQZ, step=0.05, minval=0.3, maxval=0.95, tooltip="Squeeze ON when fast YZ < slow YZ × this ratio. Lower = tighter squeeze required")
int i_sqz_min_dur = input.int(3, "Min Compression Bars (Filter ①)", group=G_SQZ, minval=1, maxval=20, tooltip="Squeeze must be compressed for at least this many bars before release is valid. Eliminates 1-2 bar transient false signals")
string i_sqz_up_txt = input.string("SqUp","Bull Label Text", group=G_SQZ)
string i_sqz_dn_txt = input.string("SqDn","Bear Label Text", group=G_SQZ)
color i_sqz_up_col = input.color(color.new(#00E676,0), "SqUp Color", group=G_SQZ)
color i_sqz_dn_col = input.color(color.new(#FF1744,0), "SqDn Color", group=G_SQZ)
int i_sqz_lbl_tr = input.int(20, "Label Background Transparency (0-100)", group=G_SQZ, minval=0, maxval=100)
string i_sqz_lbl_sz = input.string("Small","Label Size", group=G_SQZ, options=["Tiny","Small","Normal","Large"])
string i_sqz_txt_sz = input.string("Small","Text Size", group=G_SQZ, options=["Tiny","Small","Normal"])
float i_sqz_offset = input.float(0.5, "Label Offset (x ATR14)", group=G_SQZ, step=0.1, minval=0.0, maxval=5.0)
const string G_FRZ = "⑱ FROZEN ZONE DISPLAY (BasisMatrix §13)"
bool i_show_frz = input.bool(true, "Show Supply/Demand Frozen Zones", group=G_FRZ)
float i_frz_mult = input.float(2.0, "Zone Sensitivity (×σ basis)", group=G_FRZ, step=0.1)
float i_frz_vfac = input.float(1.5, "Volume Spike Factor", group=G_FRZ, step=0.1)
int i_frz_warmup = input.int(10, "Warmup (bars)", group=G_FRZ, minval=0, maxval=100)
// [v27] EXPANSION SCORE + MR-INTO-TREND — display-only (label only → 0 plot-budget)
const string G_XMT = "⑲ EXPANSION + MR-INTO-TREND (display)"
bool i_xmt_on = input.bool(true, "Enable Expansion / MR-into-Trend module", group=G_XMT, tooltip="Two reads from the 3-primitives framework:\n• EXPANSION = breakout trigger (this bar's range ≫ trailing average).\n• MR-into-TREND = buy-the-dip WITH the trend (pullback/retest to the g1 flip level inside an established trend — NOT a fade against it).\nDISPLAY-ONLY: no gate / conf_score / entry touched.")
bool i_exp_lbl = input.bool(true, " Show Expansion labels", group=G_XMT)
int i_exp_len = input.int(5, " Expansion avg window (bars)", group=G_XMT, minval=2, maxval=100, tooltip="Trailing bars for the average range. Transcript: last 5 candles avg 1%, 6th = 2% → expansion.")
float i_exp_thr = input.float(2.0, " Expansion multiple (× avg range)", group=G_XMT, step=0.1, minval=1.1, tooltip="Flag EXPANSION when this bar's range ≥ this × average range.")
bool i_mrt_lbl = input.bool(true, " Show MR-into-Trend labels", group=G_XMT)
int i_mrt_look = input.int(20, " Retrace lookback (bars)", group=G_XMT, minval=5, maxval=200, tooltip="Bars used to find the recent swing extreme for the pullback-depth read shown in the tooltip.")
color i_xmt_up = input.color(color.new(#00E676,0), " Bullish label color", group=G_XMT)
color i_xmt_dn = input.color(color.new(#FF1744,0), " Bearish label color", group=G_XMT)
color i_exp_col = input.color(color.new(#FFD700,0), " Expansion label color", group=G_XMT)
string i_xmt_sz = input.string("Small"," Label size",group=G_XMT,options=["Tiny","Small","Normal","Large"])
// [v28] REGIME MATRIX + Γ-PROXY — display-only (one table → 0 plot-budget)
const string G_RM = "⑳ REGIME MATRIX + Γ-PROXY (display)"
bool i_rm_on = input.bool(true, "Enable Regime Matrix + Γ-proxy", group=G_RM, tooltip="Unifies direction × volatility into the 6-regime matrix + a POSITIVE/NEGATIVE-gamma PROXY, and prescribes fade / follow / stand-aside.\n\nΓ-proxy = a VOL-BEHAVIOUR proxy, NOT real dealer gamma (gold spot has no options chain). It reads the FOOTPRINT gamma leaves: vol dampening (pos-Γ → fade, failed breakouts) vs amplification (neg-Γ → follow, trends). Eyes, not a validated edge.\nDISPLAY-ONLY — no gate / conf_score / entry touched.")
int i_rm_dir_len= input.int(200, " Direction baseline EMA (bars)", group=G_RM, minval=20, maxval=1000, tooltip="Bull if close>baseline & rising, Bear if close<baseline & falling, else Sideways.")
int i_rm_dir_sl = input.int(20, " Baseline slope lookback (bars)", group=G_RM, minval=2, maxval=200)
int i_rm_vr_k = input.int(6, " Variance Ratio k", group=G_RM, minval=2, maxval=50, tooltip="VR(k)=Var(k-bar ret)/(k·Var(1-bar ret)). >1 trending (neg-Γ) · <1 mean-revert (pos-Γ). Replaces Hurst (same persistence read; Hurst still lives in QC).")
int i_rm_vr_len = input.int(100, " Variance Ratio window", group=G_RM, minval=20, maxval=500)
int i_rm_er_len = input.int(20, " Trend-efficiency (ER) window", group=G_RM, minval=5, maxval=200, tooltip="Kaufman efficiency = |net move| / path. High=follow-through (neg-Γ), low=chop/failed-BO (pos-Γ). Used only as ONE Γ-vote (not a direction gate — that's the ER lesson).")
int i_rm_rv_len = input.int(20, " Realized-vol window (vs GVZ)", group=G_RM, minval=10, maxval=200, tooltip="Annualized realized vol compared to GVZ implied. RV≫GVZ = vol-amplifying (neg-Γ); RV≪GVZ = dampening (pos-Γ). The honest IV-vs-RV analog.")
string i_rm_pos = input.string("Top Left", " Table position", group=G_RM, options=["Top Left","Top Center","Top Right","Middle Left","Middle Right","Bottom Left","Bottom Center","Bottom Right"])
string i_rm_sz = input.string("Small", " Table text size", group=G_RM, options=["Tiny","Small","Normal","Large"])
color i_rm_bg = input.color(color.new(color.black, 0), " Table background", group=G_RM)
// [v29] auto-flip ACTION when Γ overrides the direction-follow
bool i_rm_autoflip = input.bool(true, " Auto-flip ACTION on Γ conflict [v29]", group=G_RM, tooltip="When the Γ-proxy strongly contradicts the direction cell (POS-Γ under a FOLLOW/SHORT-TREND cell, or NEG-Γ under an MR-FADE cell), flip the ACTION headline (FADE/RANGE ↔ FOLLOW/BREAK) + route + colour. OFF = v28 behaviour (headline stays, only a ⚠ tag). Info is identical either way — this only removes the mis-read.")
int i_rm_gth = input.int(2, " Γ-conflict threshold |score|", group=G_RM, minval=1, maxval=5, tooltip="Flip only when |Γ-score| ≥ this (2 = POS/NEG-Γ, 3 = strong).")
int i_rm_hyst = input.int(3, " Flip hysteresis (bars)", group=G_RM, minval=1, maxval=50, tooltip="Conflict must persist this many bars before the headline flips — kills flicker.")
// [v29] ADX / DI — isolated, table rows only (0 plot-budget)
bool i_rm_adx = input.bool(false, " Show ADX/DI rows [v29]", group=G_RM, tooltip="Adds ADX (trend strength) + DI+/DI− (direction) rows to the table. ⚠ ADX is direction-agnostic — read it WITH DI, never as a lone gate (the ER lesson). Display-only.")
int i_rm_adx_len = input.int(14, " ADX/DI length", group=G_RM, minval=2, maxval=100)
int i_rm_adx_sm = input.int(14, " ADX smoothing", group=G_RM, minval=2, maxval=100)
float i_rm_adx_str = input.float(25.0, " ADX strong level", group=G_RM, minval=10.0, maxval=60.0)
// [v29] deep-Fib premium / discount — isolated, box/line/label only (0 plot-budget)
bool i_rm_fib = input.bool(false, " Show deep-Fib premium/discount [v29]", group=G_RM, tooltip="Splits a swing range into PREMIUM (upper — sell) / DISCOUNT (lower — buy) with the deep 0.705–0.886 zones (Kmer 'trade from discount'). Drawn as boxes on price (line/box/label = 0 plot-budget). Display-only.")
int i_rm_fib_len = input.int(60, " Fib swing lookback (bars)", group=G_RM, minval=10, maxval=500)
float i_rm_fib_lo = input.float(0.705, " Deep-Fib low", group=G_RM, minval=0.5, maxval=0.8, step=0.001)
float i_rm_fib_hi = input.float(0.886, " Deep-Fib high", group=G_RM, minval=0.7, maxval=0.95, step=0.001)
color i_rm_fib_disc = input.color(color.new(#26A69A,0), " Discount zone (buy) color", group=G_RM)
color i_rm_fib_prem = input.color(color.new(#EF5350,0), " Premium zone (sell) color", group=G_RM)
// ═══════════════════════════════════════════════════════════════════════════════
// §2 TYPES + FUNCTIONS
// ═══════════════════════════════════════════════════════════════════════════════
type MLMIData
array<float> parameter1
array<float> parameter2
array<float> priceArray
array<float> resultArray
method mlmi_store(MLMIData d, float p1, float p2) =>
d.parameter1.push(d.parameter1.get(d.parameter1.size() - 1))
d.parameter2.push(d.parameter2.get(d.parameter2.size() - 1))
d.priceArray.push(d.priceArray.get(d.priceArray.size() - 1))
d.resultArray.push(close >= d.priceArray.get(d.priceArray.size() - 1) ? 1.0 : -1.0)
d.parameter1.set(d.parameter1.size() - 1, p1)
d.parameter2.set(d.parameter2.size() - 1, p2)
d.priceArray.set(d.priceArray.size() - 1, close)
// [v24-2] RE-FIX: bound kNN memory — drop oldest trades beyond cap (keeps recent regime)
int _cap = math.max(i_mlmi_cap, i_mlmi_k)
if d.parameter1.size() > _cap
d.parameter1.shift()
d.parameter2.shift()
d.priceArray.shift()
d.resultArray.shift()
method mlmi_predict(MLMIData d, float p1, float p2, int k) =>
distances = array.new_float(0)
int n = d.parameter1.size() - 1
for i = 0 to n
float dist = math.sqrt(math.pow(p1 - d.parameter1.get(i), 2.0) + math.pow(p2 - d.parameter2.get(i), 2.0))
distances.push(dist)
sortedD = distances.copy()
sortedD.sort()
selected = sortedD.slice(0, math.min(k, sortedD.size()))
float maxDist = selected.max()
neighbors = array.new_float(0)
for i = 0 to distances.size() - 1
if distances.get(i) <= maxDist
neighbors.push(d.resultArray.get(i))
neighbors.sum()
f_alma(float src, int len, float off, float sig) =>
float _m = off * float(len - 1)
float _s = float(len) / sig
float _ws = 0.0
float _wv = 0.0
for _i = 0 to len - 1
float _w = math.exp(-math.pow(float(_i) - _m, 2.0) / (2.0 * math.pow(_s, 2.0)))
_wv += src[len - 1 - _i] * _w
_ws += _w
_ws > 0.0 ? _wv / _ws : src
f_ls(string s) =>
switch s
"Solid" => line.style_solid
"Dotted" => line.style_dotted
=> line.style_dashed
f_lsz(string s) =>
switch s
"Small" => size.small
"Normal" => size.normal
=> size.tiny
f_dsz(string s) =>
switch s
"tiny" => size.tiny
"normal" => size.normal
=> size.small
// Yang-Zhang realized volatility estimator (gold desk standard)
f_yz(_len, _mult) =>
float _c_ret = math.log(math.max(close / math.max(open, syminfo.mintick), syminfo.mintick)) // log(Close/Open)
float _o_ret = math.log(math.max(open / math.max(nz(close[1], close), syminfo.mintick), syminfo.mintick)) // log(Open/Close_prev)
float _ho = math.log(math.max(high / math.max(open, syminfo.mintick), syminfo.mintick))
float _lo = math.log(math.max(low / math.max(open, syminfo.mintick), syminfo.mintick))
float _v_c = ta.variance(_c_ret, _len) // V_close
float _v_o = ta.variance(_o_ret, _len) // V_overnight
float _vrs = ta.sma((_ho * (_ho - _c_ret)) + (_lo * (_lo - _c_ret)), _len)
float _k = 0.34 / (1.34 + float(_len + 1) / float(math.max(_len - 1, 1)))
float _vyz = _v_o + _k * _v_c + (1.0 - _k) * _vrs
math.sqrt(math.max(_vyz, 0.0)) * close * _mult
f_touch(float price, float target) => math.abs(price - target) <= i_tol
f_dir_score(bool _is_buy, bool _bub_b3, bool _bub_s3, bool _gvz_c, bool _gvz_n, bool _gvz_el, bool _gvz_ex, string _sig_rg, bool _is_l, bool _is_n, bool _is_a, bool _dxy_pb, bool _dxy_ps, bool _frm_ok, bool _sqz_u, bool _sqz_d, float _b_dev) =>
int sc = 50
sc := sc + (_is_buy and _bub_b3 ? 12 : 0)
sc := sc - (_is_buy and _bub_s3 ? 10 : 0)
sc := sc + (not _is_buy and _bub_s3 ? 12 : 0)
sc := sc - (not _is_buy and _bub_b3 ? 10 : 0)
sc := sc + (_gvz_c ? 12 : _gvz_n ? 6 : _gvz_el ? -8 : _gvz_ex ? -20 : 0)
sc := sc + (_sig_rg == "COMPRESSED" ? 8 : _sig_rg == "NORMAL" ? 4 : _sig_rg == "EXPANDING" ? -5 : -12)
sc := sc + (_is_l ? 8 : _is_n ? 4 : _is_a ? -8 : 0)
sc := sc - (_is_buy and _dxy_pb ? 10 : 0)
sc := sc - (not _is_buy and _dxy_ps ? 10 : 0)
sc := sc + (_frm_ok ? 5 : -10)
sc := sc + (_is_buy and _sqz_u ? 8 : 0)
sc := sc + (not _is_buy and _sqz_d ? 8 : 0)
sc := sc + (_b_dev < 1.0 ? 5 : _b_dev > 2.0 ? -5 : 0)
math.min(95, math.max(5, sc))
f_body(float o, float c, float h, float l) =>
float rng = math.max(math.abs(h - l), syminfo.mintick)
math.abs(c - o) / rng
f_emaema(float src, int len) =>
ta.ema(ta.ema(src, len), len)
f_qa_cons(bool pS, bool pM, bool pL) =>
int hits = (pS ? 1 : 0) + (pM ? 1 : 0) + (pL ? 1 : 0)
hits >= 2
// QuantAlgo volume formatter (K/M/B)
f_qa_fmtn(float v) =>
float av = math.abs(v)
string sg = v < 0.0 ? "-" : ""
string result = sg + str.tostring(av, "#")
if av >= 1000000000.0
result := sg + str.tostring(av / 1000000000.0, "#.##") + "B"
else if av >= 1000000.0
result := sg + str.tostring(av / 1000000.0, "#.##") + "M"
else if av >= 1000.0
result := sg + str.tostring(av / 1000.0, "#.##") + "K"
result
// ═══════════════════════════════════════════════════════════════════════════════
// §3 RS DATA FETCH (7 calls — _efp_fut_h4 H4 restored in v21 revised)
// ═══════════════════════════════════════════════════════════════════════════════
float fut_live = request.security(i_fut_sym, timeframe.period, close, barmerge.gaps_off, barmerge.lookahead_off, ignore_invalid_symbol=true)
float fut_d = request.security(i_fut_sym, "D", close[1], barmerge.gaps_off, barmerge.lookahead_off, ignore_invalid_symbol=true)
float spt_d = request.security(syminfo.tickerid, "D", close[1], barmerge.gaps_off, barmerge.lookahead_off)
float gvz_d = request.security(i_gvz_sym, "D", close[1], barmerge.gaps_off, barmerge.lookahead_off, ignore_invalid_symbol=true)
float fut_1m = na // not fetched; see basis_1m below
float _efp_fut_h4 = request.security(i_fut_sym, "240", close[1], barmerge.gaps_off, barmerge.lookahead_off, ignore_invalid_symbol=true)
float _efp_spt_h4 = request.security(syminfo.tickerid, "240", close[1], barmerge.gaps_off, barmerge.lookahead_off)
float dxy_raw = request.security("TVC:DXY", "D", close[1], barmerge.gaps_off, barmerge.lookahead_off, ignore_invalid_symbol=true)
float fut_now = nz(fut_live, close)
float d_spt = nz(spt_d, close)
float d_fut = nz(fut_d, fut_now)
float gvz_v = nz(gvz_d, 18.0)
float basis_1m = fut_now - close // fut_1m RS removed (saves 6 plot-budget units); equivalent to raw_basis
// ═══════════════════════════════════════════════════════════════════════════════
// §4 BASIS ENGINE + COMEX CIRCUIT BREAKER TIERS
// ═══════════════════════════════════════════════════════════════════════════════
float raw_basis = fut_now - close
float b_mean = ta.sma(raw_basis, i_basis_len)
float b_std = ta.stdev(raw_basis, i_basis_len)
float p_std = ta.stdev(fut_now, i_basis_len)
float atr14 = ta.atr(14)
float vol_sma50 = ta.sma(volume, 50)
int _hm = hour(time,"UTC+0") * 100 + minute(time,"UTC+0")
bool _is_asia = _hm >= 2000 or _hm < 300
bool _is_lon = _hm >= 300 and _hm < 800
bool _is_ny = _hm >= 800 and _hm < 1700
int _cur_sess = _is_ny ? 3 : _is_lon ? 2 : 1
// LBMA and CME NY Fix windows (UTC)
int _fix_hm = _hm
bool in_lbma_am = _fix_hm >= 1000 and _fix_hm < 1030
bool in_lbma_pm = _fix_hm >= 1500 and _fix_hm < 1515
bool in_fix = in_lbma_am or in_lbma_pm
bool in_pre_fix = (_fix_hm >= 930 and _fix_hm < 1000) or (_fix_hm >= 1430 and _fix_hm < 1500)
bool is_globex_open = dayofweek == dayofweek.sunday and _hm >= 2300
string fix_lbl = in_lbma_am ? "AM FIX" : in_lbma_pm ? "PM FIX" : in_pre_fix ? "PRE-FIX" : is_globex_open ? "GLOBEX OPEN" : ""
bool _sess_ok_mr = not i_sess_filt or not _is_asia
var int _last_s = 0
var float _frozen = na
if na(_frozen) and not na(raw_basis)
_frozen := raw_basis
bool is_new_day = dayofmonth != dayofmonth[1] or month != month[1] or year != year[1]
int _prev_sess = _last_s
if _cur_sess != _last_s
_last_s := _cur_sess
_frozen := nz(raw_basis, nz(b_mean, 0.0))
float fb = nz(_frozen, nz(b_mean, 0.0))
var float _snap_asia = na
var float _snap_lon = na
var float _snap_ny = na
var string _sess_lbl = "--"
bool _sess_flip = _cur_sess != 0 and _cur_sess != _prev_sess
if _sess_flip
if _cur_sess == 1
_sess_lbl := "ASIA"
_snap_asia := nz(raw_basis, 0.0)
else if _cur_sess == 2
_sess_lbl := "LON"
_snap_lon := nz(raw_basis, 0.0)
else if _cur_sess == 3
_sess_lbl := "NY"
_snap_ny := nz(raw_basis, 0.0)
float _snap_sess = _cur_sess == 3 ? nz(_snap_ny, nz(raw_basis, fb)) : _cur_sess == 2 ? nz(_snap_lon, nz(raw_basis, fb)) : nz(_snap_asia, nz(raw_basis, fb))
float _rb_safe = nz(raw_basis, nz(raw_basis[1], nz(raw_basis[2], 0.0)))
float _bv_raw = _rb_safe - nz(_rb_safe[5], _rb_safe)
float basis_vel = b_std > 0.0 ? _bv_raw / b_std : 0.0
bool basis_conv= (raw_basis > 0 and basis_vel < -0.2) or (raw_basis < 0 and basis_vel > 0.2)
bool basis_divg= (raw_basis > 0 and basis_vel > 0.2) or (raw_basis < 0 and basis_vel < -0.2)
string basis_trend_s = basis_conv ? "CONV" : basis_divg ? "DIV" : "FLAT"
var float[] _sz_asia = array.new_float(0)
var float[] _sz_lon = array.new_float(0)
var float[] _sz_ny = array.new_float(0)
if barstate.isconfirmed and not na(raw_basis)
if _is_asia
array.push(_sz_asia, raw_basis)
if array.size(_sz_asia) > 60
array.shift(_sz_asia)
else if _is_lon
array.push(_sz_lon, raw_basis)
if array.size(_sz_lon) > 60
array.shift(_sz_lon)
else
array.push(_sz_ny, raw_basis)
if array.size(_sz_ny) > 60
array.shift(_sz_ny)
float[] _cur_sarr = _cur_sess == 3 ? _sz_ny : _cur_sess == 2 ? _sz_lon : _sz_asia
float _sess_mean = array.size(_cur_sarr) > 1 ? array.avg(_cur_sarr) : nz(b_mean, fb)
float _sess_std = array.size(_cur_sarr) > 1 ? array.stdev(_cur_sarr) : nz(b_std, 0.5)
float sess_z = _sess_std > 0.0 ? (_rb_safe - _sess_mean) / _sess_std : 0.0
bool sess_z_ext = math.abs(sess_z) >= 2.0
float _gofo_rate_dec = i_gofo_rate / 100.0
float gofo_carry = close * _gofo_rate_dec * (30.0 / 365.0)
float gofo_excess = _rb_safe - gofo_carry
bool gofo_backw = gofo_excess < -nz(b_std, 0.5) * 0.3
bool gofo_cont = gofo_excess > nz(b_std, 0.5) * 0.3
string gofo_regime = gofo_backw ? "BACKWRD" : gofo_cont ? "CNTNG+" : "FAIR"
float bm = switch i_efp_mode
"SESSION" => _snap_sess
"1-MINUTE" => basis_1m
=> nz(b_mean, fb)
float basis_cv = math.abs(bm) > 0.001 ? math.abs(b_std / bm) : 1.0
bool basis_stable = basis_cv <= 0.5
string basis_qual = basis_stable ? "STABLE" : "UNSTABLE"
float _basis_delta = _rb_safe - fb
bool is_divergent = b_std > 0.0 and math.abs(_basis_delta) >= b_std * 1.5
float _cb_settle = nz(d_fut, close) // prior COMEX futures settlement
float cb_t1_u = _cb_settle * 1.03
float cb_t1_d = _cb_settle * 0.97
float cb_t2_u = _cb_settle * 1.06
float cb_t2_d = _cb_settle * 0.94
float cb_t3_u = _cb_settle * 1.09
float cb_t3_d = _cb_settle * 0.91
bool cb_t1_active = close > cb_t1_u or close < cb_t1_d
bool cb_t2_active = close > cb_t2_u or close < cb_t2_d
bool cb_t3_active = close > cb_t3_u or close < cb_t3_d
string cb_tier_str = cb_t3_active ? "CB-T3 ±9%" : cb_t2_active ? "CB-T2 ±6%" : cb_t1_active ? "CB-T1 ±3%" : "CB:NORM"
color cb_tier_col = cb_t3_active ? #D500F9 : cb_t2_active ? #FF1744 : cb_t1_active ? #FF9800 : #00E676
float _efp_orig = not na(_efp_fut_h4) and not na(_efp_spt_h4)
? _efp_fut_h4 - _efp_spt_h4
: nz(d_fut, close) - nz(d_spt, close)
float bm_h4 = _efp_orig
float fut_impl_h4 = close + bm_h4
float base_block_h4 = math.round(fut_impl_h4 / i_block) * i_block
float qb_h4_u2 = base_block_h4 + (i_block * 2.0) - bm_h4
float qb_h4_u1 = base_block_h4 + i_block - bm_h4
float qb_h4_0 = base_block_h4 - bm_h4
float qb_h4_d1 = base_block_h4 - i_block - bm_h4
float qb_h4_d2 = base_block_h4 - (i_block * 2.0) - bm_h4
float basis_drift = bm - bm_h4
string basis_mode_str = math.abs(basis_drift) > b_std * 0.5 ? "DRIFT $" + str.tostring(math.abs(basis_drift),"#.##") : "STABLE"
float efp_d = d_fut - d_spt
// ═══════════════════════════════════════════════════════════════════════════════
// §5 SPOTEX LEVELS
// ═══════════════════════════════════════════════════════════════════════════════
float implied_spot = fut_now - bm
float _atm_c = math.ceil(fut_now / i_block) * i_block
float _atm_p = math.floor(fut_now / i_block) * i_block
float sp_c1 = _atm_c - bm
float sp_c2 = (_atm_c + i_block) - bm
float sp_c3 = (_atm_c + i_block * 2.0) - bm
float sp_c4 = (_atm_c + i_block * 3.0) - bm
float sp_p1 = _atm_p - bm
float sp_p2 = (_atm_p - i_block) - bm
float sp_p3 = (_atm_p - i_block * 2.0) - bm
float sp_p4 = (_atm_p - i_block * 3.0) - bm
float sd_u = implied_spot + p_std * i_sd_mult
float sd_d = implied_spot - p_std * i_sd_mult
float _pbv_anc = d_spt + efp_d
float pbv_l1_u = _pbv_anc * (1.0 + i_pbv_1 / 100.0) - efp_d
float pbv_l1_d = _pbv_anc * (1.0 - i_pbv_1 / 100.0) - efp_d
float pbv_l2_u = _pbv_anc * (1.0 + i_pbv_2 / 100.0) - efp_d
float pbv_l2_d = _pbv_anc * (1.0 - i_pbv_2 / 100.0) - efp_d
float pbv_l3_u = _pbv_anc * (1.0 + i_pbv_3 / 100.0) - efp_d
float pbv_l3_d = _pbv_anc * (1.0 - i_pbv_3 / 100.0) - efp_d
// ═══════════════════════════════════════════════════════════════════════════════
// §6 GEX PHYSICS ENGINE + VWAP (London daily-reset fix) + ALMA
// ═══════════════════════════════════════════════════════════════════════════════
bool is_lon_open = _hm == 300
var float _lv_pv = 0.0
var float _lv_v = 0.0
var bool _lon_started = false
if is_new_day
_lv_pv := 0.0
_lv_v := 0.0
_lon_started := false
if is_lon_open or (not _lon_started and _is_lon)
_lv_pv := hlc3 * volume
_lv_v := volume
_lon_started := true
else if _lon_started
_lv_pv += hlc3 * volume
_lv_v += volume
float lon_vwap = _lv_v > 0.0 ? _lv_pv / _lv_v : hlc3
var float _dv_pv = 0.0
var float _dv_v = 0.0
if is_new_day
_dv_pv := 0.0
_dv_v := 0.0
_dv_pv += hlc3 * volume
_dv_v += volume
float daily_vwap = _dv_v > 0.0 ? _dv_pv / _dv_v : hlc3
float anchor = _lon_started ? lon_vwap : daily_vwap
float sigma_raw = f_yz(i_vol_lb, i_vol_mult)
float sigma_floor_val = nz(atr14, sigma_raw) * i_sig_floor
float sigma = math.max(sigma_raw, sigma_floor_val)
float sigma_pct = anchor > 0 ? sigma / anchor * 100.0 : 0.0
string sig_regime = sigma_pct < 0.8 ? "COMPRESSED" : sigma_pct < 1.5 ? "NORMAL" : sigma_pct < 2.5 ? "EXPANDING" : "EXTREME"
color sig_r_col = sigma_pct < 0.8 ? #00BCD4 : sigma_pct < 1.5 ? #B0BEC5 : sigma_pct < 2.5 ? #FF9800 : #FF1744
float _g1_eff = i_sigma_mode == "GAUSSIAN" ? 1.0 : i_g1
float _g2_eff = i_sigma_mode == "GAUSSIAN" ? 2.0 : i_g2
float _g3_eff = i_sigma_mode == "GAUSSIAN" ? 3.0 : i_g3
string _prob_g1= i_sigma_mode == "GAUSSIAN" ? "68.3%" : "89.4%"
string _prob_g2= i_sigma_mode == "GAUSSIAN" ? "95.5%" : "99.9%"
float g1_up = anchor + sigma * _g1_eff
float g1_dn = anchor - sigma * _g1_eff
float g2_up = anchor + sigma * _g2_eff
float g2_dn = anchor - sigma * _g2_eff
float g3_up = anchor + sigma * _g3_eff
float g3_dn = anchor - sigma * _g3_eff
float frame_width = g1_up - g1_dn
bool frame_ok = frame_width >= i_tol * 4.0
float em_1sigma = gvz_v > 0.0 and not na(gvz_d) ? close * (gvz_v / 100.0) / math.sqrt(252.0) : sigma * 4.8
float em_upper = anchor + em_1sigma
float em_lower = anchor - em_1sigma
float em_upper_2 = anchor + em_1sigma * 2.0
float em_lower_2 = anchor - em_1sigma * 2.0
float em_upper_3 = anchor + em_1sigma * 3.0
float em_lower_3 = anchor - em_1sigma * 3.0
float yz_band_u = anchor + sigma * 1.0
float yz_band_d = anchor - sigma * 1.0
float _gvz_roc_em = gvz_v > 0.0 and gvz_v[1] > 0.0 ? gvz_v - gvz_v[1] : 0.0
float _price_roc = close > 0.0 and close[5] > 0.0 ? (close - close[5]) / close[5] * 100.0 : 0.0
bool rr_put_skew = _gvz_roc_em > 0.5 and _price_roc < -0.1
bool rr_call_skew = _gvz_roc_em < -0.5 and _price_roc > 0.1
string rr_str = rr_put_skew ? "PUT SKEW (RR-)" : rr_call_skew ? "CALL SKEW (RR+)" : "NEUTRAL"
color rr_col = rr_put_skew ? color.new(#FF1744,0) : rr_call_skew ? color.new(#00E676,0) : color.new(#B0BEC5,0)
float _buy_vol = close >= open ? volume : 0.0
float _sell_vol = close < open ? volume : 0.0
float _bv_ema = ta.ema(_buy_vol, 20)
float _sv_ema = ta.ema(_sell_vol, 20)
float _tot_ema = math.max(_bv_ema + _sv_ema, 1.0)
float vpin_proxy = (_bv_ema - _sv_ema) / _tot_ema
bool vpin_bull = vpin_proxy > 0.2
bool vpin_bear = vpin_proxy < -0.2
string vpin_str = vpin_bull ? "INST BUY " + str.tostring(vpin_proxy * 100,"#") + "%" : vpin_bear ? "INST SELL " + str.tostring(math.abs(vpin_proxy) * 100,"#") + "%" : "BALANCED"
color vpin_col = vpin_bull ? color.new(#00E676,0) : vpin_bear ? color.new(#FF1744,0) : color.new(#B0BEC5,0)
float alma_l1 = i_show_alma ? f_alma(close, i_al1_len, i_al1_offset, i_al1_sigma) : na
float alma_l2 = i_show_alma ? f_alma(close, i_al2_len, i_al2_offset, i_al2_sigma) : na
float alma_l3 = i_show_alma ? f_alma(close, i_al3_len, i_al3_offset, i_al3_sigma) : na
bool alma_bull = not na(alma_l1) and alma_l1 > alma_l2 and alma_l2 > alma_l3
bool alma_bear = not na(alma_l1) and alma_l1 < alma_l2 and alma_l2 < alma_l3
string alma_regime = alma_bull ? "BULL" : alma_bear ? "BEAR" : "MIXED"
color alma_reg_col = alma_bull ? #00FF88 : alma_bear ? #FF0044 : #B0BEC5
float qb_0 = math.round(fut_now / i_block) * i_block - bm
float qb_u1 = qb_0 + i_block
float qb_u2 = qb_0 + i_block * 2.0
float qb_d1 = qb_0 - i_block
float qb_d2 = qb_0 - i_block * 2.0
// ═══════════════════════════════════════════════════════════════════════════════
// §5b DUAL-SYSTEM SD LEVELS
// ═══════════════════════════════════════════════════════════════════════════════
float sd_phi_u = implied_spot + p_std * i_sd_mult
float sd_phi_d = implied_spot - p_std * i_sd_mult
float sigma_delta = gvz_v > 0.0 and not na(gvz_d) ?
close * (gvz_v / 100.0) / math.sqrt(252.0) * math.sqrt(math.max(i_delta_dte, 0.1)) :
sigma * 4.8
float _sd_45d_u = anchor + sigma_delta * 0.125
float _sd_45d_d = anchor - sigma_delta * 0.125
float _sd_35d_u = anchor + sigma_delta * 0.385
float _sd_35d_d = anchor - sigma_delta * 0.385
float _sd_25d_u = anchor + sigma_delta * 0.674
float _sd_25d_d = anchor - sigma_delta * 0.674
float _sd_15d_u = anchor + sigma_delta * 1.036 * i_skew_15d_c
float _sd_15d_d = anchor - sigma_delta * 1.036 * i_skew_15d_p
float _sd_5d_u = anchor + sigma_delta * 1.645 * i_skew_5d_c
float _sd_5d_d = anchor - sigma_delta * 1.645 * i_skew_5d_p
if i_sd_signal == "DELTA"
sd_u := _sd_25d_u
sd_d := _sd_25d_d
else
sd_u := sd_phi_u
sd_d := sd_phi_d
bool _sd_25d_u_in_frame = _sd_25d_u < g1_up and _sd_25d_u > g1_dn
bool _sd_25d_d_in_frame = _sd_25d_d > g1_dn and _sd_25d_d < g1_up
bool _sd_15d_u_in_frame = _sd_15d_u < g1_up and _sd_15d_u > g1_dn
bool _sd_15d_d_in_frame = _sd_15d_d > g1_dn and _sd_15d_d < g1_up
bool _sd_phi_u_in_frame = sd_phi_u < g1_up and sd_phi_u > g1_dn
bool _sd_phi_d_in_frame = sd_phi_d > g1_dn and sd_phi_d < g1_up
bool _sd_25d_u_conf = math.abs(g3_up - _sd_25d_u) <= i_tol * 2.5
bool _sd_25d_d_conf = math.abs(g3_dn - _sd_25d_d) <= i_tol * 2.5
bool _sd_phi_u_conf = math.abs(g3_up - sd_phi_u) <= i_tol * 2.5
bool _sd_phi_d_conf = math.abs(g3_dn - sd_phi_d) <= i_tol * 2.5
bool _using_delta_sig = i_sd_signal == "DELTA"
bool _show_phi_sys = i_show_sd and i_show_phi
bool _show_delta_sys = i_show_sd and i_show_delta_sys
// ═══════════════════════════════════════════════════════════════════════════════
// §7 GVZ VOLATILITY REGIME
// ═══════════════════════════════════════════════════════════════════════════════
float gvz_sma = ta.sma(gvz_v, 20)
float gvz_z = gvz_sma > 0 ? (gvz_v - gvz_sma) / math.max(ta.stdev(gvz_v, 20), 0.001) : 0.0
bool gvz_compressed = not na(gvz_d) and gvz_v < i_gvz_norm
bool gvz_normal = not na(gvz_d) and gvz_v >= i_gvz_norm and gvz_v < i_gvz_elev
bool gvz_elevated = not na(gvz_d) and gvz_v >= i_gvz_elev and gvz_v < i_gvz_ext
bool gvz_extreme = not na(gvz_d) and gvz_v >= i_gvz_ext
bool gvz_spiking = gvz_z > 1.5 and not gvz_compressed
bool gvz_crisis = gvz_z > 2.5
bool gvz_block_mr = i_gvz_en and (gvz_extreme or gvz_crisis)
bool gvz_reduce_mr = i_gvz_en and (gvz_elevated or gvz_spiking)
string gvz_tier = gvz_extreme ? "EXTREME" : gvz_elevated ? "ELEVATED" : gvz_normal ? "NORMAL" : "COMPRESSED"
color gvz_tier_col = gvz_extreme ? #FF1744 : gvz_elevated ? #FF9800 : gvz_normal ? #B0BEC5 : #00BCD4
// ═══════════════════════════════════════════════════════════════════════════════
// §8 DXY MACRO FILTER [v19 fix: fully implemented — was stub in v18]
// ═══════════════════════════════════════════════════════════════════════════════
float dxy_now = nz(dxy_raw, 100.0)
var float _dxy_prev = na
var float _dxy_d1 = na
if is_new_day and dxy_now > 0.0
_dxy_prev := _dxy_d1
_dxy_d1 := dxy_now
float _dxy_ref = nz(_dxy_prev, dxy_now)
float dxy_roc = _dxy_ref > 0.0 ? (dxy_now - _dxy_ref) / _dxy_ref * 100.0 : 0.0
bool dxy_bull = i_dxy_en and dxy_roc > i_dxy_thr
bool dxy_bear = i_dxy_en and dxy_roc < -i_dxy_thr
bool dxy_penalise_buy = dxy_bull // DXY rising → headwind for Gold long
bool dxy_penalise_sell = dxy_bear // DXY falling → headwind for Gold short
color dxy_col = dxy_bull ? color.new(#FF1744,0) : dxy_bear ? color.new(#00E676,0) : color.new(#B0BEC5,0)
string dxy_str = dxy_bull ? "DXY+" + str.tostring(dxy_roc,"#.##") + "% BEARISH XAU" : dxy_bear ? "DXY" + str.tostring(dxy_roc,"#.##") + "% BULLISH XAU" : "DXY NEUTRAL"
// ═══════════════════════════════════════════════════════════════════════════════
// §9 MLMI COMPUTATION (k=987, momentumWindow=10, session-aware decay)
// ═══════════════════════════════════════════════════════════════════════════════
float _ml_ma_q = ta.wma(close, 5)
float _ml_ma_s = ta.wma(close, 20)
float _ml_rsi_q = ta.wma(ta.rsi(close, 5), i_mlmi_mw)
float _ml_rsi_s = ta.wma(ta.rsi(close, 20), i_mlmi_mw)
bool _ml_pos = ta.crossover(_ml_ma_q, _ml_ma_s)
bool _ml_neg = ta.crossunder(_ml_ma_q, _ml_ma_s)
var MLMIData _mlmi_data = MLMIData.new(
array.new_float(1, 0.0), array.new_float(1, 0.0),
array.new_float(1, 0.0), array.new_float(1, 0.0))
if _ml_pos or _ml_neg
_mlmi_data.mlmi_store(_ml_rsi_s, _ml_rsi_q)
float mlmi_prediction = _mlmi_data.mlmi_predict(_ml_rsi_s, _ml_rsi_q, i_mlmi_k)
float mlmi_pred_ma = ta.wma(mlmi_prediction, 20)
var int _mlmi_cross_bar = -999
if _ml_pos or _ml_neg
_mlmi_cross_bar := bar_index
int _mlmi_age = bar_index - _mlmi_cross_bar
int _mlmi_decay_win = _is_asia ? i_mlmi_d_asia : i_mlmi_d_lon
bool mlmi_fresh = _mlmi_age <= _mlmi_decay_win
bool mlmi_valid = _mlmi_age <= i_mlmi_expire
bool mlmi_bull = mlmi_prediction > 0.0
bool mlmi_bear = mlmi_prediction < 0.0
bool mlmi_neutral = mlmi_prediction == 0.0 // initial warmup state only
bool _mlmi_c_gate = not i_mlmi_gate or mlmi_neutral or (mlmi_fresh and mlmi_bull)
bool _mlmi_d_gate = not i_mlmi_gate or mlmi_neutral or (mlmi_fresh and mlmi_bear)
bool _mlmi_a_gate = not i_mlmi_gate or mlmi_neutral or (mlmi_valid and mlmi_bull)
bool _mlmi_b_gate = not i_mlmi_gate or mlmi_neutral or (mlmi_valid and mlmi_bear)
// ═══════════════════════════════════════════════════════════════════════════════
// §10 SMI COMPUTATION (K=10, D=3, EMA=3 — OB=+40, OS=-40)
// ═══════════════════════════════════════════════════════════════════════════════
float _smi_hh = ta.highest(high, i_smi_k)
float _smi_ll = ta.lowest(low, i_smi_k)
float _smi_rng = _smi_hh - _smi_ll
float _smi_rel = close - (_smi_hh + _smi_ll) / 2.0
float _smi_num = f_emaema(_smi_rel, i_smi_d)
float _smi_den = f_emaema(_smi_rng, i_smi_d)
float smi = _smi_den > 0.0 ? 200.0 * _smi_num / _smi_den : 0.0
float smi_ema = ta.ema(smi, i_smi_ema)
bool smi_overbought = smi >= i_smi_ob
bool smi_oversold = smi <= i_smi_os
bool smi_bull_cross = ta.crossover(smi, smi_ema)
bool smi_bear_cross = ta.crossunder(smi, smi_ema)
bool _smi_g_gate = not i_mlmi_gate or smi_bull_cross or smi_oversold
bool _smi_h_gate = not i_mlmi_gate or smi_bear_cross or smi_overbought
// ═══════════════════════════════════════════════════════════════════════════════
// §11 QUANTALGO VOLUME INTELLIGENCE
// ═══════════════════════════════════════════════════════════════════════════════
float _qa_rng = math.max(high - low, syminfo.mintick)
float _qa_buy_vol = volume * ((close - low) / _qa_rng)
float _qa_sell_vol = volume * ((high - close) / _qa_rng)
float _qa_net_dlt = _qa_buy_vol - _qa_sell_vol
float _qa_abs_dlt = math.abs(_qa_net_dlt)
float _dSS = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_short, i_qa_sm_pct)
float _dSM = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_mid, i_qa_sm_pct)
float _dSL = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_long, i_qa_sm_pct)
float _dMS = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_short, i_qa_md_pct)
float _dMM = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_mid, i_qa_md_pct)
float _dML = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_long, i_qa_md_pct)
float _dBS = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_short, i_qa_bg_pct)
float _dBM = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_mid, i_qa_bg_pct)
float _dBL = ta.percentile_linear_interpolation(_qa_abs_dlt, i_qa_long, i_qa_bg_pct)
bool _qa_big = f_qa_cons(_qa_abs_dlt >= _dBS, _qa_abs_dlt >= _dBM, _qa_abs_dlt >= _dBL)
bool _qa_med = not _qa_big and f_qa_cons(_qa_abs_dlt >= _dMS, _qa_abs_dlt >= _dMM, _qa_abs_dlt >= _dML)
bool _qa_small = not _qa_big and not _qa_med and f_qa_cons(_qa_abs_dlt >= _dSS, _qa_abs_dlt >= _dSM, _qa_abs_dlt >= _dSL)
bool _qa_is_buy = _qa_net_dlt > 0.0
bool _qa_is_sell = _qa_net_dlt < 0.0
color _qa_bub_col = _qa_is_buy ? i_qa_c_buy : _qa_is_sell ? i_qa_c_sell : i_qa_c_mix
bool qa_big_bull = _qa_big and _qa_is_buy
bool qa_big_bear = _qa_big and _qa_is_sell
bool qa_any_bull = (_qa_big or _qa_med or _qa_small) and _qa_is_buy
bool qa_any_bear = (_qa_big or _qa_med or _qa_small) and _qa_is_sell
bool qa_bull_3 = qa_any_bull or qa_any_bull[1] or qa_any_bull[2]
bool qa_bear_3 = qa_any_bear or qa_any_bear[1] or qa_any_bear[2]
bool qa_big_bull3 = qa_big_bull or qa_big_bull[1] or qa_big_bull[2]
bool qa_big_bear3 = qa_big_bear or qa_big_bear[1] or qa_big_bear[2]
float _qa_avg_vol = ta.sma(volume, i_qa_mid)
float _qa_vol_ratio = _qa_avg_vol > 0.0 ? volume / _qa_avg_vol : 0.0
bool _qa_vis_sm = _qa_small and i_qa_show_sm
bool _qa_vis_md = _qa_med and i_qa_show_md
bool _qa_vis_bg = _qa_big and i_qa_show_bg
bool _qa_any_vis = _qa_vis_sm or _qa_vis_md or _qa_vis_bg
bool _qa_t0 = _qa_any_vis and _qa_vol_ratio < 2.5
bool _qa_t1 = _qa_any_vis and _qa_vol_ratio >= 2.5 and _qa_vol_ratio < 4.0
bool _qa_t2 = _qa_any_vis and _qa_vol_ratio >= 4.0 and _qa_vol_ratio < 6.5
bool _qa_t3 = _qa_any_vis and _qa_vol_ratio >= 6.5 and _qa_vol_ratio < 10.0
bool _qa_t4 = _qa_any_vis and _qa_vol_ratio >= 10.0
float _qa_plot_y = _qa_any_vis ? (_qa_is_sell ? high : low) : na
var array<label> _qa_lbs = array.new_label()
if _qa_any_vis and i_qa_show_lbl
string _qa_fv = f_qa_fmtn(volume)
string _qa_fdlt = _qa_net_dlt >= 0.0 ? "+" + f_qa_fmtn(_qa_net_dlt) : f_qa_fmtn(_qa_net_dlt)
string _qa_rx = str.tostring(_qa_vol_ratio, "#.#") + "x"
string _qa_txt = switch i_qa_lbl_cnt
"Delta" => _qa_fdlt
"Ratio" => _qa_rx
"Vol+Delta" => _qa_fv + "\n" + _qa_fdlt
"Vol+Ratio" => _qa_fv + "\n" + _qa_rx
=> _qa_fv
int _qa_clvl = _qa_vis_bg ? 3 : _qa_vis_md ? 2 : 1
string _qa_lvl = _qa_clvl == 3 ? "BIG" : _qa_clvl == 2 ? "MEDIUM" : "SMALL"
string _qa_side = _qa_is_buy ? "BUY" : _qa_is_sell ? "SELL" : "MIXED"
bool _dS = _qa_clvl == 3 ? _qa_abs_dlt >= _dBS : _qa_clvl == 2 ? _qa_abs_dlt >= _dMS : _qa_abs_dlt >= _dSS
bool _dM = _qa_clvl == 3 ? _qa_abs_dlt >= _dBM : _qa_clvl == 2 ? _qa_abs_dlt >= _dMM : _qa_abs_dlt >= _dSM
bool _dL = _qa_clvl == 3 ? _qa_abs_dlt >= _dBL : _qa_clvl == 2 ? _qa_abs_dlt >= _dML : _qa_abs_dlt >= _dSL
string _qa_dwin = (_dS ? "S" : "·") + " " + (_dM ? "M" : "·") + " " + (_dL ? "L" : "·")
string _qa_tip = "── " + _qa_lvl + " " + _qa_side + " ──" +
"\nVolume: " + _qa_fv +
"\nDelta: " + _qa_fdlt +
"\nRatio: " + str.tostring(_qa_vol_ratio, "#.##") + "x" +
"\nMethod: Delta Only (wick-weighted M5 proxy)" +
"\nDelta Windows: [" + _qa_dwin + "]" +
"\n─────────────────────" +
"\nSess: " + (_is_lon ? "LONDON" : _is_ny ? "NY" : "ASIA") +
"\nMLMI: " + (mlmi_fresh ? "FRESH" : mlmi_valid ? "VALID" : "EXPIRED") +
" SMI: " + str.tostring(smi, "#.1") +
"\nDXY: " + dxy_str +
"\nCB Tier: " + cb_tier_str +
"\nNote: Pine proxy +/-20% vs tick data"
array.push(_qa_lbs, label.new(bar_index, _qa_plot_y, _qa_txt,
style = label.style_label_center,
color = color.new(chart.fg_color, 100),
textcolor = chart.fg_color,
size = size.small,
tooltip = _qa_tip))
if array.size(_qa_lbs) > 400
label.delete(array.shift(_qa_lbs))
var float _qa_cum_vol = 0.0
_qa_cum_vol += nz(volume)
// ═══════════════════════════════════════════════════════════════════════════════
// §11b BUBBLE CONTEXT — LTF INTRABAR POSITION → AMT EVENT CLASSIFIER [v26]
// ─────────────────────────────────────────────────────────────────────────────
// Upgrades the ⑫ volume bubbles: the whole-bar delta only tells BUY vs SELL.
// Here we drill into the current candle with lower-TF bars, locate the price bin
// with the largest |delta| (the biggest intrabar order-flow imbalance = the cluster),
// read the net delta AT that cluster, and — combined with candle direction and WHERE the
// cluster sits (top wick / body / bottom wick) — name the AMT event:
// abs-continue · acceptance · abs-contrarian · rejection
// Display-only: touches no gate / conf_score / entry logic.
// ─────────────────────────────────────────────────────────────────────────────
// 2 lower-TF pulls only (plot-budget: each request.security_lower_tf costs 1 plot unit;
// the file sits near the 64 ceiling → we drop the separate volume pull and weight the
// cluster by |delta| instead — which also better matches what a "bubble" is: the price
// where the biggest order-flow IMBALANCE happened, not merely the busiest price).
// Net delta is computed inside the LTF context via wick-weighting.
array<float> _ltf_price = request.security_lower_tf(syminfo.tickerid, i_bctx_ltf, hl2)
array<float> _ltf_dlt = request.security_lower_tf(syminfo.tickerid, i_bctx_ltf,
volume * ((close - low) / math.max(high - low, syminfo.mintick))
- volume * ((high - close) / math.max(high - low, syminfo.mintick)))
bool _bctx_gate_ok = switch i_bctx_gate
"Small+" => _qa_vis_sm or _qa_vis_md or _qa_vis_bg
"Big only" => _qa_vis_bg
=> _qa_vis_md or _qa_vis_bg
bool _bctx_run = i_bctx_on and _bctx_gate_ok and barstate.isconfirmed
// hoisted for optional alerts
string _bctx_pat = ""
bool _bctx_out_bull = false
bool _bctx_is_rev = false
bool _bctx_fired = false
var array<label> _bctx_lbs = array.new_label()
if _bctx_run and array.size(_ltf_price) > 0
int _n = i_bctx_bins
float _clo = low
float _crng = math.max(high - low, syminfo.mintick)
array<float> _binA = array.new_float(_n, 0.0) // |delta| weight per bin
array<float> _binD = array.new_float(_n, 0.0) // signed delta per bin
int _m = math.min(array.size(_ltf_price), array.size(_ltf_dlt))
if _m > 0
for _j = 0 to _m - 1
float _p = array.get(_ltf_price, _j)
float _d = array.get(_ltf_dlt, _j)
if not na(_p) and not na(_d)
int _bi = math.floor((_p - _clo) / _crng * _n)
_bi := math.max(0, math.min(_n - 1, _bi))
array.set(_binA, _bi, array.get(_binA, _bi) + math.abs(_d))
array.set(_binD, _bi, array.get(_binD, _bi) + _d)
// POC = bin with the largest |delta| (biggest intrabar order-flow imbalance)
int _poc = 0
float _pocv = -1.0
for _bi = 0 to _n - 1
float _bv = array.get(_binA, _bi)
if _bv > _pocv
_pocv := _bv
_poc := _bi
if _pocv > 0.0
float _poc_frac = (_poc + 0.5) / _n
float _poc_y = _clo + _poc_frac * _crng
float _poc_dlt = array.get(_binD, _poc)
bool _poc_buy = _poc_dlt > 0.0
bool _poc_sell = _poc_dlt < 0.0
string _zone = _poc_frac >= i_bctx_top ? "TOP" : _poc_frac <= i_bctx_bot ? "BOT" : "MID"
bool _bull = close >= open
// ── classification ──────────────────────────────────────────────
if _bull
if _zone == "TOP"
_bctx_pat := _poc_sell ? "rejection" : "abs-contrarian"
_bctx_out_bull := false
else if _zone == "MID"
_bctx_pat := _poc_buy ? "acceptance buy" : "abs-continue"
_bctx_out_bull := true
else
_bctx_pat := _poc_sell ? "abs-continue" : "acceptance buy"
_bctx_out_bull := true
else
if _zone == "BOT"
_bctx_pat := _poc_buy ? "rejection" : "abs-contrarian"
_bctx_out_bull := true
else if _zone == "MID"
_bctx_pat := _poc_sell ? "acceptance sell" : "abs-continue"
_bctx_out_bull := false
else
_bctx_pat := _poc_buy ? "abs-continue" : "acceptance sell"
_bctx_out_bull := false
_bctx_is_rev := (_bull and not _bctx_out_bull) or (not _bull and _bctx_out_bull)
_bctx_fired := _bctx_pat != ""
// ── drawing ─────────────────────────────────────────────────────
color _bctx_out_col = _bctx_out_bull ? i_bctx_up : i_bctx_dn
color _bctx_side_col= _poc_buy ? i_qa_c_buy : _poc_sell ? i_qa_c_sell : i_qa_c_mix
string _bctx_side_s = _poc_buy ? "BUY" : _poc_sell ? "SELL" : "MIXED"
string _bctx_szr = switch i_bctx_sz
"Tiny" => size.tiny
"Normal" => size.normal
"Large" => size.large
=> size.small
float _bctx_off = nz(atr14, 5.0) * 0.6
string _bctx_tt = "── BUBBLE CONTEXT ──" +
"\nPattern: " + _bctx_pat + (_bctx_is_rev ? " (reversal)" : " (continuation)") +
"\nCandle: " + (_bull ? "BULLISH" : "BEARISH") +
"\nCluster: " + _zone + " zone @ $" + str.tostring(_poc_y, "#.##") +
" (" + str.tostring(_poc_frac * 100.0, "#") + "% of range)" +
"\nCluster side: " + _bctx_side_s + " Δ " + str.tostring(_poc_dlt, format.volume) +
"\nLTF: " + i_bctx_ltf + " bins " + str.tostring(_n) +
"\nBias: expect " + (_bctx_out_bull ? "UP ▲" : "DOWN ▼") +
"\nNote: LTF intrabar proxy — eyes, not a validated edge"
// position dot at the true LTF cluster (colored by cluster side)
if i_bctx_dot
array.push(_bctx_lbs, label.new(bar_index, _poc_y, "●",
style = label.style_label_center,
color = color.new(color.black, 100),
textcolor = _bctx_side_col,
size = _bctx_szr,
tooltip = _bctx_tt))
if array.size(_bctx_lbs) > 300
label.delete(array.shift(_bctx_lbs))
// context text tag — above high (bearish outcome) / below low (bullish outcome)
if i_bctx_lbl
string _arw = i_bctx_arrow ? (_poc_buy ? "▲ " : _poc_sell ? "▼ " : "◆ ") : ""
array.push(_bctx_lbs, label.new(bar_index,
_bctx_out_bull ? low - _bctx_off : high + _bctx_off,
_arw + _bctx_pat,
style = _bctx_out_bull ? label.style_label_up : label.style_label_down,
color = color.new(_bctx_out_col, 82),
textcolor = _bctx_out_col,
size = _bctx_szr,
tooltip = _bctx_tt))
if array.size(_bctx_lbs) > 300
label.delete(array.shift(_bctx_lbs))
// ═══════════════════════════════════════════════════════════════════════════════
// §12 AMT PATTERN ENGINE — SOVEREIGN §24b ADAPTED
// ═══════════════════════════════════════════════════════════════════════════════
float _amt_rng = math.max(high - low, syminfo.mintick)
float _amt_bvol = volume * ((close - low) / _amt_rng)
float _amt_svol = volume * ((high - close) / _amt_rng)
float _amt_wick_up = (high - math.max(close, open)) / _amt_rng
float _amt_wick_dn = (math.min(close, open) - low) / _amt_rng
bool _amt_is_bull = close >= open
float _amt_body_top = math.max(close, open)
float _amt_body_bot = math.min(close, open)
float _amt_mass = vol_sma50 > 0.0 ? volume / vol_sma50 : 1.0
bool _amt_hv = i_show_amt and _amt_mass >= i_ice_mass
string _bpat = ""
float _b_y = na
color _b_col = na
string _b_sig = ""
string _b_emj = ""
string _b_acc_txt = ""
float _atr_off = nz(atr14, 5.0) * 0.5
if _amt_hv
if _amt_is_bull
if i_amt_rej and _amt_wick_up >= i_amt_wick_rej
_bpat := "REJECTION SELL"
_b_y := high + _atr_off
_b_col := color.new(i_amt_rej_col, 0)
_b_sig := "SELL"
_b_emj := "⛔"
else if i_amt_ctr and _amt_svol > _amt_bvol * (i_amt_vol_dom * 0.8) and _amt_wick_up >= 0.12
_bpat := "CONTRARIAN WARN"
_b_y := high + _atr_off * 0.6
_b_col := color.new(#009688, 0)
_b_sig := "WARN"
_b_emj := "⚠"
else if i_amt_abs and _amt_bvol > _amt_svol * i_amt_vol_dom and _amt_wick_dn >= 0.12
_bpat := "ABSORPTION BUY"
_b_y := low - _atr_off
_b_col := color.new(i_amt_abs_col, 20)
_b_sig := "BUY"
_b_emj := "🧽"
else if i_amt_acc
_bpat := "ACCEPTANCE BUY"
_b_y := low - _atr_off * 0.5
_b_col := color.new(#00BCD4, 0)
_b_sig := "BUY"
_b_emj := "●"
_b_acc_txt := "Accept Buy"
else
if i_amt_rej and _amt_wick_dn >= i_amt_wick_rej
_bpat := "REJECTION BUY"
_b_y := low - _atr_off
_b_col := color.new(#009688, 0)
_b_sig := "BUY"
_b_emj := "⛔"
else if i_amt_ctr and _amt_bvol > _amt_svol * (i_amt_vol_dom * 0.8) and _amt_wick_dn >= 0.12
_bpat := "CONTRARIAN WARN"
_b_y := low - _atr_off * 0.6
_b_col := color.new(i_amt_rej_col, 0)
_b_sig := "WARN"
_b_emj := "⚠"
else if i_amt_abs and _amt_svol > _amt_bvol * i_amt_vol_dom and _amt_wick_up >= 0.12
_bpat := "ABSORPTION SELL"
_b_y := high + _atr_off
_b_col := color.new(i_amt_abs_col, 60)
_b_sig := "SELL"
_b_emj := "🧽"
else if i_amt_acc
_bpat := "ACCEPTANCE SELL"
_b_y := high + _atr_off * 0.5
_b_col := color.new(#E91E63, 0)
_b_sig := "SELL"
_b_emj := "●"
_b_acc_txt := "Accept Sell"
var array<label> _amt_lbs = array.new_label()
if _amt_hv and _bpat != "" and not na(_b_y)
float _bint = _amt_mass
string _btt = _bpat + " [" + _b_sig + "]" +
"\nBuy: " + str.tostring(_amt_bvol, format.volume) +
" Sell: " + str.tostring(_amt_svol, format.volume) +
"\nWick+: " + str.tostring(_amt_wick_up * 100.0, "#.#") + "%" +
" Wick-: " + str.tostring(_amt_wick_dn * 100.0, "#.#") + "%" +
"\nMass: " + str.tostring(_bint, "#.1") + "x SMA50" +
"\nMLMI: " + (mlmi_fresh ? "FRESH" : mlmi_valid ? "VALID" : "EXPIRED") +
" SMI: " + str.tostring(smi, "#.1")
string _emj_sz_resolved = switch i_amt_emj_sz
"Small" => size.small
"Normal" => size.normal
"Huge" => size.huge
=> size.large
array.push(_amt_lbs, label.new(bar_index, _b_y, _b_emj,
style = label.style_label_center,
color = color.new(color.black, 100),
textcolor= _b_col,
size = _emj_sz_resolved,
tooltip = _btt))
if array.size(_amt_lbs) > 400
label.delete(array.shift(_amt_lbs))
// [v25-1] Acceptance text label — "Accept Buy" / "Accept Sell" at size.tiny
if _b_acc_txt != ""
array.push(_amt_lbs, label.new(bar_index, _b_y, _b_acc_txt,
style = _b_sig == "BUY" ? label.style_label_up : label.style_label_down,
color = color.new(_b_col, 75),
textcolor = _b_col,
size = size.tiny,
tooltip = _btt))
if array.size(_amt_lbs) > 400
label.delete(array.shift(_amt_lbs))
// Iceberg at GEX zones
bool ice_g1_up = i_amt_ice and math.abs(close - g1_up) <= i_tol * 1.5 and _amt_mass >= i_ice_mass and close <= g1_up
bool ice_g1_dn = i_amt_ice and math.abs(close - g1_dn) <= i_tol * 1.5 and _amt_mass >= i_ice_mass and close >= g1_dn
bool ice_g2_up = i_amt_ice and math.abs(close - g2_up) <= i_tol * 1.5 and _amt_mass >= i_ice_mass
bool ice_g2_dn = i_amt_ice and math.abs(close - g2_dn) <= i_tol * 1.5 and _amt_mass >= i_ice_mass
bool ice_sell_signal = ice_g1_up or ice_g2_up
bool ice_buy_signal = ice_g1_dn or ice_g2_dn
var array<label> _ice_lbs = array.new_label()
if ice_buy_signal
string _iz_nm = ice_g1_dn ? "g1 $" + str.tostring(g1_dn,"#.##") : "g2 $" + str.tostring(g2_dn,"#.##")
string _iz_tt = "ICEBERG ORDER — SUPPORT ZONE\nZone: " + _iz_nm +
"\nMass: " + str.tostring(_amt_mass,"#.1") + "x SMA50" +
"\nPattern: Hidden institutional BUY at GEX support" +
"\nCB Tier: " + cb_tier_str
string _ize_sz = i_amt_emj_sz == "Huge" ? size.huge : i_amt_emj_sz == "Large" ? size.large : i_amt_emj_sz == "Normal" ? size.normal : size.small
array.push(_ice_lbs, label.new(bar_index, low - nz(atr14,5.0) * 0.3, "❄️",
style = label.style_label_center,
color = color.new(color.black, 100),
textcolor= i_amt_ice_col,
size = _ize_sz,
tooltip = _iz_tt))
if array.size(_ice_lbs) > 200
label.delete(array.shift(_ice_lbs))
if ice_sell_signal
string _iz_nm = ice_g1_up ? "g1 $" + str.tostring(g1_up,"#.##") : "g2 $" + str.tostring(g2_up,"#.##")
string _iz_tt = "ICEBERG ORDER — RESISTANCE ZONE\nZone: " + _iz_nm +
"\nMass: " + str.tostring(_amt_mass,"#.1") + "x SMA50" +
"\nPattern: Hidden institutional SELL at GEX resistance" +
"\nCB Tier: " + cb_tier_str
string _ize_sz = i_amt_emj_sz == "Huge" ? size.huge : i_amt_emj_sz == "Large" ? size.large : i_amt_emj_sz == "Normal" ? size.normal : size.small
array.push(_ice_lbs, label.new(bar_index, high + nz(atr14,5.0) * 0.3, "❄️",
style = label.style_label_center,
color = color.new(color.black, 100),
textcolor= i_amt_ice_col,
size = _ize_sz,
tooltip = _iz_tt))
if array.size(_ice_lbs) > 200
label.delete(array.shift(_ice_lbs))
// ═══════════════════════════════════════════════════════════════════════════════
// §13 CONFLUENCE CHECKS
// ═══════════════════════════════════════════════════════════════════════════════
float _conf_tol = i_tol * 2.5
bool sd_u_in_frame = sd_u < g1_up and sd_u > g1_dn
bool sd_d_in_frame = sd_d > g1_dn and sd_d < g1_up
bool sd_near_c1 = math.abs(sd_u - sp_c1) <= i_tol
bool sd_near_p1 = math.abs(sd_d - sp_p1) <= i_tol
bool pbv1_u_conf = math.abs(g2_up - pbv_l1_u) <= _conf_tol
bool pbv1_d_conf = math.abs(g2_dn - pbv_l1_d) <= _conf_tol
bool sd_u_conf = math.abs(g3_up - sd_u) <= _conf_tol
bool sd_d_conf = math.abs(g3_dn - sd_d) <= _conf_tol
bool pbv2_u_conf = math.abs(g3_up - pbv_l2_u) <= _conf_tol
bool pbv2_d_conf = math.abs(g3_dn - pbv_l2_d) <= _conf_tol
bool pbv3_u_conf = math.abs(g3_up - pbv_l3_u) <= _conf_tol
bool pbv3_d_conf = math.abs(g3_dn - pbv_l3_d) <= _conf_tol
bool exp_conf_up = sd_u_conf or pbv2_u_conf or pbv3_u_conf
bool exp_conf_dn = sd_d_conf or pbv2_d_conf or pbv3_d_conf
string _sd_sig_tag = _using_delta_sig ? " 25D" : " SD1.618s"
string _exp_tag_u = sd_u_conf and pbv2_u_conf ? " SD+PBV" : sd_u_conf ? _sd_sig_tag : pbv2_u_conf ? " PBV" + str.tostring(i_pbv_2,"#.###") + "%" : pbv3_u_conf ? " PBV3" + str.tostring(i_pbv_3,"#.###") + "%" : ""
string _exp_tag_d = sd_d_conf and pbv2_d_conf ? " SD+PBV" : sd_d_conf ? _sd_sig_tag : pbv2_d_conf ? " PBV" + str.tostring(i_pbv_2,"#.###") + "%" : pbv3_d_conf ? " PBV3" + str.tostring(i_pbv_3,"#.###") + "%" : ""
// ═══════════════════════════════════════════════════════════════════════════════
// §14 SQUEEZE + BUBBLE PROXIMITY
// ═══════════════════════════════════════════════════════════════════════════════
float body_r = f_body(open, close, high, low)
bool valid_body = body_r >= i_body_min
float prox_zone = math.max(i_tol * i_prox_mult, nz(atr14, i_tol) * 0.3)
bool near_g1_up = math.abs(close - g1_up) <= prox_zone
bool near_g1_dn = math.abs(close - g1_dn) <= prox_zone
bool _sqz_co = ta.crossover(close, anchor)
bool sqz_up = _sqz_co and _qa_abs_dlt > _dMS
bool _sqz_cu = ta.crossunder(close, anchor)
bool sqz_dn = _sqz_cu and _qa_abs_dlt > _dMS
// [v23] YZ-based Squeeze — Yang-Zhang realized vol, consistent with GEX physics
float _yz_fast = f_yz(i_sqz_yz_fast, 1.0)
float _yz_slow = f_yz(i_sqz_yz_slow, 1.0)
float _yz_ratio = _yz_slow > 0.0 ? _yz_fast / _yz_slow : 1.0
bool sqz_on = _yz_fast < _yz_slow * i_sqz_ratio
var bool _sqz_prev = false
bool sqz_fire = not sqz_on and _sqz_prev
_sqz_prev := sqz_on
var int _sqz_dur = 0
_sqz_dur := sqz_on ? _sqz_dur + 1 : 0
bool _sqz_dur_ok = _sqz_dur[1] >= i_sqz_min_dur
bool _sqz_ratio_exp = _yz_ratio > nz(_yz_ratio[1], _yz_ratio)
bool sqz_yz_bull = sqz_fire and close >= anchor and _sqz_dur_ok and _sqz_ratio_exp
bool sqz_yz_bear = sqz_fire and close < anchor and _sqz_dur_ok and _sqz_ratio_exp
var int _age_up = 999
var int _age_dn = 999
if qa_any_bull or sqz_up
_age_up := 0
else
_age_up := math.min(_age_up + 1, 999)
if qa_any_bear or sqz_dn
_age_dn := 0
else
_age_dn := math.min(_age_dn + 1, 999)
bool recent_bull = _age_up <= i_evt_win
bool recent_dn = _age_dn <= i_evt_win
// ═══════════════════════════════════════════════════════════════════════════════
// §15 REGIME FSM [v19: ATR-based breakout fallback]
// ═══════════════════════════════════════════════════════════════════════════════
bool inside_frame = close > g1_dn and close < g1_up
var int _out_cnt = 0
if inside_frame
_out_cnt := 0
else
_out_cnt := _out_cnt + 1
bool hyst_confirmed = _out_cnt >= i_out_bars
float _atr_mom = nz(atr14, 1.0)
bool _atr_bo_up = not inside_frame and close > g1_up and (close - g1_up) > _atr_mom * 0.5
bool _atr_bo_dn = not inside_frame and close < g1_dn and (g1_dn - close) > _atr_mom * 0.5
bool eff_bo_bull = recent_bull or _atr_bo_up
bool eff_bo_bear = recent_dn or _atr_bo_dn
var int regime = 0
var int _reg_prv = 0
_reg_prv := regime
if inside_frame
regime := 0
else if close > g1_up and eff_bo_bull and hyst_confirmed
regime := 1
else if close < g1_dn and eff_bo_bear and hyst_confirmed
regime := -1
float bo_gate_up = g1_up + i_tol * 0.5
float bo_gate_dn = g1_dn - i_tol * 0.5
// ═══════════════════════════════════════════════════════════════════════════════
// §16 REGIME CONFIDENCE SCORE [v19: CB tier penalty added]
// ═══════════════════════════════════════════════════════════════════════════════
int conf_score = 50
if gvz_compressed
conf_score := conf_score + 15
if gvz_normal
conf_score := conf_score + 10
if gvz_elevated
conf_score := conf_score - 10
if gvz_extreme
conf_score := conf_score - 25
if sig_regime == "COMPRESSED"
conf_score := conf_score + 10
if sig_regime == "NORMAL"
conf_score := conf_score + 5
if sig_regime == "EXPANDING"
conf_score := conf_score - 5
if sig_regime == "EXTREME"
conf_score := conf_score - 15
if frame_width > sigma * 0.5
conf_score := conf_score + 10
if not frame_ok
conf_score := conf_score - 20
if _is_lon
conf_score := conf_score + 10
if _is_ny
conf_score := conf_score + 5
if _is_asia
conf_score := conf_score - 10
if mlmi_fresh and mlmi_bull and regime == -1
conf_score := conf_score + 8
if mlmi_fresh and mlmi_bear and regime == 1
conf_score := conf_score + 8
if mlmi_valid and not mlmi_fresh
conf_score := conf_score - 3
if gvz_spiking
conf_score := conf_score - 8
if dxy_bear and regime == 1
conf_score := conf_score + 6
if dxy_bull and regime == -1
conf_score := conf_score + 6
if cb_t3_active
conf_score := conf_score - 20
else if cb_t2_active
conf_score := conf_score - 10
else if cb_t1_active
conf_score := conf_score - 5
conf_score := math.min(100, math.max(0, conf_score))
color conf_col = conf_score >= 75 ? #00E676 : conf_score >= 50 ? #FFD700 : conf_score >= 30 ? #FF9800 : #FF1744
string conf_str = str.tostring(conf_score) + "/100"
// ═══════════════════════════════════════════════════════════════════════════════
// §FRZ FROZEN ZONE DISPLAY — ported from QC_BasisMatrix v8.4 §13
// [v24-1] max_boxes_count=500 now declared in indicator() → FRZ_MAX honored.
// ═══════════════════════════════════════════════════════════════════════════════
float frz_liq_top = implied_spot + b_std * i_frz_mult
float frz_liq_bot = implied_spot - b_std * i_frz_mult
bool frz_high_vol = volume > vol_sma50 * i_frz_vfac
bool frz_ready = i_show_frz and bar_index >= i_frz_warmup
bool frz_pass_sell = frz_ready and close >= frz_liq_top and frz_high_vol
bool frz_pass_buy = frz_ready and close <= frz_liq_bot and frz_high_vol
bool frz_trig_sell = frz_pass_sell and not frz_pass_sell[1]
bool frz_trig_buy = frz_pass_buy and not frz_pass_buy[1]
const int FRZ_MAX = 500
var array<box> frz_sell_zones = array.new<box>()
var array<box> frz_buy_zones = array.new<box>()
bool frz_can_sell = frz_trig_sell and array.size(frz_sell_zones) < FRZ_MAX
bool frz_can_buy = frz_trig_buy and array.size(frz_buy_zones) < FRZ_MAX
if frz_can_sell and array.size(frz_sell_zones) > 0
if (bar_index - box.get_left(array.last(frz_sell_zones))) <= 3
frz_can_sell := false
if frz_can_buy and array.size(frz_buy_zones) > 0
if (bar_index - box.get_left(array.last(frz_buy_zones))) <= 3
frz_can_buy := false
if frz_can_sell
float _s_top = high
float _s_bot = math.max(math.max(close, frz_liq_top), _s_top - atr14 * 2.0)
if _s_top > _s_bot
array.push(frz_sell_zones, box.new(
bar_index, _s_top, bar_index + 5, _s_bot,
border_color = color.new(color.red, 40),
border_style = line.style_solid,
bgcolor = color.new(color.red, 70),
text = "Supply\n(Frozen)",
text_color = color.new(color.white, 20),
text_size = size.tiny))
if frz_can_buy
float _b_bot = low
float _b_top = math.min(math.min(close, frz_liq_bot), _b_bot + atr14 * 2.0)
if _b_top > _b_bot
array.push(frz_buy_zones, box.new(
bar_index, _b_top, bar_index + 5, _b_bot,
border_color = color.new(color.green, 40),
border_style = line.style_solid,
bgcolor = color.new(color.green, 70),
text = "Demand\n(Frozen)",
text_color = color.new(color.white, 20),
text_size = size.tiny,
text_valign = text.align_bottom))
if array.size(frz_sell_zones) > 0
for _fi = array.size(frz_sell_zones) - 1 to 0
box _fb = array.get(frz_sell_zones, _fi)
if close > box.get_top(_fb)
box.set_bgcolor(_fb, color.new(color.gray, 90))
box.set_border_color(_fb, color.new(color.gray, 85))
box.set_text(_fb, "")
box.set_right(_fb, bar_index)
array.remove(frz_sell_zones, _fi)
else
box.set_right(_fb, bar_index + 3)
if array.size(frz_buy_zones) > 0
for _fi = array.size(frz_buy_zones) - 1 to 0
box _fb = array.get(frz_buy_zones, _fi)
if close < box.get_bottom(_fb)
box.set_bgcolor(_fb, color.new(color.gray, 90))
box.set_border_color(_fb, color.new(color.gray, 85))
box.set_text(_fb, "")
box.set_right(_fb, bar_index)
array.remove(frz_buy_zones, _fi)
else
box.set_right(_fb, bar_index + 3)
// ═══════════════════════════════════════════════════════════════════════════════
// §14b SQUEEZE LABELS [v22 new] — label.new() → 0 plot-budget units
// ═══════════════════════════════════════════════════════════════════════════════
var array<label> _sqz_lbs = array.new_label()
if i_sqz_en and (sqz_yz_bull or sqz_yz_bear)
string _slsz = switch i_sqz_lbl_sz
"Tiny" => size.tiny
"Normal" => size.normal
"Large" => size.large
=> size.small
string _stsz = switch i_sqz_txt_sz
"Tiny" => size.tiny
"Normal" => size.normal
=> size.small
float _sqz_off = nz(atr14, 5.0) * i_sqz_offset
string _reg_tag = regime == 1 ? "TREND UP" : regime == -1 ? "TREND DN" : "MR ZONE"
string _sess_tag = _is_lon ? "LON" : _is_ny ? "NY" : "ASIA"
string _dur_tag = str.tostring(_sqz_dur[1] > 0 ? _sqz_dur[1] : 1) + " bars"
if sqz_yz_bull
string _tip = "SQUEEZE RELEASE — BULL (YZ v24)" +
"\n────────────────────" +
"\nYZ fast(" + str.tostring(i_sqz_yz_fast) + "): " + str.tostring(_yz_fast,"#.####") +
" slow(" + str.tostring(i_sqz_yz_slow) + "): " + str.tostring(_yz_slow,"#.####") +
"\nRatio: " + str.tostring(_yz_ratio * 100.0,"#.#") + "% (threshold " + str.tostring(i_sqz_ratio * 100.0,"#") + "%)" +
"\nCompressed for: " + _dur_tag + " (min " + str.tostring(i_sqz_min_dur) + "✓)" +
"\nRatio expanding: " + (_sqz_ratio_exp ? "YES ✓" : "NO") +
"\nClose vs anchor: +" + str.tostring(close - anchor,"#.##") +
"\n────────────────────" +
"\nSigma regime: " + sig_regime +
" GVZ: " + gvz_tier +
"\nSession: " + _sess_tag +
" Regime: " + _reg_tag +
"\nConf score: " + conf_str +
"\n────────────────────" +
"\nCB tier: " + cb_tier_str +
"\nDXY: " + (dxy_bull ? "BULL" : dxy_bear ? "BEAR" : "NEUTRAL") +
"\nNote: confirm with cond_G (Breakout BUY) or QA Big Bull"
array.push(_sqz_lbs, label.new(
bar_index, low - _sqz_off,
i_sqz_up_txt,
style = label.style_label_up,
color = color.new(i_sqz_up_col, i_sqz_lbl_tr),
textcolor = i_sqz_up_col,
size = _slsz,
tooltip = _tip))
if sqz_yz_bear
string _tip = "SQUEEZE RELEASE — BEAR (YZ v24)" +
"\n────────────────────" +
"\nYZ fast(" + str.tostring(i_sqz_yz_fast) + "): " + str.tostring(_yz_fast,"#.####") +
" slow(" + str.tostring(i_sqz_yz_slow) + "): " + str.tostring(_yz_slow,"#.####") +
"\nRatio: " + str.tostring(_yz_ratio * 100.0,"#.#") + "% (threshold " + str.tostring(i_sqz_ratio * 100.0,"#") + "%)" +
"\nCompressed for: " + _dur_tag + " (min " + str.tostring(i_sqz_min_dur) + "✓)" +
"\nRatio expanding: " + (_sqz_ratio_exp ? "YES ✓" : "NO") +
"\nClose vs anchor: " + str.tostring(close - anchor,"#.##") +
"\n────────────────────" +
"\nSigma regime: " + sig_regime +
" GVZ: " + gvz_tier +
"\nSession: " + _sess_tag +
" Regime: " + _reg_tag +
"\nConf score: " + conf_str +
"\n────────────────────" +
"\nCB tier: " + cb_tier_str +
"\nDXY: " + (dxy_bull ? "BULL" : dxy_bear ? "BEAR" : "NEUTRAL") +
"\nNote: confirm with cond_H (Breakout SELL) or QA Big Bear"
array.push(_sqz_lbs, label.new(
bar_index, high + _sqz_off,
i_sqz_dn_txt,
style = label.style_label_down,
color = color.new(i_sqz_dn_col, i_sqz_lbl_tr),
textcolor = i_sqz_dn_col,
size = _slsz,
tooltip = _tip))
if array.size(_sqz_lbs) > 400
label.delete(array.shift(_sqz_lbs))
// ═══════════════════════════════════════════════════════════════════════════════
// §16c EXPANSION SCORE + MR-INTO-TREND [v27] — DISPLAY-ONLY (label → 0 budget)
// ─────────────────────────────────────────────────────────────────────────────
// Two reads from the "3 primitives" framework, as VISUAL flags only (no entry):
// • EXPANSION = the breakout trigger — this bar's range ≫ its trailing average
// (transcript: 5 candles avg 1%, 6th moves 2% = volatility expansion).
// • MR-INTO-TREND = buy-the-dip WITH the trend — inside an established trend
// (regime ±1) price RETESTS the g1 flip level (broken resistance→support in
// an uptrend; broken support→resistance in a downtrend). This is fading
// toward the trend, the systematic opposite of fading against it.
// Touches NO gate / conf_score / entry — labels only.
// ═══════════════════════════════════════════════════════════════════════════════
float _xmt_rng = high - low
float _xmt_avg = ta.sma(_xmt_rng, i_exp_len)
float _xmt_score = _xmt_avg > 0.0 ? _xmt_rng / _xmt_avg : 0.0
bool _exp_fire = i_xmt_on and _xmt_score >= i_exp_thr
bool _exp_up = _exp_fire and close >= open
bool _exp_dn = _exp_fire and close < open
bool _exp_up_f = _exp_up and not _exp_up[1]
bool _exp_dn_f = _exp_dn and not _exp_dn[1]
float _mrt_hi = ta.highest(high, i_mrt_look)
float _mrt_lo = ta.lowest(low, i_mrt_look)
bool _mrt_buy = i_xmt_on and regime == 1 and f_touch(low, g1_up) and close >= g1_up - i_tol
bool _mrt_sell = i_xmt_on and regime == -1 and f_touch(high, g1_dn) and close <= g1_dn + i_tol
float _mrt_imp_u = _mrt_hi - g1_up
float _mrt_imp_d = g1_dn - _mrt_lo
float _mrt_depth = _mrt_buy and _mrt_imp_u > 0.0 ? (_mrt_hi - low) / _mrt_imp_u : _mrt_sell and _mrt_imp_d > 0.0 ? (high - _mrt_lo) / _mrt_imp_d : na
var int _mrt_lastb = -999
var int _mrt_lasts = -999
bool _mrt_buy_f = _mrt_buy and (bar_index - _mrt_lastb) >= i_dedup
bool _mrt_sell_f = _mrt_sell and (bar_index - _mrt_lasts) >= i_dedup
if _mrt_buy_f
_mrt_lastb := bar_index
if _mrt_sell_f
_mrt_lasts := bar_index
string _xmt_szr = switch i_xmt_sz
"Tiny" => size.tiny
"Normal" => size.normal
"Large" => size.large
=> size.small
float _xmt_off = nz(atr14, 5.0) * 0.55
var array<label> _xmt_lbs = array.new_label()
if i_xmt_on and i_exp_lbl and _exp_up_f
array.push(_xmt_lbs, label.new(bar_index, low - _xmt_off, "EXP▲ " + str.tostring(_xmt_score, "#.#") + "×",
style = label.style_label_up,
color = color.new(i_exp_col, 78),
textcolor = i_exp_col,
size = _xmt_szr,
tooltip = "EXPANSION (bull) — breakout trigger\nRange: " + str.tostring(_xmt_rng, format.mintick) + " (" + str.tostring(_xmt_score, "#.##") + "× " + str.tostring(i_exp_len) + "-bar avg)\nRegime: " + (regime == 1 ? "TREND-UP" : regime == -1 ? "TREND-DN" : "MR ZONE") + "\nConf: " + conf_str))
if array.size(_xmt_lbs) > 300
label.delete(array.shift(_xmt_lbs))
if i_xmt_on and i_exp_lbl and _exp_dn_f
array.push(_xmt_lbs, label.new(bar_index, high + _xmt_off, "EXP▼ " + str.tostring(_xmt_score, "#.#") + "×",
style = label.style_label_down,
color = color.new(i_exp_col, 78),
textcolor = i_exp_col,
size = _xmt_szr,
tooltip = "EXPANSION (bear) — breakout trigger\nRange: " + str.tostring(_xmt_rng, format.mintick) + " (" + str.tostring(_xmt_score, "#.##") + "× " + str.tostring(i_exp_len) + "-bar avg)\nRegime: " + (regime == 1 ? "TREND-UP" : regime == -1 ? "TREND-DN" : "MR ZONE") + "\nConf: " + conf_str))
if array.size(_xmt_lbs) > 300
label.delete(array.shift(_xmt_lbs))
if i_xmt_on and i_mrt_lbl and _mrt_buy_f
array.push(_xmt_lbs, label.new(bar_index, low - _xmt_off, "MR→trend BUY",
style = label.style_label_up,
color = color.new(i_xmt_up, 74),
textcolor = i_xmt_up,
size = _xmt_szr,
tooltip = "MR-INTO-TREND (buy the dip WITH the uptrend)\nRetest of g1 flip $" + str.tostring(g1_up, format.mintick) + " (broken resistance → support)\nPullback depth: " + str.tostring(nz(_mrt_depth) * 100.0, "#") + "% of impulse (deeper = higher prob)\nNOT an entry — visual flag. Conf: " + conf_str))
if array.size(_xmt_lbs) > 300
label.delete(array.shift(_xmt_lbs))
if i_xmt_on and i_mrt_lbl and _mrt_sell_f
array.push(_xmt_lbs, label.new(bar_index, high + _xmt_off, "MR→trend SELL",
style = label.style_label_down,
color = color.new(i_xmt_dn, 74),
textcolor = i_xmt_dn,
size = _xmt_szr,
tooltip = "MR-INTO-TREND (sell the rip WITH the downtrend)\nRetest of g1 flip $" + str.tostring(g1_dn, format.mintick) + " (broken support → resistance)\nPullback depth: " + str.tostring(nz(_mrt_depth) * 100.0, "#") + "% of impulse (deeper = higher prob)\nNOT an entry — visual flag. Conf: " + conf_str))
if array.size(_xmt_lbs) > 300
label.delete(array.shift(_xmt_lbs))
// ═══════════════════════════════════════════════════════════════════════════════
// §17 SIGNAL LOGIC — Priority Gate C/D > A/B > E/F (+MLMI/SMI+DXY gates)
// ═══════════════════════════════════════════════════════════════════════════════
var int _last_A = -999, var int _last_B = -999
var int _last_C = -999, var int _last_D = -999
var int _last_E = -999, var int _last_F = -999
var int _last_G = -999, var int _last_H = -999
var int _last_I = -999, var int _last_J = -999
var int _last_K = -999, var int _last_L = -999
var int _last_M = -999, var int _last_N = -999
f_dedup(int last_bar) => (bar_index - last_bar) >= i_dedup
bool cb_mr_block = i_cb_gate and cb_t1_active
bool mr_gate_ok = not gvz_block_mr and frame_ok and _sess_ok_mr and not cb_mr_block
bool mr_buy_ok = mr_gate_ok and not dxy_penalise_buy
bool mr_sell_ok = mr_gate_ok and not dxy_penalise_sell
bool _raw_C = regime == 0 and sd_d_in_frame and mr_buy_ok
and f_touch(low, sd_d) and close > sd_d - i_tol
and not qa_bear_3 and f_dedup(_last_C) and _mlmi_c_gate
if _raw_C
_last_C := bar_index
bool _raw_D = regime == 0 and sd_u_in_frame and mr_sell_ok
and f_touch(high, sd_u) and close < sd_u + i_tol
and not qa_bull_3 and f_dedup(_last_D) and _mlmi_d_gate
if _raw_D
_last_D := bar_index
bool _raw_A = regime == 0 and inside_frame and mr_buy_ok
and not sd_d_in_frame and f_touch(low, g1_dn)
and close > g1_dn - i_tol and not qa_bear_3
and f_dedup(_last_A) and _mlmi_a_gate
if _raw_A
_last_A := bar_index
bool _raw_B = regime == 0 and inside_frame and mr_sell_ok
and not sd_u_in_frame and f_touch(high, g1_up)
and close < g1_up + i_tol and not qa_bull_3
and f_dedup(_last_B) and _mlmi_b_gate
if _raw_B
_last_B := bar_index
bool _raw_E = regime == 0 and inside_frame and mr_buy_ok
and not sd_near_p1 and f_touch(low, sp_p1)
and close > sp_p1 - i_tol and not qa_bear_3 and f_dedup(_last_E)
if _raw_E
_last_E := bar_index
bool _raw_F = regime == 0 and inside_frame and mr_sell_ok
and not sd_near_c1 and f_touch(high, sp_c1)
and close < sp_c1 + i_tol and not qa_bull_3 and f_dedup(_last_F)
if _raw_F
_last_F := bar_index
bool cond_C = _raw_C
bool cond_D = _raw_D
bool cond_A = _raw_A and (not i_prio_gate or not _raw_C)
bool cond_B = _raw_B and (not i_prio_gate or not _raw_D)
bool cond_E = _raw_E and (not i_prio_gate or (not _raw_C and not _raw_A))
bool cond_F = _raw_F and (not i_prio_gate or (not _raw_D and not _raw_B))
bool cond_G = close > bo_gate_up and qa_bull_3 and qa_big_bull3
and hyst_confirmed and not qa_bear_3 and not gvz_block_mr
and frame_ok and f_dedup(_last_G) and _smi_g_gate
if cond_G
_last_G := bar_index
bool cond_H = close < bo_gate_dn and qa_bear_3 and qa_big_bear3
and hyst_confirmed and not qa_bull_3 and not gvz_block_mr
and frame_ok and f_dedup(_last_H) and _smi_h_gate
if cond_H
_last_H := bar_index
bool _raw_I = near_g1_up and qa_bear_3 and not qa_bull_3 and qa_big_bear3 and not cond_G and f_dedup(_last_I)
bool _raw_J = near_g1_dn and qa_bull_3 and not qa_bear_3 and qa_big_bull3 and not cond_H and f_dedup(_last_J)
bool cond_I = _raw_I
bool cond_J = _raw_J
if cond_I
_last_I := bar_index
if cond_J
_last_J := bar_index
bool cond_K = regime == -1 and f_touch(low, g2_dn) and close > g2_dn - i_tol and not gvz_extreme and f_dedup(_last_K)
if cond_K
_last_K := bar_index
bool cond_L = regime == 1 and f_touch(high, g2_up) and close < g2_up + i_tol and not gvz_extreme and f_dedup(_last_L)
if cond_L
_last_L := bar_index
bool cond_M = regime == -1 and exp_conf_dn and f_touch(low, g3_dn) and close > g3_dn - i_tol and f_dedup(_last_M)
if cond_M
_last_M := bar_index
bool cond_N = regime == 1 and exp_conf_up and f_touch(high, g3_up) and close < g3_up + i_tol and f_dedup(_last_N)
if cond_N
_last_N := bar_index
bool any_mr_buy = cond_A or cond_C or cond_E
bool any_mr_sell = cond_B or cond_D or cond_F
// ═══════════════════════════════════════════════════════════════════════════════
// §K K-MEANS CLUSTER VP (unchanged from v18)
// ═══════════════════════════════════════════════════════════════════════════════
var float[] _cvp_prices = array.new_float(0)
if barstate.isconfirmed and i_show_cvp
array.push(_cvp_prices, close)
if array.size(_cvp_prices) > i_cvp_lb
array.shift(_cvp_prices)
var float[] _cvp_centroids = array.new_float(0)
var int[] _cvp_counts = array.new_int(0)
// ═══════════════════════════════════════════════════════════════════════════════
// §18 CHART LINES + LABELS + CVP (barstate.islast)
// ═══════════════════════════════════════════════════════════════════════════════
var array<line> _all_lines = array.new_line()
var array<label> _all_labels = array.new_label()
var array<line> _cvp_lines = array.new_line()
var array<label> _cvp_lbls = array.new_label()
var array<linefill> _all_fills = array.new_linefill()
if barstate.islast
for _l in _all_lines
line.delete(_l)
for _lb in _all_labels
label.delete(_lb)
for _l in _cvp_lines
line.delete(_l)
for _lb in _cvp_lbls
label.delete(_lb)
for _f in _all_fills
linefill.delete(_f)
array.clear(_all_lines)
array.clear(_all_labels)
array.clear(_cvp_lines)
array.clear(_cvp_lbls)
array.clear(_all_fills)
int _lx0 = bar_index - 250
int _lx1 = bar_index + 70
int _lxl = bar_index + 4
string _sz = size.tiny
if i_show_cb and not na(_cb_settle)
array.push(_all_lines, line.new(_lx0,cb_t1_u,_lx1,cb_t1_u,color=i_cb_t1_col,style=line.style_dashed,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,cb_t1_d,_lx1,cb_t1_d,color=i_cb_t1_col,style=line.style_dashed,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,cb_t1_u,"CB-T1 +3% $"+str.tostring(cb_t1_u,"#.##")+" [COMEX halt awareness]",color=color.new(i_cb_t1_col,75),textcolor=i_cb_t1_col,style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,cb_t1_d,"CB-T1 -3% $"+str.tostring(cb_t1_d,"#.##")+" [COMEX halt awareness]",color=color.new(i_cb_t1_col,75),textcolor=i_cb_t1_col,style=label.style_label_left,size=_sz))
array.push(_all_lines, line.new(_lx0,cb_t2_u,_lx1,cb_t2_u,color=i_cb_t2_col,style=line.style_dashed,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,cb_t2_d,_lx1,cb_t2_d,color=i_cb_t2_col,style=line.style_dashed,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,cb_t2_u,"CB-T2 +6% $"+str.tostring(cb_t2_u,"#.##"),color=color.new(i_cb_t2_col,75),textcolor=i_cb_t2_col,style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,cb_t2_d,"CB-T2 -6% $"+str.tostring(cb_t2_d,"#.##"),color=color.new(i_cb_t2_col,75),textcolor=i_cb_t2_col,style=label.style_label_left,size=_sz))
array.push(_all_lines, line.new(_lx0,cb_t3_u,_lx1,cb_t3_u,color=i_cb_t3_col,style=line.style_dashed,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,cb_t3_d,_lx1,cb_t3_d,color=i_cb_t3_col,style=line.style_dashed,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,cb_t3_u,"CB-T3 +9% $"+str.tostring(cb_t3_u,"#.##")+" [EXTREME HALT]",color=color.new(i_cb_t3_col,75),textcolor=i_cb_t3_col,style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,cb_t3_d,"CB-T3 -9% $"+str.tostring(cb_t3_d,"#.##")+" [EXTREME HALT]",color=color.new(i_cb_t3_col,75),textcolor=i_cb_t3_col,style=label.style_label_left,size=_sz))
if i_ice_strikes
bool _ice_c1 = math.abs(close - sp_c1) <= i_tol * 1.5 and _amt_mass >= i_ice_mass
bool _ice_p1 = math.abs(close - sp_p1) <= i_tol * 1.5 and _amt_mass >= i_ice_mass
string _ize_sz = i_amt_emj_sz == "Huge" ? size.huge : i_amt_emj_sz == "Large" ? size.large : i_amt_emj_sz == "Normal" ? size.normal : size.small
if _ice_c1
array.push(_all_labels, label.new(_lxl, sp_c1, "❄️",
style = label.style_label_center,
color = color.new(color.black, 100),
textcolor= i_amt_ice_col,
size = _ize_sz,
tooltip = "ICEBERG WARN: CALL+1 $" + str.tostring(sp_c1,"#.##") + " [SpotEx resistance]"))
if _ice_p1
array.push(_all_labels, label.new(_lxl, sp_p1, "❄️",
style = label.style_label_center,
color = color.new(color.black, 100),
textcolor= i_amt_ice_col,
size = _ize_sz,
tooltip = "ICEBERG WARN: PUT-1 $" + str.tostring(sp_p1,"#.##") + " [SpotEx support]"))
if i_show_g1_band
string _ru = regime == 1 ? " TREND UP - NO MR" : regime == -1 ? " TREND DN - below frame" : " [MR FRAME UPPER]"
string _rd = regime == -1 ? " TREND DN - NO MR" : regime == 1 ? " TREND UP - above frame" : " [MR FRAME LOWER]"
string _m_tag_u = not mlmi_valid ? " MLMI:EXP" : mlmi_fresh ? " MLMI:FRESH" : " MLMI:STALE"
string _cb_tag = cb_t1_active ? " " + cb_tier_str : ""
array.push(_all_labels, label.new(_lxl+2, g1_up, "gFLIP +" + str.tostring(_g1_eff,"#.###") + "x $" + str.tostring(g1_up,"#.##") + _ru + _m_tag_u + _cb_tag, color=color.new(i_band_g1_col,75), textcolor=i_band_g1_col, style=label.style_label_left, size=_sz))
array.push(_all_labels, label.new(_lxl+2, g1_dn, "gFLIP -" + str.tostring(_g1_eff,"#.###") + "x $" + str.tostring(g1_dn,"#.##") + _rd, color=color.new(i_band_g1_col,75), textcolor=i_band_g1_col, style=label.style_label_left, size=_sz))
if i_show_g2_band
string _g2u_r = regime == 1 ? " MR-BLK" : gvz_block_mr ? " GVZ" : " [MR SELL if touch]"
string _g2d_r = regime == -1 ? " MR-BLK" : gvz_block_mr ? " GVZ" : " [MR BUY if touch]"
array.push(_all_labels, label.new(_lxl+2, g2_up, "gWALL +" + str.tostring(_g2_eff,"#.###") + "x CALL WALL $" + str.tostring(g2_up,"#.##") + _g2u_r, color=color.new(i_band_g2u_col,75), textcolor=i_band_g2u_col, style=label.style_label_left, size=_sz))
array.push(_all_labels, label.new(_lxl+2, g2_dn, "gWALL -" + str.tostring(_g2_eff,"#.###") + "x PUT WALL $" + str.tostring(g2_dn,"#.##") + _g2d_r, color=color.new(i_band_g2d_col,75), textcolor=i_band_g2d_col, style=label.style_label_left, size=_sz))
if i_show_g3_band
array.push(_all_labels, label.new(_lxl+2, g3_up, "gEXP +" + str.tostring(_g3_eff,"#.###") + "x EXPLOSION $" + str.tostring(g3_up,"#.##") + (exp_conf_up ? " SD+PBV CONF" : "") + " [STRONG SELL]", color=color.new(i_band_g3_col,75), textcolor=i_band_g3_col, style=label.style_label_left, size=_sz))
array.push(_all_labels, label.new(_lxl+2, g3_dn, "gEXP -" + str.tostring(_g3_eff,"#.###") + "x EXPLOSION $" + str.tostring(g3_dn,"#.##") + (exp_conf_dn ? " SD+PBV CONF" : "") + " [STRONG BUY]", color=color.new(i_band_g3_col,75), textcolor=i_band_g3_col, style=label.style_label_left, size=_sz))
if i_show_basis
color _eq = basis_stable ? #00E676 : #FF9800
color _ez = math.abs(sess_z) >= 2.0 ? #FF9800 : #00E676
string _el = "EFP " + _sess_lbl + " Z=" + str.tostring(sess_z,"#.##") + "s " + gofo_regime + " " + basis_trend_s + (in_fix ? " FIX" : "") + " GOFO " + str.tostring(i_gofo_rate,"#.##") + "%"
array.push(_all_labels, label.new(bar_index+2, anchor + p_std*(i_sd_mult+0.3), _el, style=label.style_label_left, size=size.tiny, color=in_fix ? color.new(#FFD700,50) : color.new(_eq,65), textcolor=in_fix ? #FFD700 : _eq))
if sess_z_ext
array.push(_all_labels, label.new(bar_index-5, anchor + p_std*i_sd_mult*1.1, "EFP ARB Z=" + str.tostring(sess_z,"#.##") + "s " + (sess_z > 0 ? "PREMIUM" : "DISCOUNT"), style=label.style_label_left, size=size.tiny, color=color.new(sess_z > 0 ? #FF1744 : #00E676,55), textcolor=sess_z > 0 ? #FF1744 : #00E676))
if i_show_sd
if _show_phi_sys
string _sdlsz = f_lsz(i_sd_lbl_sz)
string _pu_fr = _sd_phi_u_in_frame ? " [IN FRAME]" : " [out]"
string _pd_fr = _sd_phi_d_in_frame ? " [IN FRAME]" : " [out]"
array.push(_all_lines, line.new(_lx0, sd_phi_u, _lx1, sd_phi_u, color=i_phi_col, style=line.style_dotted, width=1, extend=extend.right))
array.push(_all_lines, line.new(_lx0, sd_phi_d, _lx1, sd_phi_d, color=i_phi_col, style=line.style_dotted, width=1, extend=extend.right))
array.push(_all_labels, label.new(_lxl, sd_phi_u, "+" + str.tostring(i_sd_mult,"#.###") + "s phi $" + str.tostring(sd_phi_u,"#.##") + (_sd_phi_u_conf ? " g3" : "") + (_using_delta_sig ? "" : " [SIG]") + _pu_fr, color=color.new(i_phi_col,i_phi_lbl_tr), textcolor=i_phi_col, style=label.style_label_left, size=_sdlsz))
array.push(_all_labels, label.new(_lxl, sd_phi_d, "-" + str.tostring(i_sd_mult,"#.###") + "s phi $" + str.tostring(sd_phi_d,"#.##") + (_sd_phi_d_conf ? " g3" : "") + (_using_delta_sig ? "" : " [SIG]") + _pd_fr, color=color.new(i_phi_col,i_phi_lbl_tr), textcolor=i_phi_col, style=label.style_label_left, size=_sdlsz))
if _show_delta_sys
color _c25 = i_d25_col
color _c15 = i_d15_col
color _c5 = i_d5_col
string _sdlsz = f_lsz(i_sd_lbl_sz)
line l_45u = line.new(_lx0,_sd_45d_u,_lx1,_sd_45d_u,color=i_d45_col,style=line.style_dotted,width=1,extend=extend.right)
line l_45d = line.new(_lx0,_sd_45d_d,_lx1,_sd_45d_d,color=i_d45_col,style=line.style_dotted,width=1,extend=extend.right)
array.push(_all_lines, l_45u)
array.push(_all_lines, l_45d)
line l_35u = line.new(_lx0,_sd_35d_u,_lx1,_sd_35d_u,color=i_d35_col,style=line.style_dotted,width=1,extend=extend.right)
line l_35d = line.new(_lx0,_sd_35d_d,_lx1,_sd_35d_d,color=i_d35_col,style=line.style_dotted,width=1,extend=extend.right)
array.push(_all_lines, l_35u)
array.push(_all_lines, l_35d)
line l_25u = line.new(_lx0,_sd_25d_u,_lx1,_sd_25d_u,color=_c25,style=line.style_dotted,width=1,extend=extend.right)
line l_25d = line.new(_lx0,_sd_25d_d,_lx1,_sd_25d_d,color=_c25,style=line.style_dotted,width=1,extend=extend.right)
array.push(_all_lines, l_25u)
array.push(_all_lines, l_25d)
line l_15u = line.new(_lx0,_sd_15d_u,_lx1,_sd_15d_u,color=_c15,style=line.style_dotted,width=1,extend=extend.right)
line l_15d = line.new(_lx0,_sd_15d_d,_lx1,_sd_15d_d,color=_c15,style=line.style_dotted,width=1,extend=extend.right)
array.push(_all_lines, l_15u)
array.push(_all_lines, l_15d)
line l_5u = line.new(_lx0,_sd_5d_u,_lx1,_sd_5d_u,color=_c5,style=line.style_dotted,width=1,extend=extend.right)
line l_5d = line.new(_lx0,_sd_5d_d,_lx1,_sd_5d_d,color=_c5,style=line.style_dotted,width=1,extend=extend.right)
array.push(_all_lines, l_5u)
array.push(_all_lines, l_5d)
if i_show_fill
array.push(_all_fills, linefill.new(l_5u, l_15u, i_fill_5_15))
array.push(_all_fills, linefill.new(l_15u, l_25u, i_fill_15_25))
array.push(_all_fills, linefill.new(l_25u, l_35u, i_fill_25_35))
array.push(_all_fills, linefill.new(l_35u, l_45u, i_fill_35_45))
array.push(_all_fills, linefill.new(l_5d, l_15d, i_fill_5_15))
array.push(_all_fills, linefill.new(l_15d, l_25d, i_fill_15_25))
array.push(_all_fills, linefill.new(l_25d, l_35d, i_fill_25_35))
array.push(_all_fills, linefill.new(l_35d, l_45d, i_fill_35_45))
string _25u_fr = _sd_25d_u_in_frame ? " [IN FRAME]" : " [out]"
string _25d_fr = _sd_25d_d_in_frame ? " [IN FRAME]" : " [out]"
string _25_sig = _using_delta_sig ? " [SIG]" : ""
array.push(_all_labels, label.new(_lxl, _sd_25d_u, "+25D $" + str.tostring(_sd_25d_u,"#.##") + " 0.674s" + _25_sig + (_sd_25d_u_conf ? " g3" : "") + _25u_fr, color=color.new(_c25,i_d25_lbl_tr), textcolor=_c25, style=label.style_label_left, size=_sdlsz))
array.push(_all_labels, label.new(_lxl, _sd_25d_d, "-25D $" + str.tostring(_sd_25d_d,"#.##") + " 0.674s" + _25_sig + (_sd_25d_d_conf ? " g3" : "") + _25d_fr, color=color.new(_c25,i_d25_lbl_tr), textcolor=_c25, style=label.style_label_left, size=_sdlsz))
string _15u_fr = _sd_15d_u_in_frame ? " [IN FRAME]" : " [out]"
string _15d_fr = _sd_15d_d_in_frame ? " [IN FRAME]" : " [out]"
string _15u_tag = i_skew_15d_c != 1.0 ? "x" + str.tostring(i_skew_15d_c,"#.##") : ""
string _15d_tag = i_skew_15d_p != 1.0 ? "x" + str.tostring(i_skew_15d_p,"#.##") : ""
array.push(_all_labels, label.new(_lxl, _sd_15d_u, "+15D $" + str.tostring(_sd_15d_u,"#.##") + " 1.036s" + _15u_tag + _15u_fr, color=color.new(_c15,i_d15_lbl_tr), textcolor=_c15, style=label.style_label_left, size=_sdlsz))
array.push(_all_labels, label.new(_lxl, _sd_15d_d, "-15D $" + str.tostring(_sd_15d_d,"#.##") + " 1.036s" + _15d_tag + _15d_fr, color=color.new(_c15,i_d15_lbl_tr), textcolor=_c15, style=label.style_label_left, size=_sdlsz))
string _5u_fr = _sd_5d_u < g1_up and _sd_5d_u > g1_dn ? " [IN FRAME]" : " [out]"
string _5d_fr = _sd_5d_d > g1_dn and _sd_5d_d < g1_up ? " [IN FRAME]" : " [out]"
array.push(_all_labels, label.new(_lxl, _sd_5d_u, " +5D $" + str.tostring(_sd_5d_u,"#.##") + " 1.645s", color=color.new(_c5,i_d5_lbl_tr), textcolor=_c5, style=label.style_label_left, size=_sdlsz))
array.push(_all_labels, label.new(_lxl, _sd_5d_d, " -5D $" + str.tostring(_sd_5d_d,"#.##") + " 1.645s", color=color.new(_c5,i_d5_lbl_tr), textcolor=_c5, style=label.style_label_left, size=_sdlsz))
array.push(_all_lines, line.new(_lx0,pbv_l1_u,_lx1,pbv_l1_u,color=i_c_pbv,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,pbv_l1_d,_lx1,pbv_l1_d,color=i_c_pbv,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,pbv_l1_u,"PBV L1+" + str.tostring(i_pbv_1,"#.###") + "% $" + str.tostring(pbv_l1_u,"#.##") + (pbv1_u_conf ? " g2" : ""),color=color.new(i_c_pbv,80),textcolor=i_c_pbv,style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,pbv_l1_d,"PBV L1-" + str.tostring(i_pbv_1,"#.###") + "% $" + str.tostring(pbv_l1_d,"#.##") + (pbv1_d_conf ? " g2" : ""),color=color.new(i_c_pbv,80),textcolor=i_c_pbv,style=label.style_label_left,size=_sz))
array.push(_all_lines, line.new(_lx0,pbv_l2_u,_lx1,pbv_l2_u,color=color.new(i_c_pbv,30),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,pbv_l2_d,_lx1,pbv_l2_d,color=color.new(i_c_pbv,30),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,pbv_l2_u,"PBV L2+" + str.tostring(i_pbv_2,"#.###") + "% $" + str.tostring(pbv_l2_u,"#.##") + (pbv2_u_conf ? " g3" : ""),color=color.new(i_c_pbv,85),textcolor=color.new(i_c_pbv,30),style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,pbv_l2_d,"PBV L2-" + str.tostring(i_pbv_2,"#.###") + "% $" + str.tostring(pbv_l2_d,"#.##") + (pbv2_d_conf ? " g3" : ""),color=color.new(i_c_pbv,85),textcolor=color.new(i_c_pbv,30),style=label.style_label_left,size=_sz))
array.push(_all_lines, line.new(_lx0,pbv_l3_u,_lx1,pbv_l3_u,color=color.new(i_c_pbv,20),style=line.style_dotted,width=2,extend=extend.right))
array.push(_all_lines, line.new(_lx0,pbv_l3_d,_lx1,pbv_l3_d,color=color.new(i_c_pbv,20),style=line.style_dotted,width=2,extend=extend.right))
array.push(_all_labels, label.new(_lxl,pbv_l3_u,"PBV L3+" + str.tostring(i_pbv_3,"#.###") + "% $" + str.tostring(pbv_l3_u,"#.##") + (pbv3_u_conf ? " g3 CONF [Explosion]" : " [Explosion Tier]"),color=color.new(i_c_pbv,75),textcolor=color.new(i_c_pbv,10),style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,pbv_l3_d,"PBV L3-" + str.tostring(i_pbv_3,"#.###") + "% $" + str.tostring(pbv_l3_d,"#.##") + (pbv3_d_conf ? " g3 CONF [Explosion]" : " [Explosion Tier]"),color=color.new(i_c_pbv,75),textcolor=color.new(i_c_pbv,10),style=label.style_label_left,size=_sz))
if i_show_str
bool _blk_c = regime == 1
bool _blk_p = regime == -1
color _cc1 = _blk_c ? i_c_blk_ln : i_cc_line
color _cp1 = _blk_p ? i_c_blk_ln : i_cp_line
array.push(_all_lines, line.new(_lx0,sp_c1,_lx1,sp_c1,color=_cc1,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,sp_p1,_lx1,sp_p1,color=_cp1,style=line.style_dotted,width=1,extend=extend.right))
float _b_dev = b_std > 0.0 ? math.abs(raw_basis - b_mean) / b_std : 0.0
int _sc_sell = f_dir_score(false,qa_bull_3,qa_bear_3,gvz_compressed,gvz_normal,gvz_elevated,gvz_extreme,sig_regime,_is_lon,_is_ny,_is_asia,dxy_penalise_buy,dxy_penalise_sell,frame_ok,sqz_up,sqz_dn,_b_dev)
int _sc_buy = f_dir_score(true, qa_bull_3,qa_bear_3,gvz_compressed,gvz_normal,gvz_elevated,gvz_extreme,sig_regime,_is_lon,_is_ny,_is_asia,dxy_penalise_buy,dxy_penalise_sell,frame_ok,sqz_up,sqz_dn,_b_dev)
string _sell_grade = _sc_sell >= 70 ? "SELL " : _sc_sell >= 50 ? "sell " : "wk "
string _buy_grade = _sc_buy >= 70 ? "BUY " : _sc_buy >= 50 ? "buy " : "wk "
string _qa_s = qa_big_bear3 ? " QA-BIG" : qa_any_bear ? " qa-sm" : ""
string _qa_b = qa_big_bull3 ? " QA-BIG" : qa_any_bull ? " qa-sm" : ""
string _mlm_s = mlmi_fresh ? (mlmi_bear ? " ML:BEAR" : " ML:--") : ""
string _mlm_b = mlmi_fresh ? (mlmi_bull ? " ML:BULL" : " ML:--") : ""
string _smi_s = smi_overbought ? " SMI:OB" : smi_bear_cross ? " SMI:Xdn" : ""
string _smi_b = smi_oversold ? " SMI:OS" : smi_bull_cross ? " SMI:Xup" : ""
string _gvz_s = gvz_compressed ? " sGVZ" : gvz_extreme ? " GVZ!" : gvz_elevated ? " GVZ~" : ""
string _dxy_s = dxy_bull ? " DXY+" : dxy_bear ? " DXY-" : ""
string _sess = _is_lon ? " LON" : _is_ny ? " NY" : " ASIA"
string _sc1 = "CALL+1 $" + str.tostring(sp_c1,"#.##") + " " + (_blk_c ? "MR-BLK" : (_sell_grade + str.tostring(_sc_sell) + "%" + (i_rich_lbl ? _qa_s + _gvz_s + _dxy_s + _smi_s + _mlm_s + _sess : "")))
string _sp1 = "PUT-1 $" + str.tostring(sp_p1,"#.##") + " " + (_blk_p ? "MR-BLK" : (_buy_grade + str.tostring(_sc_buy) + "%" + (i_rich_lbl ? _qa_b + _gvz_s + _dxy_s + _smi_b + _mlm_b + _sess : "")))
color _lc1 = _blk_c ? i_c_blk_bg : _sc_sell >= 70 ? i_cc_bg_str : _sc_sell >= 50 ? i_cc_bg_med : i_cc_bg_norm
color _lcp = _blk_p ? i_c_blk_bg : _sc_buy >= 70 ? i_cp_bg_str : _sc_buy >= 50 ? i_cp_bg_med : i_cp_bg_norm
color _tc1 = _blk_c ? i_c_blk_txt : _sc_sell >= 70 ? i_cc_txt_str : _sc_sell >= 50 ? i_cc_txt_med : i_cc_txt_norm
color _tcp = _blk_p ? i_c_blk_txt : _sc_buy >= 70 ? i_cp_txt_str : _sc_buy >= 50 ? i_cp_txt_med : i_cp_txt_norm
array.push(_all_labels, label.new(_lxl,sp_c1,_sc1,color=_lc1,textcolor=_tc1,style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,sp_p1,_sp1,color=_lcp,textcolor=_tcp,style=label.style_label_left,size=_sz))
if i_n_str >= 2
array.push(_all_lines, line.new(_lx0,sp_c2,_lx1,sp_c2,color=color.new(_cc1,35),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,sp_p2,_lx1,sp_p2,color=color.new(_cp1,35),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,sp_c2,"CALL+2 $"+str.tostring(sp_c2,"#.##"),color=color.new(_cc1,85),textcolor=color.new(_tc1,30),style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,sp_p2,"PUT-2 $"+str.tostring(sp_p2,"#.##"),color=color.new(_cp1,85),textcolor=color.new(_tcp,30),style=label.style_label_left,size=_sz))
if i_n_str >= 3
array.push(_all_lines, line.new(_lx0,sp_c3,_lx1,sp_c3,color=color.new(_cc1,55),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,sp_p3,_lx1,sp_p3,color=color.new(_cp1,55),style=line.style_dotted,width=1,extend=extend.right))
if i_n_str >= 4
array.push(_all_lines, line.new(_lx0,sp_c4,_lx1,sp_c4,color=color.new(_cc1,65),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,sp_p4,_lx1,sp_p4,color=color.new(_cp1,65),style=line.style_dotted,width=1,extend=extend.right))
if cond_I
float _sbuy = sp_c1 + i_tol
array.push(_all_lines, line.new(_lx0,_sbuy,_lx1,_sbuy,color=#FFD700,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,_sbuy,"gSTOP BUY $"+str.tostring(_sbuy,"#.##"),color=color.new(#FFD700,75),textcolor=#FFD700,style=label.style_label_left,size=_sz))
if cond_J
float _ssell = sp_p1 - i_tol
array.push(_all_lines, line.new(_lx0,_ssell,_lx1,_ssell,color=#FFD700,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,_ssell,"gSTOP SELL $"+str.tostring(_ssell,"#.##"),color=color.new(#FFD700,75),textcolor=#FFD700,style=label.style_label_left,size=_sz))
if i_show_em
color _em_c1 = color.new(#00BCD4,30)
string _ep = gvz_v > 0.0 and not na(gvz_d) ? str.tostring(gvz_v,"#.1") + "% GVZ" : "YZ fallback"
array.push(_all_lines, line.new(_lx0,em_upper,_lx1,em_upper,color=_em_c1,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,em_lower,_lx1,em_lower,color=_em_c1,style=line.style_dotted,width=1,extend=extend.right))
if i_show_em_lbl
array.push(_all_labels, label.new(_lxl,em_upper,"EM+1s 68.3% $"+str.tostring(em_upper,"#.##")+" +/-$"+str.tostring(em_1sigma,"#.##")+" ["+_ep+"]",color=color.new(#00BCD4,75),textcolor=color.new(#00BCD4,0),style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,em_lower,"EM-1s 68.3% $"+str.tostring(em_lower,"#.##"),color=color.new(#00BCD4,75),textcolor=color.new(#00BCD4,0),style=label.style_label_left,size=_sz))
if i_show_em2
array.push(_all_lines, line.new(_lx0,em_upper_2,_lx1,em_upper_2,color=color.new(#00BCD4,50),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,em_lower_2,_lx1,em_lower_2,color=color.new(#00BCD4,50),style=line.style_dotted,width=1,extend=extend.right))
if i_show_em_lbl
array.push(_all_labels, label.new(_lxl,em_upper_2,"EM+2s 95.5% $"+str.tostring(em_upper_2,"#.##"),color=color.new(#00BCD4,80),textcolor=color.new(#00BCD4,25),style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,em_lower_2,"EM-2s 95.5% $"+str.tostring(em_lower_2,"#.##"),color=color.new(#00BCD4,80),textcolor=color.new(#00BCD4,25),style=label.style_label_left,size=_sz))
if i_show_em3
array.push(_all_lines, line.new(_lx0,em_upper_3,_lx1,em_upper_3,color=color.new(i_c_em3,20),style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,em_lower_3,_lx1,em_lower_3,color=color.new(i_c_em3,20),style=line.style_dotted,width=1,extend=extend.right))
if i_show_em_lbl
array.push(_all_labels, label.new(_lxl,em_upper_3,"EM+3s 99.7% $"+str.tostring(em_upper_3,"#.##")+" TAIL RISK",color=color.new(i_c_em3,70),textcolor=i_c_em3,style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,em_lower_3,"EM-3s 99.7% $"+str.tostring(em_lower_3,"#.##")+" TAIL RISK",color=color.new(i_c_em3,70),textcolor=i_c_em3,style=label.style_label_left,size=_sz))
if i_show_yz_av
color _yz_col = color.new(#CE93D8,55)
array.push(_all_lines, line.new(_lx0,yz_band_u,_lx1,yz_band_u,color=_yz_col,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_lines, line.new(_lx0,yz_band_d,_lx1,yz_band_d,color=_yz_col,style=line.style_dotted,width=1,extend=extend.right))
array.push(_all_labels, label.new(_lxl,yz_band_u,"YZ s+ $"+str.tostring(yz_band_u,"#.##")+" [Realized Vol]",color=color.new(#CE93D8,80),textcolor=color.new(#CE93D8,20),style=label.style_label_left,size=_sz))
array.push(_all_labels, label.new(_lxl,yz_band_d,"YZ s- $"+str.tostring(yz_band_d,"#.##")+" [Realized Vol]",color=color.new(#CE93D8,80),textcolor=color.new(#CE93D8,20),style=label.style_label_left,size=_sz))
string _mlmi_tag = mlmi_fresh ? " ML:F" : mlmi_valid ? " ML:S" : " ML:X"
string _smi_tag = smi_overbought ? " SMI:OB" : smi_oversold ? " SMI:OS" : " SMI:" + str.tostring(smi,"#.0")
string _dxy_tag = dxy_bull ? " DXY:BEAR-XAU" : dxy_bear ? " DXY:BULL-XAU" : ""
string _cb_reg = cb_t1_active ? " " + cb_tier_str : ""
string _sfx = conf_str + _mlmi_tag + _smi_tag + _dxy_tag + _cb_reg
string _reg_txt = switch regime
1 => "g TREND UP TGT $" + str.tostring(g2_up,"#.##") + " MR@CALL+1 CONF:" + _sfx
-1 => "g TREND DN TGT $" + str.tostring(g2_dn,"#.##") + " MR@PUT-1 CONF:" + _sfx
=> "g MR ZONE CALL+1 $" + str.tostring(sp_c1,"#.##") + " / PUT-1 $" + str.tostring(sp_p1,"#.##") + " CONF:" + _sfx
color _reg_col = switch regime
1 => color(#00E5FF)
-1 => color(#FF6F00)
=> color(#00E676)
array.push(_all_labels, label.new(bar_index+2, close, _reg_txt, color=color.new(_reg_col,40), textcolor=_reg_col, style=label.style_label_left, size=size.small))
int _np = array.size(_cvp_prices)
if i_show_cvp and _np >= math.max(i_n_clusters * 3, 15)
float _pmin = array.min(_cvp_prices)
float _pmax = array.max(_cvp_prices)
float _prng = math.max(_pmax - _pmin, syminfo.mintick * 10)
int _nc = i_n_clusters
array.clear(_cvp_centroids)
array.clear(_cvp_counts)
for _k = 0 to _nc - 1
array.push(_cvp_centroids, _pmin + _prng * (float(_k) + 0.5) / float(_nc))
array.push(_cvp_counts, 0)
for _iter = 0 to i_km_iter - 1
float[] _sums = array.new_float(_nc, 0.0)
int[] _cnts = array.new_int(_nc, 0)
for _pi = 0 to _np - 1
float _px = array.get(_cvp_prices, _pi)
int _bk = 0
float _bd = math.abs(_px - array.get(_cvp_centroids, 0))
for _k = 1 to _nc - 1
float _d = math.abs(_px - array.get(_cvp_centroids, _k))
if _d < _bd
_bd := _d
_bk := _k
array.set(_sums, _bk, array.get(_sums, _bk) + _px)
array.set(_cnts, _bk, array.get(_cnts, _bk) + 1)
for _k = 0 to _nc - 1
if array.get(_cnts, _k) > 0
array.set(_cvp_centroids, _k, array.get(_sums, _k) / float(array.get(_cnts, _k)))
if _iter == i_km_iter - 1
for _k = 0 to _nc - 1
array.set(_cvp_counts, _k, array.get(_cnts, _k))
int _poc_k = 0
int _poc_cnt = 0
for _k = 0 to _nc - 1
if array.get(_cvp_counts, _k) > _poc_cnt
_poc_cnt := array.get(_cvp_counts, _k)
_poc_k := _k
int[] _sorted_idx = array.new_int(_nc, 0)
for _k = 0 to _nc - 1
array.set(_sorted_idx, _k, _k)
for _i = 0 to _nc - 2
for _j = 0 to _nc - _i - 2
int _ia = array.get(_sorted_idx, _j)
int _ib = array.get(_sorted_idx, _j + 1)
if array.get(_cvp_centroids, _ia) > array.get(_cvp_centroids, _ib)
array.set(_sorted_idx, _j, _ib)
array.set(_sorted_idx, _j + 1, _ia)
int _lx_start = bar_index - i_cvp_lb
int _lx_end = bar_index + i_cvp_ext
for _r = 0 to _nc - 1
int _k = array.get(_sorted_idx, _r)
float _lev = array.get(_cvp_centroids, _k)
int _cnt = array.get(_cvp_counts, _k)
bool _is_poc = _k == _poc_k
float _dens = _np > 0 ? float(_cnt) / float(_np) * 100.0 : 0.0
color _lc = _is_poc ? color.new(i_cvp_poc_col,0) : color.new(i_cvp_col,40)
int _lw = _is_poc ? math.max(i_cvp_line_w+1,2) : i_cvp_line_w
string _cvp_s = _is_poc ? i_cvp_poc_sty : i_cvp_clus_sty
array.push(_cvp_lines, line.new(_lx_start,_lev,_lx_end,_lev,color=_lc,style=f_ls(_cvp_s),width=_lw,extend=extend.none))
if i_cvp_label
string _lt = "C" + str.tostring(_r+1) + (_is_poc ? " POC" : "") + " $" + str.tostring(_lev,"#.##") + " " + str.tostring(_dens,"#.0") + "%"
array.push(_cvp_lbls, label.new(_lx_end+2,_lev,_lt,color=color.new(_lc,60),textcolor=_lc,style=label.style_label_left,size=f_lsz(i_cvp_lbl_sz)))
if i_cvp_dots and math.abs(close - _lev) <= i_tol * 2.0
array.push(_cvp_lbls, label.new(bar_index,_lev,"",style=label.style_circle,color=_is_poc ? i_cvp_poc_col : i_cvp_col,size=f_dsz(i_cvp_dot_sz2)))
// ═══════════════════════════════════════════════════════════════════════════════
// §19 CHART PLOTS + SIGNALS
// ═══════════════════════════════════════════════════════════════════════════════
plot(i_show_g1_band ? g1_up : na, "Gamma Flip (+)", color=i_band_g1_col, linewidth=i_band_g1_w, style=plot.style_line)
plot(i_show_g1_band ? g1_dn : na, "Gamma Flip (-)", color=i_band_g1_col, linewidth=i_band_g1_w, style=plot.style_line)
plot(i_show_g2_band ? g2_up : na, "Call Wall (+)", color=i_band_g2u_col, linewidth=i_band_g2_w, style=plot.style_line)
plot(i_show_g2_band ? g2_dn : na, "Put Wall (-)", color=i_band_g2d_col, linewidth=i_band_g2_w, style=plot.style_line)
plot(i_show_g3_band ? g3_up : na, "Explosion (+)", color=i_band_g3_col, linewidth=i_band_g3_w, style=plot.style_line)
plot(i_show_g3_band ? g3_dn : na, "Explosion (-)", color=i_band_g3_col, linewidth=i_band_g3_w, style=plot.style_line)
plot(i_show_alma ? alma_l1 : na, "ALMA L1 (Fast)", color=i_al1_col, linewidth=i_al1_w, style=plot.style_line)
plot(i_show_alma ? alma_l2 : na, "ALMA L2 (Med)", color=i_al2_col, linewidth=i_al2_w, style=plot.style_line)
plot(i_show_alma ? alma_l3 : na, "ALMA L3 (Slow)", color=i_al3_col, linewidth=i_al3_w, style=plot.style_line)
plot(i_show_qblk ? qb_h4_u2 : na, "Q-Block +2", color=color.new(color.red, 50), style=plot.style_circles)
plot(i_show_qblk ? qb_h4_u1 : na, "Q-Block +1", color=color.new(color.red, 20), style=plot.style_circles)
plot(i_show_qblk ? qb_h4_0 : na, "Q-Block W0", color=color.new(color.gray, 10), style=plot.style_circles, linewidth=2)
plot(i_show_qblk ? qb_h4_d1 : na, "Q-Block -1", color=color.new(color.teal, 20), style=plot.style_circles)
plot(i_show_qblk ? qb_h4_d2 : na, "Q-Block -2", color=color.new(color.teal, 50), style=plot.style_circles)
plot(i_show_vwap ? lon_vwap : na, "London VWAP", color=color.new(#FFD700,30), linewidth=1, style=plot.style_line)
var array<label> _sig_stop_lbs = array.new_label()
var array<label> _sig_exp_lbs = array.new_label()
if cond_I
array.push(_sig_stop_lbs, label.new(bar_index, high, "gSTOP BUY",
style=label.style_label_down, color=color.new(#FFD700,20),
textcolor=color.black, size=size.tiny,
tooltip="gSTOP BUY — Wrong-dir Bear QA at g1_up"))
if cond_J
array.push(_sig_stop_lbs, label.new(bar_index, low, "gSTOP SELL",
style=label.style_label_up, color=color.new(#FFD700,20),
textcolor=color.black, size=size.tiny,
tooltip="gSTOP SELL — Wrong-dir Bull QA at g1_dn"))
if array.size(_sig_stop_lbs) > 100
label.delete(array.shift(_sig_stop_lbs))
if cond_M
array.push(_sig_exp_lbs, label.new(bar_index, low, "gEXP ▲",
style=label.style_label_up, color=color.new(#D500F9,0),
textcolor=color.white, size=size.large,
tooltip="gEXP STRONG BUY — SD/PBV confluence at g3_dn. Regime=DN."))
if cond_N
array.push(_sig_exp_lbs, label.new(bar_index, high, "gEXP ▼",
style=label.style_label_down, color=color.new(#D500F9,0),
textcolor=color.white, size=size.large,
tooltip="gEXP STRONG SELL — SD/PBV confluence at g3_up. Regime=UP."))
if array.size(_sig_exp_lbs) > 100
label.delete(array.shift(_sig_exp_lbs))
plotshape((_qa_t0 or _qa_t1) ? _qa_plot_y : na, title="QA Bubble 1-2 (<4x)", style=shape.circle, location=location.absolute, color=_qa_bub_col, size=size.normal, text="", textcolor=color.new(color.white,100))
plotshape(_qa_t2 ? _qa_plot_y : na, title="QA Bubble 3 (4-6.5x)", style=shape.circle, location=location.absolute, color=_qa_bub_col, size=size.large, text="", textcolor=color.new(color.white,100))
plotshape(_qa_t3 ? _qa_plot_y : na, title="QA Bubble 4 (6.5-10x)", style=shape.circle, location=location.absolute, color=_qa_bub_col, size=size.large, text="", textcolor=color.new(color.white,100))
plotshape(_qa_t4 ? _qa_plot_y : na, title="QA Bubble 5 (10x+)", style=shape.circle, location=location.absolute, color=_qa_bub_col, size=size.huge, text="", textcolor=color.new(color.white,100))
// ═══════════════════════════════════════════════════════════════════════════════
// §19b NO-VOLUME WARNING TABLE
// ═══════════════════════════════════════════════════════════════════════════════
var table _qa_warn_tbl = table.new(position.middle_center, 1, 1, bgcolor=color.new(color.red, 100))
if barstate.islast
if _qa_cum_vol == 0.0
table.cell(_qa_warn_tbl, 0, 0,
"\n NO VOLUME DATA \n\n GEX+EFP Matrix Volume Bubbles requires volume data. \n\n Switch to a symbol with volume on exchange. \n",
text_color = chart.fg_color,
text_size = size.large,
bgcolor = #FF0000)
else
table.cell(_qa_warn_tbl, 0, 0, "",
text_color = color.new(color.red, 100),
bgcolor = color.new(color.red, 100))
// ═══════════════════════════════════════════════════════════════════════════════
// §20 ALERTS (all const string — CE10123 compliant)
// ═══════════════════════════════════════════════════════════════════════════════
alertcondition(cond_A, title="[GEX+EFP Matrix] g MR BUY — Gamma Flip (MLMI stale gate)", message="GEX+EFP Matrix — gFLIP MR BUY at g1_dn. MLMI valid. Priority Gate: Tier 2.")
alertcondition(cond_B, title="[GEX+EFP Matrix] g MR SELL — Gamma Flip (MLMI stale gate)", message="GEX+EFP Matrix — gFLIP MR SELL at g1_up. MLMI valid. Priority Gate: Tier 2.")
alertcondition(cond_C, title="[GEX+EFP Matrix] g SD MR BUY — 25D/PHI (MLMI fresh gate)", message="GEX+EFP Matrix — gSD MR BUY. MLMI fresh confirmed. Tier 1 priority.")
alertcondition(cond_D, title="[GEX+EFP Matrix] g SD MR SELL — 25D/PHI (MLMI fresh gate)", message="GEX+EFP Matrix — gSD MR SELL. MLMI fresh confirmed. Tier 1 priority.")
alertcondition(cond_E, title="[GEX+EFP Matrix] g STRIKE MR BUY — Put-1", message="GEX+EFP Matrix — gSTRIKE MR BUY at Put-1. Tier 3 fallback.")
alertcondition(cond_F, title="[GEX+EFP Matrix] g STRIKE MR SELL — Call+1", message="GEX+EFP Matrix — gSTRIKE MR SELL at Call+1. Tier 3 fallback.")
alertcondition(cond_G, title="[GEX+EFP Matrix] g BREAKOUT BUY (SMI gate)", message="GEX+EFP Matrix — gBO BUY. QA Big Bull + SMI confirmed. Target Wall 2x.")
alertcondition(cond_H, title="[GEX+EFP Matrix] g BREAKOUT SELL (SMI gate)", message="GEX+EFP Matrix — gBO SELL. QA Big Bear + SMI confirmed. Target Wall 2x.")
alertcondition(cond_I, title="[GEX+EFP Matrix] g STOP BUY PENDING", message="GEX+EFP Matrix — Wrong-dir QA Bear at g1_up. STOP BUY pending.")
alertcondition(cond_J, title="[GEX+EFP Matrix] g STOP SELL PENDING", message="GEX+EFP Matrix — Wrong-dir QA Bull at g1_dn. STOP SELL pending.")
alertcondition(cond_K, title="[GEX+EFP Matrix] g WALL BUY | Regime=DN", message="GEX+EFP Matrix — gWALL MR BUY at gamma wall -2x in downtrend.")
alertcondition(cond_L, title="[GEX+EFP Matrix] g WALL SELL | Regime=UP", message="GEX+EFP Matrix — gWALL MR SELL at gamma wall +2x in uptrend.")
alertcondition(cond_M, title="[GEX+EFP Matrix] g EXPLOSION STRONG BUY", message="GEX+EFP Matrix — gEXP STRONG BUY. SD/PBV confluence + Regime=DN.")
alertcondition(cond_N, title="[GEX+EFP Matrix] g EXPLOSION STRONG SELL", message="GEX+EFP Matrix — gEXP STRONG SELL. SD/PBV confluence + Regime=UP.")
alertcondition(gvz_extreme and not gvz_extreme[1], title="[GEX+EFP Matrix] GVZ EXTREME — MR Blocked", message="GEX+EFP Matrix — GVZ EXTREME. All MR signals blocked.")
alertcondition(gvz_crisis and not gvz_crisis[1], title="[GEX+EFP Matrix] GVZ CRISIS SPIKE", message="GEX+EFP Matrix — GVZ crisis Z>2.5s. Stand aside.")
alertcondition(is_lon_open, title="[GEX+EFP Matrix] London Open — VWAP Reset", message="GEX+EFP Matrix — London 03:00 UTC. VWAP reset. Highest signal quality window.")
alertcondition(qa_any_bull and not qa_any_bull[1], title="[GEX+EFP Matrix] QA Bubble BULL | Watch BO", message="GEX+EFP Matrix — QuantAlgo BULL delta cluster. Watch g1_up for BO.")
alertcondition(qa_any_bear and not qa_any_bear[1], title="[GEX+EFP Matrix] QA Bubble BEAR | Watch BO", message="GEX+EFP Matrix — QuantAlgo BEAR delta cluster. Watch g1_dn for BO.")
alertcondition(qa_big_bull and not qa_big_bull[1], title="[GEX+EFP Matrix] QA BIG BULL Cluster", message="GEX+EFP Matrix — QuantAlgo BIG BULL cluster. Top 3% delta percentile.")
alertcondition(qa_big_bear and not qa_big_bear[1], title="[GEX+EFP Matrix] QA BIG BEAR Cluster", message="GEX+EFP Matrix — QuantAlgo BIG BEAR cluster. Top 3% delta percentile.")
alertcondition(ice_buy_signal and not ice_buy_signal[1], title="[GEX+EFP Matrix] ICEBERG BUY at GEX Zone", message="GEX+EFP Matrix — Iceberg mass order at g1_dn or g2_dn. Bullish.")
alertcondition(ice_sell_signal and not ice_sell_signal[1], title="[GEX+EFP Matrix] ICEBERG SELL at GEX Zone", message="GEX+EFP Matrix — Iceberg mass order at g1_up or g2_up. Bearish.")
// [v26-1] Bubble-Context reversal alerts removed to stay within the 64-plot budget
// (each alertcondition = 1 plot count; file was at 63/64). The §11b engine
// still computes _bctx_fired / _bctx_is_rev / _bctx_out_bull — re-add these two
// alerts only if you free 2 plot units elsewhere (e.g. disable 2 unused alerts).
alertcondition(_ml_pos and mlmi_fresh, title="[GEX+EFP Matrix] MLMI FRESH BULL Cross", message="GEX+EFP Matrix — MLMI k=987 fresh bullish WMA crossover. Decay window active.")
alertcondition(_ml_neg and mlmi_fresh, title="[GEX+EFP Matrix] MLMI FRESH BEAR Cross", message="GEX+EFP Matrix — MLMI k=987 fresh bearish WMA crossover. Decay window active.")
alertcondition(smi_bull_cross and smi_oversold, title="[GEX+EFP Matrix] SMI BULL Cross from OS", message="GEX+EFP Matrix — SMI K=10 bullish cross from oversold. BO BUY gate open.")
alertcondition(smi_bear_cross and smi_overbought, title="[GEX+EFP Matrix] SMI BEAR Cross from OB", message="GEX+EFP Matrix — SMI K=10 bearish cross from overbought. BO SELL gate open.")
alertcondition(cb_t1_active and not cb_t1_active[1], title="[GEX+EFP Matrix] COMEX CB TIER-1 BREACH ±3%", message="GEX+EFP Matrix — COMEX circuit breaker Tier 1 (±3%) breached. Elevated halt risk.")
alertcondition(dxy_bull and not dxy_bull[1], title="[GEX+EFP Matrix] DXY BULL TURN — Bearish XAU", message="GEX+EFP Matrix — DXY ROC exceeded threshold bearish for Gold. BUY signals penalised.")
alertcondition(sqz_yz_bull, title="[GEX+EFP Matrix] SQUEEZE RELEASE BULL", message="GEX+EFP Matrix — YZ squeeze released BULL. Close above VWAP anchor. Confirm with cond_G Breakout BUY or QA Big Bull cluster.")
alertcondition(sqz_yz_bear, title="[GEX+EFP Matrix] SQUEEZE RELEASE BEAR", message="GEX+EFP Matrix — YZ squeeze released BEAR. Close below VWAP anchor. Confirm with cond_H Breakout SELL or QA Big Bear cluster.")
// ═══════════════════════════════════════════════════════════════════════════════
// §19 REGIME MATRIX + Γ-PROXY [v28] — DISPLAY-ONLY (one table → 0 plot-budget)
// ─────────────────────────────────────────────────────────────────────────────
// Direction × Volatility → the 6-regime matrix (which setup / how much / or step
// aside). Plus a POSITIVE/NEGATIVE-gamma PROXY: not real dealer gamma (gold spot
// has no options chain) but the vol-behaviour FOOTPRINT gamma leaves —
// pos-Γ = vol dampening → fade, failed breakouts · neg-Γ = amplifying → follow.
// Five orthogonal votes → signed Γ-score. Touches NO gate / conf_score / entry.
// ═══════════════════════════════════════════════════════════════════════════════
float _rm_base = ta.ema(close, i_rm_dir_len)
float _rm_slope = _rm_base - _rm_base[i_rm_dir_sl]
int _rm_dir = (close > _rm_base and _rm_slope > 0.0) ? 1 : (close < _rm_base and _rm_slope < 0.0) ? -1 : 0
bool _rm_volat = _yz_ratio > 1.0 or gvz_elevated or gvz_extreme
float _rm_lr1 = math.log(close / math.max(close[1], syminfo.mintick))
float _rm_lrk = math.log(close / math.max(close[i_rm_vr_k], syminfo.mintick))
float _rm_var1 = ta.variance(_rm_lr1, i_rm_vr_len)
float _rm_vark = ta.variance(_rm_lrk, i_rm_vr_len)
float _rm_vr = _rm_var1 > 0.0 ? _rm_vark / (i_rm_vr_k * _rm_var1) : 1.0
float _rm_tfm = math.max(timeframe.in_seconds(timeframe.period) / 60.0, 1.0)
float _rm_byr = 252.0 * 1440.0 / _rm_tfm
float _rm_rv = ta.stdev(_rm_lr1, i_rm_rv_len) * math.sqrt(_rm_byr) * 100.0
float _rm_rvgz = _rm_rv - gvz_v
float _rm_ernum= math.abs(close - close[i_rm_er_len])
float _rm_erden= math.sum(math.abs(close - close[1]), i_rm_er_len)
float _rm_er = _rm_erden > 0.0 ? _rm_ernum / _rm_erden : 0.0
bool _rm_inframe = close > g1_dn and close < g1_up
int _rm_v_vr = _rm_vr > 1.1 ? 1 : _rm_vr < 0.9 ? -1 : 0
int _rm_v_rv = _rm_rvgz > 1.0 ? 1 : _rm_rvgz < -1.0 ? -1 : 0
int _rm_v_yz = _yz_ratio> 1.0 ? 1 : _yz_ratio< i_sqz_ratio ? -1 : 0
int _rm_v_er = _rm_er > 0.40 ? 1 : _rm_er < 0.25 ? -1 : 0
int _rm_v_g1 = _rm_inframe ? -1 : 1
int _rm_gsc = _rm_v_vr + _rm_v_rv + _rm_v_yz + _rm_v_er + _rm_v_g1
string _rm_gst = _rm_gsc >= 2 ? "NEG-Γ" : _rm_gsc <= -2 ? "POS-Γ" : "NEUTRAL"
color _rm_gcl = _rm_gsc >= 2 ? #EF9800 : _rm_gsc <= -2 ? #26A69A : #9aa4b2
string _rm_act = _rm_dir == 1 and not _rm_volat ? "FOLLOW" : _rm_dir == 1 and _rm_volat ? "FOLLOW" : _rm_dir == -1 and not _rm_volat ? "SHORT-TREND" : _rm_dir == -1 and _rm_volat ? "PRESERVE" : _rm_dir == 0 and not _rm_volat ? "MR-FADE" : "STAND ASIDE"
string _rm_pr = _rm_dir == 1 and not _rm_volat ? "full size" : _rm_dir == 1 and _rm_volat ? "size ×0.6 · wide" : _rm_dir == -1 and not _rm_volat ? "rare" : _rm_dir == -1 and _rm_volat ? "size ×0.5" : _rm_dir == 0 and not _rm_volat ? "@VA edge" : "no edge"
string _rm_rt = _rm_act == "MR-FADE" ? "→GexCluster" : _rm_act == "STAND ASIDE" ? "→paper" : _rm_act == "PRESERVE" ? "→caution" : "→DeskTrend"
bool _rm_fadectx = _rm_act == "MR-FADE"
string _rm_gtag = _rm_fadectx and _rm_gst == "POS-Γ" ? " Γ✓" : _rm_fadectx and _rm_gst == "NEG-Γ" ? " Γ⚠trend" : (not _rm_fadectx and _rm_act != "STAND ASIDE") and _rm_gst == "NEG-Γ" ? " Γ✓" : (not _rm_fadectx and _rm_act != "STAND ASIDE") and _rm_gst == "POS-Γ" ? " Γ⚠fade-risk" : ""
// [v29] auto-flip the ACTION headline when Γ strongly overrides the direction cell
bool _rm_toFade = (_rm_act == "FOLLOW" or _rm_act == "SHORT-TREND") and _rm_gsc <= -i_rm_gth
bool _rm_toFoll = (_rm_act == "MR-FADE") and _rm_gsc >= i_rm_gth
bool _rm_conf = _rm_toFade or _rm_toFoll
var int _rm_cdur = 0
_rm_cdur := _rm_conf ? _rm_cdur + 1 : 0
bool _rm_flip = i_rm_autoflip and _rm_conf and _rm_cdur >= i_rm_hyst
string _rm_eact = _rm_flip and _rm_toFade ? "FADE/RANGE" : _rm_flip and _rm_toFoll ? "FOLLOW/BREAK" : _rm_act
string _rm_epr = _rm_flip and _rm_toFade ? "fade→POC/VWAP" : _rm_flip and _rm_toFoll ? "follow breakout" : _rm_pr
string _rm_ert = _rm_flip and _rm_toFade ? "→GexCluster" : _rm_flip and _rm_toFoll ? "→DeskTrend" : _rm_rt
string _rm_enote = _rm_flip ? " (Γ override)" : _rm_gtag
color _rm_eactc = _rm_flip and _rm_toFade ? #FFD700 : _rm_flip and _rm_toFoll ? #26A69A : _rm_act == "STAND ASIDE" ? #EF9800 : _rm_act == "MR-FADE" ? #FFD700 : _rm_dir == -1 ? #EF5350 : #26A69A
// [v29] ADX / DI (global — ta.* must run every bar)
[_rm_dip, _rm_dim, _rm_adxv] = ta.dmi(i_rm_adx_len, i_rm_adx_sm)
// [v29] deep-Fib swing range + premium/discount zone levels
float _rm_swh = ta.highest(high, i_rm_fib_len)
float _rm_swl = ta.lowest(low, i_rm_fib_len)
float _rm_swr = math.max(_rm_swh - _rm_swl, syminfo.mintick)
float _rm_eq = _rm_swl + _rm_swr * 0.5
float _rm_disc_hi = _rm_swh - i_rm_fib_lo * _rm_swr
float _rm_disc_lo = _rm_swh - i_rm_fib_hi * _rm_swr
float _rm_prem_lo = _rm_swl + i_rm_fib_lo * _rm_swr
float _rm_prem_hi = _rm_swl + i_rm_fib_hi * _rm_swr
_rm_pos_r = switch i_rm_pos
"Top Center" => position.top_center
"Top Right" => position.top_right
"Middle Left" => position.middle_left
"Middle Right" => position.middle_right
"Bottom Left" => position.bottom_left
"Bottom Center" => position.bottom_center
"Bottom Right" => position.bottom_right
=> position.top_left
string _rm_sz_r = switch i_rm_sz
"Tiny" => size.tiny
"Normal" => size.normal
"Large" => size.large
=> size.small
var table _rm_t = table.new(_rm_pos_r, 4, 13, border_width=1, frame_color=color.new(#2c3440, 0), frame_width=1)
if barstate.islast
table.clear(_rm_t, 0, 0, 3, 12)
if i_rm_on
color _bg = i_rm_bg
color _mut = #7f8b99
bool _aBQ = _rm_dir == 1 and not _rm_volat
bool _aBV = _rm_dir == 1 and _rm_volat
bool _aSQ = _rm_dir == 0 and not _rm_volat
bool _aSV = _rm_dir == 0 and _rm_volat
bool _aRQ = _rm_dir == -1 and not _rm_volat
bool _aRV = _rm_dir == -1 and _rm_volat
table.cell(_rm_t, 0, 0, "REGIME v29", text_color=#8b98a8, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 0, "", bgcolor=_bg)
table.cell(_rm_t, 2, 0, "", bgcolor=_bg)
table.cell(_rm_t, 3, 0, "", bgcolor=_bg)
table.cell(_rm_t, 0, 1, "", bgcolor=_bg)
table.cell(_rm_t, 1, 1, "BULL", text_color=#26A69A, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 1, "SIDE", text_color=#9aa4b2, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 1, "BEAR", text_color=#EF5350, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 0, 2, "QUIET", text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 2, "follow", text_color=_aBQ ? color.white : _mut, text_size=_rm_sz_r, bgcolor=_aBQ ? color.new(#26A69A,45) : _bg)
table.cell(_rm_t, 2, 2, "MR-fade", text_color=_aSQ ? color.white : _mut, text_size=_rm_sz_r, bgcolor=_aSQ ? color.new(#FF9800,45) : _bg)
table.cell(_rm_t, 3, 2, "short-tr",text_color=_aRQ ? color.white : _mut, text_size=_rm_sz_r, bgcolor=_aRQ ? color.new(#EF5350,45) : _bg)
table.cell(_rm_t, 0, 3, "VOLAT", text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 3, "foll ×.6", text_color=_aBV ? color.white : _mut, text_size=_rm_sz_r, bgcolor=_aBV ? color.new(#26A69A,35) : _bg)
table.cell(_rm_t, 2, 3, "ASIDE", text_color=_aSV ? color.white : _mut, text_size=_rm_sz_r, bgcolor=_aSV ? color.new(#FF1744,35) : _bg)
table.cell(_rm_t, 3, 3, "×0.5", text_color=_aRV ? color.white : _mut, text_size=_rm_sz_r, bgcolor=_aRV ? color.new(#EF5350,35) : _bg)
table.cell(_rm_t, 0, 4, "Γ-PROXY", text_color=#8b98a8, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 4, _rm_gst, text_color=_rm_gcl, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 4, (_rm_gsc > 0 ? "+" : "") + str.tostring(_rm_gsc) + "/5", text_color=_rm_gcl, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 4, "", bgcolor=_bg)
table.cell(_rm_t, 0, 5, "VR" + str.tostring(i_rm_vr_k), text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 5, str.tostring(_rm_vr, "#.##"), text_color=#c9d1d9, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 5, _rm_v_vr == 1 ? "▲neg" : _rm_v_vr == -1 ? "▼pos" : "·", text_color=_rm_v_vr == 1 ? #EF9800 : _rm_v_vr == -1 ? #26A69A : _mut, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 5, "", bgcolor=_bg)
table.cell(_rm_t, 0, 6, "RV−GVZ", text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 6, (_rm_rvgz >= 0.0 ? "+" : "") + str.tostring(_rm_rvgz, "#.#"), text_color=#c9d1d9, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 6, _rm_v_rv == 1 ? "▲neg" : _rm_v_rv == -1 ? "▼pos" : "·", text_color=_rm_v_rv == 1 ? #EF9800 : _rm_v_rv == -1 ? #26A69A : _mut, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 6, "", bgcolor=_bg)
table.cell(_rm_t, 0, 7, "YZ f/s", text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 7, str.tostring(_yz_ratio, "#.##"), text_color=#c9d1d9, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 7, _rm_v_yz == 1 ? "▲neg" : _rm_v_yz == -1 ? "▼pos" : "·", text_color=_rm_v_yz == 1 ? #EF9800 : _rm_v_yz == -1 ? #26A69A : _mut, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 7, "", bgcolor=_bg)
table.cell(_rm_t, 0, 8, "trend-ER", text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 8, str.tostring(_rm_er, "#.##"), text_color=#c9d1d9, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 8, _rm_v_er == 1 ? "▲neg" : _rm_v_er == -1 ? "▼pos" : "·", text_color=_rm_v_er == 1 ? #EF9800 : _rm_v_er == -1 ? #26A69A : _mut, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 8, "", bgcolor=_bg)
table.cell(_rm_t, 0, 9, "vs g1", text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 9, _rm_inframe ? "inside" : "outside", text_color=#c9d1d9, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 9, _rm_v_g1 == 1 ? "▲neg" : "▼pos", text_color=_rm_v_g1 == 1 ? #EF9800 : #26A69A, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 9, "", bgcolor=_bg)
table.cell(_rm_t, 0, 10, "ACTION", text_color=#8b98a8, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 10, _rm_eact + " · " + _rm_epr + " " + _rm_ert + _rm_enote, text_color=_rm_eactc, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 2, 10, "", bgcolor=_bg)
table.cell(_rm_t, 3, 10, "", bgcolor=_bg)
if i_rm_adx
bool _rm_diUp = _rm_dip >= _rm_dim
string _rm_adxs = _rm_adxv >= i_rm_adx_str ? "strong" : _rm_adxv < 20.0 ? "weak" : "mid"
color _rm_adxc = _rm_adxv >= i_rm_adx_str ? #FFD700 : _mut
table.cell(_rm_t, 0, 11, "ADX" + str.tostring(i_rm_adx_len), text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 11, str.tostring(_rm_adxv, "#"), text_color=#c9d1d9, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 11, _rm_adxs, text_color=_rm_adxc, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 11, "", bgcolor=_bg)
table.cell(_rm_t, 0, 12, "DI ±", text_color=_mut, text_size=_rm_sz_r, bgcolor=_bg, text_halign=text.align_left)
table.cell(_rm_t, 1, 12, "+" + str.tostring(_rm_dip, "#") + " / −" + str.tostring(_rm_dim, "#"), text_color=#c9d1d9, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 2, 12, _rm_diUp ? "up ▲" : "dn ▼", text_color=_rm_diUp ? #26A69A : #EF5350, text_size=_rm_sz_r, bgcolor=_bg)
table.cell(_rm_t, 3, 12, "", bgcolor=_bg)
// ═══════════════════════════════════════════════════════════════════════════════
// §19c DEEP-FIB PREMIUM / DISCOUNT [v29] — box/line/label only → 0 plot-budget
// ─────────────────────────────────────────────────────────────────────────────
// Splits a swing range into PREMIUM (upper — sell) / DISCOUNT (lower — buy) with the
// deep 0.705–0.886 zones (Kmer "trade from discount, not premium"). Isolated block,
// own toggle, own handles — touches no existing logic.
// ═══════════════════════════════════════════════════════════════════════════════
var box _rm_disc_bx = na
var box _rm_prem_bx = na
var line _rm_eq_ln = na
var label _rm_disc_lb = na
var label _rm_prem_lb = na
if barstate.islast
box.delete(_rm_disc_bx)
box.delete(_rm_prem_bx)
line.delete(_rm_eq_ln)
label.delete(_rm_disc_lb)
label.delete(_rm_prem_lb)
if i_rm_fib
int _fx0 = bar_index - math.min(i_rm_fib_len, 300)
int _fx1 = bar_index + 8
_rm_disc_bx := box.new(_fx0, _rm_disc_hi, _fx1, _rm_disc_lo, border_color=color.new(i_rm_fib_disc, 45), border_style=line.style_dotted, border_width=1, bgcolor=color.new(i_rm_fib_disc, 88))
_rm_prem_bx := box.new(_fx0, _rm_prem_hi, _fx1, _rm_prem_lo, border_color=color.new(i_rm_fib_prem, 45), border_style=line.style_dotted, border_width=1, bgcolor=color.new(i_rm_fib_prem, 88))
_rm_eq_ln := line.new(_fx0, _rm_eq, _fx1, _rm_eq, color=color.new(#9aa4b2, 30), style=line.style_dashed, width=1)
_rm_disc_lb := label.new(_fx1, (_rm_disc_hi + _rm_disc_lo) / 2.0, "DISCOUNT buy " + str.tostring(i_rm_fib_lo, "#.###") + "-" + str.tostring(i_rm_fib_hi, "#.###"), style=label.style_label_left, color=color.new(i_rm_fib_disc, 80), textcolor=i_rm_fib_disc, size=size.tiny)
_rm_prem_lb := label.new(_fx1, (_rm_prem_hi + _rm_prem_lo) / 2.0, "PREMIUM sell", style=label.style_label_left, color=color.new(i_rm_fib_prem, 80), textcolor=i_rm_fib_prem, size=size.tiny)
// == END Gex and EFP Basis Matrix v29 | +§19 auto-flip + ADX/DI + deep-Fib | CE:0 RE:0 ==