Idea in brief
Anthony Crudele, an index futures trader with twenty years of experience, starts every trade by asking about the environment. There are three environments: consolidation, trend, mean reversion. Crudele identifies them with daily Bollinger Bands with a period of 20 and three standard deviations instead of the usual two. Once the environment is known, Crudele trades in one direction. Both directions are allowed only in consolidation.
Bands narrowing: consolidation, and moves out of the range come back more often. Flat bands start to diverge and price takes out a high: trend, longs only (shorts only when the expansion is downward). After a trend the bands converge: mean reversion, trades against the previous trend with a target in the middle of the bands.
Variant B comes from Kieran Duff, who runs a portfolio of 20-30 automated strategies on CFDs: the filter adds metrics up into a score and decides which signals to let through. Kieran did not name the weights or thresholds, so the scoring below is a Finetiq formalization.
Unlike in bollinger-squeeze, the bands here do not generate entries. They distribute permissions between breakout strategies and mean reversion strategies. The difference from zero-parameter-filters is the form: a three-state switch instead of yes or no.
Why it might work
Crudele came to this system after losses: Crudele was a contrarian, faded rallies and breakouts, and lost money when the market turned in 2000. Crudele sees the cause in not identifying the environment. The three deviations were chosen for indices: the NASDAQ breaks through two-deviation bands on an ordinary day. Crudele describes the benefit of the rule this way: it keeps the trader out of fading trends and out of breakouts inside a range.
Kieran solves the same problem for a portfolio. When ADX is rising, price is moving away from the averages and ATR is expanding, breakouts do well, and mean reversion strategies and shorts are better switched off. The filter only removes lower-probability signals, and Kieran admits that sometimes it will block a trade that would have won back yesterday's loss.
Neither author has a test of the classifier itself. Kieran's figures refer to Kieran's five-strategy portfolio on the in-sample period where Kieran first switched the filter on. Not all of Kieran's strategies have been added yet, and Kieran says the final output will look different.
Rules
Bands and features (author)
// daily bars, index futures ES, NQ, RTY
Mid = SMA(Close, 20)
SD = StdDev(Close, 20) // population
Upper = Mid + 3 * SD // author: 20 periods, 3 deviations
Lower = Mid - 3 * SD
Width = Upper - Lower
Outward = Upper > Upper[1] AND Lower < Lower[1] // author: bands point outward; Finetiq: both edges over one bar
Inward = Width < Width[1] AND Width[1] < Width[2] // author: bands converge; Finetiq: 2 bars in a row
Narrow = Width < SMA(Width, 50) // Finetiq: bands are squeezed
Environment classifier (author, thresholds Finetiq)
// Env persists between bars, initial value CONSOLIDATION
NewUp = Outward AND Close > Highest(High, 20)[1] // author: expansion and a new high; Finetiq: over 20 bars
NewDown = Outward AND Close < Lowest(Low, 20)[1]
IF NewUp AND Env <> TREND_UP
Env = TREND_UP; EpisodeStart = current bar // Finetiq: the episode start is set only when the environment changes
IF NewDown AND Env <> TREND_DOWN
Env = TREND_DOWN; EpisodeStart = current bar
// a new high within the same trend does not move EpisodeStart
IF Env IN (TREND_UP, TREND_DOWN) AND Inward // author: after a trend the bands converge
PeakUp = highest Upper since EpisodeStart // Finetiq: band peaks over the episode
PeakDown = lowest Lower since EpisodeStart
PrevTrend = Env
Env = MEAN_REV
IF Env = MEAN_REV AND (Narrow OR 50% target reached OR 10 bars without a new trend)
Env = CONSOLIDATION // author: the bands have contracted, this is consolidation; then wait, hands in pockets
// Finetiq: the 50% target and 10 bars as fallback conditions
Permissions by environment (author)
TREND_UP: longs only; shorts and fades are prohibited // author
TREND_DOWN: shorts only // author
CONSOLIDATION: both sides, at the edges of the range, not in the middle // author
a move out of the range will probably come back // author
Finetiq: breakout strategies switched off
MEAN_REV: trades against PrevTrend, size 0.5 // author: against the main trend with small
// size; Finetiq: 0.5
trades in the PrevTrend direction are prohibited // author: no longer wants to be long
Reversion levels and targets (author, construction Finetiq)
Crudele builds a Fibonacci grid not on price but on the bands: from the upper band peak to the lower band peak. Crudele's Beacon indicator draws it automatically. How the peaks are chosen is shown only on a whiteboard and on one chart, and below is our reading.
Range = PeakUp - PeakDown
// after TREND_UP: short
L30 = PeakUp - 0.30 * Range
L50 = PeakUp - 0.50 * Range
IF Env = MEAN_REV AND PrevTrend = TREND_UP AND Close < L30 // author: daily close below 30%
SELL SHORT AT NEXT BAR OPEN
Target = L50 // author: 50% target
IF Close > L30 THEN EXIT AT NEXT BAR OPEN // author: hold until the close gets back above
StopLoss = high of the bar where the trend reversed // author; Finetiq: episode high
// the author uses the 70% level to gauge the strength of the reversal, not for entry
// after TREND_DOWN, mirrored from PeakDown: close above 30%, target 50%
// target in a trend (author): the previous band peak, "unfinished business"
TrendTarget_Up = Highest(Upper, 60) before EpisodeStart // Finetiq: window 60
In a trend, Crudele manages exits with a VWAP anchored at the reversal bar and the 8, 21 and 34 averages, and sizes the position from the distance to the stop.
Variant B. Regime scoring (Kieran Duff, weights and thresholds Finetiq)
The metrics in Kieran's filter: ATR, SMA 50, SMA 200, ADX, the close of the last daily bar, the ATR of the current bar, the ATR percentile, a volume regime and a trend regime. The interview gives no formulas, weights or thresholds. For VIX, Kieran suggests not a threshold but the expansion over 2 days versus the average over 2 months, but Kieran has not built this module yet.
// daily values of the last closed bar
ATR14 = ATR(14); ADX14 = ADX(14) // Finetiq: periods
Dist = ABS(Close - SMA(Close, 50)) / ATR14
S1 = ADX14 > ADX14[5] // author: ADX rising; Finetiq: over 5 days
S2 = Dist > Dist[5] // author: price moving away from the averages
S3 = ATR14 > ATR14[5] // author: ATR expanding
S4 = PercentRank(ATR14, 250) >= 50 // author: ATR percentile; Finetiq: window and threshold
S5 = SMA(Volume, 10) > SMA(Volume, 50) // author: volume regime; Finetiq: comparison
TrendUp = Close > SMA(Close, 200) AND SMA(Close, 50) > SMA(Close, 200) // author: trend regime
TrendDown = Close < SMA(Close, 200) AND SMA(Close, 50) < SMA(Close, 200) // Finetiq: definition
Score = S1 + S2 + S3 + S4 + S5 // Finetiq: equal weights, from 0 to 5
IF Score >= 4 AND TrendUp THEN breakout longs; mean reversion and shorts off // author: the action; Finetiq: threshold 4
IF Score >= 4 AND TrendDown THEN breakout shorts; mean reversion off // Finetiq
IF Score >= 4 AND NOT TrendUp AND NOT TrendDown THEN breakouts both ways, size 0.5 // Finetiq
IF Score <= 1 THEN mean reversion strategies; breakout strategies off // Finetiq
IF Score IN (2, 3) THEN all strategies, size 0.5 // Finetiq
Plugging into cards in the base (Finetiq)
// example 1: prev-high-breakout-adx. Filter ADX(5) < 35, BUY STOP above the prior session high
Allowed_A = DailyADX < 35 // as in the card
Allowed_B = Allowed_A AND Env = TREND_UP // Crudele: breakouts only in a trend
Allowed_C = Allowed_A AND Env <> CONSOLIDATION // softer: blocked only in a range
// note the conflict: ADX(5) < 35 selects quiet days, TREND_UP requires expanding bands
// example 2: five-day-low-mr. Buying a 5-day low, exit above MA5
Allowed_MR = Env IN (CONSOLIDATION, TREND_UP) // buying a pullback does not contradict "long only"
OR (Env = MEAN_REV AND PrevTrend = TREND_DOWN) // reversion after a decline, size 0.5
// in TREND_DOWN and in MEAN_REV after a rally, purchases are prohibited
Parameters
| Parameter | Value | Source |
|---|---|---|
| Timeframe | daily | author |
| Bollinger Bands | SMA 20, 3 standard deviations | author |
| Bands outward | upper rises and lower falls over one bar | Finetiq |
| Breakout in a trend | close beyond the 20-day extreme | Finetiq |
| Bands converging | width falls 2 bars in a row | Finetiq |
| Bands squeezed | width below its SMA 50 | Finetiq |
| Reversion levels | 30, 50, 70% between band peaks | author |
| Reversion entry | daily close beyond the 30% level | author |
| Reversion target | 50%, exit on a close back beyond 30% | author |
| Size against the main trend | 0.5 | Finetiq (author: small) |
| Exit from MEAN_REV | bands squeezed (Narrow), 50% target or 10 bars | author (band squeeze), Finetiq (squeeze threshold, target, 10 bars) |
| Target in a trend | previous band peak, 60-bar window | author, window Finetiq |
| Variant B: metrics | ADX, ATR, ATR percentile, SMA 50 and 200, volume, trend | author |
| Variant B: periods, weights, thresholds | ADX 14, ATR 14, 5 and 250 days, scores 4 and 1 | Finetiq |
What to test
- Does the classifier separate the market. Label the ES and NQ history by environment and calculate for each one the average price change over 5 days, the share of 20-day extreme breakouts that continue, and the share of returns to Mid. If breakouts in TREND_UP continue no more often than in CONSOLIDATION, the classifier does not work.
- Three deviations versus two. The same classifier on 20/2 and 20/2.5: how often the environment changes, and the result. Crudele considers two deviations too tight for indices.
- Neighborhood of the Finetiq thresholds. Breakout over 10, 20 and 40 bars; convergence over 1, 2 and 3 bars; Narrow window of 30, 50 and 100. A jump in the result from a neighboring value means overfitting.
- Strategy with and without the filter. The three versions of
prev-high-breakout-adxfrom the example: how many trades the filter removed and what those trades were like. - The 30/50/70 levels. Entry beyond 30% versus 50% and versus entering immediately on Inward, a 50% target versus the current Mid.
- Kieran's scoring. Equal weights versus ADX alone and the ATR percentile alone. Choose thresholds on the in-sample only.
- Switching costs. How many times a year the environment changes. Switches on borderline bars generate trades that only pay the spread.
Platform notes
TradingView (Pine Script)
ta.bb(close, 20, 3)uses the population deviation, likeStdDevin EasyLanguage andiBandsin MT5, so the 30/50/70 levels will match.- Store the environment and band peaks in
varvariables and update them only on a closed bar. - For variant B, take ADX from
ta.dmi(14, 14), which uses Wilder smoothing. ATR percentile:ta.percentrank(atr, 250). - The ES daily bar in TradingView starts at 18:00 ET. Bands on the cash index and on the futures differ, so calculate them on the series you trade.
MultiCharts and TradeStation (EasyLanguage)
- It is simpler to calculate the bands explicitly:
Average(Close, 20) + 3 * StdDev(Close, 20).StdDevSis the sample deviation and gives wider bands. - For futures, the TradeStation daily bar closes at settlement, while the 1440-minute bar closes at the last trade. A close beyond the 30% level may fall on different days. Run the backtest and live trading on the same bar type.
AvgTrueRangeis a simple average of TR, while ATR in Pine uses Wilder smoothing. Features S2, S3 and S4 of variant B will fire on different days unless you calculate the Wilder version manually.- Copy the classifier into the code of every strategy it filters. That way, in the backtest all of them see the same prior-day value.
MetaTrader 5 (MQL5)
iBands(_Symbol, PERIOD_D1, 20, 0, 3, PRICE_CLOSE)gives bands on the population deviation. Take values from bar 1.- A CFD daily bar is built on the broker's server time. Short Sunday bars add extra closes to the 20-bar window and shift the bands.
- For variant B, use
iADXWilder, sinceiADXsmooths differently.iATRis a simple average of TR. - For CFDs, the volume regime is calculated from tick volume (
iTickVolume). Kieran trades CFDs exactly this way, but it measures the broker's quote activity, not traded volume.
Where the idea can break
- Crudele trades with discretion: targets at other people's levels, exits on VWAP and averages, options when the stop is wide, size based on the macro backdrop. A mechanical version does not reproduce this.
- Crudele names the hardest part: the transition after mean reversion, when it is unclear whether a consolidation or a new trend will follow. This is where Crudele gets hit most often, and this is where most of our thresholds are.
- The definitions of "bands outward" and "converging" and the choice of peaks for the grid are ours. Different readings will give different dates for environment changes.
- The video has no statistics, only whiteboard diagrams and one ES chart from 2025. The episode contains a lot of prop firm advertising.
- Kieran's figures come from the 2018-2019 in-sample, the first run of the filter, and not the whole portfolio. They say nothing about out-of-sample.
- A five-feature score with thresholds is easy to overfit. The author's weights are unknown, and our equal weights are only a starting point.