Appearance
Personalize your experience
Cornish-Fisher Tail Fade
FreeFades rejections of fat-tail-adjusted 99 % quantiles
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
Fades moves that reach the fat-tail-adjusted 99 % quantile and close back inside it. The quantiles come from a Cornish-Fisher expansion of the rolling return distribution (skew and excess kurtosis), so the bands widen when tails are heavy and the fade only triggers on moves that are extreme even for this market. Entry: the bar trades through the 99 % band and closes back inside the 95 % band (rejection). Exit: target at the previous close (the distribution centre), stop beyond the bar's extreme, time stop after `hold` bars. Risk: 1 % per trade. Method: Cornish and Fisher (1938).
Settings
Return window: 250
Maximum bars held: 12
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
- ▸ the bar trades through the 99 % band and closes back inside the 95 % band (rejection)
Exit Conditions
- ▸ target at the previous close (the distribution centre), stop beyond the bar's extreme, time stop after `hold` bars
Measured backtest
BTCUSDT 1h (Binance), 2025-11-01 to 2026-11-01 · backtest engine, script costs included
-0.5%
Return
-0.07
Sharpe
-5.9%
Max DD
58.3%
Win Rate
36
Trades
| Market | Trades | Return | Sharpe | Max DD | Win rate | Profit factor |
|---|---|---|---|---|---|---|
| BTCUSDT 1h | 36 | -0.5% | -0.07 | -5.9% | 58.3% | 0.97 |
| ETHUSDT 1h | 33 | 2.8% | 0.65 | -2.3% | 60.6% | 1.27 |
Past results on historical data do not predict future returns.
Source Code
Edit in IDE| 1 | strategy "Cornish-Fisher Tail Fade" { |
| 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 | /// Fades moves that reach the fat-tail-adjusted 99 % quantile and close back inside it. The |
| 12 | /// quantiles come from a Cornish-Fisher expansion of the rolling return distribution (skew and |
| 13 | /// excess kurtosis), so the bands widen when tails are heavy and the fade only triggers on moves |
| 14 | /// that are extreme even for this market. |
| 15 | /// Entry: the bar trades through the 99 % band and closes back inside the 95 % band (rejection). |
| 16 | /// Exit: target at the previous close (the distribution centre), stop beyond the bar's extreme, |
| 17 | /// time stop after `hold` bars. Risk: 1 % per trade. Method: Cornish and Fisher (1938). |
| 18 | use "viz/premium" as pr |
| 19 | len = param.int(250, title = "Return window", min = 30, max = 3000, group = "Distribution") |
| 20 | hold = param.int(12, title = "Maximum bars held", min = 1, max = 200, group = "Exit") |
| 21 | r = math.log(close / close[1]) |
| 22 | mu = ta.sma(r, len) |
| 23 | sd = stat.stdev(r, len) |
| 24 | S = math.clamp(stat.skew(r, len), -3, 3) |
| 25 | K = math.clamp(stat.kurtosis(r, len), -2, 20) |
| 26 | fn cf(z: float, s: float, k: float) -> float { |
| 27 | return z + (z * z - 1) * s / 6 + (z * z * z - 3 * z) * k / 24 - (2 * z * z * z - 5 * z) * s * s / 36 |
| 28 | } |
| 29 | zu99 = cf(2.326, S, K) |
| 30 | zd99 = cf(-2.326, S, K) |
| 31 | zu95 = cf(1.645, S, K) |
| 32 | zd95 = cf(-1.645, S, K) |
| 33 | u99 = close[1] * math.exp(mu[1] + zu99[1] * sd[1]) |
| 34 | d99 = close[1] * math.exp(mu[1] + zd99[1] * sd[1]) |
| 35 | u95 = close[1] * math.exp(mu[1] + zu95[1] * sd[1]) |
| 36 | d95 = close[1] * math.exp(mu[1] + zd95[1] * sd[1]) |
| 37 | flat = position.size == 0 |
| 38 | rej_lo = low < d99 and close > d95 |
| 39 | rej_hi = high > u99 and close < u95 |
| 40 | if flat and rej_lo { |
| 41 | order.market("L", side.long) |
| 42 | exit.bracket("L exit", entry = "L", stop = low - 0.25 * (high - low), target = close + (close[1] - low) * 0.8) |
| 43 | } |
| 44 | if flat and rej_hi { |
| 45 | order.market("S", side.short) |
| 46 | exit.bracket("S exit", entry = "S", stop = high + 0.25 * (high - low), target = close - (high - close[1]) * 0.8) |
| 47 | } |
| 48 | if position.size != 0 and position.bars_held >= hold { exit.close_all() } |
| 49 | risk.max_drawdown(25) |
| 50 | p1 = render.line(u99, "Upper 99 %", color = color.translucent(color.orange.300, 40), width = 1) |
| 51 | p2 = render.line(u95, "Upper 95 %", color = color.transparent, width = 0) |
| 52 | p3 = render.line(d95, "Lower 95 %", color = color.transparent, width = 0) |
| 53 | p4 = render.line(d99, "Lower 99 %", color = color.translucent(color.sky.300, 40), width = 1) |
| 54 | render.band(p1, p2, upper_color = color.ramp(K[1], 0, 8, "inferno"), lower_color = color.transparent, opacity = 0.5, title = "Upper tail") |
| 55 | render.band(p3, p4, upper_color = color.transparent, lower_color = color.ramp(K[1], 0, 8, "inferno"), opacity = 0.5, title = "Lower tail") |
| 56 | render.mark(rej_lo, shape = shape.triangle_up, at = anchor.below_bar, color = color.sky.300, size = 0.7, title = "Lower tail rejection") |
| 57 | render.mark(rej_hi, shape = shape.triangle_down, at = anchor.above_bar, color = color.orange.300, size = 0.7, title = "Upper tail rejection") |
| 58 | persist t = draw.table.create(anchor.top_right, 4, 2) |
| 59 | if bar.is_last { |
| 60 | pr.heading(t, 2, "Cornish-Fisher Tail Fade", "Strategy · modified VaR rejection") |
| 61 | pr.row(t, 2, "Excess kurtosis", str.format("{:.2f}", K), K > 3 ? pr.WARN : color.white) |
| 62 | pr.row(t, 3, "Skewness", str.format("{:+.2f}", S), color.white) |
| 63 | } |
| 64 |
Reviews
No reviews yet. Be the first to review this listing.