indicator luxy boss mode - support & resistance for tradingview.pine
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator luxy boss mode - support & resistance for tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
Поиск по коду файла
indicator("Luxy BOSS MODE — Support & Resistance", shorttitle="Luxy Support Resistance", overlay=true, max_bars_back=1000, max_boxes_count=500, max_lines_count=500, max_labels_count=500)
import orenluxy/LuxyEnergyIndex/1 as LEI
type SRZone
int id
string source
float top
float bottom
float mid
int bar_created
string htf_source
bool is_support
bool is_fresh
int touches
int violations
int flip_count
float creation_volume
float touch_vol_avg
float width_atr
int last_touch_bar
int confluence_count
float score
string grade
string regime_at_creation
bool is_naked_poc
string catalyst_label
int box_id
int label_id
int bounce_count // times price bounced at this zone
int break_count // times price broke through this zone
float avg_dist_at_touch_atr // running avg distance from zone mid at touch moment (ATR units)
string momentum_signal // real-time: "⬆ BOUNCE" | "⚠ BREAK" | "—"
GROUP_MODE = "🎯 Trading Mode ═══════════════════════════════════"
GROUP_REGIME = "🧭 Regime Classifier ══════════════════════════════"
GROUP_ZONES = "🎯 Zone Detection ═════════════════════════════════"
GROUP_SWING = "📐 Swing Pivots ════════════════════════════════════"
GROUP_OB = "🧱 Order Blocks ════════════════════════════════════"
GROUP_VOLPROF = "📊 Volume POC ══════════════════════════════════════"
GROUP_FVG = "💨 Fair Value Gaps ═════════════════════════════════"
GROUP_LIQ = "💧 Liquidity Pools ═════════════════════════════════"
GROUP_AVWAP = "⚓ Anchored VWAP ════════════════════════════════════"
GROUP_SCORE = "⚖️ Scoring ═════════════════════════════════════════"
GROUP_ASSET = "🌍 Asset-Class Adaptation ══════════════════════════"
GROUP_WARN = "🚨 Warnings ════════════════════════════════════════"
GROUP_VISUAL = "🎨 Visual Settings ═════════════════════════════════"
GROUP_DASH = "📊 Dashboard ═══════════════════════════════════════"
GROUP_ALERTS = "🔔 Alerts ══════════════════════════════════════════"
i_trading_mode = input.string("Swing", "Trading Mode", options=["Scalp", "Intraday", "Swing"], group=GROUP_MODE, tooltip="Auto-adjusts zone width, lookback, and sensitivity.\n\nScalp: 5-15m tight zones\nIntraday: 30m-4H balanced\nSwing: 4H-D wide zones")
i_regime_adx_len = input.int(14, "ADX Length", minval=5, maxval=30, group=GROUP_REGIME, tooltip="ADX period for trend strength")
i_regime_bb_len = input.int(20, "BB Length", minval=10, maxval=50, group=GROUP_REGIME, tooltip="BB period for squeeze detection")
i_regime_ema_len = input.int(50, "EMA Slope Length", minval=20, maxval=100, group=GROUP_REGIME, tooltip="EMA period for slope calculation")
i_enable_swing = input.bool(true, "📐 Swing Pivots", group=GROUP_ZONES, inline="det1", tooltip="Detect zones from swing pivots")
i_enable_ob = input.bool(true, "🧱 Order Blocks", group=GROUP_ZONES, inline="det1", tooltip="📐 Swing Pivots — classic swing highs/lows (current TF + Daily + Weekly)\n🧱 Order Blocks — last candle before a strong impulsive move, confirmed by volume")
i_enable_vp = input.bool(true, "📊 Volume POC", group=GROUP_ZONES, inline="det2", tooltip="Detect high-volume cluster zones")
i_enable_fvg = input.bool(true, "💨 FVG", group=GROUP_ZONES, inline="det2", tooltip="📊 Volume POC — highest-volume price cluster (where most contracts traded)\n💨 FVG — Fair Value Gap: 3-candle imbalance where price left unfilled range")
i_enable_liq = input.bool(true, "💧 Liquidity", group=GROUP_ZONES, inline="det3", tooltip="Detect equal-high/low liquidity pools")
i_enable_avwap = input.bool(true, "⚓ AVWAP", group=GROUP_ZONES, inline="det3", tooltip="💧 Liquidity Pools — equal highs/lows where stop orders cluster (sweep targets)\n⚓ AVWAP — Anchored VWAP from gap+volume catalyst events (institutional fair value)")
i_max_zones = input.int(30, "Max Zones", minval=5, maxval=60, group=GROUP_ZONES, inline="det4", tooltip="Max zones in memory (lowest-score evicted)")
i_swing_left = input.int(5, "Left Bars", minval=2, maxval=20, group=GROUP_SWING, inline="sw1", tooltip="Left bars for pivot confirmation")
i_swing_right = input.int(5, "Right Bars", minval=2, maxval=20, group=GROUP_SWING, inline="sw1", tooltip="Left Bars — how many bars to the left must be lower (for high) or higher (for low)\nRight Bars — how many bars to the right confirm the pivot (no-repaint: zones register with delay equal to this value)\n\nDefault 5/5 = solid detection with minimal lag")
i_swing_zone_pct = input.float(0.5, "Zone Width (ATR)", minval=0.05, maxval=1.5, step=0.05, group=GROUP_SWING, tooltip="Zone box height as a fraction of ATR.\n\n0.25 = zone spans 25% of ATR\n0.5 = wider zones, good for daily charts (default)\n0.1 = tight zones, good for intraday\n\nATR = Average True Range (daily volatility)")
i_ob_lookback = input.int(60, "OB Lookback", minval=5, maxval=100, group=GROUP_OB, tooltip="Bars to scan for order block formations")
i_ob_min_move = input.float(1.5, "Min Move %", minval=0.5, maxval=10.0, step=0.25, group=GROUP_OB, tooltip="Minimum impulsive move % to qualify OB")
i_ob_vol_mult = input.float(1.5, "Volume Mult", minval=1.0, maxval=5.0, step=0.1, group=GROUP_OB, tooltip="Min volume ratio vs average at formation")
i_vp_lookback = input.int(100, "POC Lookback", minval=20, maxval=200, group=GROUP_VOLPROF, tooltip="Bars for volume-at-price histogram")
i_vp_num_bins = input.int(20, "Price Bins", minval=10, maxval=40, group=GROUP_VOLPROF, tooltip="Price resolution for histogram")
i_fvg_min_size = input.float(0.3, "Min FVG Size %", minval=0.1, maxval=3.0, step=0.1, group=GROUP_FVG, tooltip="Minimum gap size as percent of price")
i_fvg_show_filled = input.bool(false, "Keep Filled FVGs", group=GROUP_FVG, tooltip="Keep showing FVG zones after price fills them")
i_liq_length = input.int(20, "Swing Length", minval=3, maxval=30, group=GROUP_LIQ, tooltip="Bars to look back for equal high/low clusters")
i_liq_tolerance = input.float(0.1, "Touch Tolerance %", minval=0.05, maxval=0.5, step=0.05, group=GROUP_LIQ, tooltip="Price tolerance (%) to consider two highs/lows as equal")
i_avwap_auto = input.bool(true, "Auto-Anchor on Gap+Volume", group=GROUP_AVWAP, tooltip="Auto-anchor VWAP when gap > 3% and volume > 3x average")
i_avwap_gap_pct = input.float(3.0, "Auto-Anchor Gap %", minval=1.0, maxval=20.0, step=0.5, group=GROUP_AVWAP, tooltip="Minimum gap % to trigger auto-anchor")
i_avwap_vol_mult = input.float(3.0, "Auto-Anchor Vol Mult", minval=1.5, maxval=10.0, step=0.5, group=GROUP_AVWAP, tooltip="Min volume multiplier to trigger auto-anchor")
i_avwap_date = input.time(0, "Custom Catalyst Date", group=GROUP_AVWAP, confirm=false, tooltip="Set a specific catalyst date (earnings, FDA, halving, FOMC)\nLeave at 0 to disable manual anchor")
i_w_touch_vol = input.int(18, "Touch Volume Weight", minval=0, maxval=30, group=GROUP_SCORE, tooltip="Per-touch volume conviction (unique vs competitors)")
i_w_confluence = input.int(18, "Confluence Weight", minval=0, maxval=30, group=GROUP_SCORE, tooltip="Multi-source zone overlap score")
i_w_htf = input.int(16, "HTF Weight", minval=0, maxval=30, group=GROUP_SCORE, tooltip="Higher timeframe origin bonus")
i_w_touch = input.int(12, "Touch Count Weight", minval=0, maxval=30, group=GROUP_SCORE, tooltip="Number of price reactions")
i_w_create_vol = input.int(12, "Creation Volume Weight", minval=0, maxval=30, group=GROUP_SCORE, tooltip="Volume at zone creation")
i_w_regime = input.int(12, "Regime Fit Weight", minval=0, maxval=30, group=GROUP_SCORE, tooltip="Alignment with market regime direction")
i_w_fresh = input.int(8, "Freshness Weight", minval=0, maxval=20, group=GROUP_SCORE, tooltip="Untouched or recently touched bonus")
i_asset_override = input.string("Auto", "Asset Class", options=["Auto", "Stock", "Crypto", "Forex", "Index", "Futures"], group=GROUP_ASSET, tooltip="Auto-detects asset class.\n\nCrypto: 24/7, percent bands\nForex: pip widths, session zones\nIndex: volume-agnostic fallback\nFutures: rollover-aware")
i_sub5_override = input.bool(false, "Force Sub-$5 Mode", group=GROUP_ASSET, tooltip="Forces percent-band zone widths for low-price securities")
i_warn_approach = input.bool(true, "Zone Approach", group=GROUP_WARN, inline="w1", tooltip="Alert when within 0.5 ATR of Grade A/B zone")
i_warn_cluster = input.bool(true, "Zone Cluster", group=GROUP_WARN, inline="w1", tooltip="Zone Approach — fires when price is within the ATR distance you set below of any Grade A or B zone\nZone Cluster — fires when 3 or more zones overlap within 1 ATR of current price (clustered S/R = strong area)")
i_warn_sweep = input.bool(true, "Sweep Imminent", group=GROUP_WARN, inline="w2", tooltip="Alert when approaching liquidity pool")
i_warn_fvg = input.bool(true, "FVG Filling", group=GROUP_WARN, inline="w2", tooltip="Sweep Imminent — price is within 0.3 ATR of a Liquidity Pool zone AND volume is accelerating (likely stop hunt)\nFVG Filling — price has entered an unfilled Fair Value Gap zone for the first time")
i_warn_trap = input.bool(true, "Trap Suspected", group=GROUP_WARN, inline="w3", tooltip="Alert when close-through is low-volume (likely fake)")
i_warn_regime = input.bool(true, "Regime Shift", group=GROUP_WARN, inline="w3", tooltip="Trap Suspected — price closed through a zone on below-average volume (fake breakout pattern — often reverses)\nRegime Shift — market regime just changed direction AND a Grade-A zone is nearby (high-significance event)")
i_warn_atr_dist = input.float(0.5, "Approach Distance (ATR)", minval=0.1, maxval=2.0, step=0.1, group=GROUP_WARN, tooltip="ATR distance to trigger ZONE_APPROACH warning")
i_top_n_zones = input.int(10, "Show Top N Zones", minval=3, maxval=20, group=GROUP_VISUAL, inline="vis1", tooltip="Show only N highest-scoring zones")
i_adaptive_hide = input.bool(true, "Adaptive Hide", group=GROUP_VISUAL, inline="vis1", tooltip="Show Top N — render only the N highest-scored zones (sorted by score 0-100). Reduces clutter. Default 10.\nAdaptive Hide — automatically hides zones more than 2.5 ATR from current price. Keeps chart clean as price moves.")
i_show_grade_d = input.bool(false, "Show Grade D", group=GROUP_VISUAL, inline="vis2", tooltip="Include low-quality zones in rendering")
i_zone_transp = input.int(70, "Transparency", minval=30, maxval=90, group=GROUP_VISUAL, inline="vis2", tooltip="Show Grade D — include very weak zones (score <50). OFF by default — they add clutter.\nTransparency — box fill opacity. 30 = nearly opaque (vivid), 90 = almost invisible. Default 70.")
i_show_simple = input.bool(true, "Simple S/R Lines on Chart", group=GROUP_VISUAL, tooltip="Show clear horizontal lines for nearest Support and Resistance directly on chart.\n\nGreen line = nearest SUPPORT below price\nRed line = nearest RESISTANCE above price\nLabel shows price + ATR distance\n\nFor quick reading — no detailed analysis needed.")
i_show_dash = input.bool(true, "Show Dashboard", group=GROUP_DASH)
i_show_legend = input.bool(true, "Show Legend", group=GROUP_DASH, tooltip="Show a small legend explaining zone symbols and colors")
i_dash_pos = input.string("Top Right", "Position", options=["Top Left", "Top Center", "Top Right", "Middle Left", "Middle Center", "Middle Right", "Bottom Left", "Bottom Center", "Bottom Right"], group=GROUP_DASH, inline="dash")
i_dash_size = input.string("Normal", "Size", options=["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], group=GROUP_DASH, inline="dash", tooltip="Position — where the dashboard table appears on the chart (9 options)\nSize — text size inside the dashboard. Normal = default readable. Large if chart is large, Tiny if you want minimal footprint.")
i_alert_json = input.bool(false, "Structured JSON Alerts", group=GROUP_ALERTS, tooltip="Include JSON payload in alerts for webhook automation\n\n{brand, ticker, tf, price, atr, regime, warning, zone{id,source,score,grade,confluence}}")
GROUP_TRADE = "💰 Trade Plan ══════════════════════════════════════"
i_enable_trade_plan = input.bool(true, "Enable Trade Plan", group=GROUP_TRADE, tooltip="Automatically calculates Entry, Stop Loss, Target, and Position Size for the best setup near price.\n\nOnly shows trades that meet the minimum R:R requirement.\n\nLONG = price approaching support from above\nSHORT = price approaching resistance from below")
i_account_size = input.float(10000, "Account Size ($)", minval=100, maxval=10000000, step=1000, group=GROUP_TRADE, tooltip="Total account value in dollars.\n\nUsed to calculate how many shares to buy based on your risk per trade.\n\nExample: $10,000 account × 1% risk = $100 risk per trade")
i_risk_pct = input.float(1.0, "Risk per Trade (%)", minval=0.1, maxval=5.0, step=0.1, group=GROUP_TRADE, tooltip="How much of your account to risk on each trade.\n\n1.0% = standard professional\n0.5% = conservative\n2.0% = aggressive\n\nFormula: (Account × Risk%) / (Entry - Stop) = Shares")
i_min_rr = input.float(2.0, "Min R:R to Show", minval=1.0, maxval=5.0, step=0.5, group=GROUP_TRADE, tooltip="Minimum Risk:Reward ratio to display a trade plan.\n\nOnly setups where Target gives this R:R or better will be shown.\n\n2.0 = target must be 2× the stop distance away\n1.5 = looser filter, more setups shown")
var array<SRZone> g_zones = array.new<SRZone>()
var array<int> g_zone_id_arr = array.from(0)
var string g_warning = "—"
var int g_warn_bar = 0
var float g_avwap_anchor_price = na
var float g_avwap_cum_pv = 0.0
var float g_avwap_cum_v = 0.0
var int g_avwap_anchor_bar = -1
var string g_avwap_label = ""
var int g_hits_total = 0
var int g_tests_total = 0
var float g_lb_vol = 0.0 // sum of touch_vol_avg on BOUNCE events
var float g_lb_htf = 0.0 // sum of htf_n on BOUNCE events
var float g_lb_conf = 0.0 // sum of confluence_n on BOUNCE events
var float g_lb_fresh = 0.0 // sum of fresh_n on BOUNCE events
var float g_lbr_vol = 0.0 // sum of touch_vol_avg on BREAK events
var float g_lbr_htf = 0.0
var float g_lbr_conf = 0.0
var float g_lbr_fresh = 0.0
var int g_n_bounce = 0 // total bounce events observed
var int g_n_break = 0 // total break events observed
var string g_tp_dir = "—"
var float g_tp_entry = na
var float g_tp_stop = na
var float g_tp_target = na
var float g_tp_rr = na
var int g_tp_shares = 0
var float g_tp_score = 0.0
var line tp_entry_ln = na
var line tp_stop_ln = na
var line tp_tgt_ln = na
var label tp_plan_lbl = na
get_table_pos(p) =>
p == "Top Left" ? position.top_left : p == "Top Center" ? position.top_center : p == "Top Right" ? position.top_right : p == "Middle Left" ? position.middle_left : p == "Middle Center" ? position.middle_center : p == "Middle Right" ? position.middle_right : p == "Bottom Left" ? position.bottom_left : p == "Bottom Center" ? position.bottom_center : position.bottom_right
get_text_size(s) =>
s == "Auto" ? size.auto : s == "Tiny" ? size.tiny : s == "Small" ? size.small : s == "Normal" ? size.normal : s == "Large" ? size.large : size.huge
get_regime_color(r) =>
r == "STRONG_BULL" ? color.new(#26a69a, 20) : r == "WEAK_BULL" ? color.new(#66bb6a, 30) : r == "SQUEEZE" ? color.new(#ab47bc, 20) : r == "STRONG_BEAR" ? color.new(#ef5350, 20) : r == "WEAK_BEAR" ? color.new(#ff7043, 30) : color.new(color.gray, 30)
get_heat_color(score, is_sup, transp) =>
if is_sup
score >= 80 ? color.new(#00e5ff, transp) : score >= 65 ? color.new(#00c853, transp) : score >= 50 ? color.new(#40c4ff, transp) : score >= 35 ? color.new(#80deea, transp) : color.new(#546e7a, transp)
else
score >= 80 ? color.new(#ff1744, transp) : score >= 65 ? color.new(#ff5722, transp) : score >= 50 ? color.new(#ff9800, transp) : score >= 35 ? color.new(#ef9a9a, transp) : color.new(#78909c, transp)
get_border_color_grade(grade) =>
grade == "A" ? color.new(#ffffff, 5) : grade == "B" ? color.new(#e0e0e0, 35) : color.new(color.gray, 60)
get_border_w(htf) => htf == "W" or htf == "M" ? 3 : htf == "D" ? 2 : 1
get_grade(s) => s >= 80 ? "A" : s >= 65 ? "B" : s >= 50 ? "C" : "D"
get_src_emoji(src) => src == "SWING" ? "📐" : src == "OB" ? "🧱" : src == "POC" ? "📊" : src == "FVG" ? "💨" : src == "LIQ" ? "💧" : "⚓"
calc_adaptive_w(base_w, b_sum, br_sum, n_b, n_br) =>
float aw = base_w
if n_b >= 10 and n_br >= 10
b_avg = b_sum / n_b
br_avg = br_sum / n_br
ratio = b_avg / math.max(br_avg, 0.0001)
aw := math.max(base_w * 0.4, math.min(base_w * 2.5, base_w * math.pow(ratio, 0.6)))
aw
classify_momentum(z_is_sup, dist_atr, z_touches, lei_val, vol_r, spd) =>
string sig = "—"
if dist_atr <= 1.2 and z_touches > 0
approaching = z_is_sup ? (close < close[2]) : (close > close[2])
fast_hi = spd > 0.40 and vol_r > 1.50
slow_low = spd < 0.20 and vol_r < 0.80
if not na(lei_val)
if lei_val >= 70
sig := "⬆ BOUNCE" // Exhaustion zone: move depleted, bounce expected
else if lei_val <= 30
sig := approaching ? "⚠ BREAK" : "⬆ BOUNCE"
else if slow_low // Neutral LEI — fallback to speed/volume
sig := "⬆ BOUNCE"
else if fast_hi
sig := approaching ? "⚠ BREAK" : "—"
else
if slow_low
sig := "⬆ BOUNCE"
else if fast_hi
sig := approaching ? "⚠ BREAK" : "—"
sig
detect_asset_class() =>
if i_asset_override != "Auto"
i_asset_override
else
t = syminfo.type
t == "crypto" ? "Crypto" : t == "forex" or t == "spread" ? "Forex" : t == "index" ? "Index" : t == "futures" or t == "economic" ? "Futures" : "Stock"
var string g_asset = "Stock"
var bool g_sub5 = false
var bool g_crypto = false
var bool g_forex = false
var bool g_index = false
var string g_session = "RTH"
if barstate.isfirst
g_asset := detect_asset_class()
g_sub5 := i_sub5_override or (g_asset == "Stock" and close < 1.0)
g_crypto := g_asset == "Crypto"
g_forex := g_asset == "Forex"
g_index := g_asset == "Index"
if g_asset == "Stock" or g_asset == "Futures"
session_regular = not na(time("1", "0930-1600:23456", "America/New_York"))
session_pre = not na(time("1", "0400-0930:23456", "America/New_York"))
g_session := session_regular ? "RTH" : session_pre ? "PRE" : "AH"
get_zone_width(atr_v) =>
g_sub5 ? close * i_swing_zone_pct * 0.01 : atr_v * i_swing_zone_pct
atr_val = ta.atr(14)
[bb_mid, bb_up, bb_dn] = ta.bb(close, i_regime_bb_len, 2.0)
bbw = (bb_up - bb_dn) / bb_mid * 100.0
bbw_rank = ta.percentrank(bbw, 100)
atr_pct = atr_val / close * 100.0
atr_rank = ta.percentrank(atr_pct, 100)
[dmi_plus, dmi_minus, adx_val] = ta.dmi(i_regime_adx_len, i_regime_adx_len)
ema50 = ta.ema(close, i_regime_ema_len)
ema_slope = (ema50 - ema50[5]) / ema50[5] * 100.0
is_squeeze = bbw_rank < 10 and atr_rank < 15
regime_state = is_squeeze ? "SQUEEZE" : adx_val > 25 and ema_slope > 0.5 ? "STRONG_BULL" : adx_val > 18 and ema_slope > 0.1 ? "WEAK_BULL" : adx_val > 25 and ema_slope < -0.5 ? "STRONG_BEAR" : adx_val > 18 and ema_slope < -0.1 ? "WEAK_BEAR" : "RANGE"
var string prev_regime = "RANGE"
htf_d_v = request.security(syminfo.tickerid, "D", volume, lookahead=barmerge.lookahead_off)
htf_w_v = request.security(syminfo.tickerid, "W", volume, lookahead=barmerge.lookahead_off)
htf_d_ph = request.security(syminfo.tickerid, "D", ta.pivothigh(high, i_swing_left, i_swing_right), lookahead=barmerge.lookahead_off)
htf_d_pl = request.security(syminfo.tickerid, "D", ta.pivotlow(low, i_swing_left, i_swing_right), lookahead=barmerge.lookahead_off)
htf_w_ph = request.security(syminfo.tickerid, "W", ta.pivothigh(high, i_swing_left, i_swing_right), lookahead=barmerge.lookahead_off)
htf_w_pl = request.security(syminfo.tickerid, "W", ta.pivotlow(low, i_swing_left, i_swing_right), lookahead=barmerge.lookahead_off)
avg_vol_20 = ta.sma(volume, 20)
lei_value = LEI.lei(close)
lei_zone_str = LEI.getZone(lei_value)
approach_spd = math.abs(close - close[2]) / math.max(atr_val, 0.0001)
vol_ratio = volume / math.max(avg_vol_20, 1)
zone_exists_near(price_level, half_width) =>
found = false
n = array.size(g_zones)
if n > 0
for i = 0 to n - 1
z = array.get(g_zones, i)
if math.abs(z.mid - price_level) < half_width * 2
found := true
break
found
push_zone(src, z_top, z_bot, htf, supp, vol_at_creation, cat_label) =>
if array.size(g_zones) >= i_max_zones
min_idx = 0
min_score = 999.0
for i = 0 to array.size(g_zones) - 1
zs = array.get(g_zones, i).score
if zs < min_score
min_score := zs
min_idx := i
array.remove(g_zones, min_idx)
cur_id = array.get(g_zone_id_arr, 0) + 1
array.set(g_zone_id_arr, 0, cur_id)
vol_norm = avg_vol_20 > 0 ? vol_at_creation / avg_vol_20 : 1.0
nz = SRZone.new(id=cur_id, source=src, top=z_top, bottom=z_bot, mid=(z_top+z_bot)/2, bar_created=bar_index, htf_source=htf, is_support=supp, is_fresh=true, touches=0, violations=0, flip_count=0, creation_volume=vol_norm, touch_vol_avg=0.0, width_atr=(z_top-z_bot)/math.max(atr_val,0.0001), last_touch_bar=bar_index, confluence_count=1, score=50.0, grade="C", regime_at_creation=regime_state, is_naked_poc=false, catalyst_label=cat_label, box_id=-1, label_id=-1, bounce_count=0, break_count=0, avg_dist_at_touch_atr=0.0, momentum_signal="—")
array.push(g_zones, nz)
if i_enable_swing
ph_curr = ta.pivothigh(high, i_swing_left, i_swing_right)
pl_curr = ta.pivotlow(low, i_swing_left, i_swing_right)
zw = get_zone_width(atr_val)
if not na(ph_curr) and not zone_exists_near(ph_curr, zw)
push_zone("SWING", ph_curr + zw * 0.5, ph_curr - zw * 0.5, timeframe.period, false, volume[i_swing_right], "")
if not na(pl_curr) and not zone_exists_near(pl_curr, zw)
push_zone("SWING", pl_curr + zw * 0.5, pl_curr - zw * 0.5, timeframe.period, true, volume[i_swing_right], "")
zw_d = zw * 1.5
if not na(htf_d_ph) and not zone_exists_near(htf_d_ph, zw_d)
push_zone("SWING", htf_d_ph + zw_d * 0.5, htf_d_ph - zw_d * 0.5, "D", false, htf_d_v, "")
if not na(htf_d_pl) and not zone_exists_near(htf_d_pl, zw_d)
push_zone("SWING", htf_d_pl + zw_d * 0.5, htf_d_pl - zw_d * 0.5, "D", true, htf_d_v, "")
zw_w = zw * 2.0
if not na(htf_w_ph) and not zone_exists_near(htf_w_ph, zw_w)
push_zone("SWING", htf_w_ph + zw_w * 0.5, htf_w_ph - zw_w * 0.5, "W", false, htf_w_v, "")
if not na(htf_w_pl) and not zone_exists_near(htf_w_pl, zw_w)
push_zone("SWING", htf_w_pl + zw_w * 0.5, htf_w_pl - zw_w * 0.5, "W", true, htf_w_v, "")
if i_enable_ob and bar_index >= i_ob_lookback
avg_vol_ob = ta.sma(volume, i_ob_lookback)
is_bear1 = close[1] < open[1]
bull_move = (close - open[1]) / math.max(open[1], 0.0001) * 100 >= i_ob_min_move
vol_bull = volume >= avg_vol_ob * i_ob_vol_mult
bull_disp = close > math.max(high[2], math.max(high[3], math.max(high[4], high[5])))
if is_bear1 and bull_move and vol_bull and bull_disp
ob_t = math.max(open[1], close[1])
ob_b = math.min(open[1], close[1])
if not zone_exists_near((ob_t + ob_b) / 2, ob_t - ob_b)
push_zone("OB", ob_t, ob_b, timeframe.period, true, volume[1], "")
is_bull1 = close[1] > open[1]
bear_move = (open[1] - close) / math.max(open[1], 0.0001) * 100 >= i_ob_min_move
vol_bear = volume >= avg_vol_ob * i_ob_vol_mult
bear_disp = close < math.min(low[2], math.min(low[3], math.min(low[4], low[5])))
if is_bull1 and bear_move and vol_bear and bear_disp
ob_t = math.max(open[1], close[1])
ob_b = math.min(open[1], close[1])
if not zone_exists_near((ob_t + ob_b) / 2, ob_t - ob_b)
push_zone("OB", ob_t, ob_b, timeframe.period, false, volume[1], "")
if i_enable_vp and bar_index >= i_vp_lookback and bar_index % 5 == 0
vp_h = ta.highest(high, i_vp_lookback)
vp_l = ta.lowest(low, i_vp_lookback)
bsz = (vp_h - vp_l) / i_vp_num_bins
if bsz > 0
max_bv = 0.0
poc_bin = 0
for b = 0 to i_vp_num_bins - 1
bv = 0.0
bb = vp_l + b * bsz
bt = bb + bsz
for k = 0 to i_vp_lookback - 1
bm = (high[k] + low[k]) / 2
if bm >= bb and bm < bt
bv += volume[k]
if bv > max_bv
max_bv := bv
poc_bin := b
poc_price = vp_l + (poc_bin + 0.5) * bsz
if not zone_exists_near(poc_price, bsz * 2)
push_zone("POC", poc_price + bsz * 0.5, poc_price - bsz * 0.5, timeframe.period, close < poc_price, max_bv, "")
if i_enable_fvg and bar_index >= 2
min_gap = close * i_fvg_min_size / 100.0
bull_fvg_top = low[0]
bull_fvg_bot = high[2]
bull_mid_impulsive = close[1] > open[1] and (close[1] - open[1]) >= atr_val * 0.3
if bull_fvg_top > bull_fvg_bot and bull_fvg_top - bull_fvg_bot >= min_gap and bull_mid_impulsive
fvg_mid = (bull_fvg_top + bull_fvg_bot) / 2
if not zone_exists_near(fvg_mid, (bull_fvg_top - bull_fvg_bot) * 0.5)
push_zone("FVG", bull_fvg_top, bull_fvg_bot, timeframe.period, true, volume[1], "")
bear_fvg_top = low[2]
bear_fvg_bot = high[0]
bear_mid_impulsive = close[1] < open[1] and (open[1] - close[1]) >= atr_val * 0.3
if bear_fvg_top > bear_fvg_bot and bear_fvg_top - bear_fvg_bot >= min_gap and bear_mid_impulsive
fvg_mid = (bear_fvg_top + bear_fvg_bot) / 2
if not zone_exists_near(fvg_mid, (bear_fvg_top - bear_fvg_bot) * 0.5)
push_zone("FVG", bear_fvg_top, bear_fvg_bot, timeframe.period, false, volume[1], "")
if i_enable_liq and bar_index >= i_liq_length
tol = close * i_liq_tolerance / 100.0
liq_h = ta.highest(high, i_liq_length)
liq_l = ta.lowest(low, i_liq_length)
eq_h_count = 0
eq_l_count = 0
for k = 0 to i_liq_length - 1
if math.abs(high[k] - liq_h) <= tol
eq_h_count += 1
if math.abs(low[k] - liq_l) <= tol
eq_l_count += 1
if eq_h_count >= 2 and not zone_exists_near(liq_h, tol * 2)
push_zone("LIQ", liq_h + tol, liq_h - tol, timeframe.period, false, ta.sma(volume, i_liq_length), "")
if eq_l_count >= 2 and not zone_exists_near(liq_l, tol * 2)
push_zone("LIQ", liq_l + tol, liq_l - tol, timeframe.period, true, ta.sma(volume, i_liq_length), "")
gap_pct = bar_index > 0 ? math.abs(open - close[1]) / math.max(close[1], 0.0001) * 100 : 0.0
auto_anchor_trigger = i_enable_avwap and i_avwap_auto and gap_pct >= i_avwap_gap_pct and volume >= avg_vol_20 * i_avwap_vol_mult
manual_anchor_trigger = i_enable_avwap and i_avwap_date > 0 and time >= i_avwap_date and time[1] < i_avwap_date
if auto_anchor_trigger or manual_anchor_trigger
g_avwap_anchor_bar := bar_index
g_avwap_cum_pv := 0.0
g_avwap_cum_v := 0.0
g_avwap_anchor_price := open
g_avwap_label := auto_anchor_trigger ? "Gap+" + str.tostring(math.round(gap_pct, 1)) + "%" : "Catalyst"
if g_avwap_anchor_bar >= 0 and bar_index >= g_avwap_anchor_bar
typ_p = (high + low + close) / 3
g_avwap_cum_pv += typ_p * volume
g_avwap_cum_v += volume
avwap_value = g_avwap_cum_v > 0 ? g_avwap_cum_pv / g_avwap_cum_v : na
if i_enable_avwap and not na(avwap_value) and bar_index % 10 == 0
zw_av = get_zone_width(atr_val) * 0.8
if not zone_exists_near(avwap_value, zw_av * 3)
push_zone("AVWAP", avwap_value + zw_av * 0.5, avwap_value - zw_av * 0.5, timeframe.period, close < avwap_value, volume, g_avwap_label)
plot(avwap_value, "AVWAP", color=color.new(#ab47bc, 30), linewidth=2, style=plot.style_line)
var label avwap_label = na
if barstate.islast
label.delete(avwap_label)
if not na(avwap_value)
avwap_label := label.new(bar_index + 3, avwap_value, "⚓ AVWAP " + g_avwap_label, color=color.new(#ab47bc, 10), textcolor=color.white, style=label.style_label_left, size=size.small, tooltip="AVWAP = Anchored Volume-Weighted Average Price\n\nThis PURPLE LINE is the institutional fair value anchor.\nIt starts from: " + g_avwap_label + "\n\nPrice ABOVE AVWAP → trading at a premium (expensive)\nPrice BELOW AVWAP → trading at a discount (cheap)\n\nInstitutions use AVWAP as a reference price.\nZones near AVWAP are especially strong.\n\n── Why it matters ──\nWhen price returns to AVWAP = fair value magnet\nAVWAP breaks = significant shift in sentiment")
if array.size(g_zones) > 0
for i = array.size(g_zones) - 1 to 0
z = array.get(g_zones, i)
in_zone_now = low <= z.top and high >= z.bottom
close_above = close > z.top
close_below = close < z.bottom
if in_zone_now and bar_index > z.bar_created
z.is_fresh := false
z.touches += 1
tvr = avg_vol_20 > 0 ? volume / avg_vol_20 : 1.0
z.touch_vol_avg := z.touches == 1 ? tvr : (z.touch_vol_avg * (z.touches - 1) + tvr) / z.touches
z.last_touch_bar := bar_index
g_tests_total += 1
bounced = z.is_support ? close > z.mid : close < z.mid
if bounced
g_hits_total += 1
is_first_bounce = z.bounce_count == 0 // capture before incrementing
z.bounce_count += 1
b_dist = math.abs(close - z.mid) / math.max(atr_val, 0.0001)
z.avg_dist_at_touch_atr := z.bounce_count == 1 ? b_dist : (z.avg_dist_at_touch_atr * (z.bounce_count - 1) + b_dist) / z.bounce_count
if is_first_bounce
htf_f = z.htf_source == "W" ? 1.0 : z.htf_source == "D" ? 0.8 : 0.4
conf_f = math.min(z.confluence_count, 5) / 5.0
fresh_f = z.is_fresh ? 1.0 : math.max(0.0, 1.0 - float(bar_index - z.last_touch_bar) / 300.0)
g_lb_vol += z.touch_vol_avg
g_lb_htf += htf_f
g_lb_conf += conf_f
g_lb_fresh += fresh_f
g_n_bounce += 1
z.momentum_signal := classify_momentum(z.is_support, math.abs(z.mid - close) / math.max(atr_val, 0.0001), z.touches, lei_value, vol_ratio, approach_spd)
was_violated = z.is_support ? close_below : close_above
if was_violated
z.violations += 1
if z.violations == 1
z.break_count += 1
htf_f = z.htf_source == "W" ? 1.0 : z.htf_source == "D" ? 0.8 : 0.4
conf_f = math.min(z.confluence_count, 5) / 5.0
fresh_f = z.is_fresh ? 1.0 : math.max(0.0, 1.0 - float(bar_index - z.last_touch_bar) / 300.0)
g_lbr_vol += z.touch_vol_avg
g_lbr_htf += htf_f
g_lbr_conf += conf_f
g_lbr_fresh += fresh_f
g_n_break += 1
if z.violations >= 2
z.is_support := not z.is_support
z.flip_count += 1
if z.violations >= 3 or (z.source == "FVG" and not i_fvg_show_filled and z.touches >= 1)
array.remove(g_zones, i)
else
array.set(g_zones, i, z)
n_zones = array.size(g_zones)
if n_zones > 0
for i = 0 to n_zones - 1
zi = array.get(g_zones, i)
conf = 1
for j = 0 to n_zones - 1
if i != j
zj = array.get(g_zones, j)
if zi.top >= zj.bottom and zi.bottom <= zj.top
conf += 1
zi.confluence_count := conf
array.set(g_zones, i, zi)
aw_vol = calc_adaptive_w(i_w_touch_vol, g_lb_vol, g_lbr_vol, g_n_bounce, g_n_break)
aw_htf = calc_adaptive_w(i_w_htf, g_lb_htf, g_lbr_htf, g_n_bounce, g_n_break)
aw_conf = calc_adaptive_w(i_w_confluence, g_lb_conf, g_lbr_conf, g_n_bounce, g_n_break)
aw_fresh = calc_adaptive_w(i_w_fresh, g_lb_fresh, g_lbr_fresh, g_n_bounce, g_n_break)
total_w = aw_vol + aw_conf + aw_htf + i_w_touch + i_w_create_vol + i_w_regime + aw_fresh
n_score = array.size(g_zones)
if n_score > 0
for i = 0 to n_score - 1
z = array.get(g_zones, i)
touch_n = math.min(z.touches, 5) / 5.0
vol_conv = math.min(z.touch_vol_avg, 3.0) / 3.0
create_vn = math.min(z.creation_volume, 3.0) / 3.0
conf_n = math.min(z.confluence_count, 5) / 5.0
fresh_n = z.is_fresh ? 1.0 : math.max(0.0, 1.0 - float(bar_index - z.last_touch_bar) / 300.0)
htf_n = z.htf_source == "W" ? 1.0 : z.htf_source == "D" ? 0.8 : z.htf_source == "240" ? 0.6 : 0.3
viol_pen = math.min(z.violations * 0.25, 1.0)
rf = 0.5
if z.is_support
rf := regime_state == "STRONG_BULL" ? 1.0 : regime_state == "WEAK_BULL" ? 0.8 : regime_state == "RANGE" ? 0.5 : regime_state == "SQUEEZE" ? 0.6 : 0.2
else
rf := regime_state == "STRONG_BEAR" ? 1.0 : regime_state == "WEAK_BEAR" ? 0.8 : regime_state == "RANGE" ? 0.5 : regime_state == "SQUEEZE" ? 0.6 : 0.2
stat_bonus = z.bounce_count + z.break_count > 4 ? (float(z.bounce_count) / math.max(z.bounce_count + z.break_count, 1) - 0.5) * 10.0 : 0.0
raw = (touch_n * i_w_touch + vol_conv * aw_vol + create_vn * i_w_create_vol + htf_n * aw_htf + conf_n * aw_conf + fresh_n * aw_fresh + rf * i_w_regime - viol_pen * 6.0) / math.max(total_w, 1) * 100.0 + stat_bonus
z.score := math.max(0.0, math.min(100.0, raw))
z.grade := get_grade(z.score) // grade ALWAYS derived from final score — no sync bug
array.set(g_zones, i, z)
var string active_warning = "—"
var string warning_severity = "INFO"
var int warning_zone_id = -1
var string warning_zone_src = ""
var float warning_zone_score = 0.0
var string warning_zone_grade = ""
regime_changed = regime_state != prev_regime
prev_regime := regime_state
active_warning := "—"
warning_severity := "INFO"
if barstate.isconfirmed
n_warn = array.size(g_zones)
if n_warn > 0
for i = 0 to n_warn - 1
z = array.get(g_zones, i)
dist = math.abs(z.mid - close)
if i_warn_regime and regime_changed and dist < atr_val * 1.5 and z.grade == "A"
active_warning := "REGIME_SHIFT"
warning_severity := "HIGH"
warning_zone_id := z.id
warning_zone_src := z.source
warning_zone_score := z.score
warning_zone_grade := z.grade
break
if i_warn_trap and z.violations >= 1 and dist < atr_val * 0.3 and volume < avg_vol_20 * 0.7
active_warning := "TRAP_SUSPECTED"
warning_severity := "HIGH"
warning_zone_id := z.id
warning_zone_src := z.source
warning_zone_score := z.score
warning_zone_grade := z.grade
break
if i_warn_sweep and z.source == "LIQ" and dist < atr_val * 0.3 and volume > avg_vol_20 * 1.5
active_warning := "SWEEP_IMMINENT"
warning_severity := "HIGH"
warning_zone_id := z.id
warning_zone_src := z.source
warning_zone_score := z.score
warning_zone_grade := z.grade
break
if i_warn_fvg and z.source == "FVG" and low <= z.top and high >= z.bottom and z.touches == 0
active_warning := "FVG_FILLING"
warning_severity := "INFO"
warning_zone_id := z.id
if i_warn_approach and (z.grade == "A" or z.grade == "B") and dist < atr_val * i_warn_atr_dist
active_warning := "ZONE_APPROACH"
warning_severity := z.grade == "A" ? "WARN" : "INFO"
warning_zone_id := z.id
warning_zone_src := z.source
warning_zone_score := z.score
warning_zone_grade := z.grade
if active_warning == "—" and i_warn_cluster and n_warn > 0
cluster_count = 0
for i = 0 to n_warn - 1
if math.abs(array.get(g_zones, i).mid - close) < atr_val
cluster_count += 1
if cluster_count >= 3
active_warning := "ZONE_CLUSTER_AHEAD"
warning_severity := "WARN"
g_warning := active_warning
g_warn_bar := bar_index
g_tp_dir := "—"
g_tp_entry := na
g_tp_stop := na
g_tp_target := na
g_tp_rr := na
g_tp_shares := 0
g_tp_score := 0.0
if i_enable_trade_plan
float best_long_score = 0.0
float best_long_top = na
float best_long_bot = na
float best_long_mid = na
float best_short_score = 0.0
float best_short_top = na
float best_short_bot = na
float best_short_mid = na
n_tp = array.size(g_zones)
if n_tp > 0
for i = 0 to n_tp - 1
z = array.get(g_zones, i)
dist_atr = math.abs(z.mid - close) / math.max(atr_val, 0.0001)
if z.is_support and close > z.top and dist_atr < 1.5 and z.score > 60
regime_ok = regime_state == "STRONG_BULL" or regime_state == "WEAK_BULL" or regime_state == "RANGE" or regime_state == "SQUEEZE"
if regime_ok and z.score > best_long_score
best_long_score := z.score
best_long_top := z.top
best_long_bot := z.bottom
best_long_mid := z.mid
if not z.is_support and close < z.bottom and dist_atr < 1.5 and z.score > 60
regime_ok = regime_state == "STRONG_BEAR" or regime_state == "WEAK_BEAR" or regime_state == "RANGE" or regime_state == "SQUEEZE"
if regime_ok and z.score > best_short_score
best_short_score := z.score
best_short_top := z.top
best_short_bot := z.bottom
best_short_mid := z.mid
if not na(best_long_top) and best_long_score > 0
tp_entry = best_long_top + atr_val * 0.1
tp_stop = best_long_bot - atr_val * 0.5
tp_risk = math.abs(tp_entry - tp_stop)
if tp_risk > 0
tp_tgt = 999999.0
n_tp2 = array.size(g_zones)
if n_tp2 > 0
for i = 0 to n_tp2 - 1
z = array.get(g_zones, i)
if not z.is_support and z.mid > tp_entry and z.mid < tp_tgt
tp_tgt := z.mid
if tp_tgt < 999999.0
tp_rr_val = (tp_tgt - tp_entry) / tp_risk
if tp_rr_val >= i_min_rr
g_tp_dir := "LONG"
g_tp_entry := tp_entry
g_tp_stop := tp_stop
g_tp_target := tp_tgt
g_tp_rr := tp_rr_val
g_tp_score := best_long_score
risk_dollar = i_account_size * i_risk_pct / 100
g_tp_shares := int(math.round(risk_dollar / tp_risk))
if not na(best_short_bot) and best_short_score > 0 and g_tp_dir == "—"
tp_entry = best_short_bot - atr_val * 0.1
tp_stop = best_short_top + atr_val * 0.5
tp_risk = math.abs(tp_stop - tp_entry)
if tp_rПоказано первые 50% кода (символов: 61623)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.