diff --git a/crates/aura-cli/src/campaign_run.rs b/crates/aura-cli/src/campaign_run.rs index 25f820c..1a2eb52 100644 --- a/crates/aura-cli/src/campaign_run.rs +++ b/crates/aura-cli/src/campaign_run.rs @@ -735,6 +735,17 @@ fn persist_campaign_traces( let space = crate::blueprint_axis_probe(blueprint_json, env).param_space(); let point = crate::point_from_params(&space, &nominee_report.manifest.params); let (from, to) = nominee_report.manifest.window; + // Same resolved pip the nominee ran at (`CliMemberRunner::run_member`'s + // `geo.pip_size`), else the C1 drift-alarm equality below would trip + // spuriously on a re-run computed at a different (default) pip. + let geo = instrument_geometry(server, &cell_rec.instrument).ok_or_else(|| { + format!( + "no recorded geometry for symbol '{}' at {} — refusing to re-run a \ + real instrument with a guessed pip", + cell_rec.instrument, + env.data_path() + ) + })?; let no_data = || { format!( "no data for instrument {} in the nominee window [{}, {}] (epoch-ns)", @@ -764,7 +775,7 @@ fn persist_campaign_traces( let (tx_ex, rx_ex) = mpsc::channel(); let (tx_r, rx_r) = mpsc::channel(); let (tx_req, rx_req) = mpsc::channel(); - let mut h = crate::wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, false) + let mut h = crate::wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, false, geo.pip_size) .bootstrap_with_cells(&point) .expect("the nominee's point re-bootstraps (it already ran this realization)"); let sources: Vec> = vec![Box::new(source)]; diff --git a/crates/aura-cli/src/main.rs b/crates/aura-cli/src/main.rs index bbf9749..f4b6990 100644 --- a/crates/aura-cli/src/main.rs +++ b/crates/aura-cli/src/main.rs @@ -1093,7 +1093,7 @@ fn reproduce_family_in( let (tx_r, _) = mpsc::channel(); let (tx_req, _) = mpsc::channel(); let space = - wrap_r(reload(), tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true).param_space(); + wrap_r(reload(), tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true, SYNTHETIC_PIP_SIZE).param_space(); let point = point_from_params(&space, &stored.manifest.params); // A MonteCarlo member carries no tuning params (the params-join is empty), so its // reproduce line would print a BLANK member label; the seed IS its realization @@ -1261,12 +1261,13 @@ fn wrap_r( tx_req: mpsc::Sender<(Timestamp, Vec)>, stop: StopRule, reduce: bool, + pip_size: f64, ) -> Composite { let mut g = GraphBuilder::new("r_sma"); // SMA-cross signal → Bias, nested as a serializable `price`→`bias` leg. let sig = g.add(BlueprintNode::Composite(signal)); // pip branch (verbatim from the retired `sample_blueprint_with_sinks`, #159). - let broker = g.add(SimBroker::builder(SYNTHETIC_PIP_SIZE)); + let broker = g.add(SimBroker::builder(pip_size)); // R branch: bias + price → RiskExecutor(vol_stop) → dense R-record. The stop is a // fixed `StopRule` — the pinned default constants, or an arbitrary per-regime rule // the caller resolved. @@ -1370,12 +1371,12 @@ fn run_signal_r( // The req tap (r_equity recorder) is wired but not persisted on this path; keep the // receiver alive so the sink's sends do not fail, but do not drain it. let (tx_req, _rx_req) = mpsc::channel(); - let wrapped = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, false); + let (sources, window, pip_size) = resolve_run_data(&data, env); + let wrapped = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, false, pip_size); let flat = wrapped .compile_with_params(params) .expect("signal binds + wraps to a valid harness"); let mut h = Harness::bootstrap(flat).expect("valid r-sma harness"); - let (sources, window, pip_size) = resolve_run_data(&data, env); h.run(sources); let eq_rows: Vec<(Timestamp, Vec)> = rx_eq.try_iter().collect(); let ex_rows: Vec<(Timestamp, Vec)> = rx_ex.try_iter().collect(); @@ -1414,7 +1415,7 @@ fn run_blueprint_member( let (tx_ex, rx_ex) = mpsc::channel(); let (tx_r, rx_r) = mpsc::channel(); let (tx_req, _rx_req) = mpsc::channel(); - let mut h = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, true) + let mut h = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, true, pip) .bootstrap_with_cells(point) .expect("member bootstraps (point kind-checked against param_space)"); h.run(sources); @@ -1461,7 +1462,7 @@ fn blueprint_axis_probe(doc: &str, env: &project::Env) -> Composite { let (tx_ex, _) = mpsc::channel(); let (tx_r, _) = mpsc::channel(); let (tx_req, _) = mpsc::channel(); - wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true) + wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true, SYNTHETIC_PIP_SIZE) } /// `aura sweep --list-axes`: one `:` line per open @@ -3386,6 +3387,7 @@ mod tests { tx_req, StopRule::Vol { length: 3, k: 2.0 }, false, + SYNTHETIC_PIP_SIZE, ) .compile_with_params(&[]) .expect("r-meanrev signal wraps to a valid harness"); diff --git a/crates/aura-cli/tests/cli_run.rs b/crates/aura-cli/tests/cli_run.rs index d1bfec7..e4fe732 100644 --- a/crates/aura-cli/tests/cli_run.rs +++ b/crates/aura-cli/tests/cli_run.rs @@ -1952,7 +1952,7 @@ fn walkforward_real_e2e_pins_the_exact_current_grade() { assert_eq!(wf["windows"].as_u64(), Some(9), "window count: {grade_line}"); // EXACT floats -- the byte-identity anchor the dissolution must preserve. // stitched_total_pips is retained only if the campaign runner keeps the OOS curve. - assert_eq!(wf["stitched_total_pips"].as_f64(), Some(-10398606.666650848), "stitched OOS pips: {grade_line}"); + assert_eq!(wf["stitched_total_pips"].as_f64(), Some(-1039.8606666650755), "stitched OOS pips: {grade_line}"); let r = &wf["oos_r"]; assert_eq!(r["n_trades"].as_u64(), Some(20681), "pooled OOS trade count: {grade_line}"); assert_eq!(r["expectancy_r"].as_f64(), Some(-0.002397100685333715), "pooled OOS expectancy R: {grade_line}"); @@ -2119,7 +2119,7 @@ fn walkforward_real_e2e_pins_the_exact_current_plateau_grade() { let wf = &v["walkforward"]; assert_eq!(wf["windows"].as_u64(), Some(9), "window count: {grade_line}"); // EXACT floats -- the byte-identity anchor a plateau-vs-argmax regression must preserve. - assert_eq!(wf["stitched_total_pips"].as_f64(), Some(-9683776.66663749), "stitched OOS pips: {grade_line}"); + assert_eq!(wf["stitched_total_pips"].as_f64(), Some(-968.3776666637464), "stitched OOS pips: {grade_line}"); let r = &wf["oos_r"]; assert_eq!(r["n_trades"].as_u64(), Some(20667), "pooled OOS trade count: {grade_line}"); assert_eq!(r["expectancy_r"].as_f64(), Some(0.007635120926372627), "pooled OOS expectancy R: {grade_line}");