The Learning Library
Contents

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 t and execute at the open of bar t+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 risk

The Step-by-Step Decision Process

  1. Compute completed HTF features (H1 20 EMA, H1 ADX, PDH/PDL).
  2. Stamp HTF data at bar close: Use label="right", closed="right" in pandas/Polars.
  3. Perform a backward as-of join: Align completed HTF values to M5 timestamps.
  4. Evaluate M5 trigger at bar t close: Check trend alignment, volatility gates, and cost ceilings.
  5. Execute at bar t+1 open: Pay the spread on entry; manage stops and targets bar by bar.
  6. 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

  1. 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.
  2. 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.
  3. 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:

  1. 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.
  2. 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.
  3. Worst-Case Ambiguous Resolution: Same-bar barrier touches resolve stop-first.
  4. Mandatory Session Flatten: Every position is closed at or before the session boundary.
  5. 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

  1. Prepare clean M5 data. Construct right-labeled H1 EMA trend, ATR percentile, and daily PDH/PDL levels.
  2. Verify causal alignment by printing boundary rows around H1 bar closes.
  3. Replay the ungated M5 breakout baseline and record total session P&L.
  4. Replay the HTF-gated M5 breakout setup under identical execution rules.
  5. Perform a walk-forward ablation comparing net return per session across both variants.
  6. 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


Next: Module 10 — Intraday Trend-Following & Momentum Playbooks · Companion: Module 9 Strategies — Multi-Timeframe Experiments