Appearance

Personalize your experience

Mode
Accent Color
Direction
MarketplacestrategiesAnchored VWAP Reclaim
QuaScript

Anchored VWAP Reclaim

Admin's ChoiceFree

Buys the reclaim of the swing-low VWAP after a flush

0.0(0)
0 installs 0 0 comments
Q
159 listings

The QuaTick team's QuaScript analyses, run by the native C++ engine.

View Profile
quascriptstrategyvwapanchoredpullback
Free
Backtest this strategy Open in QuaTick IDE Edit in IDE
Version
Updated
Compatible

Live engine preview

QuaScriptQuaScript

The QuaScript engine's own output on the chart the terminal uses. Change the settings or edit the code and press Run to recompute it.

Anchored VWAP Reclaimengine result
Loading the engine result…
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

About

Trades the moment the crowd that bought the last swing low is back in profit. A VWAP is anchored at every confirmed swing low and swing high. In an uptrend, a pullback that closes below the swing-low VWAP puts those buyers under water; when price closes back above it within a few bars, the dip was absorbed and the buyers defend their average. Shorts mirror this with the swing-high VWAP in a downtrend. Entry: trend filter (close beyond a rising 200-bar EMA), a close at least `flush` ATR below the newest swing-low VWAP, then a close back above it by the margin within `window` bars (mirror for shorts). Exit: stop beyond the dip extreme (at least 1 ATR), target `reward` R, trailing exit on a close back through the VWAP. Risk: 1 % per trade.


Settings

Swing bars left: 10

Swing bars right: 5

Trend EMA: 200

Reclaim window (bars): 6

Reclaim margin (ATR): 0.15

Flush depth (ATR): 0.3

Target (R): 2.5


Measured backtests

Run by the backtest engine on public candles, 2025-11-01 to 2026-11-01, with the script's own commission and slippage, on BTCUSDT 1h (Binance) and ETHUSDT 1h (Binance). The figures per market are in the Measured backtest panel below. Past results do not predict future returns.


Backtest it yourself

Open it on the backtesting page to run it on any symbol, interval and date range, then use Monte Carlo, optimisation, walk-forward and robustness tests.

Strategy Rules

Entry Conditions

  • ▸ trend filter (close beyond a rising 200-bar EMA), a close at least `flush` ATR below the newest swing-low VWAP, then a close back above it by the margin within `window` bars (mirror for shorts)

Exit Conditions

  • ▸ stop beyond the dip extreme (at least 1 ATR), target `reward` R, trailing exit on a close back through the VWAP

Measured backtest

BTCUSDT 1h (Binance), 2025-11-01 to 2026-11-01 · backtest engine, script costs included

Backtest this strategy

-18.5%

Return

-1.43

Sharpe

-23.1%

Max DD

26.6%

Win Rate

139

Trades

MarketTradesReturnSharpeMax DDWin rateProfit factor
BTCUSDT 1h139-18.5%-1.43-23.1%26.6%0.74
ETHUSDT 1h109-6.0%-0.35-14.3%31.2%0.91

Past results on historical data do not predict future returns.

Source Code

Edit in IDE
quascript
1strategy "Anchored VWAP Reclaim" {
2 overlay = true
3 capital = 100000
4 commission = 0.05
5 slippage = 1
6 sizing = risk_percent
7 max_leverage = 1
8 size = 1
9 pyramiding = 1
10}
11/// Trades the moment the crowd that bought the last swing low is back in profit. A VWAP is anchored
12/// at every confirmed swing low and swing high. In an uptrend, a pullback that closes below the
13/// swing-low VWAP puts those buyers under water; when price closes back above it within a few
14/// bars, the dip was absorbed and the buyers defend their average. Shorts mirror this with the
15/// swing-high VWAP in a downtrend.
16/// Entry: trend filter (close beyond a rising 200-bar EMA), a close at least `flush` ATR below the
17/// newest swing-low VWAP, then a
18/// close back above it by the margin within `window` bars (mirror for shorts). Exit: stop beyond
19/// the dip extreme (at least 1 ATR), target `reward` R, trailing exit on a close back through the
20/// VWAP. Risk: 1 % per trade.
21use "viz/premium" as pr
22left = param.int(10, title = "Swing bars left", min = 2, max = 50, group = "Swings")
23right = param.int(5, title = "Swing bars right", min = 1, max = 30, group = "Swings")
24trend_n = param.int(200, title = "Trend EMA", min = 20, max = 1000, group = "Filter")
25window = param.int(6, title = "Reclaim window (bars)", min = 1, max = 50, group = "Signals")
26margin = param.float(0.15, title = "Reclaim margin (ATR)", min = 0, max = 2, step = 0.05, group = "Signals")
27flush = param.float(0.3, title = "Flush depth (ATR)", min = 0, max = 3, step = 0.05, group = "Signals")
28reward = param.float(2.5, title = "Target (R)", min = 0.5, max = 10, step = 0.1, group = "Risk")
29pl = ta.pivot_low(left, right)
30ph = ta.pivot_high(left, right)
31pv = bar.typical * volume
32persist lp = na
33persist lv = na
34persist hp = na
35persist hv = na
36lp := lp + pv
37lv := lv + volume
38hp := hp + pv
39hv := hv + volume
40sp = 0.0
41sv = 0.0
42if not math.is_na(pl) or not math.is_na(ph) {
43 for i in 0..=right {
44 sp := sp + pv[i]
45 sv := sv + volume[i]
46 }
47}
48if not math.is_na(pl) {
49 lp := sp
50 lv := sv
51}
52if not math.is_na(ph) {
53 hp := sp
54 hv := sv
55}
56vl = lp / lv
57vh = hp / hv
58ema = ta.ema(close, trend_n)
59a = ta.atr(14)
60slope = (ema - ema[20]) / math.max(a, 1e-12)
61up = close > ema and slope > 0.5
62dn = close < ema and slope < -0.5
63below = close < vl - flush * a
64above = close > vh + flush * a
65since_below = ta.bars_since(below)
66since_above = ta.bars_since(above)
67dip_low = ta.lowest(low, window + 1)
68pop_high = ta.highest(high, window + 1)
69go_l = up and close > vl + margin * a and not below and math.coalesce(since_below, 1000000) <= window and since_below >= 1
70go_s = dn and close < vh - margin * a and not above and math.coalesce(since_above, 1000000) <= window and since_above >= 1
71// one trade per reclaim: re-arm once price trades through the line again
72persist used_l = false
73persist used_s = false
74if below { used_l := false }
75if above { used_s := false }
76flat = position.size == 0
77if flat and go_l and not used_l {
78 stop = math.min(dip_low, close - a)
79 order.market("L", side.long)
80 exit.bracket("L exit", entry = "L", stop = stop, target = close + (close - stop) * reward)
81 used_l := true
82}
83if flat and go_s and not used_s {
84 stop = math.max(pop_high, close + a)
85 order.market("S", side.short)
86 exit.bracket("S exit", entry = "S", stop = stop, target = close - (stop - close) * reward)
87 used_s := true
88}
89if position.size > 0 and close < vl - a { exit.close("L") }
90if position.size < 0 and close > vh + a { exit.close("S") }
91risk.max_drawdown(25)
92render.line(ema, "Trend EMA", color = color.translucent(color.slate.300, 50), width = 1)
93render.line(vl, "Swing-low VWAP", color = color.emerald.300, width = 1.75)
94render.line(vh, "Swing-high VWAP", color = color.rose.300, width = 1.75)
95render.mark(go_l and flat and not used_l[1], shape = shape.triangle_up, at = anchor.below_bar, color = color.emerald.300, text = "Reclaim", title = "Long reclaim")
96render.mark(go_s and flat and not used_s[1], shape = shape.triangle_down, at = anchor.above_bar, color = color.rose.300, text = "Reject", title = "Short rejection")
97persist t = draw.table.create(anchor.top_right, 5, 2)
98if bar.is_last {
99 pr.heading(t, 2, "Anchored VWAP Reclaim", "Strategy · swing-anchored VWAPs")
100 pr.row(t, 2, "Trend", up ? "Up" : "Down", up ? pr.BULL : pr.BEAR)
101 pr.row(t, 3, "Swing-low VWAP", str.format("{:.2f} ({:+.2%})", vl, close / vl - 1), close > vl ? pr.BULL : pr.BEAR)
102 pr.row(t, 4, "Swing-high VWAP", str.format("{:.2f} ({:+.2%})", vh, close / vh - 1), close > vh ? pr.BULL : pr.BEAR)
103}
104 
Read-only preview. Open in the QuaTick IDE to edit and deploy.

Reviews

No reviews yet. Be the first to review this listing.

Discussion

Sign in to join the discussion. Your posts and replies show up on your profile.