Appearance
Personalize your experience
Volume-Confirmed Trend
FreeHull average crosses confirmed by return-volume correlation
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
Joins trends that volume confirms. Two things are measured: whether up bars carry the volume (the correlation of signed returns with volume) and whether the trend average is sloping. A cross of price over the average is taken only when the correlation agrees with its direction, which filters out drifts that happen on thin, one-sided volume. Entry: close crosses the Hull average with the return-volume correlation above (below) the level. Exit: opposite cross or ATR trailing stop. Risk: 1 % per trade. Method: rolling Pearson correlation of log returns and log volume.
Settings
Hull average: 55
Correlation window: 60
Confirmation level: 0.08
Trailing stop (ATR): 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
- ▸ close crosses the Hull average with the return-volume correlation above (below) the level
Exit Conditions
- ▸ opposite cross or ATR trailing stop
Measured backtest
BTCUSDT 1h (Binance), 2025-11-01 to 2026-11-01 · backtest engine, script costs included
-4.8%
Return
-0.36
Sharpe
-13.9%
Max DD
26.1%
Win Rate
188
Trades
| Market | Trades | Return | Sharpe | Max DD | Win rate | Profit factor |
|---|---|---|---|---|---|---|
| BTCUSDT 1h | 188 | -4.8% | -0.36 | -13.9% | 26.1% | 0.90 |
| ETHUSDT 1h | 179 | -19.8% | -2.35 | -25.0% | 22.4% | 0.58 |
Past results on historical data do not predict future returns.
Source Code
Edit in IDE| 1 | strategy "Volume-Confirmed Trend" { |
| 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 | /// Joins trends that volume confirms. Two things are measured: whether up bars carry the volume |
| 12 | /// (the correlation of signed returns with volume) and whether the trend average is sloping. A cross |
| 13 | /// of price over the average is taken only when the correlation agrees with its direction, which |
| 14 | /// filters out drifts that happen on thin, one-sided volume. |
| 15 | /// Entry: close crosses the Hull average with the return-volume correlation above (below) the level. |
| 16 | /// Exit: opposite cross or ATR trailing stop. Risk: 1 % per trade. |
| 17 | /// Method: rolling Pearson correlation of log returns and log volume. |
| 18 | use "viz/premium" as pr |
| 19 | hull_l = param.int(55, title = "Hull average", min = 5, max = 500, group = "Trend") |
| 20 | c_len = param.int(60, title = "Correlation window", min = 10, max = 1000, group = "Volume") |
| 21 | c_min = param.float(0.08, title = "Confirmation level", min = 0, max = 0.8, step = 0.01, group = "Volume") |
| 22 | stop_k = param.float(2.5, title = "Trailing stop (ATR)", min = 0.5, max = 8, step = 0.1, group = "Risk") |
| 23 | h = ta.hull(close, hull_l) |
| 24 | r = math.log(close / close[1]) |
| 25 | corr = stat.corr(r, math.log(math.max(volume, 1)), c_len) |
| 26 | a = ta.atr(20) |
| 27 | up_x = ta.cross_up(close, h) |
| 28 | dn_x = ta.cross_down(close, h) |
| 29 | long_sig = up_x and corr > c_min and h > h[1] |
| 30 | short_sig = dn_x and corr < -c_min and h < h[1] |
| 31 | if position.size == 0 and long_sig { |
| 32 | order.market("L", side.long) |
| 33 | exit.bracket("L exit", entry = "L", stop = close - stop_k * a, trail_offset = stop_k * a, trail_trigger = close) |
| 34 | } |
| 35 | if position.size == 0 and short_sig { |
| 36 | order.market("S", side.short) |
| 37 | exit.bracket("S exit", entry = "S", stop = close + stop_k * a, trail_offset = stop_k * a, trail_trigger = close) |
| 38 | } |
| 39 | if (position.side > 0 and dn_x) or (position.side < 0 and up_x) { exit.close_all() } |
| 40 | risk.max_drawdown(25) |
| 41 | render.line(h, "Hull average", color = corr > c_min ? color.emerald.300 : corr < -c_min ? color.rose.300 : color.slate.500, width = 2) |
| 42 | render.mark(long_sig, shape = shape.triangle_up, at = anchor.below_bar, color = color.emerald.300, size = 0.7, title = "Confirmed up") |
| 43 | render.mark(short_sig, shape = shape.triangle_down, at = anchor.above_bar, color = color.rose.300, size = 0.7, title = "Confirmed down") |
| 44 | persist t = draw.table.create(anchor.top_right, 4, 2) |
| 45 | if bar.is_last { |
| 46 | pr.heading(t, 2, "Volume-Confirmed Trend", "Strategy · return-volume correlation") |
| 47 | pr.row(t, 2, "Correlation", str.format("{:+.2f}", corr), corr > c_min ? pr.BULL : corr < -c_min ? pr.BEAR : pr.LABEL) |
| 48 | pr.row(t, 3, "Volume", corr > c_min ? "Buyers lead" : corr < -c_min ? "Sellers lead" : "Neutral", color.white) |
| 49 | } |
| 50 |
Reviews
No reviews yet. Be the first to review this listing.