feat(aura-engine): sweep named-binding — zip_params + SweepFamily.named_params (C12 #57)
Thread a derived named view of a sweep point so consumers stop hand-zipping param_space() names onto the bare &[Scalar]. The free function zip_params(space, point) -> Vec<(String, Scalar)> in aura-core is the one shared projection; GridSpace retains the ParamSpec list it already receives in new() (it was validated then discarded); SweepFamily carries it (stamped once in sweep_with_threads) and exposes named_params(i). The three CLI hand-zip sites collapse to one zip_params call each. The run-closure signature `Fn(&[Scalar]) -> RunReport` is byte-unchanged — the named view is a derived projection (C23: slot is identity, name is derived), not a closure-currency change — so #52's RandomSpace plugs into the same sweep() execution layer with zero signature reconciliation (#71 firewall held). sim_optimal_manifest now takes typed Vec<(String, Scalar)> and does the lossy f64 collapse internally (one place; the manifest's f64-precursor field owns its own lossiness — the typed-manifest upgrade stays the deferred typed-param-space item, a non-goal here). All eight call sites migrated: three sweep closures pass zip_params, five hand-listing callers (run_sample, run_sample_real, mc_family, run_macd, run_sample_seeded) pass Scalar::F64 literals. Behaviour-preserving: the collapse output is identical to the old per-site zip, so aura sweep / walkforward / run output is byte-identical; SweepFamily.space threaded into the aura-registry optimize test literal. Verified by the orchestrator: cargo test --workspace green (4 new tests: zip_params x2, sweep_family_carries_param_space, family_named_params_round_trips), cargo clippy --workspace --all-targets -D warnings clean. (rust-analyzer emitted stale mid-edit diagnostics; the real cargo build/test is clean.) refs #57
This commit is contained in:
+24
-36
@@ -13,7 +13,7 @@
|
||||
|
||||
mod render;
|
||||
|
||||
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
||||
use aura_core::{zip_params, Firing, Scalar, ScalarKind, Timestamp};
|
||||
use aura_engine::{
|
||||
f64_field, monte_carlo, param_stability, summarize, walk_forward, window_of, Composite, Edge,
|
||||
FlatGraph, GraphBuilder, Harness, McAggregate, McFamily, RollMode, RunManifest, RunReport,
|
||||
@@ -128,10 +128,13 @@ fn sample_harness() -> (
|
||||
/// label keeps it a single source (and a single edit point for #22's per-asset
|
||||
/// pip work).
|
||||
fn sim_optimal_manifest(
|
||||
params: Vec<(String, f64)>,
|
||||
params: Vec<(String, Scalar)>,
|
||||
window: (Timestamp, Timestamp),
|
||||
seed: u64,
|
||||
) -> RunManifest {
|
||||
// The lossy f64 collapse lives here — the manifest field (the deferred typed
|
||||
// param-space precursor) owns its own lossiness; callers pass typed Scalars.
|
||||
let params = params.into_iter().map(|(n, s)| (n, scalar_as_param_f64(&s))).collect();
|
||||
RunManifest {
|
||||
commit: option_env!("AURA_COMMIT").unwrap_or("unknown").to_string(),
|
||||
params,
|
||||
@@ -160,9 +163,9 @@ fn run_sample() -> RunReport {
|
||||
RunReport {
|
||||
manifest: sim_optimal_manifest(
|
||||
vec![
|
||||
("sma_fast".to_string(), 2.0),
|
||||
("sma_slow".to_string(), 4.0),
|
||||
("exposure_scale".to_string(), 0.5),
|
||||
("sma_fast".to_string(), Scalar::F64(2.0)),
|
||||
("sma_slow".to_string(), Scalar::F64(4.0)),
|
||||
("exposure_scale".to_string(), Scalar::F64(0.5)),
|
||||
],
|
||||
window,
|
||||
0,
|
||||
@@ -223,9 +226,9 @@ fn run_sample_real(symbol: &str, from_ms: Option<i64>, to_ms: Option<i64>) -> Ru
|
||||
RunReport {
|
||||
manifest: sim_optimal_manifest(
|
||||
vec![
|
||||
("sma_fast".to_string(), 2.0),
|
||||
("sma_slow".to_string(), 4.0),
|
||||
("exposure_scale".to_string(), 0.5),
|
||||
("sma_fast".to_string(), Scalar::F64(2.0)),
|
||||
("sma_slow".to_string(), Scalar::F64(4.0)),
|
||||
("exposure_scale".to_string(), Scalar::F64(0.5)),
|
||||
],
|
||||
window,
|
||||
0,
|
||||
@@ -383,13 +386,8 @@ fn sweep_family() -> SweepFamily {
|
||||
h.run(sources);
|
||||
let equity = f64_field(&rx_eq.try_iter().collect::<Vec<_>>(), 0);
|
||||
let exposure = f64_field(&rx_ex.try_iter().collect::<Vec<_>>(), 0);
|
||||
let params = space
|
||||
.iter()
|
||||
.zip(point)
|
||||
.map(|(ps, v)| (ps.name.clone(), scalar_as_param_f64(v)))
|
||||
.collect();
|
||||
RunReport {
|
||||
manifest: sim_optimal_manifest(params, window, 0),
|
||||
manifest: sim_optimal_manifest(zip_params(&space, point), window, 0),
|
||||
metrics: summarize(&equity, &exposure),
|
||||
}
|
||||
})
|
||||
@@ -500,13 +498,8 @@ fn sweep_over(from: Timestamp, to: Timestamp) -> SweepFamily {
|
||||
h.run(sources);
|
||||
let equity = f64_field(&rx_eq.try_iter().collect::<Vec<_>>(), 0);
|
||||
let exposure = f64_field(&rx_ex.try_iter().collect::<Vec<_>>(), 0);
|
||||
let params = space
|
||||
.iter()
|
||||
.zip(point)
|
||||
.map(|(ps, v)| (ps.name.clone(), scalar_as_param_f64(v)))
|
||||
.collect();
|
||||
RunReport {
|
||||
manifest: sim_optimal_manifest(params, window, 0),
|
||||
manifest: sim_optimal_manifest(zip_params(&space, point), window, 0),
|
||||
metrics: summarize(&equity, &exposure),
|
||||
}
|
||||
})
|
||||
@@ -527,13 +520,8 @@ fn run_oos(params: &[Scalar], from: Timestamp, to: Timestamp) -> (Vec<(Timestamp
|
||||
h.run(sources);
|
||||
let equity = f64_field(&rx_eq.try_iter().collect::<Vec<_>>(), 0);
|
||||
let exposure = f64_field(&rx_ex.try_iter().collect::<Vec<_>>(), 0);
|
||||
let named = space
|
||||
.iter()
|
||||
.zip(params)
|
||||
.map(|(ps, v)| (ps.name.clone(), scalar_as_param_f64(v)))
|
||||
.collect();
|
||||
let report = RunReport {
|
||||
manifest: sim_optimal_manifest(named, window, 0),
|
||||
manifest: sim_optimal_manifest(zip_params(&space, params), window, 0),
|
||||
metrics: summarize(&equity, &exposure),
|
||||
};
|
||||
(equity, report)
|
||||
@@ -612,9 +600,9 @@ fn mc_family() -> McFamily {
|
||||
RunReport {
|
||||
manifest: sim_optimal_manifest(
|
||||
vec![
|
||||
("sma_fast".to_string(), 2.0),
|
||||
("sma_slow".to_string(), 4.0),
|
||||
("exposure_scale".to_string(), 0.5),
|
||||
("sma_fast".to_string(), Scalar::F64(2.0)),
|
||||
("sma_slow".to_string(), Scalar::F64(4.0)),
|
||||
("exposure_scale".to_string(), Scalar::F64(0.5)),
|
||||
],
|
||||
window,
|
||||
seed,
|
||||
@@ -868,10 +856,10 @@ fn run_macd() -> RunReport {
|
||||
RunReport {
|
||||
manifest: sim_optimal_manifest(
|
||||
vec![
|
||||
("ema_fast".to_string(), 2.0),
|
||||
("ema_slow".to_string(), 4.0),
|
||||
("ema_signal".to_string(), 3.0),
|
||||
("exposure_scale".to_string(), 0.5),
|
||||
("ema_fast".to_string(), Scalar::F64(2.0)),
|
||||
("ema_slow".to_string(), Scalar::F64(4.0)),
|
||||
("ema_signal".to_string(), Scalar::F64(3.0)),
|
||||
("exposure_scale".to_string(), Scalar::F64(0.5)),
|
||||
],
|
||||
window,
|
||||
0,
|
||||
@@ -969,9 +957,9 @@ mod tests {
|
||||
let report = RunReport {
|
||||
manifest: sim_optimal_manifest(
|
||||
vec![
|
||||
("sma_fast".to_string(), 2.0),
|
||||
("sma_slow".to_string(), 4.0),
|
||||
("exposure_scale".to_string(), 0.5),
|
||||
("sma_fast".to_string(), Scalar::F64(2.0)),
|
||||
("sma_slow".to_string(), Scalar::F64(4.0)),
|
||||
("exposure_scale".to_string(), Scalar::F64(0.5)),
|
||||
],
|
||||
window,
|
||||
seed,
|
||||
|
||||
Reference in New Issue
Block a user