Indicator · Pine Script v6 · On the chart

Deep Trades Whales v4

by shubhamtaywade82

Deep Trades Whales v4 is an indicator that detects large institutional trades by analyzing volume spikes against historical percentiles and Z-scores.

View on GitHub

Archived by its author

GitHub stars1on the repository
Pine versionv6current
Lines of code606
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update5 months ago31 May 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

606 lines of Pine Script v6 from indicators/whales/Deep Trades Whales v4 [nemesis].pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

Deep Trades Whales v4 [nemesis].pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © shubhamtaywade82

// ============================================================
// Deep Trades Whales v4 [nemesis] — Lean, Honest, Tradable
// Pine Script v6 | indicator() | overlay=true
// ============================================================
// 7 ISSUES FIXED FROM v3:
//
//  Fix 1 — FAKE DELTA DEMOTED
//    close_pos delta proxy is kept for divergence context ONLY.
//    It no longer contributes to whale detection or score.
//    Score weight reassigned to liquidity location (better signal).
//    Label tags it as "PROXY Δ" so you know it isn't real delta.
//
//  Fix 2 — ROLLING VWAP (crypto-correct, no daily reset)
//    Replaced daily-anchored VWAP with a rolling volume-weighted
//    moving average over `vwap_len` bars. No session reset.
//    Works correctly on 24/7 crypto futures and traditional markets.
//    Optional: weekly anchor for swing context.
//
//  Fix 3 — REGIME-DYNAMIC SCORE WEIGHTS
//    Score weights now shift based on regime:
//    TRENDING (EMA expanding): momentum weighted higher
//    RANGING  (ATR low, EMAs flat): absorption/divergence weighted higher
//    The four pillars remain the same; their contribution changes.
//
//  Fix 4 — HTF MARKET STRUCTURE (EMA trend + swing)
//    Added HTF EMA200 and EMA50 trend filter via request.security().
//    Whale buy above HTF EMA50 = with-trend (bonus score).
//    Whale sell below HTF EMA50 = with-trend (bonus score).
//    Against-trend signals are labelled [COUNTER] and score-penalised.
//    Hard block option: reject counter-trend signals entirely.
//
//  Fix 5 — ICEBERG REQUIRES LOCATION CONTEXT
//    Absorption signal now requires price is within `iceberg_zone_atr`
//    ATR of a prior swing high or swing low (liquidity pool).
//    "High-volume nothing-happened" at a structural level = real signal.
//    Same event in mid-range = filtered out.
//
//  Fix 6 — EXHAUSTION REQUIRES WICK REJECTION
//    Two conditions now required (both must pass):
//      a. Next-bar volume collapse (< avg × ratio)  [was the only gate]
//      b. Rejection wick ≥ wick_mult × body on the follow-through bar
//    This filters weekend lulls and session transitions.
//
//  Fix 7 — STRONG+ ONLY BY DEFAULT
//    T1 (WEAK) and T2 (MOD) bubbles hidden by default.
//    New input: `min_display_score` defaults to 55 (STRONG).
//    T3/T4 only. Chart stays clean. Lower it if you want more signals.
// ============================================================

//@version=6
indicator(
     title            = "Deep Trades Whales v4 [nemesis]",
     shorttitle       = "DTW v4",
     overlay          = true,
     max_labels_count = 300,
     max_lines_count  = 50
 )

// ════════════════════════════════════════════════════════════
// ░░  INPUTS
// ════════════════════════════════════════════════════════════

grp_adapt = "🧠 Adaptive Engine"
vol_len        = input.int(50,   "Volume Lookback",             minval=10, maxval=500, group=grp_adapt)
regime_len     = input.int(100,  "Regime ATR Lookback",         minval=20, maxval=500, group=grp_adapt)
vol_pct_thr    = input.float(85.0,"Whale Volume Percentile",   minval=60.0, maxval=99.0, step=1.0, group=grp_adapt)
z_thr_base     = input.float(1.8, "Z-Score Base Threshold",    minval=0.5, maxval=5.0, step=0.1, group=grp_adapt)
regime_hi_pct  = input.float(70.0,"HIGH Regime Threshold",     minval=50.0, maxval=95.0, step=1.0, group=grp_adapt)
regime_lo_pct  = input.float(30.0,"LOW Regime Threshold",      minval=5.0,  maxval=49.0, step=1.0, group=grp_adapt)

grp_price = "💥 Price Impact"
atr_len        = input.int(14,    "ATR Length",                minval=1, group=grp_price)
impact_thr     = input.float(0.65,"Impact Base (ATR)",         minval=0.05, step=0.05, group=grp_price)
close_pos_bull = input.float(0.60,"Bull Close Position",       minval=0.50, maxval=1.00, step=0.01, group=grp_price)
close_pos_bear = input.float(0.40,"Bear Close Position",       minval=0.00, maxval=0.50, step=0.01, group=grp_price)

grp_ice = "🧊 Iceberg / Absorption"
absorb_vol_pct   = input.float(75.0,"Iceberg Volume Percentile",minval=50.0, maxval=99.0, step=1.0, group=grp_ice)
absorb_body_max  = input.float(0.20,"Max Body (ATR, NORMAL)",  minval=0.01, step=0.01, group=grp_ice)
absorb_move_max  = input.float(0.35,"Max Net Move (ATR)",      minval=0.01, step=0.01, group=grp_ice)
absorb_range_max = input.float(0.90,"Max Range (ATR)",         minval=0.05, step=0.05, group=grp_ice)
cluster_min      = input.int(2,    "Min bars for cluster",     minval=2, maxval=5, group=grp_ice)
// FIX 5: location context
iceberg_zone_atr = input.float(1.5,"Swing Proximity (ATR)",    minval=0.3, maxval=5.0, step=0.1, group=grp_ice,
                     tooltip="Iceberg only fires within this many ATRs of a prior swing high or low.")
ice_swing_len    = input.int(20,   "Swing Lookback for Location",minval=5, maxval=100, group=grp_ice)

// FIX 1: delta demoted to context-only
grp_delta = "⚡ Delta Context (proxy — not real bid/ask)"
use_delta     = input.bool(true,  "Enable Delta Proxy Context",  group=grp_delta,
                  tooltip="close_pos proxy. NOT real exchange delta. Used for divergence labelling only — not in score.")
cd_len        = input.int(20,     "Cumulative Delta Lookback",   minval=3, maxval=100, group=grp_delta)
show_cd_div   = input.bool(true,  "Show Divergence Labels",      group=grp_delta)

// FIX 4: HTF market structure
grp_htf = "🌐 HTF Market Structure"
use_htf         = input.bool(true,  "Enable HTF Filter",         group=grp_htf)
htf_tf          = input.timeframe("60","HTF Timeframe",          group=grp_htf)
htf_ema_fast    = input.int(50,    "HTF Fast EMA",               group=grp_htf, minval=5)
htf_ema_slow    = input.int(200,   "HTF Slow EMA",               group=grp_htf, minval=10)
htf_hard_block  = input.bool(false,"Block counter-trend signals",group=grp_htf,
                    tooltip="When on: whale buy below HTF EMA50 is rejected entirely. Off = allowed but score-penalised.")
htf_rvol_min    = input.float(1.2, "HTF Min RVOL (if enabled)",  group=grp_htf, minval=1.0, step=0.1)
use_htf_rvol    = input.bool(false,"Also require HTF RVOL",       group=grp_htf)

// FIX 2: Rolling VWAP
grp_vwap = "📐 Rolling VWAP"
use_vwap     = input.bool(true,  "Enable Rolling VWAP",          group=grp_vwap,
                 tooltip="Rolling VWAP — no daily reset. Correct for 24/7 crypto futures.")
vwap_len     = input.int(200,   "VWAP Rolling Length (bars)",    group=grp_vwap, minval=20, maxval=2000,
                 tooltip="Number of bars for rolling volume-weighted price. 200 = medium-term mean.")
show_vwap    = input.bool(true,  "Show Rolling VWAP Line",        group=grp_vwap)

// FIX 6: Exhaustion requires wick rejection
grp_exhaust = "🔥 Volume Exhaustion"
use_exhaust   = input.bool(true,  "Detect Exhaustion",           group=grp_exhaust)
exhaust_ratio = input.float(0.7, "Next-bar vol < avg × ratio",   group=grp_exhaust, minval=0.1, maxval=1.0, step=0.05)
exhaust_wick  = input.float(1.5, "Required wick ≥ body × mult", group=grp_exhaust, minval=0.5, step=0.1,
                  tooltip="Follow-through bar must have a wick at least N× its body to confirm rejection.")

// FIX 7: strong-only default display
grp_vis = "🎨 Visuals"
confirm_on_close  = input.bool(true,  "Confirm On Bar Close",    group=grp_vis)
show_signals      = input.bool(true,  "Show Signal Bubbles",     group=grp_vis)
show_labels       = input.bool(true,  "Show Detail Labels",      group=grp_vis)
show_bar_color    = input.bool(true,  "Color Signal Bars",       group=grp_vis)
min_display_score = input.int(55,     "Min Score to Show Signal",group=grp_vis, minval=0, maxval=100,
                      tooltip="Default 55 = STRONG+. Set to 0 to show all. Keeps chart clean.")
max_labels        = input.int(150,   "Max Labels",              group=grp_vis, minval=0, maxval=300)
label_offset_atr  = input.float(0.5, "Label Y Offset (ATR×)",  group=grp_vis, minval=0.1, step=0.1)
show_regime_lbl   = input.bool(true, "Show Regime Labels",      group=grp_vis)
show_regime_bg    = input.bool(true, "Regime Background",       group=grp_vis)

grp_dash = "📋 Dashboard"
show_dashboard = input.bool(true, "Show Dashboard", group=grp_dash)
dash_pos       = input.string("Top Right", "Position",
                   options=["Top Right","Top Left","Bottom Right","Bottom Left"], group=grp_dash)

// ════════════════════════════════════════════════════════════
// ░░  HELPERS
// ════════════════════════════════════════════════════════════
f_clamp(x, lo, hi) => math.max(lo, math.min(x, hi))

f_score_tier(s) =>
    s >= 75 ? "EXTREME" : s >= 55 ? "STRONG" : s >= 35 ? "MOD" : "WEAK"

f_score_color(s) =>
    s >= 75 ? color.new(#ff00ff, 0) :
    s >= 55 ? color.new(#ff3d3d, 0) :
    s >= 35 ? color.new(#ff9900, 0) :
              color.new(#888888, 0)

// ════════════════════════════════════════════════════════════
// ░░  REGIME CLASSIFIER (preserved from v3)
// ════════════════════════════════════════════════════════════
atr_raw   = ta.atr(atr_len)
atr_safe  = math.max(atr_raw, syminfo.mintick)
atr_prank = ta.percentrank(atr_raw, regime_len)

regime     = atr_prank >= regime_hi_pct ? 2 : atr_prank <= regime_lo_pct ? 0 : 1
regime_lbl = regime == 2 ? "HIGH 🔴" : regime == 0 ? "LOW 🟢" : "NORMAL 🟡"

regime_scalar     = regime == 2 ? 1.5 : regime == 0 ? 0.65 : 1.0
adaptive_rvol_min = regime == 2 ? 2.0 : regime == 0 ? 1.2 : 1.5
adaptive_z_thr    = regime == 2 ? z_thr_base * 1.4 : regime == 0 ? z_thr_base * 0.75 : z_thr_base

adaptive_impact_thr  = impact_thr     * regime_scalar
adaptive_body_max    = absorb_body_max  * regime_scalar
adaptive_move_max    = absorb_move_max  * regime_scalar
adaptive_range_max   = absorb_range_max * regime_scalar

var int prev_regime = regime
regime_changed = regime != prev_regime
prev_regime := regime

bgcolor(show_regime_bg ?
     (regime == 2 ? color.new(#ff3d3d, 97) :
      regime == 0 ? color.new(#00c87a, 97) : color.new(#ffcc00, 99)) : na, title="Regime BG")

if show_regime_lbl and regime_changed
    _col = regime == 2 ? color.new(#ff3d3d, 10) : regime == 0 ? color.new(#00c87a, 10) : color.new(#ffcc00, 10)
    label.new(bar_index, high + atr_raw * 1.8, "Regime → " + regime_lbl,
         style=label.style_label_down, color=_col, textcolor=color.white, size=size.tiny)

// ════════════════════════════════════════════════════════════
// ░░  FIX 2 — ROLLING VWAP (no daily reset)
// ════════════════════════════════════════════════════════════
// ta.vwap() resets on session. We compute our own rolling VWAP:
//   rolling_vwap = sum(tp × vol, len) / sum(vol, len)
// This is sessionless and works on 24/7 crypto correctly.

tp = (high + low + close) / 3.0
rolling_vwap = ta.sma(tp * volume, vwap_len) / math.max(ta.sma(volume, vwap_len), 1.0)

above_vwap = close > rolling_vwap
below_vwap = close < rolling_vwap

plot(show_vwap and use_vwap ? rolling_vwap : na, "Rolling VWAP",
     color=color.new(color.white, 40), linewidth=1, style=plot.style_linebr)

// ════════════════════════════════════════════════════════════
// ░░  FIX 4 — HTF MARKET STRUCTURE (EMA trend)
// ════════════════════════════════════════════════════════════
htf_ema_f    = request.security(syminfo.tickerid, htf_tf,
                   ta.ema(close, htf_ema_fast), lookahead=barmerge.lookahead_off)
htf_ema_s    = request.security(syminfo.tickerid, htf_tf,
                   ta.ema(close, htf_ema_slow), lookahead=barmerge.lookahead_off)
htf_close    = request.security(syminfo.tickerid, htf_tf,
                   close, lookahead=barmerge.lookahead_off)
htf_vol_raw  = request.security(syminfo.tickerid, htf_tf,
                   volume, lookahead=barmerge.lookahead_off)
htf_vol_base = request.security(syminfo.tickerid, htf_tf,
                   ta.ema(volume, vol_len), lookahead=barmerge.lookahead_off)
htf_rvol     = htf_vol_raw / math.max(nz(htf_vol_base, 1.0), 1.0)

// HTF trend: bullish = close above EMA50 AND EMA50 above EMA200
htf_trend_bull = htf_close > htf_ema_f and htf_ema_f > htf_ema_s
htf_trend_bear = htf_close < htf_ema_f and htf_ema_f < htf_ema_s
htf_trend_flat = not htf_trend_bull and not htf_trend_bear

// With-trend and counter-trend classification
with_trend_long  = htf_trend_bull
with_trend_short = htf_trend_bear
counter_long     = htf_trend_bear   // whale buy in downtrend
counter_short    = htf_trend_bull   // whale sell in uptrend

// HTF RVOL gate (optional)
htf_rvol_ok = not use_htf_rvol or htf_rvol >= htf_rvol_min

// Hard block: if enabled, counter-trend signals never fire
htf_long_ok  = not use_htf or (not htf_hard_block or with_trend_long)  and htf_rvol_ok
htf_short_ok = not use_htf or (not htf_hard_block or with_trend_short) and htf_rvol_ok

// ════════════════════════════════════════════════════════════
// ░░  BASE VOLUME + PRICE CALCULATIONS
// ════════════════════════════════════════════════════════════
vol_base     = ta.ema(volume, vol_len)
vol_std      = ta.stdev(volume, vol_len)
vol_safe     = math.max(nz(vol_base, 0.0), 1.0)
rvol         = volume / vol_safe
vol_z        = (volume - vol_base) / math.max(nz(vol_std, 1.0), 1.0)
vol_prank    = ta.percentrank(volume, vol_len)

range_hl     = high - low
body         = math.abs(close - open)
net_move     = close - close[1]
range_atr    = range_hl / atr_safe
body_atr     = body     / atr_safe
move_atr     = math.abs(net_move) / atr_safe
close_pos    = range_hl > 0.0 ? (close - low) / range_hl : 0.5

// ── FIX 1: Delta proxy — context/display only, NOT in detection ──────
// Label as proxy so users understand the limitation
net_delta_proxy = use_delta ? volume * (2.0 * close_pos - 1.0) : 0.0   // ranges -vol to +vol
cum_delta       = use_delta ? math.sum(net_delta_proxy, cd_len) : 0.0
delta_proxy_bull = cum_delta > 0.0
delta_proxy_bear = cum_delta < 0.0
cd_rising        = cum_delta > nz(cum_delta[1], cum_delta)
cd_falling       = cum_delta < nz(cum_delta[1], cum_delta)

// ── FIX 5: Swing levels for iceberg location context ─────────────────
swing_hi = ta.highest(high, ice_swing_len)
swing_lo = ta.lowest(low,   ice_swing_len)
// Price within iceberg_zone_atr ATRs of a swing high or low
near_swing_hi = math.abs(close - swing_hi) <= iceberg_zone_atr * atr_safe
near_swing_lo = math.abs(close - swing_lo) <= iceberg_zone_atr * atr_safe
near_swing    = near_swing_hi or near_swing_lo

// ════════════════════════════════════════════════════════════
// ░░  VOLUME ANOMALY (triple gate — preserved from v3)
// ════════════════════════════════════════════════════════════
vol_prank_ok = vol_prank >= vol_pct_thr
vol_z_ok     = vol_z >= adaptive_z_thr
rvol_ok      = rvol >= adaptive_rvol_min
vol_anomaly  = vol_prank_ok and vol_z_ok and rvol_ok

confirmed    = not confirm_on_close or barstate.isconfirmed

impact_up = close > open and net_move > 0.0 and move_atr >= adaptive_impact_thr and close_pos >= close_pos_bull
impact_dn = close < open and net_move < 0.0 and move_atr >= adaptive_impact_thr and close_pos <= close_pos_bear

// FIX 1: delta removed from whale gate — it was misleading
// FIX 4: htf_ok now uses EMA structure, not just RVOL
whale_buy  = confirmed and vol_anomaly and impact_up and htf_long_ok
whale_sell = confirmed and vol_anomaly and impact_dn and htf_short_ok

// ── FIX 5: Iceberg requires swing proximity ───────────────────────────
absorb_vol_ok = ta.percentrank(volume, vol_len) >= absorb_vol_pct

iceberg_raw = confirmed and
              absorb_vol_ok and
              body_atr  <= adaptive_body_max and
              move_atr  <= adaptive_move_max  and
              range_atr <= adaptive_range_max and
              near_swing and                       // ← FIX 5: must be at swing level
              not whale_buy and not whale_sell

var int absorb_streak = 0
absorb_streak    := iceberg_raw ? absorb_streak + 1 : 0
iceberg_cluster   = iceberg_raw and absorb_streak >= cluster_min
iceberg           = iceberg_raw

// ── FIX 6: Exhaustion requires volume collapse AND wick rejection ─────
next_bar_vol_low = volume < vol_base * exhaust_ratio
// Wick check on current bar (the follow-through after the whale):
//   upper wick ≥ body × exhaust_wick (for whale buy exhaustion)
//   lower wick ≥ body × exhaust_wick (for whale sell exhaustion)
upper_wick = high - math.max(open, close)
lower_wick = math.min(open, close) - low
body_safe  = math.max(body, atr_safe * 0.1)   // avoid div by zero on doji
has_rejection_wick_bull = upper_wick >= body_safe * exhaust_wick   // wick up = rejection of rally
has_rejection_wick_bear = lower_wick >= body_safe * exhaust_wick   // wick down = rejection of selloff

whale_exhaustion = use_exhaust and
                   ((whale_buy[1]  and next_bar_vol_low and has_rejection_wick_bull) or
                    (whale_sell[1] and next_bar_vol_low and has_rejection_wick_bear))

// ── Delta divergence (context label only, not in score) ──────────────
price_new_hi   = high == ta.highest(high, cd_len)
price_new_lo   = low  == ta.lowest(low,   cd_len)
delta_div_bear = show_cd_div and use_delta and price_new_hi and cd_falling and confirmed
delta_div_bull = show_cd_div and use_delta and price_new_lo and cd_rising  and confirmed

// ════════════════════════════════════════════════════════════
// ░░  FIX 3 — REGIME-DYNAMIC SCORE WEIGHTS
// ════════════════════════════════════════════════════════════
// Four pillars: Volume, Impact, Location (replaces delta), Structure
// Weights shift based on regime:
//   TRENDING (HIGH vol + EMA expanding): momentum pillars weighted up
//   RANGING  (LOW vol, EMAs flat):       location/absorption weighted up

// Pillar 1: Volume strength (RVOL + Z + prank)
rvol_norm   = f_clamp((rvol - adaptive_rvol_min) / adaptive_rvol_min, 0.0, 1.0)
z_excess    = f_clamp((vol_z - adaptive_z_thr)   / adaptive_z_thr,   0.0, 1.0)
vol_pillar  = (rvol_norm * 0.6 + z_excess * 0.4) * 100.0

// Pillar 2: Price impact (move ATR normalised)
move_norm    = f_clamp(move_atr / (adaptive_impact_thr * 3.0), 0.0, 1.0)
impact_pillar = move_norm * 100.0

// Pillar 3: Location quality (swing proximity + VWAP side + HTF alignment)
//   Replaces fake delta in score. Actual market context.
loc_swing_pt  = near_swing ? 40.0 : 0.0
loc_vwap_pt   = not use_vwap ? 20.0 :
                (whale_buy and below_vwap) or (whale_sell and above_vwap) ? 40.0 :
                (whale_buy and above_vwap) or (whale_sell and below_vwap) ? 10.0 : 20.0
loc_htf_pt    = not use_htf ? 20.0 :
                (whale_buy and with_trend_long)  or (whale_sell and with_trend_short) ? 40.0 :
                htf_trend_flat ? 20.0 : 0.0
loc_pillar    = f_clamp(loc_swing_pt + loc_vwap_pt + loc_htf_pt, 0.0, 100.0)

// Pillar 4: Regime bonus (signal is harder to achieve in HIGH regime)
regime_pillar = regime == 2 ? 80.0 : regime == 1 ? 50.0 : 30.0

// DYNAMIC WEIGHTS — shift with market state
// Trending (HIGH): volume(35) + impact(35) + location(20) + regime(10)
// Normal:          volume(30) + impact(25) + location(30) + regime(15)
// Ranging (LOW):   volume(20) + impact(20) + location(40) + regime(20)
w_vol    = regime == 2 ? 0.35 : regime == 0 ? 0.20 : 0.30
w_impact = regime == 2 ? 0.35 : regime == 0 ? 0.20 : 0.25
w_loc    = regime == 2 ? 0.20 : regime == 0 ? 0.40 : 0.30
w_regime = regime == 2 ? 0.10 : regime == 0 ? 0.20 : 0.15

score_raw = vol_pillar * w_vol + impact_pillar * w_impact + loc_pillar * w_loc + regime_pillar * w_regime
score     = int(math.round(f_clamp(score_raw, 0.0, 100.0)))

// ════════════════════════════════════════════════════════════
// ░░  FIX 7 — STRONG+ ONLY BY DEFAULT
// ════════════════════════════════════════════════════════════
show_this = show_signals and score >= min_display_score

// Buy/sell/ice conditions gated by min_display_score
plot_buy  = show_this and whale_buy
plot_sell = show_this and whale_sell
plot_ice  = show_this and iceberg

// Size from score (no tiers — single clean bubble, size = quality)
f_sig_size(s) =>
    s >= 75 ? size.large : s >= 55 ? size.normal : size.small

plotshape(plot_buy,  "Whale Buy",  shape.circle,  location.belowbar,
     f_score_color(score), size=f_sig_size(score), text="WB")
plotshape(plot_sell, "Whale Sell", shape.circle,  location.abovebar,
     f_score_color(score), size=f_sig_size(score), text="WS")
plotshape(plot_ice,  "Iceberg",    shape.diamond, location.abovebar,
     color.new(color.orange, 0), size=f_sig_size(score), text="IC")

plotshape(show_signals and iceberg_cluster and score >= min_display_score,
     "Cluster", shape.square, location.abovebar,
     color.new(color.purple, 0), size=size.small, text="CLU")
plotshape(show_signals and whale_exhaustion,
     "Exhaustion", shape.xcross, location.abovebar,
     color.new(color.yellow, 0), size=size.small, text="EXH")
plotshape(delta_div_bear, "CD Div Bear", shape.triangledown,
     location.abovebar, color.new(#ff00ff, 30), size=size.tiny, text="DIV↓")
plotshape(delta_div_bull, "CD Div Bull", shape.triangleup,
     location.belowbar, color.new(#00ffff, 30), size=size.tiny, text="DIV↑")

barcolor(show_bar_color ?
     (whale_buy        ? color.new(color.lime,   20) :
      whale_sell       ? color.new(color.red,    20) :
      iceberg_cluster  ? color.new(color.purple, 20) :
      iceberg          ? color.new(color.orange, 20) :
      whale_exhaustion ? color.new(color.yellow, 40) : na) : na)

// ════════════════════════════════════════════════════════════
// ░░  DETAIL LABELS
// ════════════════════════════════════════════════════════════
var label[] sig_labels = array.new<label>(0)
f_push_label(lb) =>
    array.push(sig_labels, lb)
    if array.size(sig_labels) > max_labels
        label.delete(array.shift(sig_labels))

label_offset = atr_safe * label_offset_atr

// FIX 1: delta tag says "PROXY Δ" — honest labelling
delta_ctx_tag(bull) =>
    not use_delta ? "" :
    bull ? (delta_proxy_bull ? " PROXY Δ↑" : " PROXY Δ↓") :
           (delta_proxy_bear ? " PROXY Δ↓" : " PROXY Δ↑")

vwap_ctx_tag(bull) =>
    not use_vwap ? "" :
    bull ? (below_vwap ? " [Accum]" : " [Dist]") :
           (above_vwap ? " [Dist]"  : " [Accum]")

htf_ctx_tag(bull) =>
    not use_htf ? "" :
    bull ? (with_trend_long ? " WITH-TREND ✓" : counter_long ? " COUNTER ⚠" : " FLAT") :
           (with_trend_short ? " WITH-TREND ✓" : counter_short ? " COUNTER ⚠" : " FLAT")

if show_labels and whale_buy and score >= min_display_score
    txt = "🐋 Whale Buy [" + f_score_tier(score) + "] " + regime_lbl + "\n" +
          htf_ctx_tag(true) + vwap_ctx_tag(true) + delta_ctx_tag(true) + "\n" +
          "Vol: " + str.tostring(volume, format.volume) +
          "  RVOL: " + str.tostring(rvol, "#.##") + "×  Z: " + str.tostring(vol_z, "#.##") + "\n" +
          "Impact: " + str.tostring(move_atr, "#.##") + " ATR  Score: " + str.tostring(score)
    lb = label.new(bar_index, low - label_offset, txt,
         xloc=xloc.bar_index, yloc=yloc.price,
         style=label.style_label_up,
         color=f_score_color(score), textcolor=color.white, size=size.small)
    f_push_label(lb)

if show_labels and whale_sell and score >= min_display_score
    txt = "🐋 Whale Sell [" + f_score_tier(score) + "] " + regime_lbl + "\n" +
          htf_ctx_tag(false) + vwap_ctx_tag(false) + delta_ctx_tag(false) + "\n" +
          "Vol: " + str.tostring(volume, format.volume) +
          "  RVOL: " + str.tostring(rvol, "#.##") + "×  Z: " + str.tostring(vol_z, "#.##") + "\n" +
          "Impact: " + str.tostring(move_atr, "#.##") + " ATR  Score: " + str.tostring(score)
    lb = label.new(bar_index, high + label_offset, txt,
         xloc=xloc.bar_index, yloc=yloc.price,
         style=label.style_label_down,
         color=f_score_color(score), textcolor=color.white, size=size.small)
    f_push_label(lb)

if show_labels and (iceberg_cluster or iceberg) and score >= min_display_score
    _near = near_swing_hi ? "near swing HIGH" : near_swing_lo ? "near swing LOW" : "—"
    txt = (iceberg_cluster ? "🧊 Cluster [" + str.tostring(absorb_streak) + " bars]" : "🧊 Iceberg") +
          " " + regime_lbl + "\n" +
          "Location: " + _near + "\n" +
          "Vol: " + str.tostring(volume, format.volume) +
          "  Body: " + str.tostring(body_atr, "#.##") + " ATR  Score: " + str.tostring(score)
    lb = label.new(bar_index, high + label_offset, txt,
         xloc=xloc.bar_index, yloc=yloc.price,
         style=label.style_label_down,
         color=iceberg_cluster ? color.new(color.purple,10) : color.new(color.orange,10),
         textcolor=color.white, size=size.small)
    f_push_label(lb)

if show_labels and whale_exhaustion
    _dir = whale_buy[1] ? "Buy" : "Sell"
    _wick = whale_buy[1] ? str.tostring(upper_wick / atr_safe, "#.##") : str.tostring(lower_wick / atr_safe, "#.##")
    txt = "⚡ Exhaustion — " + _dir + " rejected\n" +
          "Vol: " + str.tostring(rvol, "#.##") + "× avg  Wick: " + _wick + " ATR"
    lb = label.new(bar_index, high + label_offset, txt,
         xloc=xloc.bar_index, yloc=yloc.price,
         style=label.style_label_down,
         color=color.new(color.yellow, 10), textcolor=color.black, size=size.tiny)
    f_push_label(lb)

// ════════════════════════════════════════════════════════════
// ░░  ALERTS
// ════════════════════════════════════════════════════════════
alertcondition(whale_buy,                    "🐋 Whale Buy",             "Whale Buy | " + regime_lbl + " | Score: " + str.tostring(score) + " | Close: {{close}}")
alertcondition(whale_sell,                   "🐋 Whale Sell",            "Whale Sell | " + regime_lbl + " | Score: " + str.tostring(score) + " | Close: {{close}}")
alertcondition(whale_buy and with_trend_long, "🐋 WITH-TREND Whale Buy", "With-trend Whale Buy | HTF bullish | Close: {{close}}")
alertcondition(whale_sell and with_trend_short,"🐋 WITH-TREND Whale Sell","With-trend Whale Sell | HTF bearish | Close: {{close}}")
alertcondition(iceberg_cluster,              "🧊 Cluster at Swing",      "Absorption cluster at swing level | Close: {{close}}")
alertcondition(whale_exhaustion,             "⚡ Exhaustion",            "Whale exhaustion confirmed (vol+wick) | Close: {{close}}")
alertcondition(delta_div_bear,               "📉 Proxy Δ Divergence ↓", "Price new high / delta proxy falling | Close: {{close}}")
alertcondition(delta_div_bull,               "📈 Proxy Δ Divergence ↑", "Price new low / delta proxy rising | Close: {{close}}")
alertcondition(whale_buy  and score >= 75,   "🔥 EXTREME Whale Buy",    "EXTREME score Whale Buy | Score≥75 | Close: {{close}}")
alertcondition(whale_sell and score >= 75,   "🔥 EXTREME Whale Sell",   "EXTREME score Whale Sell | Score≥75 | Close: {{close}}")
alertcondition(regime_changed and regime == 2,"⚡ Regime → HIGH",        "Volatility expanded to HIGH on {{ticker}}")
alertcondition(regime_changed and regime == 0,"🌙 Regime → LOW",         "Volatility compressed to LOW on {{ticker}}")

// ════════════════════════════════════════════════════════════
// ░░  DASHBOARD
// ════════════════════════════════════════════════════════════
state_txt = whale_buy        ? "🐋 Whale Buy"     :
            whale_sell       ? "🐋 Whale Sell"    :
            iceberg_cluster  ? "🧊 Cluster"       :
            iceberg          ? "🧊 Iceberg"       :
            whale_exhaustion ? "⚡ Exhaustion"    :
            delta_div_bear   ? "📉 Proxy Div ↓"  :
            delta_div_bull   ? "📈 Proxy Div ↑"  :
            vol_anomaly      ? "📊 Vol Anomaly"   : "— Neutral"

state_col = whale_buy        ? color.new(color.lime,   20) :
            whale_sell       ? color.new(color.red,    20) :
            iceberg_cluster  ? color.new(color.purple, 20) :
            iceberg          ? color.new(color.orange, 20) :
            whale_exhaustion ? color.new(color.yellow, 20) :
            vol_anomaly      ? color.new(color.yellow, 50) :
                               color.new(color.gray,   50)

score_col  = score >= 75 ? color.new(#ff00ff, 20) : score >= 55 ? color.new(#ff3d3d, 20) :
             score >= 35 ? color.new(#ff9900, 20) : color.new(#555555, 20)
regime_col = regime == 2 ? color.new(#ff3d3d, 20) : regime == 0 ? color.new(#00c87a, 20) : color.new(#ffcc00, 30)
htf_col    = with_trend_long or with_trend_short ? color.new(color.lime, 30) :
             htf_trend_flat ? color.new(color.gray, 40) : color.new(color.red, 30)

dash_position = switch dash_pos
    "Top Left"     => position.top_left
    "Bottom Right" => position.bottom_right
    "Bottom Left"  => position.bottom_left
    =>                position.top_right

var table dash = table.new(dash_position, 3, 16,
     bgcolor=color.new(color.black, 10),
     border_color=color.new(color.gray, 60), border_width=1,
     frame_color=color.new(color.gray, 40), frame_width=1)

dc(c, r, t, bg, tc) =>
    table.cell(dash, c, r, t, bgcolor=bg, text_color=tc, text_size=size.small)

if show_dashboard and barstate.islast
    BG = color.new(color.black, 20); HD = color.new(#1a1a2e, 10); wht = color.white

    dc(0, 0, "DTW v4",        HD, wht); dc(1, 0, "STATUS", HD, wht); dc(2, 0, "VALUE", HD, wht)

    dc(0, 1, "🌡 Regime",     BG, wht)
    dc(1, 1, regime_lbl,      regime_col, wht)
    dc(2, 1, str.tostring(atr_prank, "#.0") + "th pctile", BG, wht)

    dc(0, 2, "Signal",        BG, wht); dc(1, 2, state_txt, state_col, wht); dc(2, 2, "", BG, wht)
    dc(0, 3, "Score",         BG, wht)
    dc(1, 3, str.tostring(score) + "/100 [" + f_score_tier(score) + "]", score_col, wht)
    dc(2, 3, "min show: " + str.tostring(min_display_score), BG, wht)

    dc(0, 4, "── HTF Structure ──", HD, wht); dc(1, 4, "", HD, wht); dc(2, 4, "", HD, wht)

    dc(0, 5, "HTF Trend",     BG, wht)
    dc(1, 5, with_trend_long ? "BULL ✓" : with_trend_short ? "BEAR ✓" : "FLAT",
             htf_col, wht)
    dc(2, 5, str.tostring(htf_ema_fast) + "/" + str.tostring(htf_ema_slow) + " EMA", BG, wht)

    dc(0, 6, "HTF RVOL",      BG, wht)
    dc(1, 6, str.tostring(htf_rvol, "#.##") + "×  " + (htf_rvol >= htf_rvol_min ? "✓" : "✗"),
             htf_rvol >= htf_rvol_min ? color.new(color.lime,30) : BG, wht)
    dc(2, 6, use_htf_rvol ? "required" : "informational", BG, wht)

    dc(0, 7, "── Volume ──",  HD, wht); dc(1, 7, "", HD, wht); dc(2, 7, "", HD, wht)

    dc(0, 8, "RVOL",          BG, wht)
    dc(1, 8, str.tostring(rvol, "#.##") + "×",
             rvol >= adaptive_rvol_min * 1.5 ? color.new(color.lime,20) :
             rvol >= adaptive_rvol_min ? color.new(color.orange,30) : BG, wht)
    dc(2, 8, "≥ " + str.tostring(adaptive_rvol_min, "#.##") + "× (adapt)", regime_col, wht)

    dc(0, 9, "Z-Score",       BG, wht)
    dc(1, 9, str.tostring(vol_z, "#.##"),
             vol_z >= adaptive_z_thr ? color.new(color.lime,30) : BG, wht)
    dc(2, 9, "≥ " + str.tostring(adaptive_z_thr, "#.##") + " (adapt)", regime_col, wht)

    dc(0,10, "Vol Prank",     BG, wht)
    dc(1,10, str.tostring(vol_prank, "#.0") + "%",
             vol_prank >= vol_pct_thr ? color.new(color.lime,30) : BG, wht)
    dc(2,10, "≥ " + str.tostring(vol_pct_thr, "#.0") + "%", BG, wht)

    dc(0,11, "── Context ──", HD, wht); dc(1,11, "", HD, wht); dc(2,11, "", HD, wht)

    dc(0,12, "Rolling VWAP",  BG, wht)
    dc(1,12, use_vwap ? (above_vwap ? "Above ▲" : "Below ▼") : "off",
             use_vwap ? (above_vwap ? color.new(color.lime,40) : color.new(color.red,40)) : BG, wht)
    dc(2,12, use_vwap ? str.tostring(math.round(rolling_vwap, 2)) : "—", BG, wht)

    dc(0,13, "Near Swing",    BG, wht)
    dc(1,13, near_swing_hi ? "Near HIGH ✓" : near_swing_lo ? "Near LOW ✓" : "Mid-range",
             near_swing ? color.new(color.orange,30) : BG, wht)
    dc(2,13, "±" + str.tostring(iceberg_zone_atr, "#.#") + " ATR", BG, wht)

    dc(0,14, "Proxy Delta",   BG, wht)
    dc(1,14, use_delta ? (delta_proxy_bull ? "▲ Net Buy" : "▼ Net Sell") : "off",
             use_delta ? (delta_proxy_bull ? color.new(color.lime,40) : color.new(color.red,40)) : BG, wht)
    dc(2,14, "⚠ PROXY only", color.new(color.yellow, 40), wht)

    dc(0,15, "Absorb Streak", BG, wht)
    dc(1,15, str.tostring(absorb_streak) + " bar(s)" + (iceberg_cluster ? " 🧊" : ""),
             absorb_streak >= cluster_min ? color.new(color.purple,30) : BG, wht)
    dc(2,15, near_swing ? "at swing ✓" : "no location ✗",
             near_swing ? color.new(color.lime,40) : color.new(color.red,40), wht)

Overview

Deep Trades Whales v4 identifies whale activity through iceberg absorption patterns that require proximity to prior swing highs or lows, using ATR-based filters for range, body, and net move. The script dynamically weights signals by market regime detected via ATR and EMAs, applies HTF trend filters, and shows rolling VWAP. Labels appear on the price chart for buy and sell signals based on absorption confirmation and score thresholds. Settings control lookback periods, percentile thresholds, and iceberg parameters. It draws all signals and lines directly on the price chart and does not repaint.

Details

Published by

shubhamtaywade82 on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Volume, Volatility & bands, Support & resistance, SMC / ICT / price action

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Volume Lookbackint50vol_len
Regime ATR Lookbackint100regime_len
Whale Volume Percentilefloat85.0vol_pct_thr
Z-Score Base Thresholdfloat1.8z_thr_base
HIGH Regime Thresholdfloat70.0regime_hi_pct
LOW Regime Thresholdfloat30.0regime_lo_pct
ATR Lengthint14atr_len
Impact Base (ATR)float0.65impact_thr
Bull Close Positionfloat0.60close_pos_bull
Bear Close Positionfloat0.40close_pos_bear
Iceberg Volume Percentilefloat75.0absorb_vol_pct
Max Body (ATR, NORMAL)float0.20absorb_body_max
Show all 40 settings
SettingTypeDefaultVariable
Max Net Move (ATR)float0.35absorb_move_max
Max Range (ATR)float0.90absorb_range_max
Min bars for clusterint2cluster_min
Swing Proximity (ATR)float1.5iceberg_zone_atr
Swing Lookback for Locationint20ice_swing_len
Enable Delta Proxy Contextbooltrueuse_delta
Cumulative Delta Lookbackint20cd_len
Show Divergence Labelsbooltrueshow_cd_div
Enable HTF Filterbooltrueuse_htf
HTF Timeframetimeframe60htf_tf
HTF Fast EMAint50htf_ema_fast
HTF Slow EMAint200htf_ema_slow
Block counter-trend signalsboolfalsehtf_hard_block
HTF Min RVOL (if enabled)float1.2htf_rvol_min
Also require HTF RVOLboolfalseuse_htf_rvol
Enable Rolling VWAPbooltrueuse_vwap
VWAP Rolling Length (bars)int200vwap_len
Show Rolling VWAP Linebooltrueshow_vwap
Detect Exhaustionbooltrueuse_exhaust
Next-bar vol < avg × ratiofloat0.7exhaust_ratio
Required wick ≥ body × multfloat1.5exhaust_wick
Confirm On Bar Closebooltrueconfirm_on_close
Show Signal Bubblesbooltrueshow_signals
Show Detail Labelsbooltrueshow_labels
Color Signal Barsbooltrueshow_bar_color
Min Score to Show Signalint55min_display_score
Max Labelsint150max_labels
Label Y Offset (ATR×)float0.5label_offset_atr
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

1 stars

The Adaptive Liquidity Matrix indicator calculates and plots a synthetic liquidity matrix on the price chart. It anchors to the highest volume candle on a selected macro timeframe, reads its polarity to set support or resistance levels, and expands the matrix

Indicator v6 Volatility & bandsSupport & resistance
Updated 6 months ago · AGPL-3.0 GitHub repository of Adaptive Liquidity Matrix

ICT Liquidity Void Fill

by ArunKBhaskar
575 stars

This overlay indicator marks ICT liquidity void fills on the price chart and can show long and short signals. It places a Fibonacci level inside a displacement candle, defaulting to the midpoint, and draws lines in a chosen style. Optional filters limit the fi

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Liquidity Void Fill

Snag - VWAP

by dearvn
257 stars

This indicator plots a custom Anchored Volume-Weighted Average Price (VWAP) directly on the price chart along with optional standard deviation bands. Users can anchor the VWAP to standard time periods like sessions, weeks, or months, or to corporate events suc

Indicator v5 Moving averagesVolatility & bands Repaints
Updated 6 weeks ago · None stated GitHub repository of Snag - VWAP
218 stars

This indicator maps market structure and supply and demand zones on the price chart. It marks validated and optional unvalidated swing highs and lows using a pivot length and extra confirmation bars. Consolidation and impulse moves are measured against ATR to

Indicator v6 SMC / ICT / price actionSupport & resistance Repaints
Updated 3 months ago · None stated GitHub repository of Market Structure + Supply/Demand

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers