Appearance
Personalize your experience
Drawdown Recovery
FreeBuys measured pullbacks in an uptrend once they recover
Live engine preview
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.
About
Buys measured pullbacks inside a long-term uptrend and only once the pullback shows it is over. The drawdown from the rolling high is measured in ATR units; a pullback of at least the minimum depth, with price still above the long-term average, is bought when price reclaims the prior bar's high. The trade aims for a retest of the high that started the pullback. Entry: drawdown between the minimum and maximum depth, close above the slow EMA, close above the previous high. Exit: target at the pullback's starting high, stop below the pullback low, time stop. Long only. Risk: 1 % per trade.
Settings
High lookback: 60
Minimum depth (ATR): 3
Maximum depth (ATR): 10
Trend EMA: 200
Maximum bars held: 80
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
- ▸ drawdown between the minimum and maximum depth, close above the slow EMA, close above the previous high
Exit Conditions
- ▸ target at the pullback's starting high, stop below the pullback low, time stop
- ▸ Long only
Measured backtest
BTCUSDT 1h (Binance), 2025-11-01 to 2026-11-01 · backtest engine, script costs included
-10.0%
Return
-0.75
Sharpe
-13.3%
Max DD
39.7%
Win Rate
121
Trades
| Market | Trades | Return | Sharpe | Max DD | Win rate | Profit factor |
|---|---|---|---|---|---|---|
| BTCUSDT 1h | 121 | -10.0% | -0.75 | -13.3% | 39.7% | 0.84 |
| ETHUSDT 1h | 116 | -17.7% | -1.26 | -19.9% | 36.2% | 0.73 |
Past results on historical data do not predict future returns.
Source Code
Edit in IDE| 1 | strategy "Drawdown Recovery" { |
| 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 | /// Buys measured pullbacks inside a long-term uptrend and only once the pullback shows it is over. |
| 12 | /// The drawdown from the rolling high is measured in ATR units; a pullback of at least the minimum |
| 13 | /// depth, with price still above the long-term average, is bought when price reclaims the prior |
| 14 | /// bar's high. The trade aims for a retest of the high that started the pullback. |
| 15 | /// Entry: drawdown between the minimum and maximum depth, close above the slow EMA, close above |
| 16 | /// the previous high. Exit: target at the pullback's starting high, stop below the pullback low, |
| 17 | /// time stop. Long only. Risk: 1 % per trade. |
| 18 | use "viz/premium" as pr |
| 19 | look = param.int(60, title = "High lookback", min = 10, max = 1000, group = "Pullback") |
| 20 | d_min = param.float(3, title = "Minimum depth (ATR)", min = 0.5, max = 20, step = 0.5, group = "Pullback") |
| 21 | d_max = param.float(10, title = "Maximum depth (ATR)", min = 1, max = 40, step = 0.5, group = "Pullback") |
| 22 | trend = param.int(200, title = "Trend EMA", min = 20, max = 2000, group = "Trend") |
| 23 | hold = param.int(80, title = "Maximum bars held", min = 2, max = 1000, group = "Exit") |
| 24 | hh = ta.highest(high, look) |
| 25 | ll = ta.lowest(low, 10) |
| 26 | a = math.max(ta.atr(50), 1e-12) |
| 27 | depth = (hh - close) / a |
| 28 | t = ta.ema(close, trend) |
| 29 | setup = depth[1] >= d_min and depth[1] <= d_max and close > t and close > high[1] |
| 30 | if position.size == 0 and setup { |
| 31 | order.market("L", side.long) |
| 32 | exit.bracket("L exit", entry = "L", stop = ll - 0.2 * a, target = hh) |
| 33 | } |
| 34 | if position.size != 0 and position.bars_held >= hold { exit.close_all() } |
| 35 | risk.max_drawdown(25) |
| 36 | render.line(hh, "Rolling high", color = color.translucent(color.emerald.300, 40), width = 1, stroke = style.dashed) |
| 37 | render.line(t, "Trend EMA", color = color.amber.300, width = 1.5) |
| 38 | render.mark(setup and position.size == 0, shape = shape.triangle_up, at = anchor.below_bar, color = color.emerald.300, text = "Recover", title = "Pullback recovery") |
| 39 | persist tb = draw.table.create(anchor.top_right, 4, 2) |
| 40 | if bar.is_last { |
| 41 | pr.heading(tb, 2, "Drawdown Recovery", "Strategy · measured pullbacks") |
| 42 | pr.row(tb, 2, "Depth", str.format("{:.1f} ATR", depth), depth >= d_min ? pr.WARN : color.white) |
| 43 | pr.row(tb, 3, "Trend", close > t ? "Up" : "Down", close > t ? pr.BULL : pr.BEAR) |
| 44 | } |
| 45 |
Reviews
No reviews yet. Be the first to review this listing.