Strategies
US Semiconductor Shock Diffusion into Tokyo: trade 6 Japanese chip names (JPEQ, 1-DAY) in the direction of a >=1.5-sigma SMH session, next-Tokyo-open entry, fixed 3-session clock, long + short (SMH.USEQ as signal source only)
Outcome: Abandoned
UsSemiShockTokyoDiffusionLS
Outcome Summary
UsSemiShockTokyoDiffusionLS tested whether large SMH moves carry into six Japanese semiconductor names over the next three Tokyo sessions, trading both directions. Backtest Review sent it to optimization: the strategy returned 149% in JPY with a 0.54% mean net trade, well above the cost floor, though drawdown was 43%. After 2 iterations, the analyst found that the pre-registered short arm, the check against the universe's survivorship bias, failed badly in the holdout while the long arm alone made the profit. The analyst ruled the premise falsified for this six-name symmetric design, and optimization was also rejected for breaking the drawdown limit.
Hypothesis
premise_falsified: The test the hypothesis pre-registered against its own survivorship bias failed out of sample. In the holdout (2025-01-23 to 2026-10-28) the short arm lost -9.0M JPY (133 trades, PF 0.43, -1.91% per trade), while the long arm, built from today's top-cap Japanese chip names, earned +12.7M JPY (PF 2.80). Over the full history the short arm is net negative (-0.89M JPY). The hypothesis stated that a long-only result does not show the premise. The edge is not a fee problem: the mean net trade return of 0.54% is well above the 0.12% JPEQ floor, and profit factor is 1.26. Separately, the optimization was rejected because only 2 of 20 walk-forward windows produced a candidate within the pre-registered 25% drawdown. The March 2020 sign-flip whipsaw drives the 43% full-history drawdown and sits in every later training window, so no out-of-sample record exists. This rejects this six-name, symmetric long/short operationalization of cross-time-zone diffusion, not the diffusion idea tested on a bias-free universe or benchmark-hedged design.
Implementation
Trades six Japanese chip names (8035, 6857, 6920, 7735, 6723, 4063 on JPEQ, daily bars) in the direction of a US SMH session whose return is at least shock_z (1.5) times its trailing 60-session std. SMH.USEQ is a signal-only leg and is never traded. The first Tokyo session after the shock is the event session; orders decided at its close fill at the next open. Each leg is sized at 16% of equity in 100-share board lots (one lot allowed up to 27%), and gross exposure is capped at 100%. A leg is closed after 3 sessions (open[T+1] to open[T+4]) or when an opposite-sign event fires. Long and short.
Verification Results
No code change. Run the backtest and the optimization with SF_SESSION_LEG_OPEN_FILLS on, or check the trade ledger's fill prices against the JPEQ session opens.
Fill timing is a platform concern, not a code defect. The code correctly expects a next-open fill: it decides at the T close and the order fills at the T+1 open. But in a multi-instrument session basket, the engine fills each leg at its own open only when SF_SESSION_LEG_OPEN_FILLS is on (default off). With it off, the overnight SMH data point or the first JPEQ leg's open tick can fill the other legs at their stale previous close.
Acceptable as is. Optionally keep a small buffer (e.g. cap at 0.97 x equity) so that a gap does not trim the lowest-ranked leg.
The gross cap and leg sizes are computed from session-T close prices, but the orders fill at the T+1 open. An overnight gap can push realised gross slightly above max_gross x equity. The base margin_capped_size then trims the last leg, which can leave it off the lot grid or skip it.
Make sure the paper warmup covers at least 130 JPEQ sessions and 61 SMH bars.
Paper/live restart: the regression deques and the pending-shock state are rebuilt only from replayed bars. A paper warmup shorter than ~130 Tokyo sessions plus 60 SMH bars would leave the strategy unable to trade after a restart. This does not affect the backtest.
Fill timing in a multi-leg session basket depends on a platform switch, not on this code. With SF_SESSION_LEG_OPEN_FILLS off (the default), NautilusTrader releases in-flight orders after ANY data point (session_open_gate.py docstring). The six JPEQ orders decided at the 15:30 JST close of session T could then be released by the overnight SMH.USEQ bar (~05:00-06:00 JST) or by the first JPEQ leg's open tick, and fill at the previous Tokyo close instead of each name's own T+1 open. That is a same-close fill: it would hand the strategy the overnight move after a US shock day, exactly the drift this hypothesis claims to capture. Before trusting any number, the analyst should confirm the run's frozen execution settings had SF_SESSION_LEG_OPEN_FILLS on, or check that fill prices equal the JPEQ opens. Separately, the six legs on one event date are one correlated bet (~222 independent dates), and the long arm carries winner bias. Read the short arm separately, as pre-registered.
Backtest Review
- Sharpe
- 0.59
- Total return
- 149.05%
- Max drawdown
- 43.31%
- Trades
- 1378
- Win rate
- 53.4%
- Profit factor
- 1.26
Development-period results warrant optimization: 1,107 closed positions across 188 entry dates, profit factor 1.311 and mean net trade return 0.566%, above the JPEQ 0.15% review floor.
Both arms earn: 607 longs average 0.554% net and 500 shorts average 0.581% net. Profitability is not confined to the survivorship-biased long arm.
QA’s stale-close hypothesis is not borne out by the entry-price comparison: 1,071 of 1,107 entries match their instrument’s catalog open within JPY 0.03; only 39 match the previous close. Spot checks across all six names support Tokyo-open execution and three-session holds.
The remaining 36 entry prices require reconciliation; the frozen execution switch settings were not supplied, so their loaded state remains unverified.
Drawdown of 43.31% exceeds the registered 25% risk objective. Optimization must assess whether permitted parameters improve risk without changing fixed sizing.
The six names are correlated: 188 entry dates describe event coverage better than 1,107 trades. Survivorship bias remains; preserve separate long and short reporting.
The required outbox write failed with PermissionError. The verdict was not saved to the specified file.
Iteration History
Make min_bars_required() return 2 (or delete the override). calculate_signal already guards its own readiness: _session_return needs 2 bars, _beta_sd needs a full 120-pair window and the SMH z needs 60 returns. The regression windows then start filling from the first bars, and the strategy is ready after about 121 sessions, inside the declared 130-bar warmup.
Warmup is counted twice, which leaves a dead zone in every validation window. min_bars_required returns beta_lookback + 2 = 122. The base template (base_template.py ~) does not call calculate_signal at all until len(self._bars) >= 122. The regression windows self._reg are filled ONLY inside calculate_signal, and _beta_sd returns None until a window holds 120 pairs. Every candidate needs `st is not None`, even with gap_k = 0, because beta also sets the gross-cap ranking. So the first trade can come only after about 122 + 120 = 242 Tokyo sessions. The frozen research contract declares evaluation.warmup_bars = 130 with boundary_policy 'reset_with_warmup'. After each walk-forward reset, the strategy gets 130 warmup bars and then cannot trade for about the first 112 sessions (~5 months) of the window. Events in that span are silently dropped, so per-window trade counts and validation Sharpe no longer measure the registered rule. The full backtest also loses about one extra year of 2018-2019 events.
Optional: keep the most recent unconsumed qualifying SMH bar (its z, r and ts) until a Tokyo session consumes it, and define the precedence when two shocks of different signs are pending.
A shock can be overwritten across a Tokyo holiday. Event detection reads only the LATEST SMH bar (smh_last_z / smh_last_r). If a qualifying SMH shock (say Friday) is followed by another SMH bar (Monday) before the next Tokyo session (Tuesday, after a Japanese Monday holiday), the earlier shock never triggers. The hypothesis says the first JPEQ session after a qualifying SMH bar is an event session. This happens only a few times a year (Japanese holidays where the intervening US bar is not itself a shock).
Optional: leave a small buffer (e.g. cap = 0.97 x equity) or check self.legs_balanced() / order failures in the report.
The gross cap is computed from session-T closes, but the orders fill at the T+1 open. On a large overnight gap the filled gross can slightly exceed 100% of equity at leverage 1.0, and the venue can then refuse or shrink the last leg. This is a small distortion, not a rule violation.
Make sure the paper warmup covers more than 130 Tokyo sessions plus the SMH lookback.
Paper restart: the regression deques and _smh_rets are not persisted scalars. The code depends on the bar replay to rebuild them, which needs at least 120 Tokyo sessions plus 60 SMH bars of warmup history. A disclosed same-direction event that falls on a leg's clock-expiry day re-targets the leg and nets it against the open position; this is reasonable and documented.
Outcome Summary
When the universe is chosen from today's top market caps, a profitable long arm says little; test cross-time-zone diffusion on a universe without survivorship bias or with a benchmark-hedged design, where a symmetric long/short split shows whether the edge is real.
The analyst abandoned it with the reason premise_falsified: in the 2025-01-23 to 2026-10-28 holdout, the short arm (the hypothesis's own check against survivorship bias) lost -9.0M JPY (PF 0.43, -1.91% per trade). The long arm earned +12.7M JPY, and the short arm was net negative over the full history. Optimization was also rejected because only 2 of 20 walk-forward windows produced a candidate within the pre-registered 25% drawdown limit.
After a US session in which SMH moved at least 1.5 times its trailing 60-session standard deviation, it traded six Tokyo chip names (JPEQ, daily bars) in the direction of SMH, long or short, entering at the next Tokyo open and exiting on a fixed 3-session clock, on the idea that the US shock reaches Japanese stocks over several days.
Over the full history (2018-07 to 2026-10) the backtest returned +149.1% in JPY (+74.3% in USD after a -74.7% FX effect) over 1,378 closed trades. Sharpe was 0.59 (CI -0.06 to 1.34), profit factor 1.26, mean net trade return 0.54% and max drawdown 43.3%, with losses of -29.9% in the COVID crash window and -10.3% in the 2025 tariff shock.
Backtest and paper results are hypothetical. Trading involves risk of loss.