Module 9 — Causal Multi-Timeframe Context for Intraday Entries
Part III · Intraday Design, Alpha & Playbooks · Priority 🎯 Core Status: Draft v0.2 · Scope: commodity ETFs/ETPs + BTC/ETH spot & linear perps · Horizon: M1/M5 (M15 where appropriate), same-session flat Prerequisites: M5, M8, M7, M22, M23
Overview
Start every multi-timeframe system with the instrument you can actually execute. Never start with an unaligned higher-timeframe chart.
A commodity ETP trades during U.S. regular hours. Its market price can deviate from NAV, and creation/redemption mechanisms operate through authorized participants SEC ETF bulletin. A futures-based commodity pool rolls contracts continuously, creating divergence from spot prices when the futures curve is in contango or backwardation Fidelity on contango/backwardation. A physical trust like GLD holds bullion and publishes daily holdings SPDR Gold Shares (GLD). Meanwhile, a BTC or ETH linear perpetual exchanges funding payments between longs and shorts on an exchange-specific schedule Coinbase perpetual funding.
Our core hypothesis is narrow: a completed H1, H4, or D1 context that gates, routes, or weights intraday M1/M5 entries toward dominant institutional flow improves net session expectancy compared to an isolated intraday trigger, without ever extending hold times past the session close.
The economic intuition is clear:
- Intraday pullbacks in the direction of the higher trend represent temporary liquidity absorption by larger market participants.
- Pullbacks against the higher trend frequently mark the beginning of structural distribution.
- Aligning execution with higher-timeframe flow filters out low-conviction chop and reduces transaction friction.
Evidence status: hypothesis, mechanics-supported. Exchange and wrapper mechanics explain why higher-timeframe context behaves as it does. They do not prove that an intraday edge exists. You must verify net profitability through rigorous out-of-sample replay.
The primary pitfall in multi-timeframe modeling is lookahead leakage. A backtester that joins a still-forming H1 or D1 bar to an M5 decision inside that same period gives the intraday strategy unearned knowledge of the future close. Left-labeled forward-filling in pandas or Pine Script without explicit shift offsets causes this exact bias TradingView on other timeframes and Tradepilot on lookahead. This module enforces a strictly causal, close-stamped join discipline.
💡 The Division of Labor Analogy: Multi-timeframe trading is like corporate division of labor:
- The Higher Timeframe (HTF): The executive who grants directional permission (trend alignment).
- The Medium Timeframe (MTF): The manager who sets operational boundaries (prior-day high/low levels).
- The Lower Timeframe (LTF): The field operator who times the precise entry (M5 trigger). Joining an unclosed HTF bar is like booking revenue before goods are shipped—an accounting violation that invalidates your audit.
📌 Data Contract: This module operates strictly on OHLCV + spread data. We assume no order book, tick data, or partial fills. Decisions evaluate on the close of bar
tand execute at the open of bart+1. Spreads are deducted on entry and exit. Completed H1/H4/D1 bars serve as causal context only. All positions force flatten before session close.
How It Works
A causal multi-timeframe system assigns distinct responsibilities across three technical families.
The Three Context Families
| Context Family | Slower Input (Completed Bar) | Intraday Job (M1/M5) | Plain-English Rule |
|---|---|---|---|
| Trend Alignment | H1/H4 20 EMA slope, ADX(14), Donchian mid | Directional Permission | Only buy when the completed higher-timeframe trend is upward. |
| Volatility Gate | Completed H1 ATR percentile (trailing 100 bars) | Market Participation Filter | Only trade when the market is neither dead flat nor explosively stretched. |
| Prior-Session Levels | Prior Day High/Low (PDH/PDL), Prior H4 High/Low | Structural Reference Points | Score breakouts or sweep-reversals against levels fixed before the open. |
Causal Synchronization & Release Timing
An HTF bar becomes usable only after its close timestamp has passed. For example, an H1 bar spanning 10:00 to 11:00 closes at 11:00. Its features become tradable starting at the 11:05 M5 open. The forming 10:00–11:00 bar is completely invisible to intraday logic prior to 11:00.
Figure: The causal multi-timeframe decision cascade. Slower data passes through a synchronization checkpoint before filtering intraday signals.
flowchart TD
htf[(Completed H1/H4/D1 history)] --> sync{Source bar<br/>fully closed?}
sync -->|"no: forming bar"| reject[REJECT - embryo<br/>bar is look-ahead]
sync -->|"yes: confirmed"| release["Release at close + lag<br/>stamp at closing time"]
release --> bias["Trend bias locked<br/>EMA slope / ADX / Donchian"]
release --> vol["Volatility gate armed<br/>ATR percentile"]
release --> levels["Level map armed<br/>PDH/PDL/prior H4 HL"]
bias --> scan["M5 trigger scans<br/>inside session window"]
vol --> scan
levels --> scan
scan --> cost{"Spread-to-ATR<br/>+ cost-to-target pass?"}
cost -->|"no"| aside["Stand aside<br/>bar too expensive"]
cost -->|"yes"| conflict{"Trigger agrees<br/>with HTF bias?"}
conflict -->|"no: conflict rule"| aside
conflict -->|"yes: aligned"| arm["Arm entry for<br/>next M5 open t+1"]
arm --> manage["Manage with time stop<br/>+ forced session flatten"]
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 htf data
class bias,vol,levels,scan,arm,manage,release process
class sync,cost,conflict decision
class reject,aside riskThe Step-by-Step Decision Process
- Compute completed HTF features (H1 20 EMA, H1 ADX, PDH/PDL).
- Stamp HTF data at bar close: Use
label="right", closed="right"in pandas/Polars. - Perform a backward as-of join: Align completed HTF values to M5 timestamps.
- Evaluate M5 trigger at bar
tclose: Check trend alignment, volatility gates, and cost ceilings. - Execute at bar
t+1open: Pay the spread on entry; manage stops and targets bar by bar. - Force flatten at session end: Close all open trades at the session boundary.
Strategy Rules
These rules define the multi-timeframe execution contract.
Bar-Synchronization Invariants
- Closed Bars Only: All HTF indicators resolve strictly to the last completed H1, H4, or D1 bar. In Pine Script terms:
request.security(..., expr[1], lookahead=barmerge.lookahead_off)Supa.is on Pine v6 lookahead. - Boundary Actionability: An H1 bar closing at 11:00 becomes tradable at the 11:05 M5 open. Signals never fill at the closing price of the signal bar.
- Right-Labeled Resampling: When aggregating data, stamp rows with their closing timestamp. Forward-filling left-labeled bars leaks future data backward into intraday rows.
# The Resampling Trap: Wrong vs. Right
import pandas as pd
# WRONG: Left-labeling stamps 09:00-10:00 bar as '09:00'. Forward-filling leaks future close.
wrong = m5["close"].resample("1h").last().reindex(m5.index, method="ffill")
# RIGHT: Right-labeling stamps 09:00-10:00 bar as '10:00'. Forward-filling is causal.
right = m5["close"].resample("1h", label="right", closed="right").last().reindex(m5.index, method="ffill")
Context Family Configurations
1. Trend Alignment Gate
- H1 20 EMA Slope: Longs permitted only when
EMA20[H1] > EMA20[H1].shift(1). - H1 ADX(14): Permitted only when
ADX ≥ 18(verifies trend strength).
2. Volatility Gate
- ATR Percentile: Compute 14-period ATR on completed H1 bars; rank against trailing 100 bars.
- Tradable Band: Trade only when ATR percentile is between 20% and 85% DesireToTrade on ATR percentile. Discard dead or explosive regimes.
3. Prior-Session Level Map
- PDH / PDL: High and low of the previous completed daily session LuxAlgo on prior period levels.
- Execution Buffer: Require an M5 close beyond
PDH + (0.10 × ATR)to confirm a breakout and avoid spread churn.
Conflict & Staleness Rules
- Signal Conflict: If M5 triggers long but H1 bias is short, stand aside (no trade).
- Stale Context: If the HTF feed is delayed by more than 1 period, freeze last known state for 1 bar, then force stand-aside.
- Session Boundary: HTF alignment never overrides the mandatory session forced flatten.
📌 Transfer Evidence Note: Multi-timeframe heuristics from foreign exchange or equity index futures represent transfer evidence. Do not assume thresholds transfer directly to commodity trusts or crypto perpetuals. Always re-evaluate on your target lane.
Building It In Python
Below is a complete, vectorized Polars and pandas implementation of causal multi-timeframe alignment.
1. Intuition: Build Causal HTF Context
We compute H1 EMA trend, ATR percentile, and prior-day levels from completed bars and align them causally.
# Causal HTF feature engineering and backward alignment
# Q: What HTF values were legitimately knowable at each M5 close?
import pandas as pd
import numpy as np
def build_causal_htf_context(m5_df: pd.DataFrame) -> pd.DataFrame:
# 1. Resample to completed H1 bars (Right-labeled)
h1 = m5_df["close"].resample("1h", label="right", closed="right").last().to_frame()
# 2. Compute H1 20 EMA and Slope
h1["ema20"] = h1["close"].ewm(span=20, min_periods=20).mean()
h1["ema_slope"] = h1["ema20"].diff()
h1["h1_bullish"] = h1["ema_slope"] > 0
# 3. Compute Completed Daily Levels (PDH / PDL)
d1_high = m5_df["high"].resample("1D", label="right", closed="right").max()
d1_low = m5_df["low"].resample("1D", label="right", closed="right").min()
# 4. Backward Causal Alignment to M5 Index
m5_df["h1_bullish"] = h1["h1_bullish"].reindex(m5_df.index, method="ffill").fillna(False)
m5_df["pdh"] = d1_high.reindex(m5_df.index, method="ffill")
m5_df["pdl"] = d1_low.reindex(m5_df.index, method="ffill")
return m5_df
2. Intuition: Arm Gated M5 Signals
We combine lower-timeframe triggers with higher-timeframe trend and level permission.
# Gated M5 signal generation
# Q: Does our entry align with higher institutional flow?
def generate_gated_m5_signals(m5_df: pd.DataFrame) -> pd.DataFrame:
# M5 ATR and Feasibility Gates
prev_close = m5_df["close"].shift(1)
tr = np.maximum(
m5_df["high"] - m5_df["low"],
np.maximum((m5_df["high"] - prev_close).abs(), (m5_df["low"] - prev_close).abs())
)
m5_df["atr14"] = tr.ewm(span=14, adjust=False).mean()
m5_df["spread_to_atr"] = m5_df["spread"] / m5_df["atr14"]
cost_pass = m5_df["spread_to_atr"] <= 0.15
# M5 Level-Breakout Trigger
buffer = 0.10 * m5_df["atr14"]
level_break_long = m5_df["close"] > (m5_df["pdh"] + buffer)
# Causal Gating: Trigger + HTF Bullish Bias + Cost Gate
m5_df["signal_long"] = level_break_long & m5_df["h1_bullish"] & cost_pass
return m5_df
3. Intuition: Boundary Audit Verification
We print the transition rows around an H1 close to verify that no future data leaks into M5 rows.
# Boundary row audit
# Q: Does the 10:05 M5 bar see only the 10:00 H1 close?
def audit_boundary_alignment(m5_df: pd.DataFrame, h1_timestamp: str):
ts = pd.Timestamp(h1_timestamp)
window = m5_df.loc[ts - pd.Timedelta("15min"): ts + pd.Timedelta("15min"),
["close", "h1_bullish", "pdh", "signal_long"]]
print(window)
Hand-Checkable Numeric Example
Suppose an M5 commodity ETP setup produces the following readings at 13:25:
| Check | Reading at 13:25 | Status / Verdict |
|---|---|---|
| M5 Close vs. PDH | Close $48.86 > \text{PDH } $48.80 + 0.10 \times \text{ATR } ($0.03)$ | ✅ Breakout Confirmed |
| H1 Trend Bias | Locked at 13:00 H1 close; 20 EMA slope is positive | ✅ Direction Approved |
| H1 Volatility Gate | ATR percentile = 45% (within 20%–85% band) | ✅ Volatility Normal |
| Cost Gate | Spread $0.012 ÷ \text{ATR } 0.11 = 10.9% \le 15%$ | ✅ Toll Covered |
| Execution Action | Arm long trade for 13:30 M5 open at ask price | ✅ Trade Armed |
What this means for your P&L: At 13:25, the breakout aligns with the 13:00 H1 trend, volatility is healthy, and the spread toll is small. The trade executes at the 13:30 open. If this same setup occurred at 12:55, it would be forced to wait for the 13:00 H1 close to confirm direction.
Testing It Honestly
Honest testing requires comparing gated strategies against an identical ungated baseline:
- Gated vs. Ungated Ablation: Run the same M5 trigger with and without the HTF gate. The gate is justified only if it improves net return per session after accounting for reduced trade count.
- Next-Bar-Open Execution: Fills occur at the open of bar
t+1. Never fill at the signal bar’s close Saral on next-bar-open execution. - Worst-Case Ambiguous Resolution: Same-bar barrier touches resolve stop-first.
- Mandatory Session Flatten: Every position is closed at or before the session boundary.
- Purged Walk-Forward Splits: Test folds are session-aligned with embargoes to prevent information leakage.
Troubleshooting Diagnostic Table
| Symptom | Probable Cause | Corrective Action |
|---|---|---|
| Strategy reports massive backtest profits that vanish live | HTF data was forward-filled using left-labeled open timestamps | Re-resample with label="right", closed="right" and verify boundary rows |
| HTF gate raises win rate but cuts total session P&L | Gate eliminates too many profitable setups | Widen HTF filters or test H4 instead of H1 |
| Strategy enters counter-trend positions during strong trends | Missing conflict stand-aside rule | Enforce strict stand-aside when M5 trigger opposes HTF bias |
Variants & Extensions
| Variant | Modification | Practical Purpose | Trade-off |
|---|---|---|---|
| H1 vs. H4 Trend Source | Use H4 bars for trend permission | Provides smoother, less noisy trend direction | Fewer trades; slower reaction to intraday turns |
| Prior H4 High/Low Map | Use prior H4 levels instead of PDH/PDL | Provides closer intraday structural references | Triggers more frequently with higher noise |
| ATR Percentile Band Tuning | Adjust tradable band (e.g., 25%–75%) | Restricts trading to ideal volatility conditions | Further reduces session opportunity count |
| Directional Sizing Modifier | Reduce size by 50% on counter-trend setups | Allows taking counter-trend trades with reduced risk | Increases trade tracking complexity |
Hands-On Project
Deliverable: docs/research/m09_causal_mtf_lab.md and reproducible notebook notebooks/m09_causal_mtf_lab.ipynb.
Project Card — M9 Causal Multi-Timeframe Lab (v1.0)
| Area | Pre-Registration Requirement |
|---|---|
| Identity | One commodity ETP (GLD or PDBC) and one crypto perpetual (BTC or ETH) on an approved venue. |
| Timeframes | Execution on M5; causal context from completed H1 and Daily bars. |
| Session Calendars | ETP: RTH 09:30–16:00 ET; Crypto: UTC 00:00–23:50 synthetic session (flatten at 23:50 UTC). |
| Execution Model | Signal on close of bar t → fill at open of bar t+1; deduct timestamped spread; stop-first ambiguous resolution. |
| Ablation Protocol | Direct side-by-side evaluation of Ungated M5 Baseline vs. HTF-Gated Setup. |
| Acceptance Criteria | Gated net expectancy exceeds ungated baseline on purged OOS; session trade floor met; ambiguous share < 5%. |
Step-by-Step Instructions
- Prepare clean M5 data. Construct right-labeled H1 EMA trend, ATR percentile, and daily PDH/PDL levels.
- Verify causal alignment by printing boundary rows around H1 bar closes.
- Replay the ungated M5 breakout baseline and record total session P&L.
- Replay the HTF-gated M5 breakout setup under identical execution rules.
- Perform a walk-forward ablation comparing net return per session across both variants.
- Publish the final research memo documenting whether the HTF gate earned its complexity.
Key Takeaways
- Division of labor creates clarity: HTF grants directional permission; MTF establishes key levels; LTF times the precise entry.
- Never peek at unclosed bars: HTF features must be stamped at bar close and joined backward. Forward-filling open-stamped bars is lookahead bias.
- Ablation is the ultimate test: An HTF gate must beat the ungated baseline on net return per session, not just win rate.
- Prior-day levels provide objective references: PDH and PDL are fixed before the open and offer structural breakout benchmarks.
- Enforce conservative execution: Fill at next-bar open, deduct full spreads, resolve ambiguous bars stop-first, and force flatten at session end.
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. Futures roll mechanics and curve slope.
- SSGA — SPDR Gold Shares (GLD) — https://www.ssga.com/us/en/intermediary/etfs/spdr-gold-shares-gld — Mechanics. Physical trust wrapper disclosures.
- Coinbase — Funding Rates on Perpetual Futures — https://help.coinbase.com/en/derivatives/perpetual-style-futures/funding-rate — Mechanics. Perpetual funding cash-flow mechanism.
- LuxAlgo — Prior Period Levels Concept — https://www.luxalgo.com/library/concept/prior-period-levels/ — Mechanics. Objective horizontal level mapping.
- FXGlory — ATR and ADX Strategy Guide — https://fxglory.com/learn/forex-strategies/atr-and-adx-strategy/ — Mechanics / Transfer. ATR and ADX indicator pairing.
- DesireToTrade — Volatility Filter: ATR Percentile — https://www.desiretotrade.com/docs/volatility-filter-indicator-atr-percentile-volatility/ — Mechanics. Normalized volatility ranking.
- Supa.is — Fix Pine Script v6 Request Security Lookahead — https://supa.is/article/pine-script-v6-request-security-lookahead-fix-2026 — Mechanics. Causal MTF synchronization in code.
- Jayadevrana — Non-Repainting Multi-Timeframe Patterns — https://jayadevrana.com/pine-script-request-security-lookahead/ — Mechanics. Offset discipline for completed HTF bars.
- Tradepilot — Multi-Timeframe Scripting Without Repainting — https://tradepilot.co.in/blog/multi-timeframe-pine-script-request-security — Mechanics. Anti-lookahead MTF design.
- TradingView — Other Timeframes and Data Documentation — https://www.tradingview.com/pine-script-docs/concepts/other-timeframes-and-data/ — Mechanics. Official
request.securitymechanics.
Next: Module 10 — Intraday Trend-Following & Momentum Playbooks · Companion: Module 9 Strategies — Multi-Timeframe Experiments