Volume-Weighted S/R Zones [WillyAlgoTrader]📊 Volume-Weighted S/R Zones is an overlay indicator that automatically detects support and resistance zones from price pivots, scores them by volume and price reaction, tracks breaks and retests, and instantly places a full risk-management plan on the chart with a stop-loss and three take-profits. No manual lines — everything is calculated and drawn automatically.
The core idea: not all levels are equal. A level where price reversed on heavy volume and ran far from it is dozens of times more valuable than a level formed on thin volume with no reaction. The indicator assigns each zone a Strength Score from 0 to 100 , combining volume at the pivot bar, price reaction strength, and touch count — and displays only the zones that actually work.
The indicator is completely free and open-source . Works on any instrument (crypto, forex, stocks, futures, indices) and any timeframe.
🧩 WHY THESE COMPONENTS WORK TOGETHER
A classic pivot indicator draws lines on every local high and low — the chart turns into a mess of dozens of levels, and it's impossible to tell which ones matter. Volume profiles show where heavy trading happened, but don't tie that to specific reversal levels. Pure Price Action gives the right zones, but requires manual markup.
This indicator solves all three problems with one integrated pipeline:
Pivot Detection → Volume Score + Reaction Score → ATR clustering of nearby pivots → Strength Score 0..100 → Age Decay → Break Detection (with filters) → Retest Detection → Zone-Aware SL/TP → Trade Statistics
Each step adds something the previous one cannot. Pivot Detection finds raw reversal points. Volume Score answers the question "was there heavy trading here". Reaction Score answers "did price bounce off the level". ATR clustering merges pivots into a single zone if they sit within N×ATR — giving zone width instead of a thin line. Age Decay gradually reduces the weight of old zones. Break/Retest turn zones into trade signals. Zone-Aware SL places the stop behind the broken zone instead of at an abstract ATR distance. Trade Stats show whether your settings actually work on your instrument.
Remove any component and the system breaks: pivots without scoring are noise, scoring without clustering produces dozens of thin lines, clustering without break/retest gives no signals, signals without zone-aware SL get stopped out on noise.
🔍 WHAT MAKES THIS INDICATOR ORIGINAL
1️⃣ Strength Score 0..100 — three-component zone quality measurement.
Each zone receives a strength score by the formula:
Score = VolScore + ReactionScore + 10 (base bonus), then clamp(0, 100)
Where:
— VolScore (0..40) : computed as min(40, volumeRatio × 20) , where volumeRatio = volume on the pivot bar / average volume over N bars (default 20). On instruments without volume (some forex pairs) a base value of 20 is assigned.
— ReactionScore (0..30) : measured as min(30, max_move / ATR × 10) , where max_move is the maximum price movement AWAY from the pivot in the first N bars after it (default 5). Computed against ATR at the pivot bar, not current ATR — this is the correct normalization.
When the same zone is touched again (a new pivot within ATR × MergeDistance radius, default 0.5), zones merge, the touch counter grows, and a bonus of min(20, √touches × 4) × 0.5 is added to the score. This means: 4 touches give +4, 9 touches +6, 16 touches +8. Logarithmic growth to avoid over-weighting.
Zones are divided into 4 tiers by score: ★ (weak, 0-30), ★★ (medium, 30-60), ★★★ (strong, 60-85), 🔥 (very strong, 85+) . The tier is shown directly on the zone label and affects box transparency — stronger zones are more visually prominent.
2️⃣ Age Decay — old zones lose strength gradually, not abruptly.
Each bar the zone score is reduced by ageDecayRate × 0.1 . By default (0.5) that's −0.05 per bar, so a zone loses about 25 points over 500 bars. This gives an honest forgetting mechanism: a level from last week matters, but not as much as a level from last hour. Can be disabled (set to 0) or made aggressive (1.0 = −0.10 per bar).
Additionally zones are removed by three conditions: age exceeds Max Zone Age (default 30 Days, measured independently of timeframe), score drops below MIN_VIABLE_SCORE = 5.0 , or zone is broken and more than 2×ReactionWindow bars have passed since the break (nobody will retest a stale broken zone).
3️⃣ Break Detection with a dual-volume filter (floor + cap).
The standard "break volume ≥ N×average" filter is easily bypassed by news spikes and gaps. Solution:
— Volume Floor : volume ≥ avg × VolMult (default 1.3) — filters thin-volume breakouts.
— Volume Cap (optional) : volume ≤ avg × VolCap (default 5.0) — filters abnormally large candles (opening gaps, news spikes). Especially important on stocks.
Additionally: Momentum Filter requires the break candle's range to be ≥ N×ATR (default 1.0). This filters "doji breaks" where the candle body barely crossed the level.
4️⃣ Retest Detection with reaction validation.
After a break, the indicator waits for a retest within a Min..Max bars window (default 2..30). A retest counts only if:
— Price touched the broken zone (low ≤ zoneTop for a bullish break)
— Price closed back in trend direction (close > zoneTop)
— Reaction from the zone ≥ ATR × ReactionMin (default 0.5×ATR)
Optionally enable Mitigation Filter , which skips a retest if the zone was already tested once — for traders who only want the first retest.
5️⃣ Zone-Aware Stop-Loss — stops behind real structure, not in thin air.
With Zone-Aware SL enabled, the stop is placed not just at ATR×Mult distance, but by formula:
— For long: SL = max(close − ATR×SLMult, zoneBot − ATR×0.2)
— For short: SL = min(close + ATR×SLMult, zoneTop + ATR×0.2)
The LESS aggressive stop is chosen: either the standard ATR stop, or "behind the zone with a 0.2×ATR buffer". Logic: if the zone is broken, it became resistance (for longs) or support (for shorts). If price returns back INTO the zone — the breakout idea is invalidated, you should exit. This gives a clear exit criterion and usually a wider but more meaningful stop.
6️⃣ Risk presets and three take-profits with partial scaling.
Four ready-made risk presets:
— Conservative : SL 2.5×ATR, TP 1R / 2R / 4R
— Balanced (default): SL 1.5×ATR, TP 1R / 2R / 3R
— Aggressive : SL 1.0×ATR, TP 1.5R / 2.5R / 4R
— Scalping : SL 0.8×ATR, TP 0.8R / 1.5R / 2R
— Custom : configure manually
The model assumes splitting the position into three equal parts: 1/3 on TP1, 1/3 on TP2, 1/3 on TP3. When a TP is touched, the line turns solid cyan with a ✓ checkmark.
7️⃣ Break-Even Trail — after TP1 the stop automatically moves to entry.
With Break-Even After TP1 enabled, on first touch of TP1 the SL is pulled to the entry price. Only TP2 and TP3 remain in play — but the risk is now zero. If price reverses, the trade closes at break-even instead of the original stop. Classic "protect profit, let winners run" model.
Implemented carefully: BE activates only after a confirmed TP1 touch (with no SL break on the same bar), and on the same bar TP1 + SL is always resolved as a stop (conservative model — real brokers don't guarantee limit fills before stops on the same wick).
8️⃣ Session Trade Statistics — tracking real effectiveness.
The dashboard tracks stats right on the chart:
— Trades : total closed trades
— W/L : wins vs losses
— Win Rate : % of wins. A WIN = TP1 reached . This is a deliberate classification: if the idea worked and TP1 closed — that's a success, even if TP2/TP3 didn't fill and exited at BE.
— BE saves : diagnostic counter. How many wins closed via BE-stop rather than TP3. High BE saves ratio → TP3 is set too far.
— Avg R : average R-multiple per trade. Calculated assuming partial scaling (1/3 at each TP).
Stats reset on any settings change (including a dedicated Reset Stats Counter input made specifically for manual resets).
9️⃣ Fully adaptive theme and WCAG-contrast colors.
All colors are calculated for both TradingView themes (Dark/Light) with WCAG AA contrast verification (4.5:1 minimum). Label text on tinted backgrounds is chosen so it remains readable on both themes. Auto-detection by chart background color, or manual Dark/Light selection in settings.
🔟 TF-independent zone aging.
Max Zone Age can be set in Bars / Hours / Days . This means "30 Days" is always 30 calendar days regardless of timeframe (on 5m it's 8640 bars, on 1h — 720, on 1D — 30). Legacy indicators use bars only, which makes them break when you switch TFs — fixed here.
🧠 HOW IT WORKS — step-by-step calculation flow
Step 1 — Pivot Detection: on each bar, ta.pivothigh and ta.pivotlow are checked with equal left/right lookback (default 21). A pivot is confirmed only after N bars pass — so the indicator does NOT repaint already-drawn zones.
Step 2 — Volume Score: for a confirmed pivot, VolScore is computed against the volume on the pivot bar itself (not the current bar).
Step 3 — Reaction Score: the maximum price movement AWAY from the pivot is measured over the next N bars. ATR at the pivot bar is used for correct normalization.
Step 4 — Merge or Create: if there's already a same-type zone within ATR × MergeDistance — the pivot merges into it (zone widens, score updates, touch counter increments). Otherwise a new zone is created with boundaries ±0.15×ATR from the pivot price.
Step 5 — Age Decay & Cleanup: a reverse pass over the zone array applies decay, removes too-old, too-weak, and stale broken zones. If active zones exceed Max Active Zones — the weakest is removed.
Step 6 — Break Detection: on every confirmed bar, every unbroken zone is checked for a break. Volume Floor, Volume Cap, and Momentum Filter are applied if enabled.
Step 7 — Retest Detection: after a break, a retest with confirmed reaction is searched for in the Min..Max bars window.
Step 8 — Risk Management: on a signal (Break or Retest), with risk management enabled, a virtual position opens with SL and three TPs calculated.
Step 9 — Trade Lifecycle: on each bar, SL/TP touches are checked. TP1 → BE activates. SL or TP3 → position closes, stats update.
Step 10 — Visual & Alerts: zone boxes, SL/TP lines, BRK/RT markers, dashboard — all refresh on the last bar. Alerts fire on bar close.
📖 HOW TO USE — EVEN IF YOU'RE NEW
🎯 Quick start (3 minutes):
1. Add the indicator to your chart (any instrument, any timeframe).
2. Wait 30–50 bars — the indicator needs history for calculations. Zones will appear after that.
3. Look at the dashboard in the top-right corner — it shows current trend, active signal, and position state.
4. Don't change settings on day one. Work with defaults to understand how the indicator "breathes" on your instrument.
5. When you see a BRK or RT signal — look at the horizontal SL/TP1/TP2/TP3 lines. That's your trade plan.
👁️ Reading the chart:
— 🟢 Green box = support zone (Demand). Price approaches from below.
— 🔴 Red box = resistance zone (Supply). Price approaches from above.
— Box transparency = zone strength. The more opaque, the stronger.
— Icon on the label : ★ weak, ★★ medium, ★★★ strong, 🔥 very strong.
— ×N on label = number of zone touches.
— ✕ on label = zone already broken (you can hunt for a retest).
— BRK green below bar = resistance broken upward.
— BRK red above bar = support broken downward.
— RT = confirmed retest of broken level.
— Dotted blue line = entry price of the active trade.
— Solid red line = stop-loss. When it becomes dimmed + ENTRY label says "→ SL (BE)" — stop has moved to break-even.
— Dashed green lines = TP1, TP2, TP3. When they turn solid cyan with ✓ — that TP is reached.
📊 Dashboard (top-right by default):
— Trend : Bullish / Bearish / Neutral. Calculated as weighted difference of zone strength above vs below price.
— Signal : current status (BREAK ▲, RETEST ▼, Long Active, Wait, etc.).
— Score : strength of active signal or strongest zone.
— Zones : number of active zones on chart.
— TF : timeframe.
— SL / TP1 / TP2 / TP3 : risk management prices for the active trade.
— R:R : risk/reward ratio to TP1.
— Risk : % of price you risk to the stop.
— Trades / W/L / Win Rate / BE saves / Avg R : session stats.
🔧 Tuning — what to change and when:
— Too many zones, chart cluttered: raise Min Score to Display to 30–40. Raise Zone Merge Distance to 0.7–1.0.
— Too few zones: lower Pivot Lookback to 10–15. Lower Min Score to 0–10.
— Scalping 1m–5m: use Scalping preset, Pivot Lookback 5–8, ATR Length 10.
— Swing 1h–4h: Balanced preset, Pivot Lookback 21 (default), Max Zone Age 30 Days.
— Position trading 1D: Conservative preset, Pivot Lookback 10–15, Max Zone Age 90 Days.
— False breakouts eat your account: enable Volume Filter for Breaks + Momentum Filter.
— Trading stocks/indices with gaps: keep Volume Cap on (it's on by default).
— Want only the first retest: enable Mitigation Filter for Retests.
— Frequently closing at BE without profit: check BE saves in dashboard. If >50% of wins — TP3 is too far, shorten it.
💡 Trading ideas:
— Most reliable setup: retest of a strong zone (★★★ or 🔥) in the dashboard trend direction .
— Don't trade against the strongest zone (🔥) in your path — wait for it to break first.
— A zone touch without confirmed reaction is NOT a signal. The indicator filters this for you, but don't try to "guess" the bounce in advance.
— Use Trade Stats as feedback. If after 50 trades Win Rate < 40% and Avg R < 0 — change settings or timeframe.
⚙️ KEY SETTINGS
⚙️ Main Settings:
— Pivot Lookback (default 21): how many bars on each side must be lower/higher for a pivot
— Max Active Zones (default 8): max number of active zones on chart
— Zone Merge Distance (default 0.5×ATR): merge radius for nearby pivots
— Min Score to Display (default 15): hide zones weaker than this
📦 Zone Detection:
— ATR Length (default 14): ATR period for all calculations
— Volume Avg Lookback (default 20): average volume window
— Reaction Window (default 5): bars to measure reaction after a pivot
— Age Decay Rate (default 0.5): zone aging speed
— Max Zone Age (default 30 Days): maximum zone age
— Max Zone Age Unit (Bars / Hours / Days)
🔍 Filters (optional):
— Volume Filter for Breaks (default off): require volume ≥ N×average on break
— Volume Multiplier (default 1.3)
— Volume Cap (default on, 5.0): filter abnormal spikes
— Momentum Filter (default off): require candle range ≥ N×ATR
— Mitigation Filter (default off): first retest only
🎯 Signals:
— Show Break Signals / Show Retest Signals
— Min/Max Bars for Retest (default 2 / 30)
— Min Retest Reaction (default 0.5×ATR)
🛡️ Risk Management:
— Enable Risk Management (default on)
— Risk Preset (Conservative / Balanced / Aggressive / Scalping / Custom)
— SL ×ATR , TP1/TP2/TP3 ×Risk (for Custom)
— Zone-Aware SL (default on): place stop behind the zone
— Break-Even After TP1 (default on)
— Show SL/TP Lines / Labels
— Show % Distance on Labels
— Entry/SL/TP Line Style (Solid / Dashed / Dotted)
🎨 Visual:
— Theme (Auto / Dark / Light)
— Show Zones / Score Labels / Watermark
— Zone Forward Bars (default 5): how many bars to project zones forward
— SL/TP Label Font Size , Signal Marker Size
📊 Dashboard:
— Show Dashboard , Position
— Show Trade Stats (W/L, Win Rate, Avg R, BE saves)
— Reset Stats Counter : changing the value resets stats
🔔 ALERTS
— 🟢 BREAK UP — resistance broken upward, with price, score, SL, and three TPs
— 🔴 BREAK DOWN — support broken downward
— 🟢 RETEST LONG — confirmed long retest
— 🔴 RETEST SHORT — confirmed short retest
— 🎯 TP1 / TP2 / TP3 HIT — target reached (optional)
— 🛑 SL HIT / 🛡️ BE STOP-OUT — stop-loss hit or break-even close
— 🛡️ BREAK-EVEN ACTIVATED — stop moved to entry
All alerts available in two formats: plain text (readable for Telegram/Discord) and JSON (for webhook automation). Fire on bar close (alert.freq_once_per_bar_close) — no intra-bar flooding.
⚠️ IMPORTANT NOTES
— 🚫 No repainting. All signals use barstate.isconfirmed. Pivots are confirmed with equal left/right lookback — meaning the pivot point is always N bars in the past. This is delayed confirmation, not repainting of future values. Zones don't move after they appear.
— 📐 Zones are built from confirmed pivots. This means a zone appears on the chart N (Pivot Lookback) bars after the extreme formed. On the most recent 21 bars to the right there will be no zones — this is normal and correct.
— ⚖️ On instruments without volume (some forex pairs, some indices) VolScore defaults to 20 out of 40. Zone quality scoring is lower than on crypto/stocks with real volume.
— 🛠️ This is an analysis tool, not an automated bot. The indicator finds zones, marks signals, and proposes a structured trade plan — but entry decisions are YOURS. Past performance does not guarantee future results.
— 📊 Trade Stats counts virtual trades based on indicator signals, without slippage, commissions, or real liquidity. Use as a reference, not as a promise of results.
— 🌐 Universal compatibility: works on any ticker and timeframe. On tick/Renko charts, Hours/Days options for Max Zone Age automatically fall back to 500 bars.
— 💯 Completely free, open-source. Study the code, fork it, modify it for yourself.
If you found this indicator useful — leave a 🚀 and follow the author profile to see updates and new publications. Questions and feedback welcome in the comments.
Pine Script® göstergesi






















