Builds a downtrend channel from a linear regression + standard-deviation bands.
Flags when price breaks out above the upper band, then retests that band within a window.
Measures the forward return after N bars from the retest and computes:
number of setups,
hit rate (% with positive forward return),
average forward return.
Paste into Studies → Create:
# Downtrend Breakout->Backtest Stats (4h-friendly)
# by Rich's request
input len = 60; # channel lookback bars
input stDevMult = 2.0; # channel width
input minDownSlope = -0.02; # slope threshold per bar (negative means downtrend)
input backtestWindow = 12; # bars allowed to retest after breakout
input tol = 0.002; # 0.2% proximity tolerance to touch
input fwdBars = 12; # measure return N bars after retest
input showMarkers = yes;
# --- Linear regression channel (mid +/− sd bands)
def lr = Inertia(close, len);
def slope = (lr - lr[1]); # per-bar slope
def resid = close - lr;
def sd = StDev(resid, len);
def upper = lr + stDevMult * sd;
def lower = lr - stDevMult * sd;
# --- Define a "downtrend channel" regime
def inDowntrend = slope < minDownSlope;
# --- Breakout: close crosses above upper band while in downtrend regime
def breakout = inDowntrend[1] and close[1] <= upper[1] and close > upper;
# --- Backtest: after breakout, price tags the upper band (now support) within window
def withinTol = AbsValue(low - upper) <= tol * upper;
def backtestCandidate = withinTol;
def barsSinceBO = if breakout then 0 else if barsSinceBO[1] >= 1000 then 1000 else barsSinceBO[1] + 1;
def validBacktest = backtestCandidate and barsSinceBO > 0 and barsSinceBO <= backtestWindow;
# --- Forward return measured fwdBars after the valid backtest close
def ret = if validBacktest then (close[fwdBars] / close - 1) else Double.NaN;
# --- Accumulators
def nSetups = CompoundValue(1, nSetups[1] + (if validBacktest then 1 else 0), 0);
def sumRet = CompoundValue(1, sumRet[1] + (if validBacktest then ret else 0), 0);
def posHits = CompoundValue(1, posHits[1] + (if validBacktest and ret > 0 then 1 else 0), 0);
def hitRate = if nSetups > 0 then posHits / nSetups else Double.NaN;
def avgRet = if nSetups > 0 then sumRet / nSetups else Double.NaN;
# --- Visuals
plot UpperBand = upper; UpperBand.SetDefaultColor(Color.GRAY);
plot MidLine = lr; MidLine.SetDefaultColor(Color.DARK_GRAY);
plot LowerBand = lower; LowerBand.SetDefaultColor(Color.GRAY);
# Mark breakout and backtest
plot BO = showMarkers and breakout;
BO.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
BO.SetDefaultColor(Color.LIGHT_GREEN);
plot BT = showMarkers and validBacktest;
BT.SetPaintingStrategy(PaintingStrategy.POINTS);
BT.SetDefaultColor(Color.CYAN);
BT.SetLineWeight(3);
# Labels with live stats
AddLabel(yes, "Setups: " + nSetups, Color.WHITE);
AddLabel(nSetups > 0, "Hit Rate (" + fwdBars + " bars): " + AsPercent(hitRate),
if hitRate >= 0.5 then Color.GREEN else Color.RED);
AddLabel(nSetups > 0, "Avg Ret (" + fwdBars + " bars): " + AsPercent(avgRet),
if avgRet >= 0 then Color.GREEN else Color.RED);
How to use (for your 4-hour chart)
Keep your 4h / 180D view.
Start with defaults: len=60, stDevMult=2, backtestWindow=12, fwdBars=12, minDownSlope=-0.02.
You’ll see:
Green arrows at breakouts,
Cyan dots where the retest happened,
Live labels with # of setups, hit rate, average forward return measured fwdBars bars after the retest.
Tips
Want stricter downtrends? Make minDownSlope a larger negative (e.g., -0.05).
If you get too few events, widen tolerance (tol=0.003) or the retest window (backtestWindow=20).
For quicker confirmation stats, shorten fwdBars to 6–8; for swing confirmation, try 16–20.
Run this on CRWV first, then you can drop it on other tickers to see how reliable the pattern is across your universe. If you want, I can give you a scanner version that finds symbols currently completing the retest today.
Search This Blog
Friday, August 15, 2025
Results After Backtest of a Downchannel
Subscribe to:
Post Comments (Atom)
TTM Squeeze Scan on Stock Charts
Scanner for TTM squeeze , good daily liquidity, over $8. Detailed explanation at the bottom. ------------------------ [type is stock] a...
-
Submitted by a reader. Truth be told, the story itself and modern manifestations of "Phoenicians" fascinate me and, based on hi...
-
After reviewing the photo, do you come to the only conclusion that I come to: Directed Energy Weapons? Is there any other possible situation...
No comments:
Post a Comment