Module 8 Companion — Low-Timeframe Lab Experiments
Part III · Intraday Design, Alpha & Playbooks · Companion to Module 8 Prerequisites: M7, M8, M5, M22, M23
Overview
The core module built the testing laboratory: a bar-based, spread-deducted replay engine on M1, M5, and M15 where signals on bar t close fill at bar t+1 open, ambiguous same-bar exits resolve stop-first, and every position is forced flat before the session close.
This companion stocks the lab with three structured experiments designed to answer one central question: Is this specific intraday setup viable after spreads and fees, or should it be stepped slower, restricted to liquid hours, or rejected?
None of these experiments claims to prove alpha. Each is an empirical baseline audit with preregistered cost ceilings, explicit metrics, and objective revise/reject criteria. Subsequent strategy modules (M10–M12) inherit whichever baseline survives.
| Experiment | Core Question | Target Lane & Clock | Primary Gate |
|---|---|---|---|
| E1 — Donchian/ATR Breakout Baseline | Does a simple range-expansion control clear spreads and ambiguous-bar penalties? | One commodity ETP (RTH) + one BTC/ETH perp (UTC synthetic) | Spread-to-ATR ≤ 15%; Cost-to-Target ≤ 10%; ambiguous share < 5% |
| E2 — Bollinger/VWAP Reversion Baseline | Does a statistical-stretch control mean-revert net of costs, or does it merely churn spreads? | Same two lanes across eligible session hours | Same cost gates plus session VWAP stretch and non-trending ADX filter |
| E3 — Sensitivity & HTF-Gated Atlas | Is strategy profitability a broad parameter plateau or a fragile spike, and does an HTF gate earn its complexity? | Same lanes at winning timeframe; hourly atlas + H1 gate | Parameter plateau breadth, survival under p90 spread stress, gated net lift |
💡 The Audit Ledger Analogy: A baseline is a ruler, not a forecast. It measures whether the market’s gross wage (ATR) comfortably exceeds the broker’s toll (spread + fees) under realistic execution constraints.
📌 Data Contract: All experiments use OHLCV + spread data only. Technical calculations are deterministic functions of bar data. Signals on bar
tclose execute at bart+1open. Ambiguous bars resolve stop-first. Positions flatten before session end. Completed H1/H4/D1 bars serve as causal context only.
How It Works
The three experiments follow a coordinated evaluation pipeline.
E1 — The Breakout Baseline
We calculate ATR and Donchian channels on completed M5 bars. After filtering for Spread-to-ATR and Cost-to-Target ceilings, the breakout signal is replayed through our conservative engine: fill at next-bar open, deduct full spreads, resolve ambiguous exits stop-first, and force flatten at session end. We report net expectancy, ambiguous-bar share, and performance under p90 spread stress.
E2 — The Reversion Baseline
Using the same execution contract, we evaluate a statistical mean-reversion setup: entry occurs when price stretches beyond Bollinger Bands and session VWAP during non-trending regimes (low ADX). Profit targets aim for a reversion to the mean (VWAP or band midline). Because reversion targets are typically smaller than breakout targets, this baseline is highly sensitive to transaction friction.
E3 — Sensitivity & Causal HTF Audit
We sweep parameters (lookbacks, ATR multipliers, RSI thresholds) across E1 and E2 to verify that profitability exists across a broad parameter plateau rather than an isolated spike. We then add a completed H1 trend gate and measure whether the gate improves net return per session after accounting for reduced trade opportunity.
Figure: The Module 8 experimental workflow. E1 and E2 establish baseline performance, which E3 audits through parameter sweeps, cost stress, and higher-timeframe gating.
flowchart TD
data["OHLCV + spread<br/>M1/M5/M15 completed + H1/H4/D1 releases"] --> e1["E1 Breakout Baseline<br/>Donchian/ATR on M5"]
data --> e2["E2 Reversion Baseline<br/>BB/Keltner/RSI/VWAP on M5"]
e1 -->|"frozen trigger + gates"| e3["E3 Sensitivity & HTF-Gated Atlas<br/>plateau + p90 stress + gate ablation"]
e2 --> e3
e3 --> decision{"Plateau, net after<br/>p90, gated vs ungated?"}
decision -->|"pass"| carry["Carry frontier + clock + gates<br/>to M10–M12 as baseline"]
decision -->|"revise"| narrow["Revise: narrow clock<br/>or step to M15 or add HTF gate"]
decision -->|"reject"| reject["Reject horizon on lane<br/>document & stop spend"]
classDef data fill:#e8f0fe,stroke:#4a86e8
classDef process fill:#f3f3f3,stroke:#888
classDef decision fill:#fff4d6,stroke:#d6a300
classDef risk fill:#fde8e8,stroke:#c0392b
classDef ok fill:#e6f4ea,stroke:#2e7d32
class data data
class e1,e2,e3,narrow process
class decision decision
class reject risk
class carry okStrategy Rules
Each experiment follows our standardized nine-point protocol.
E1 — Donchian/ATR Breakout Baseline (M5 Control)
1. Market, Timeframe, and Data Assumptions
- Lanes: One commodity ETP (GLD physical trust or PDBC futures pool) on RTH and one BTC/ETH linear perpetual on an explicit UTC synthetic session (00:00–23:50 UTC).
- Timeframe: Primary replay on M5 (M1 and M15 evaluated in the frontier scan).
- Data: Clean OHLCV + timestamped spread per bar.
2. Mechanics vs. Testable Hypothesis
- Mechanics: Intraday share creation/redemption SEC ETF bulletin, futures roll yield Fidelity on contango/backwardation, and perpetual funding rates Coinbase perpetual funding dictate product friction.
- Hypothesis: An M5 Donchian breakout setup (lookback $N \in [15, 30]$) achieves positive net expectancy after deducting full spreads and fees under purged walk-forward validation, with ambiguous trades accounting for less than 5% of total volume.
3. Required Indicators & Calculations
- ATR(14) via exponential moving average.
- 20-bar Donchian Channel (
high.shift(1).rolling(20).max()). - ADX(14) trend-strength filter.
- Feasibility ratios:
Spread ÷ ATRandCost ÷ Target.
4. Causal HTF Context & Trigger
- Baseline scan is context-free.
- Signals evaluate on the close of bar
tand execute at the open of bart+1.
5. Entry, Stop, Target, Time Stop, and Forced Flatten
- Long Entry:
close[t] > donchian_high[t] * 1.0005withADX(14) > 18and cost gates passing. - Stop Loss:
entry_price - (1.2 × ATR). - Profit Target:
entry_price + (1.0 × ATR). - Time Stop: 16 bars (80 minutes on M5).
- Forced Flatten: Mandatory exit at the final eligible bar of the session. Zero overnight positions.
6. Cost Filters & Conservative Execution
- Cost Ceilings: Spread-to-ATR ≤ 15%; Cost-to-Target ≤ 10%.
- Path Ambiguity: If a bar touches both stop and target, resolve as stop-first (worst case).
7. Sizing & Risk Limits
- Sizing fixed at 1 risk unit (e.g., 0.5% equity per trade). Standard session loss caps apply from M23.
8. ML Extension (Walk-Forward Meta-Filter)
- Train a Logistic Regression classifier on rolling chronological folds to predict trade profitability using trailing spread percentiles, ADX levels, and cyclical hour encodings.
9. Failure Modes & Rejection Criteria
- Ambiguous Trade Dependency: Profitability vanishes when ambiguous bars resolve stop-first. Verdict: Reject baseline.
- Cost Collapse: Net return turns negative under p90 spread stress. Verdict: Revise trading hours or step to M15.
E2 — Bollinger / Keltner / RSI / VWAP Reversion Baseline (M5 Control)
1. Market, Timeframe, and Data Assumptions
- Same lanes and session clocks as E1. Primary replay on M5.
- Cumulative session VWAP resets strictly at the session open (09:30 ET for ETPs, 00:00 UTC for crypto).
2. Mechanics vs. Testable Hypothesis
- Mechanics: Intraday price extremes often mean-revert toward volume-weighted benchmarks during non-trending regimes Volatility Box on Keltner vs Bollinger.
- Hypothesis: Fading price excursions beyond 2 standard deviations from 20 SMA with oversold RSI and VWAP divergence produces positive net expectancy after spreads during non-trending periods (
ADX < 20).
3. Required Indicators & Calculations
- 20-period Bollinger Bands ($\pm 2.0 \text{ SD}$).
- 14-period Wilder RSI.
- Cumulative Session VWAP.
- 14-period ADX.
4. Causal HTF Context & Trigger
- Baseline operates intraday without HTF gating. Signal forms on bar
tclose; fills at bart+1open.
5. Entry, Stop, Target, Time Stop, and Forced Flatten
- Long Entry:
close[t] < bb_lower[t]andclose[t] < session_vwap * 0.998withRSI(14) < 30,ADX(14) < 20, and cost gates passing. - Stop Loss:
entry_price - (1.2 × ATR). - Profit Target: Reversion to cumulative session VWAP or Bollinger midline.
- Time Stop: 12 bars (60 minutes on M5).
- Forced Flatten: Unconditional exit at session close.
6. Cost Filters & Execution
- Strict enforcement of
Cost-to-Target ≤ 10%. Reversion setups with tight targets are immediately blocked if spreads widen.
7. Sizing & Risk
- Standard risk limits. Sizing scales inversely with stop distance.
8. ML Extension (Regime-Gated Reversion)
- Fit a 2-state Gaussian Mixture Model (GMM) on standardized ATR and ADX to restrict mean-reversion trades to low-trend, high-liquidity regimes.
9. Failure Modes & Rejection Criteria
- Trend Bleed: Fading a strong directional breakout. Corrective rule: Enforce
ADX < 20filter. - Rejection Trigger: Reject if net return after spread deduction is negative across walk-forward test folds.
E3 — Parameter Sensitivity & Causal HTF-Gated Atlas
1. Market, Timeframe, and Data Assumptions
- Evaluates surviving baselines from E1 and E2 on the winning timeframe.
- Adds completed H1 bars joined causally at their close timestamp.
2. Mechanics vs. Testable Hypothesis
- Mechanics: Robust quantitative edges display smooth parameter plateaus. Fragile curve-fits produce isolated performance spikes.
- Hypothesis: Surviving baseline profitability persists across neighboring parameter values under p90 spread stress, and adding an H1 20 EMA trend gate increases net return per session.
3. Required Indicators & Calculations
- Parameter grid sweeps across Donchian lookback ($N \in {15, 20, 25, 30}$), Bollinger multipliers ($z \in {1.8, 2.0, 2.2}$), and ATR stop multiples ($k \in {1.0, 1.2, 1.5}$).
- Completed H1 20 EMA slope.
4. Causal Synchronization
- An H1 bar closing at 10:00 is joined to M5 bars starting at the 10:05 open. The forming 10:00–11:00 bar is invisible.
5. Execution & Flatten Contract
- Standard contract: Fill at next-bar open; worst-case ambiguous resolution; mandatory session flatten.
6. Cost Filters & Stress Testing
- Every parameter combination is evaluated under both median spread and p90 spread stress.
7. Sizing & Risk
- Standard sizing constitution. Sizing is frozen across parameter sweeps.
8. ML Extension (Gate Selection Bake-Off)
- Compare a deterministic H1 trend gate against a walk-forward Logistic Regression meta-filter on identical out-of-sample folds.
9. Failure Modes & Rejection Criteria
- Single-Cell Spike: Profitability exists at only one specific parameter setting (e.g., lookback 20 works, but 19 and 21 fail). Verdict: Reject as overfit.
- Rejection Trigger: Reject the HTF gate if it reduces net session P&L compared to the ungated baseline.
Building It In Python
Below is the complete Polars implementation for E1, E2, and E3.
1. Intuition: Shared Data Preparation Pipeline
We build a unified feature engineering pipeline that computes all technical indicators causally.
# Shared laboratory preparation pipeline in Polars
# Q: How do we construct clean, causal features for all three experiments?
import polars as pl
def prepare_lab_dataset(raw_m1: pl.DataFrame, timeframe: str = "5m") -> pl.DataFrame:
# 1. Resample to target timeframe on completed bars
resampled = (
raw_m1.group_by_dynamic("timestamp", every=timeframe)
.agg([
pl.first("open").alias("open"),
pl.max("high").alias("high"),
pl.min("low").alias("low"),
pl.last("close").alias("close"),
pl.sum("volume").alias("volume"),
pl.mean("spread").alias("spread"),
pl.first("session_id").alias("session_id"),
pl.last("is_final_bar").alias("is_final_bar"),
])
.sort("timestamp")
)
# 2. Average True Range
prev_close = resampled["close"].shift(1)
tr = pl.max_horizontal([
resampled["high"] - resampled["low"],
(resampled["high"] - prev_close).abs(),
(resampled["low"] - prev_close).abs(),
])
atr14 = tr.ewm_mean(span=14, adjust=False).alias("atr_14")
# 3. Donchian Channels (shifted by 1 bar)
don_high = resampled["high"].shift(1).rolling(20).max().alias("don_high")
don_low = resampled["low"].shift(1).rolling(20).min().alias("don_low")
# 4. Bollinger Bands (20 SMA +/- 2 SD)
sma20 = resampled["close"].rolling(20).mean()
sd20 = resampled["close"].rolling(20).std()
bb_lower = (sma20 - 2.0 * sd20).alias("bb_lower")
bb_upper = (sma20 + 2.0 * sd20).alias("bb_upper")
# 5. Session VWAP
tp = (resampled["high"] + resampled["low"] + resampled["close"]) / 3
cum_pv = (tp * resampled["volume"]).cum_sum().over("session_id")
cum_vol = resampled["volume"].cum_sum().over("session_id")
vwap = (cum_pv / (cum_vol + 1e-10)).alias("session_vwap")
# 6. Wilder RSI(14)
delta = resampled["close"].diff()
gain = delta.clip(0, None).ewm_mean(alpha=1/14, adjust=False)
loss = (-delta.clip(None, 0)).ewm_mean(alpha=1/14, adjust=False)
rsi14 = (100 - (100 / (1 + (gain / (loss + 1e-10))))).alias("rsi_14")
return resampled.with_columns([atr14, don_high, don_low, bb_lower, bb_upper, vwap, rsi14])
2. Intuition: Generate E1 & E2 Signals
We generate breakout and reversion signals and enforce feasibility cost gates.
# Signal generation with cost filters
def generate_signals(frame: pl.DataFrame) -> pl.DataFrame:
# Cost gates
s2atr = frame["spread"] / frame["atr_14"]
c2t = frame["spread"] / (0.9 * frame["atr_14"])
cost_pass = (s2atr <= 0.15) & (c2t <= 0.10)
# E1 Breakout Signal
sig_breakout = (frame["close"] > frame["don_high"] * 1.0005) & cost_pass
# E2 Reversion Signal
sig_reversion = (
(frame["close"] < frame["bb_lower"]) &
(frame["close"] < frame["session_vwap"] * 0.998) &
(frame["rsi_14"] < 30) &
cost_pass
)
return frame.with_columns([
s2atr.alias("spread_to_atr"),
c2t.alias("cost_to_target"),
sig_breakout.alias("sig_breakout"),
sig_reversion.alias("sig_reversion"),
])
3. Intuition: Conservative Bar-Replay Engine
We execute trades at next-bar open, deduct full spreads, resolve ambiguous exits stop-first, and force flatten at session end.
# Conservative execution engine
def execute_conservative_replay(
frame: pl.DataFrame,
signal_col: str,
k_stop: float = 1.2,
k_target: float = 1.0,
max_hold_bars: int = 16
) -> pl.DataFrame:
records = frame.to_dicts()
trades = []
in_trade = False
entry_price = 0.0
stop_price = 0.0
target_price = 0.0
entry_bar = 0
for i in range(len(records) - 1):
curr = records[i]
nxt = records[i+1]
# Open new trade (Signal on t -> Fill on t+1 open)
if not in_trade and curr[signal_col] and not curr["is_final_bar"]:
in_trade = True
entry_price = nxt["open"] + 0.5 * nxt["spread"]
atr = curr["atr_14"]
stop_price = entry_price - (k_stop * atr)
target_price = entry_price + (k_target * atr)
entry_bar = i + 1
continue
# Manage active trade
if in_trade:
duration = i - entry_bar + 1
hit_stop = curr["low"] <= stop_price
hit_target = curr["high"] >= target_price
# Stop-First Ambiguous Resolution
if hit_stop and hit_target:
exit_price = stop_price - 0.5 * curr["spread"]
trades.append({"entry": entry_price, "exit": exit_price, "net": exit_price - entry_price, "type": "ambig_stop", "hour": curr["timestamp"].hour})
in_trade = False
elif hit_stop:
exit_price = stop_price - 0.5 * curr["spread"]
trades.append({"entry": entry_price, "exit": exit_price, "net": exit_price - entry_price, "type": "stop", "hour": curr["timestamp"].hour})
in_trade = False
elif hit_target:
exit_price = target_price - 0.5 * curr["spread"]
trades.append({"entry": entry_price, "exit": exit_price, "net": exit_price - entry_price, "type": "target", "hour": curr["timestamp"].hour})
in_trade = False
elif duration >= max_hold_bars or curr["is_final_bar"]:
exit_price = curr["close"] - 0.5 * curr["spread"]
trades.append({"entry": entry_price, "exit": exit_price, "net": exit_price - entry_price, "type": "flatten", "hour": curr["timestamp"].hour})
in_trade = False
return pl.DataFrame(trades)
4. Intuition: Parameter Sweep & Stress Audit (E3)
We evaluate parameter stability across neighbor values under normal and p90 spread stress.
# Parameter sensitivity sweep
def audit_parameter_plateau(frame: pl.DataFrame, signal_col: str, lookbacks: list, stop_mults: list) -> pl.DataFrame:
results = []
for lb in lookbacks:
for sm in stop_mults:
# Recompute indicator with new lookback
don_h = frame["high"].shift(1).rolling(lb).max()
sig = (frame["close"] > don_h * 1.0005) & (frame["spread_to_atr"] <= 0.15)
temp_frame = frame.with_columns(sig.alias("temp_sig"))
trade_log = execute_conservative_replay(temp_frame, "temp_sig", k_stop=sm, k_target=1.0)
net_pnl = trade_log["net"].sum() if trade_log.height > 0 else 0.0
results.append({
"lookback": lb,
"stop_mult": sm,
"total_trades": trade_log.height,
"net_pnl": net_pnl,
})
return pl.DataFrame(results)
Testing It Honestly
Honest backtesting enforces the following invariants:
- Next-Bar-Open Execution: Every trade enters at the open of bar
t+1. Testing with same-close fills artificially borrows the overnight gap Saral on next-bar-open execution. - Stop-First Ambiguous Resolution: When both stop and target are touched in a single bar, book the stop loss. An edge that exists only when winning ambiguous bars is fictitious ohlcv.io on bar resolution.
- Mandatory Session Flatten: Every position is closed at or before the session boundary. No overnight exposure.
- Purged Walk-Forward Splits: Folds are session-aligned with an embargo period. Scalers and thresholds fit on training windows only.
- p90 Cost Stress: Evaluate performance under 90th percentile spread spikes to ensure the strategy survives liquidity droughts.
Troubleshooting Diagnostic Table
| Symptom | Probable Cause | Corrective Action |
|---|---|---|
| Strategy reports high backtest profit but fails in paper trading | Backtest filled at signal-bar close or mid-price | Enforce open[t+1] execution and deduct full bid-ask spread |
| Backtest profitability vanishes when ambiguous bars resolve stop-first | Edge was an artifact of intrabar path optimism | Discard baseline or widen stop/target to span multiple bars |
| Parameter sweep shows an isolated spike at lookback 20 | Overfitting to a specific historical quirk | Reject the parameter; require a broad 3x3 plateau |
| Reversion baseline bleeds during trending days | Fading strong institutional momentum | Add an ADX < 20 non-trending filter |
Variants & Extensions
| Variant | Modification | Intended Benefit | Key Metric to Report |
|---|---|---|---|
| M15 Step-Out | Replay baselines on M15 bars | Rescues setups where M5 Spread-to-ATR is prohibitive | Trade frequency vs. net expectancy |
| Hourly Window Restriction | Trade only top liquid hours from M7 Atlas | Eliminates high-spread, low-ATR periods | Session P&L vs. all-hours baseline |
| Causal H1 Trend Gate | Require H1 20 EMA trend alignment | Filters out low-expectancy counter-trend setups | Gated vs. ungated net return per session |
| Funding Spike Avoidance | Stand down 15 min around crypto funding | Avoids spread spikes caused by funding arbitrage | Net return with vs. without funding windows |
Hands-On Project
Deliverable: docs/research/m08_lab_experiments.md and runnable notebook notebooks/m08_lab_experiments.ipynb.
Project Card — M8 Lab Experiments (v1.0)
| Specification Area | Project Requirement |
|---|---|
| Assets & Lanes | One commodity ETP (GLD or PDBC) and one crypto perpetual (BTC or ETH) on an approved venue. |
| Baselines Evaluated | E1 Donchian Breakout and E2 Bollinger/VWAP Reversion on M5. |
| Execution Rules | Signal on close of bar t → fill at open of bar t+1; deduct full timestamped spread; stop-first ambiguous resolution. |
| Session Calendars | ETP: RTH 09:30–16:00 ET; Crypto: UTC 00:00–23:50 synthetic session (forced flatten at 23:50 UTC). |
| Validation Design | 5-fold chronological purged walk-forward with embargo; separate untouched holdout period. |
| Acceptance Criteria | Positive net expectancy on purged OOS; parameter stability across neighbor values; ambiguous trade share < 5%. |
Step-by-Step Instructions
- Prepare clean M5 data with completed-bar ATR, Donchian, Bollinger, VWAP, and RSI.
- Replay E1 Breakout and E2 Reversion under conservative execution rules.
- Perform parameter sweeps across lookbacks and ATR multipliers to map parameter plateaus.
- Apply the E3 causal H1 trend gate and compare gated vs. ungated session P&L.
- Re-run all tests under p90 spread stress to audit liquidity survival.
- Publish the final research memo with explicit Pass, Revise, or Reject verdicts for each baseline.
Key Takeaways
- Execution discipline is non-negotiable: Enter at next-bar open, deduct full spreads, and resolve ambiguous bars stop-first.
- Baselines establish honest benchmarks: Donchian breakouts and Bollinger/VWAP reversions provide standard controls for alpha testing.
- Ambiguous bars must resolve adversely: Never assume favorable intrabar execution on OHLC bars.
- True edges form parameter plateaus: A robust strategy performs consistently across neighbor parameter values.
- HTF gates must increase session P&L: A filter that improves win rate but starves trade frequency can reduce total return.
References
- U.S. Securities and Exchange Commission — Exchange-Traded Funds Investor Bulletin — https://www.sec.gov/investor/alerts/etfs.pdf — Mechanics. ETF share trading and NAV mechanics.
- Fidelity — Commodity ETFs: Contango and Backwardation — https://www.fidelity.com/learning-center/investment-products/etf/commodity-etfs-contango-backwardation — Mechanics. Roll yield mechanics in futures-based funds.
- SPDR Gold Shares (GLD) — Prospectus and Holdings — https://www.ssga.com/us/en/intermediary/etfs/spdr-gold-shares-gld — Mechanics. Physical trust wrapper disclosures.
- Invesco — Optimum Yield Diversified Commodity Strategy No K-1 ETF (PDBC) — https://www.invesco.com/us/financial-products/etfs/invesco-optimum-yield-diversified-commodity-strategy-no-k-1-etf.html — Mechanics. Dynamic rolling pool methodology.
- Coinbase — Funding Rates on Perpetual Futures — https://help.coinbase.com/en/derivatives/perpetual-style-futures/funding-rate — Mechanics. Perpetual funding cash-flow mechanism.
- Saral Money — Backtest Execution Timing: Fill at Next Bar’s Open — https://saral.money/blog/next-bar-open-execution-timing/ — Mechanics. Same-close vs. next-open execution bias.
- ohlcv.io — The Bar Resolution Problem (Backtesting Pitfalls 04) — https://ohlcv.io/posts/backtesting-pitfalls/04-bar-resolution/ — Mechanics. Intrabar path ambiguity and conservative resolution.
- NautilusTrader — Bar-Based Execution Semantics — https://nautilustrader.io/docs/latest/concepts/backtesting/bar-execution/ — Mechanics. Synthetic intrabar path modeling.
- QuantJourney — Execution Assumptions in Backtesting — https://backtester.quantjourney.cloud/engine/execution-assumptions — Mechanics. Stop-first priority and fill assumptions.
- Volatility Box — Opening Range Volatility Breakout — https://volatilitybox.com/research/opening-range-volatility-breakout/ — Transfer Evidence. Range-expansion heuristics.
- Volatility Box — Keltner Channels vs. Bollinger Bands — https://volatilitybox.com/research/keltner-channels-vs-bollinger-bands/ — Transfer Evidence. Volatility envelope dynamics.
Next: Module 9 — Causal Multi-Timeframe Context for Intraday Entries · Core: Module 8 — Low-Timeframe Trading Lab