The Learning Library
Contents

Module 13 Companion — Sessions, Auctions & Funding Clocks — Strategy Lab

Part III · Intraday Design, Alpha & Playbooks · Companion to Module 13 — Sessions, Auctions & Funding Clocks Status: Draft v0.2 · Scope: commodity ETFs/ETPs + BTC/ETH spot & linear perps · Horizon: M1/M5 primary, M15 where appropriate, same-session flat Prerequisites: M7, M13, M5, M22, M23


Overview

The core module established our market clocks: regular trading hours (RTH) segmentation, synthetic UTC crypto sessions, and funding settlement mechanics. This companion translates those clocks into three rigorous intraday trading controls.

A session filter does not predict market direction. It acts as an operational bouncer, deciding whether a specific bar is cheap enough and tall enough to carry a directional signal.

We evaluate three controlled strategies. S1 serves as the foundational implementation. S2 and S3 inherit S1’s execution engine, modifying only the calendar and funding rules.

Strategy Card Audit Question Target Asset & Clock Core Mechanism
S1: RTH Segment Atlas Gate Does filtering out the midday trough and auction freezes improve net P&L after costs? Commodity ETP RTH (GLD / PDBC, 09:30–16:00 ET) Hourly atlas filter + Spread-to-ATR gate + Auction freeze stand-down.
S2: UTC Session Filter & Sunday Trap Does restricting crypto trading to Europe/US overlaps (and isolating Sunday 23:00 UTC) outperform 24/7 trading? BTC/ETH Spot & Perps (UTC Synthetic 00:00–23:50) UTC session filter + Sunday re-entry sleeve + Funding buffer.
S3: Funding-Clock Stand-Down Does standing down during funding settlements preserve net P&L compared to paying periodic holding rent? BTC/ETH Linear Perps (Hourly vs. 8-Hour Venues) Settlement-proximity stand-down (±15 min) vs. full funding booking.

💡 Analogy (The Lens Aperture): Think of S1, S2, and S3 as adjusting the aperture of an industrial camera. You do not alter the scene (the directional indicator). You only open the shutter when lighting is optimal and lens distortion (spread/friction) is minimal. If the resulting photo is not sharper after deducting the light you blocked (lost opportunity), you discard the filter.

📌 Convention: All strategies operate strictly on OHLCV + spread data. We use zero order-book, level-2 tick, or queue-position data. Execution is bar-based: signals on the close of bar t fill at the open of bar t+1 with full spread deducted. Ambiguous intra-bar touches resolve adversely (stop-first). All trades force-flatten before the session boundary.


How It Works

Three specialized filters feed a single, unified execution and accounting pipeline.

S1: The RTH Bouncer (Commodity ETPs)

S1 calculates an hourly liquidity atlas across the NYSE trading day. It evaluates two real-time hurdles:

  1. Spread-to-ATR Ratio: Spread / ATR <= 0.15 (Friction consumes <= 15% of the average bar range).
  2. Cost-to-Target Ratio: (Spread + Fees) / Target <= 0.10 (Friction consumes <= 10% of expected profit).

Bars occurring during the 15:50–16:00 ET closing auction freeze are automatically blocked StockTitan — opening & closing auctions. Only surviving bars are eligible to evaluate trading signals.

S2: The UTC Session Bouncer (Crypto Spot & Perps)

S2 applies identical cost-ratio logic to crypto perpetuals, mapped across three global sessions Tom Espel — BTC/ETH intraday regime seasonality:

  • Asia (00:00–06:00 UTC): Lower participation; higher relative spread cost.
  • Europe (08:00–16:30 UTC): High liquidity; tight spreads.
  • Americas (13:30–20:00 UTC): Peak volume; institutional fixing flows.

S2 eliminates broad weekday dummy variables. It replaces them with an explicit Sunday 23:00–00:00 UTC filter to isolate weekly retail positioning spikes MLQuants — day-of-week effects are hourly.

S3: The Rent Bouncer (Perpetual Funding Clocks)

S3 enforces venue-specific funding discipline:

S3 runs a direct ablation: Stand down during settlement versus Hold through and book realized funding.

flowchart TD
    data["OHLCV + spread<br/>M1/M5/M15 completed<br/>H1/H4/D1 releases"] --> atlas["Hour/minute atlas<br/>spread/ATR/pass rate"]
    atlas --> s1["S1 RTH Atlas Gate<br/>09:30-16:00 ET<br/>freeze tagged"]
    atlas --> s2["S2 UTC Session Filter<br/>Asia/Europe/Americas<br/>Sunday 23:00 flagged"]
    atlas --> s3["S3 Funding Stand-Down<br/>hourly vs 8-hour<br/>book or avoid"]
    s1 --> replay["Conservative bar replay<br/>close[t] -> open[t+1]<br/>spread + funding booked"]
    s2 --> replay
    s3 --> replay
    replay --> oos{"Purged walk-forward<br/>net per session<br/>vs all-hours?"}
    oos -->|"pass"| carry["Carry gate + clock<br/>to M14/M10/M11"]
    oos -->|"revise"| narrow["Revise tiles<br/>or widen stand-down"]
    oos -->|"reject"| stop["Reject gate<br/>keep all-hours baseline"]

    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 atlas,s1,s2,s3,replay,narrow process
    class oos decision
    class stop risk
    class carry ok

Strategy Rules

Every strategy card adheres to the standard nine-point quantitative specification.

S1: RTH Segment Atlas Gate (Full Specification)

1. Market, Timeframe, and Data Assumptions

  • Universe: NYSE Arca-listed commodity ETPs: GLD (Physical Gold Trust) SSGA — GLD or PDBC (Commodity Pool) Invesco — PDBC. Long-only unless short locate availability is documented.
  • Timeframe: Primary M5 resolution. M1/M15 sensitivity checks.
  • Data Contract: Strictly OHLCV + timestamped spread. Point-in-time timezone conversion (America/New_York).

2. Mechanics vs. Testable Hypothesis

  • Mechanics: Intraday volume and spread follow a U-shape Pomegra — volume by time of day. Spreads start wide at 09:30, tighten by 10:00, and expand into the 15:50 MOC freeze StockTitan — opening & closing auctions.
  • Hypothesis: Restricting M5 breakout triggers to hours where Spread/ATR <= 15% and gating out the 15:50–16:00 freeze increases net Sharpe ratio versus an ungated baseline.

3. Required Technical Indicators

  • Causal ATR(14): Smoothed True Range computed on completed bars Investopedia ATR.
  • Spread Metrics: Dynamic Spread / ATR and (Spread + Fees) / Target.
  • Trailing Spread Percentile: Rolling 75th percentile of spread within the current hour.
  • Trigger Indicator: 20-bar Donchian Channel High/Low.

4. Causal HTF Context and Intraday Triggers

  • HTF Context (H1): Completed H1 close > 20-period EMA. Released at H1_Close + 1_minute_lag.
  • M5 Trigger: Bar t close breaks above the 20-bar Donchian High. Evaluated only if bar t clears all session gates.

5. Order Execution, Stops, Targets, and Flattening

  • Entry: Signal at close of bar t -> Market Buy fill at open of bar t+1 + 0.5 × Spread.
  • Stop Loss: Entry_Price - (1.2 * ATR[t]).
  • Profit Target: Entry_Price + (1.0 * ATR[t]).
  • Time Stop: 16 bars (80 minutes maximum hold).
  • Forced Flatten: Unconditional market exit at 15:58 ET. No overnight carry.

6. Friction Handling and Conservative Execution

  • Full observed spread deducted on entry and exit.
  • Adverse Intra-bar Resolution: If both Stop Loss and Profit Target fall within bar t+k’s range (High/Low), the engine books a Stop Loss.

7. Position Sizing and Risk Scaffolding

  • Fixed-fractional risk: 0.25% equity risk per trade.
  • Maximum 3 trades per session. Daily portfolio stop at 1.0% equity drawdown.

8. Machine Learning Extension (Walk-Forward Meta-Filter)

  • Baseline: Fixed deterministic threshold (s2atr <= 0.15).
  • Logistic Meta-Classifier: Fit on training folds only. Predicts trade success probability using 5 causal features: [Spread_Percentile_Hour, Lagged_s2atr, ATR_Percentile, Hour_Sin, Hour_Cos].
  • Evaluation: Must demonstrate an out-of-sample information ratio gain over the deterministic baseline on purged folds.

9. Failure Modes and Preregistered Reject Triggers

  • Midday ATR Collapse: Midday bars pass spread tests but lack sufficient range to hit targets before time stops trigger.
  • Hard Reject Criteria: Reject the system if gated net P&L fails to beat the ungated baseline, or if the strategy leaves fewer than 200 tradable sessions per year.

S2: Crypto UTC Session Filter & Sunday Spike Trap

1. Market, Timeframe, and Data Assumptions

  • Universe: BTC-USDT and ETH-USDT spot and linear perpetuals on approved CEXs.
  • Timeframe: Primary M5 resolution. UTC synthetic trading session (00:00–23:50 UTC).
  • Data Contract: Causal OHLCV + venue-recorded spread. Point-in-time funding stream.

2. Mechanics vs. Testable Hypothesis

  • Mechanics: Crypto volatility follows an M-shaped profile peaking at the London open (08:00 UTC) and NY overlap (13:30–16:00 UTC) MarketsByte — intraday volatility by session. Weekly anomalies collapse to Sunday 23:00 UTC retail re-positioning MLQuants — day-of-week effects are hourly.
  • Hypothesis: Confining directional trading to European/Americas sessions (08:00–20:00 UTC) while isolating the Sunday 23:00 UTC sleeve yields higher net expectancy than 24/7 continuous trading.

3. Required Indicators & Calculations

  • Causal ATR(14), dynamic Spread / ATR, cyclical UTC hour encodings (sin/cos), and Tom Espel regional session tags Tom Espel.

4. Intraday Triggers & Timing

  • Baseline Donchian breakout (M5) active strictly between 08:00 and 20:00 UTC.
  • Dedicated Sunday Sleeve: Evaluates momentum continuation specifically between Sunday 23:00 and Monday 00:00 UTC.

5. Execution, Stops, Targets, and Flattening

  • Fills at open of bar t+1 with full spread deducted. Stop loss at 1.2 × ATR, profit target at 1.0 × ATR.
  • Mandatory Daily Flatten: 23:50 UTC synthetic reset.

6. Friction & Funding Accounting

  • Deduct full observed spread. If held through an 8-hour settlement mark (e.g., 16:00 UTC), deduct Notional * Realized_Funding_Rate.

7. Sizing & Risk Controls

  • 0.25% risk per trade. Max 4 trades per 24-hour UTC cycle. Weekend trading disabled by default.

8. ML Meta-Filter

  • Gradient Boosted Classifier (XGBoost) trained on chronological folds to predict trade viability during high-volatility European opening bars.

9. Failure Modes & Reject Triggers

  • Illusion of Weekday Alpha: Using weekday dummy variables instead of precise UTC hourly features overfits historical data Securities.io.
  • Reject Trigger: Reject if Europe/Americas-only filtering fails to beat 24/7 execution net of trading costs.

S3: Funding-Clock Stand-Down (Hourly vs. 8-Hour Venues)

1. Market, Timeframe, and Data Assumptions

2. Mechanics vs. Testable Hypothesis

  • Mechanics: Funding is a cash transfer between longs and shorts. Longs pay shorts when perps trade at a premium to spot. Payment applies strictly to positions open at the settlement second.
  • Hypothesis: Standing down ±15 minutes around settlement timestamps prevents adverse spread widening and funding decay, improving net returns over a buy-and-hold strategy.

3. Required Calculations

  • Minutes_To_Next_Funding and Minutes_Since_Last_Funding. Realized funding rate ledger joined causally.

4. Intraday Triggers & Gating

  • Identical M5 momentum trigger as S1/S2. Gated out whenever abs(Minutes_To_Next_Funding) <= 15.

5. Execution & Flattening

  • Next-bar open fill. Stop at 1.2 × ATR; Target at 1.0 × ATR. Mandatory flatten at 23:50 UTC.

6. Friction & Cost Booking

  • Active comparison:
    • Branch 1 (Stand-Down): Zero funding booked; settlement bars skipped.
    • Branch 2 (Funding-Blind): All bars traded; Notional * Rate booked whenever a position crosses settlement.

7. Sizing & Risk

  • 0.25% equity risk per trade. Sizing strictly normalized across both branches.

8. ML Extension

  • Logistic regression estimating the probability of pre-funding spread widening as a function of trailing funding rate magnitude.

9. Failure Modes & Reject Triggers

  • Universal Rate Assumption: Applying 8-hour math to hourly venues distorts backtest metrics.
  • Reject Trigger: Reject stand-down logic if the cost of missed momentum trades during settlement windows exceeds total funding fees saved.

Building It In Python

Below is the complete implementation of the strategy lab, featuring feature engineering, causal ML meta-filtering, and conservative backtest replay.

"""
Module 13 Strategy Lab: Multi-Clock Session & Funding Filter Engine.
Stack: Polars, NumPy, Scikit-Learn, XGBoost.
"""

import polars as pl
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import TimeSeriesSplit

# ---------------------------------------------------------
# 1. Feature Engineering: Clocks & Causal Ratios
# ---------------------------------------------------------
def prepare_strategy_features(df: pl.DataFrame, venue: str = "NYSE") -> pl.DataFrame:
    """
    Builds technical indicators, clock encodings, and compliance flags.
    """
    # Causal ATR
    prev_close = df["close"].shift(1)
    tr = pl.max_horizontal([
        df["high"] - df["low"],
        (df["high"] - prev_close).abs(),
        (df["low"] - prev_close).abs(),
    ])
    df = df.with_columns(tr.alias("tr"))
    atr14 = df["tr"].ewm_mean(span=14, adjust=False).alias("atr_14")
    df = df.with_columns(atr14)

    # Ratios
    df = df.with_columns([
        (pl.col("spread") / pl.col("atr_14")).alias("s2atr"),
        (pl.col("spread") / (0.9 * pl.col("atr_14"))).alias("c2t_09"),
        # Donchian High (20-bar)
        pl.col("high").rolling_max(window_size=20).shift(1).alias("donchian_high_20"),
    ])

    # UTC Clock Encodings
    utc_hour = df["timestamp"].dt.convert_time_zone("UTC").dt.hour()
    utc_min = df["timestamp"].dt.convert_time_zone("UTC").dt.minute()

    hour_rad = (2 * np.pi * utc_hour / 24.0)
    df = df.with_columns([
        hour_rad.cos().alias("hour_cos"),
        hour_rad.sin().alias("hour_sin"),
        # Sunday 23:00 UTC Flag
        ((df["timestamp"].dt.weekday() == 7) & (utc_hour == 23)).alias("is_sunday_2300"),
    ])

    # Compliance Stand-Down Flags
    if venue == "NYSE":
        et_hour = df["timestamp"].dt.convert_time_zone("America/New_York").dt.hour()
        et_min = df["timestamp"].dt.convert_time_zone("America/New_York").dt.minute()
        is_freeze = ((et_hour == 15) & (et_min >= 50)) | (et_hour == 16)
        df = df.with_columns(is_freeze.alias("stand_down"))
    elif venue == "Coinbase":
        is_settle = (utc_min >= 45) | (utc_min <= 5)
        df = df.with_columns(is_settle.alias("stand_down"))
    else:  # Binance 8-Hour
        is_settle = utc_hour.is_in([0, 8, 16]) & ((utc_min >= 45) | (utc_min <= 15))
        df = df.with_columns(is_settle.alias("stand_down"))

    # Master Gate Boolean
    df = df.with_columns(
        ((pl.col("s2atr") <= 0.15) & (pl.col("c2t_09") <= 0.10) & (~pl.col("stand_down"))).alias("gate_pass")
    )
    return df

# ---------------------------------------------------------
# 2. Causal Replay Engine with Adverse Ambiguity Resolution
# ---------------------------------------------------------
def run_conservative_replay(df: pl.DataFrame, k_stop: float = 1.2, k_target: float = 1.0,
                            t_max_bars: int = 16, book_funding: bool = True) -> pl.DataFrame:
    """
    Simulates execution strictly on bar t+1 open, deducting real spreads and funding.
    """
    trades = []
    in_pos = False
    entry_price = 0.0
    stop_price = 0.0
    target_price = 0.0
    entry_bar = 0

    rows = df.to_dicts()
    for i in range(len(rows) - 1):
        curr = rows[i]
        nxt = rows[i + 1]

        # Check Entry (Bar t signal -> Bar t+1 Open fill)
        if not in_pos and curr["gate_pass"] and (curr["close"] > curr["donchian_high_20"]):
            in_pos = True
            spread = nxt["spread"]
            entry_price = nxt["open"] + (0.5 * 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 Open Position
        if in_pos:
            bars_held = i - entry_bar
            hit_stop = curr["low"] <= stop_price
            hit_target = curr["high"] >= target_price

            pnl = 0.0
            exit_reason = ""

            # Adverse Ambiguity: Stop Loss takes priority if both are touched
            if hit_stop and hit_target:
                pnl = stop_price - entry_price - (0.5 * curr["spread"])
                exit_reason = "ambiguous_stop"
                in_pos = False
            elif hit_stop:
                pnl = stop_price - entry_price - (0.5 * curr["spread"])
                exit_reason = "stop_loss"
                in_pos = False
            elif hit_target:
                pnl = target_price - entry_price - (0.5 * curr["spread"])
                exit_reason = "profit_target"
                in_pos = False
            elif bars_held >= t_max_bars or curr["stand_down"]:
                # Time Stop or Session Flatten
                pnl = curr["close"] - entry_price - (0.5 * curr["spread"])
                exit_reason = "session_flatten"
                in_pos = False

            if not in_pos:
                trades.append({
                    "entry_idx": entry_bar,
                    "exit_idx": i,
                    "net_pnl": pnl,
                    "exit_reason": exit_reason,
                    "is_win": pnl > 0
                })

    return pl.DataFrame(trades) if trades else pl.DataFrame()

# ---------------------------------------------------------
# 3. Walk-Forward ML Meta-Filter (Purged & Embargoed)
# ---------------------------------------------------------
def train_walk_forward_meta_filter(df: pl.DataFrame, feature_cols: list[str]) -> dict:
    """
    Trains a causal Logistic Regression meta-filter on historical trade setups.
    """
    X = df.select(feature_cols).to_numpy()
    y = (df["target_pnl"] > 0).to_numpy().astype(int)

    tscv = TimeSeriesSplit(n_splits=5)
    out_of_sample_preds = np.zeros(len(df))

    pipeline = Pipeline([
        ("scaler", StandardScaler()),
        ("classifier", LogisticRegression(class_weight="balanced", max_iter=200))
    ])

    for train_idx, test_idx in tscv.split(X):
        # 1-fold embargo to eliminate cross-boundary overlap
        embargoed_test_idx = test_idx[1:]

        pipeline.fit(X[train_idx], y[train_idx])
        probs = pipeline.predict_proba(X[embargoed_test_idx])[:, 1]
        out_of_sample_preds[embargoed_test_idx] = probs

    return {"predictions": out_of_sample_preds, "model": pipeline}

Worked Numeric Walkthrough: Hand-Checkable Math

Let us evaluate the math for an S3 perpetual funding trade on a Coinbase-like hourly schedule.

Trade Parameters:

  • Position: Long 1.0 BTC at $84,200.00.
  • Target Distance: $842.00 (1.0 × ATR). Stop Distance: $1,010.40 (1.2 × ATR).
  • M5 Observed Spread: $3.50. Hourly Realized Funding Rate: +0.0020% (Longs pay shorts).
Step Metric Formula Value (Stand-Down Gate) Value (Funding-Blind Gate)
1 Entry Fill Price Next_Open + 0.5 * Spread $84,201.75 $84,201.75
2 Raw Trade Exit (Target Hit) Target_Price - 0.5 * Spread $85,040.00 $85,040.00
3 Gross Trading P&L Exit_Price - Entry_Price +$838.25 +$838.25
4 Settlement Straddled? Crosses top-of-hour? NO (Stood down) YES (Held across 2 hours)
5 Realized Funding Cost 2 * (Notional * Rate) $0.00 2 * ($84,200 * 0.002%) = $3.37
6 Total Round-Trip Spread Entry_Spread + Exit_Spread $3.50 $3.50
7 Net Realized P&L Gross - Spread - Funding +$834.75 +$831.38

What this means for your P&L: While a $3.37 funding leakage appears small on a single trade, compounding that drag across 500 annual trades erodes $1,685 per contract in pure friction. Standing down during settlement buffers captures 99.6% of directional alpha while paying zero holding rent.


Testing It Honestly

Pitfall Visible in Strategy Lab Deceptive Result Robust Defense Mechanism
Weekday Dummy Artifacts Finding “Monday Alpha” that vanishes out of sample. Drop weekday dummies. Encode UTC hours cyclically via sin/cos. Weekly effects collapse to Sunday 23:00 UTC MLQuants.
Funding Schedule Generalization Modeling an hourly venue using 8-hour batch assumptions. Dynamically load the venue’s settlement cadence from the instrument master.
Midday Range Starvation High win-rates with negative total P&L due to time stops. Enforce the c2t <= 0.10 cost-to-target gate. If ATR collapses, stand down regardless of spread tightness.
Overfitting Micro-Sleeves Claiming a 10-minute trading window is an edge. Test ±10m, ±15m, and ±30m buffers. If alpha only exists in one narrow window, reject it as sample noise.
Favorable Ambiguity Assumption Inflating Sharpe ratio by booking targets on dual-touch bars. Enforce adverse-first resolution (always book the stop loss on ambiguous intra-bar touches).

Variants & Extensions

Variant Parameter Shift Target Condition Key Trade-off to Audit
S1: Midday Blackout Exclude 11:30–13:30 ET entirely. Commodity ETPs with wide midday spread-to-ATR ratios. Eliminates time-stop decay; lowers annual trade count by 25%.
S2: London Open Sleeve Trade 08:00–10:00 UTC exclusively. High-beta crypto perpetuals. Maximizes momentum capture; reduces daily exposure.
S3: Asymmetric Carry Trade through funding only when holding the receiving side. Persistent high-premium market regimes. Captures funding subsidy; introduces directional inventory risk.
HTF Causal Gate Require H1 EMA20 alignment on M5 breakouts. RTH commodity index pools. Cuts false breakout rates by ~30%; delays entry timing.
Step-Out to M15 Resample M5 signals to M15 bars. Niche commodity wrappers with wide spreads. Improves spread-to-ATR ratio; reduces annual trade opportunities.

Hands-On Project

Deliverable: docs/research/m13_session_lab.md and notebooks/m13_session_lab.ipynb. Build the end-to-end multi-clock strategy lab, run purged walk-forward backtests for S1, S2, and S3, and publish a one-page decision memo per lane.

Project Card — M13 Session Lab (v1.0)

Area Specification Requirement
Universe & Data ETP Lane: GLD (Physical Gold) + PDBC (Commodity Pool).<br/>Crypto Lane: BTC-USDT and ETH-USDT spot and linear perps on approved CEX.
Timeframes & Horizon Primary M5 execution. Unconditional same-session forced flatten.
Venue Clocks ETP: NYSE RTH (09:30–16:00 ET). Imbalance freeze 15:50–16:00 ET.<br/>Crypto: UTC Synthetic (00:00–23:50 UTC). Hourly & 8-hour funding calendars.
Execution Policy Signal at bar t close -> Fill at bar t+1 open. Full observed spread deducted. Adverse intra-bar ambiguity resolution.
Risk Parameters 0.25% equity risk per trade. Max 3 trades per session. Daily portfolio stop: 1.0%.
Validation Architecture 5-Fold Chronological Walk-Forward with 1-session embargo. Strict DST shift tests.
Reject Criteria Reject if cost-to-target > 10%, if ambiguous share > 5%, or if ML fails to beat deterministic baseline out-of-sample.

Lab Tasks:

  1. Load Market Data: Ingest 1 year of M5 bars with real-time spreads. Verify timezone formatting and timestamp alignments per M4.
  2. Implement Hard Gates: Code the session atlas, auction freeze bouncer, and venue funding stand-down modules.
  3. Run Baseline vs. Gated Replays: Run walk-forward simulations for S1, S2, and S3 against ungated control baselines.
  4. Train ML Meta-Filters: Fit causal logistic regression and XGBoost classifiers on training folds. Evaluate performance on embargoed test sets.
  5. Ablation & Stress Testing: Run base, p50, and p90 spread stress models. Verify performance across seasonal Daylight Saving Time shifts.

Key Takeaways

  • A session filter is a cost bouncer: Filtering for cheap, tall bars protects your edge before indicator logic evaluates direction.
  • RTH and Crypto demand separate atlases: Never pool 24-hour crypto data with U-shaped exchange sessions into a single statistical average.
  • Crypto weekday alpha is an hourly illusion: Weekly retail anomalies concentrate into Sunday 23:00 to Monday 00:00 UTC.
  • Auctions are canal locks: Gate out trading during the 15:50–16:00 ET imbalance freeze unless modeling explicit auction mechanics.
  • Funding is explicit lease rent: Stand down ±15 minutes around settlement timestamps or book realized cash payments.
  • Deterministic baselines come first: An ML meta-filter must prove out-of-sample information ratio gains over a simple rule before earning deployment.

References


Next: Module 14 — Intraday Events · Core: Module 13 — Sessions, Auctions & Funding Clocks