Appearance
Personalize your experience
Hurst Regime Switch
Admin's ChoiceFreeHurst exponent picks breakout or fade-to-mean
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
Lets the Hurst exponent pick the playbook. When returns persist (H above the upper band) it trades breakouts of a Donchian channel in the direction of the move; when they mean-revert (H below the lower band) it fades closes outside a 2-sigma band back to the mean; in the random-walk zone between it stands aside. Entry: trend mode, close beyond the channel; reversion mode, close outside the band with the band turning back. Exit: ATR bracket (trend: trailing; reversion: target at the mean), or a regime change. Risk: 1 % of equity per trade, 25 % drawdown halt. Method: Hurst (1951) rescaled range on log returns.
Settings
Hurst window: 200
Random-walk band: 0.04
Breakout channel: 30
Reversion band length: 40
Stop (ATR): 2
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 mode, close beyond the channel; reversion mode, close outside the band with the band turning back
Exit Conditions
- ▸ ATR bracket (trend: trailing; reversion: target at the mean), or a regime change
Measured backtest
BTCUSDT 1h (Binance), 2025-11-01 to 2026-11-01 · backtest engine, script costs included
-20.5%
Return
-1.73
Sharpe
-25.0%
Max DD
38.1%
Win Rate
118
Trades
| Market | Trades | Return | Sharpe | Max DD | Win rate | Profit factor |
|---|---|---|---|---|---|---|
| BTCUSDT 1h | 118 | -20.5% | -1.73 | -25.0% | 38.1% | 0.65 |
| ETHUSDT 1h | 180 | -1.5% | -0.02 | -16.2% | 46.7% | 0.97 |
Past results on historical data do not predict future returns.
Source Code
Edit in IDE| 1 | strategy "Hurst Regime Switch" { |
| 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 | /// Lets the Hurst exponent pick the playbook. When returns persist (H above the upper band) it |
| 12 | /// trades breakouts of a Donchian channel in the direction of the move; when they mean-revert |
| 13 | /// (H below the lower band) it fades closes outside a 2-sigma band back to the mean; in the |
| 14 | /// random-walk zone between it stands aside. |
| 15 | /// Entry: trend mode, close beyond the channel; reversion mode, close outside the band with the |
| 16 | /// band turning back. Exit: ATR bracket (trend: trailing; reversion: target at the mean), or a |
| 17 | /// regime change. Risk: 1 % of equity per trade, 25 % drawdown halt. |
| 18 | /// Method: Hurst (1951) rescaled range on log returns. |
| 19 | use "viz/premium" as pr |
| 20 | h_len = param.int(200, title = "Hurst window", min = 50, max = 2000, group = "Regime") |
| 21 | band = param.float(0.04, title = "Random-walk band", min = 0.0, max = 0.2, step = 0.01, group = "Regime") |
| 22 | ch_len = param.int(30, title = "Breakout channel", min = 5, max = 300, group = "Trend mode") |
| 23 | mr_len = param.int(40, title = "Reversion band length", min = 10, max = 400, group = "Reversion mode") |
| 24 | stop_k = param.float(2.0, title = "Stop (ATR)", min = 0.5, max = 8, step = 0.1, group = "Risk") |
| 25 | h = stat.hurst(math.log(close / close[1]), h_len) |
| 26 | trend_mode = h > 0.5 + band |
| 27 | revert_mode = h < 0.5 - band |
| 28 | (_, upper, lower) = ta.donchian(ch_len) |
| 29 | (mid, bb_up, bb_lo) = ta.bollinger(close, mr_len, 2) |
| 30 | a = ta.atr(20) |
| 31 | flat = position.size == 0 |
| 32 | if flat and trend_mode and close > upper[1] { |
| 33 | order.market("TL", side.long) |
| 34 | exit.bracket("TL exit", entry = "TL", stop = close - stop_k * a, trail_offset = stop_k * a, trail_trigger = close + stop_k * a) |
| 35 | } |
| 36 | if flat and trend_mode and close < lower[1] { |
| 37 | order.market("TS", side.short) |
| 38 | exit.bracket("TS exit", entry = "TS", stop = close + stop_k * a, trail_offset = stop_k * a, trail_trigger = close - stop_k * a) |
| 39 | } |
| 40 | if flat and revert_mode and close[1] < bb_lo[1] and close > close[1] { |
| 41 | order.market("RL", side.long) |
| 42 | exit.bracket("RL exit", entry = "RL", stop = close - stop_k * a, target = mid) |
| 43 | } |
| 44 | if flat and revert_mode and close[1] > bb_up[1] and close < close[1] { |
| 45 | order.market("RS", side.short) |
| 46 | exit.bracket("RS exit", entry = "RS", stop = close + stop_k * a, target = mid) |
| 47 | } |
| 48 | // a regime change closes the trade it no longer supports |
| 49 | if position.size != 0 and not trend_mode and not revert_mode and position.bars_held > 5 { exit.close_all() } |
| 50 | risk.max_drawdown(25) |
| 51 | render.line(upper, "Channel high", color = color.translucent(color.orange.300, 50), width = 1) |
| 52 | render.line(lower, "Channel low", color = color.translucent(color.sky.300, 50), width = 1) |
| 53 | render.line(mid, "Mean", color = trend_mode ? color.orange.300 : revert_mode ? color.sky.300 : color.slate.500, width = 2) |
| 54 | render.background(trend_mode ? color.translucent(color.orange.500, 94) : revert_mode ? color.translucent(color.sky.500, 94) : na) |
| 55 | persist t = draw.table.create(anchor.top_right, 5, 2) |
| 56 | if bar.is_last { |
| 57 | pr.heading(t, 2, "Hurst Regime Switch", "Strategy · regime-selected playbook") |
| 58 | pr.row(t, 2, "Hurst", str.format("{:.3f}", h), trend_mode ? color.orange.300 : revert_mode ? color.sky.300 : color.slate.300) |
| 59 | pr.row(t, 3, "Playbook", trend_mode ? "Breakout" : revert_mode ? "Fade to mean" : "Stand aside", color.white) |
| 60 | pr.row(t, 4, "Position", position.side > 0 ? "Long" : position.side < 0 ? "Short" : "Flat", position.side > 0 ? pr.BULL : position.side < 0 ? pr.BEAR : pr.LABEL) |
| 61 | } |
| 62 |
Reviews
No reviews yet. Be the first to review this listing.