//! Gated integration test: the GER40 session-breakout shipped as a //! World-consumable `Composite` blueprint. Proves the blueprint //! reproduces the shipped hand-wired `FlatGraph` EXACTLY (C23) and that its //! `param_space()` is the two genuine tuning knobs only — no `delay.lag`, no //! bar-period (the desync trap, #96). //! //! Mirrors `tests/ger40_breakout_real.rs` / `real_bars.rs`: the data-gated //! checks skip with a note where the local Pepperstone archive is absent, so //! `cargo test --workspace` stays green anywhere. The `param_space()` check is //! PURE (no data) and runs everywhere. //! //! The breakout wiring — both the shipped hand-wired `FlatGraph` //! (`build_harness()`) and the new blueprint factory //! (`ger40_breakout_blueprint()`) — lives once in the shared module //! (`shared/breakout_real.rs`) and is reused by the example and the tests. use std::sync::Arc; use aura_core::Scalar; use chrono_tz::Europe::Berlin; use data_server::{DataServer, DEFAULT_DATA_PATH}; #[path = "../examples/shared/breakout_real.rs"] mod breakout_real; use breakout_real::*; // September 2024 (inclusive), the same window the example demonstrates and the // hand-wired determinism test pins. const YEAR: i32 = 2024; const MONTH: u32 = 9; /// (a) PURE — `param_space()` of the blueprint is EXACTLY the two genuine tuning /// knobs `entry_bar.target` and `exit_bar.target`, and contains NEITHER /// `delay.lag` NOR any bar-period param. This is the #96 resolution made /// executable: the bar-period is bound structurally (both Resample and Session /// at construction, locked equal) and `delay.lag` is bound out, so neither can /// be swept into a desync. No data needed — runs everywhere. #[test] fn param_space_is_exactly_entry_and_exit_bar_targets() { let (bp, _taps) = ger40_breakout_blueprint(15, 9, 0, Berlin); let space = bp.param_space(); let names: Vec<&str> = space.iter().map(|p| p.name.as_str()).collect(); assert_eq!( names, vec!["entry_bar.target", "exit_bar.target"], "param_space() must be exactly the two EqConst targets", ); // Belt-and-braces on the two specific leaks #96 named, independent of order. assert!( !names.iter().any(|n| n.contains("lag")), "delay.lag must be bound out of the space (a structural constant, not a knob)", ); assert!( !names.iter().any(|n| n.contains("period")), "no bar-period param may leak (it is a structural construction arg, locked equal)", ); } /// (c) determinism (PURE) — two blueprints constructed with the same args expose /// the identical `param_space()`; the construction is a deterministic function of /// its args. (The data-gated run-level determinism is asserted in /// `composite_matches_flatgraph_bit_identical`.) #[test] fn blueprint_param_space_is_construction_deterministic() { let a = ger40_breakout_blueprint(15, 9, 0, Berlin).0.param_space(); let b = ger40_breakout_blueprint(15, 9, 0, Berlin).0.param_space(); assert_eq!(a, b, "blueprint param_space() is a deterministic function of its args"); } /// Run the blueprint-bootstrapped harness over `[from_ms, to_ms]` and drain the /// recorded per-bar `(held, equity)` series. Fresh build per call (fresh nodes + /// channels) keeps two runs disjoint for the C1 determinism assertion. fn run_blueprint(server: &Arc, from_ms: i64, to_ms: i64) -> Vec<(f64, f64)> { let (bp, taps) = ger40_breakout_blueprint(BAR_MINUTES, SESSION_HOUR, SESSION_MINUTE, Berlin); let mut h = bp .with("entry_bar.target", Scalar::i64(3)) .with("exit_bar.target", Scalar::i64(5)) .bootstrap() .expect("blueprint bootstraps with entry=3, exit=5"); let sources = open_ohlc_sources(server, from_ms, to_ms).expect("GER40 has data in the Sept-2024 window"); h.run(sources); let trace = drain_trace(&taps); trace.iter().map(|b| (b.held, b.equity)).collect() } /// Run the shipped hand-wired `FlatGraph` over the same window — the C23 /// reference series. fn run_flatgraph(server: &Arc, from_ms: i64, to_ms: i64) -> Vec<(f64, f64)> { let (mut h, taps) = build_harness(); let sources = open_ohlc_sources(server, from_ms, to_ms).expect("GER40 has data in the Sept-2024 window"); h.run(sources); let trace = drain_trace(&taps); trace.iter().map(|b| (b.held, b.equity)).collect() } /// (b) C23 fidelity (gated) — over the GER40 2024-09 window, bootstrapping the /// blueprint (entry=3, exit=5, bar_period=15) and running it produces a recorded /// `(held, equity)` series BIT-IDENTICAL to the existing hand-wired `FlatGraph` /// `build_harness()` over the same window. This is the behaviour-preserving /// guarantee (C23): the Composite is just the authoring form of the same flat /// graph, so the numbers must match exactly — not approximately. /// /// (c) determinism (gated) — the blueprint path is bit-identical on a fresh /// disjoint rerun (C1). #[test] fn composite_matches_flatgraph_bit_identical() { let server = Arc::new(DataServer::new(DEFAULT_DATA_PATH)); if !server.has_symbol(SYMBOL) { eprintln!("skip: no local data at {DEFAULT_DATA_PATH} (symbol {SYMBOL} absent)"); return; // hermetic elsewhere; exercises the real path where files exist } let (from_ms, to_ms) = utc_month_window_ms(YEAR, MONTH); let blueprint_series = run_blueprint(&server, from_ms, to_ms); assert!(!blueprint_series.is_empty(), "window resolved to zero bars"); // C23: the Composite blueprint reproduces the hand-wired FlatGraph EXACTLY. let flatgraph_series = run_flatgraph(&server, from_ms, to_ms); assert_eq!( blueprint_series, flatgraph_series, "blueprint must reproduce the hand-wired FlatGraph bit-identically (C23)", ); // C1: a fresh disjoint blueprint run over the identical window is bit-identical. let blueprint_rerun = run_blueprint(&server, from_ms, to_ms); assert_eq!( blueprint_series, blueprint_rerun, "blueprint recorded (held, equity) series bit-identical across runs (C1)", ); }