Sequential-Engine (Consolidation→Volume→Breakout) की Precise-Definition Context: User-की-genuine-insight (\"Consolidation-के-बाद-genuinely-real-game-शुरू-होता-है, Volume-important-role\") को-genuinely-test-करने-के-लिए, हम-एक-नई-Roadmap-genuinely-design-क
1) Consolidation: same‑day vs lookback window
- Consolidation is structurally a multi‑day phenomenon; encoding it as a single‑day flag on the breakout bar under‑represents the pattern you are actually trading.
- If you only check `get_atr_compression_status()` on the breakout day, you’ll systematically miss cases where:
- ATR was compressed for many days,
- then ATR started expanding 1–2 days before the actual price breakout,
- so C(t) on the breakout day becomes 0 even though there was a valid base.
More defensible definition (recommended):
Let
- `C(t) = get_atr_compression_status(t)` ∈ {0,1} (point‑in‑time, already validated).
- Breakout day = `T` (however you already define breakout).
Define a pre‑breakout consolidation indicator based on a window:
- Choose a lookback window L (e.g., 10 trading days) and a minimum count m (e.g., 3 days).
- Define
`PC(T) = 1 if Σ_{i=T-L}^{T-1} C(i) ≥ m, else 0`
Interpretation: “There was a genuine ATR‑compression regime sometime in the last L days before breakout, with at least m compressed bars.”
You can vary L and m (examples, for daily data):
- Conservative: L = 20, m = 5
- Tighter: L = 10, m = 3
This way you are:
- Still purely point‑in‑time (PC(T) only uses information up to T‑1).
- Encoding consolidation as a period, not a single event.
- Robust to the typical pattern “compression → 1–2 expansion candles → breakout”.
Checking C(T) additionally (same day) is optional. If you want, you can keep both:
- `C_same(T) = C(T)`
- `PC(T)` as above
and later see empirically whether “compression still present on breakout day” adds incremental edge over “compression present at any point in last L days”.
2) Volume spike threshold: 1.5× 20‑day average vs alternatives
Your proposal: Volume(T) ≥ 1.5 × 20‑day average volume.
This is a reasonable and defensible starting heuristic, and close to what many discretionary traders implicitly use (1.3–2.0× some 20–50 day average). There is no universal “literature standard” like “must be 2×”; practitioners mostly treat it as a tunable hyperparameter.
To make it statistically and cross‑sectionally robust, I would suggest:
2.1. Keep the 20‑day window, but treat the multiplier as a hyperparameter
- Start with k ∈ {1.2, 1.5, 2.0}.
- Define: `V_spike_k(T) = 1 if Vol(T) ≥ k × AvgVol20(T-1)` else 0.
- Measure forward‑return distributions and hit‑rate conditional on k.
- Pick k that gives the best risk‑adjusted spread between “spike” vs “no spike”, not just best raw return.
2.2. Consider percentile / z‑score style definitions
Because volume is heavy‑tailed and regime‑dependent, two more robust constructions are:
- Percentile based (recommended for research):
- Compute, for each stock, the empirical distribution of daily volume over a long window (e.g., last 252 trading days).
- Define a spike as:
`V_spike(T) = 1 if Volume(T) ≥ P_past(Volume ≥ p-th percentile)`
with p e.g. 80, 85, 90.
- This automatically adapts to each stock’s baseline liquidity and volatility of volume.
- Z‑score on log‑volume:
- `z(T) = (logVol(T) – mean_logVol_lookback) / sd_logVol_lookback`
- `V_spike(T) = 1 if z(T) ≥ z0`, with z0 ~ 1.0–1.5 for a starting point.
Either of these is more “statistically clean” than a fixed 1.5×, but 1.5× / 20‑days is absolutely fine as Version‑1, provided you treat it as a parameter to be tested, not as a truth.
2.3. India‑specific practical tweak
For Indian equities, especially small/micro caps:
- A mere 1.5× average volume on a very illiquid stock may still be noise.
- Add an absolute liquidity filter: e.g.,
- minimum daily turnover (₹ value) threshold, and/or
- minimum median turnover over last 3 months.
This ensures your “volume spike” is institutionally meaningful, not just a few retail trades.
3) Group definition and confounds before implementation
Your proposed groups on breakout day T:
- A: ATR compression (yes) + volume spike (yes)
- B: only compression (yes)
- C: neither
Structurally, with two binary variables (Compression, Volume), the natural design is 2×2 = 4 cells:
- Compression = 1, Volume = 1 → A
- Compression = 1, Volume = 0 → B
- Compression = 0, Volume = 1 → (you are currently missing this group)
- Compression = 0, Volume = 0 → C
I strongly recommend you explicitly include the fourth cell, say:
- D: only volume spike (no prior compression)
Reason: if you exclude (no compression, high volume) from explicit analysis, you cannot cleanly separate:
- Effect of “consolidation only”
- Effect of “volume spike only”
- Interaction of “consolidation AND volume spike”
Including D allows you to do simple but powerful modelling, for example:
- Cross‑sectional regression on breakout days:
`fwd_return(T) = α + β1 PC(T) + β2 V_spike(T) + β3 [PC(T)V_spike(T)] + controls + ε`
Where β1, β2, β3 tell you exactly what consolidation, volume, and their interaction contribute, controlling for confounds.
Key confounds you should control / stratify before going live:
a) Market regime / index trend
Breakout behaviour is heavily regime‑dependent. At minimum:
- Define regime using a broad index (e.g., NIFTY 50 / NIFTY 500):
- Up‑trend vs down‑trend: index close above vs below its 200‑day moving average.
- Or low‑vol vs high‑vol: realized volatility (e.g., 20‑day ATR/price) of index above vs below median.
- Either:
- run separate analyses for each regime, or
- include regime dummies in regression (`Regime_up`, `Regime_high_vol`).
Without this, you risk “discovering” patterns that are actually just bull‑market behaviour.
b) Sector / industry effects
Different sectors naturally have different volatility and volume signatures (e.g., banks vs IT vs small‑cap manufacturing).
- Include sector fixed effects (sector dummies) if you use regression; or
- At least run the Group A/B/C/D analysis separately for a few large sectors to see if effects are stable.
c) Size / liquidity
- Small‑caps and micro‑caps in India can show huge “breakout” moves that are not scalable or repeatable.
- Bucket stocks by market cap and/or typical turnover (e.g., quartiles) and confirm that your pattern is not driven only by illiquid names.
d) Event‑driven days
Volume spikes and breakouts around:
- results announcements,
- major corporate actions,
- index addition/removal,
- block deals
may obey a different return process than technical bases.
Two options:
- Exclude event windows (e.g., earnings ±1 day) from the initial research, or
- Tag them and run results “with” and “without event days” to see robustness.
e) Basic data hygiene
- Avoid survivorship bias (include delisted names in backtest).
- Make sure `get_atr_compression_status()` itself is computed strictly point‑in‑time with no look‑ahead.
- Stick to a fixed universe definition at each point in time (e.g., top X by free‑float market cap, or NIFTY 500 membership as of that date).
4) Suggested precise sequential engine, putting it together
On daily data, one clear, implementable structure could be:
1. Pre‑compute states each day t for each stock:
- `C(t) = get_atr_compression_status(t)` (existing).
- `PC(t) = 1 if Σ_{i=t-L}^{t-1} C(i) ≥ m, else 0` (pre‑breakout consolidation, with chosen L,m).
- `V_spike(t) = 1 if Volume(t) ≥ k × AvgVol20(t-1)` (or percentile/z‑score variant).
2. Define breakout B(t):
- For example: `B(t) = 1 if Close(t) > max(High(t-N … t-1)) * (1+ε)` and any other filters you prefer.
3. On each breakout day T (B(T)=1), classify into 4 groups:
- Group A: `PC(T)=1 AND V_spike(T)=1`
- Group B: `PC(T)=1 AND V_spike(T)=0`
- Group C: `PC(T)=0 AND V_spike(T)=0`
- Group D: `PC(T)=0 AND V_spike(T)=1`
4. Evaluate forward outcomes:
- Measure returns and drawdowns over horizons H (e.g., 5, 10, 20 days) per group.
- Run cross‑sectional regressions with controls for regime, sector, size/liquidity to quantify independent and interaction effects.
This framework:
- Treats consolidation as a period state, not a one‑day event.
- Uses volume spike thresholds that are parameterized and testable.
- Explicitly separates the four logical combinations of (consolidation, volume).
- Allows you to add confounds cleanly without changing the core engine.
If you have any further queries, please connect with us on 022-6290-10141 (Timings : 09.00 AM to 05.00 PM) or you can email us on info@cniinfoxchange.com