"""The seasonal screen, pointed at the five instruments it has never seen. seasonal.py's verdict on the four tick-backed instruments (EURUSD, USDJPY, XAUUSD, SP500) is in: two directional survivors, both real, both smaller than their spread. This runs the IDENTICAL statistics - same circular-rotation family-wise null, same max-|t| bar, same split-half re-measurement - on the five SQX-decoded instruments that share no data path with the originals: FTSE100, UK100, WTI (two independent feeds), USDCAD. Breadth is the one axis the seasonal question has not been tested on, and two feeds of the same market (WTI, and FTSE100/UK100) double as a replication check: a real effect must appear in both. WHAT IS WEAKER HERE THAN IN seasonal.py, STATED UP FRONT -------------------------------------------------------- spread synthesised, not quoted: breadth.MidBook applies a flat relative spread (breadth.SPREAD_BP, rounded UP from measured peers). The move/spread and spread/ATR columns are therefore APPROXIMATE and carry no hour-of-day spread shape - a session-open spread spike is invisible. A bucket must clear its spread by a wide margin before it is worth tick-level follow-up. clock timestamps are whatever the SQX files carry (Dukascopy exports are typically UTC, the5ers feeds broker time = UTC+2). Bucket STATISTICS are unaffected - only the label's wall-clock meaning is; treat "hour k" as file-time and match sessions per feed, not across feeds. drift/t UNAFFECTED by both caveats: computed on mid-price log returns, spread-free. Run: python breadth_seasonal.py (all five, hour/dow/month) python breadth_seasonal.py UK100_the5ers ... (subset, by raw symbol name) """ import sys import numpy as np import breadth, seasonal sys.stdout.reconfigure(encoding='utf-8', errors='replace') if __name__ == '__main__': syms = [s for s in sys.argv[1:] if s in breadth.SPREAD_BP] or list(breadth.SPREAD_BP) frames = {} print("=== loading (M1 -> H1, synthesised book: see module docstring) ===") for s in syms: try: _, frames[s] = breadth.get(s, 'H1') print(f" {breadth.NICE[s]:>8}: {frames[s].n:,} H1 bars") except Exception as ex: print(f" {breadth.NICE[s]:>8}: FAILED - {ex}") survivors = [] for kind in ('hour', 'dow', 'month'): print(f"\n{'='*100}\n=== {kind.upper()} - five breadth instruments, identical null " f"and bar to seasonal.py (clock = file time) ===\n{'='*100}") for s, f in frames.items(): res = seasonal.analyse_frame(f, breadth.NICE[s], kind=kind) for k in seasonal.report(res): survivors.append((breadth.NICE[s], kind, k)) print(f"\n{'='*100}") if survivors: print("family-wise survivors across the whole run (pre split-half):") for s, kind, k in survivors: print(f" {s} {kind} bucket {k}") print("replication check: an effect real in FTSE100 must appear in UK100, and " "WTI_d in WTI_5 - same market, independent feeds.") else: print("no bucket on any of the five instruments clears its family-wise bar.")