feat(aura-engine): WalkForwardResult::named_params — mirror SweepFamily::named_params
Add the typed/named convenience view on `WalkForwardResult`, closing the symmetry cycle 0048 left open: it shares the `(space, tag-free Vec<Cell>)` idiom with `SweepFamily` but had no named-params accessor, so a consumer hand-wrote `zip_params(&result.space, &result.windows[i].run.chosen_params)`. `named_params(window)` pairs each param-space name with that window's chosen value in slot order, delegating to `zip_params` — the direct mirror of `SweepFamily::named_params`. A derived view, no new stored state. closes #76
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
|
||||
use crate::sweep::run_indexed;
|
||||
use crate::{MetricStats, ParamSpec, RunReport, ScalarKind, Timestamp};
|
||||
use aura_core::Cell;
|
||||
use aura_core::{zip_params, Cell, Scalar};
|
||||
|
||||
/// One rolling split's time bounds: an in-sample window and the out-of-sample
|
||||
/// window that follows it. Carries ONLY bounds — never tick data (#71). C2
|
||||
@@ -165,6 +165,15 @@ pub struct WalkForwardResult {
|
||||
pub stitched_oos_equity: Vec<(Timestamp, f64)>,
|
||||
}
|
||||
|
||||
impl WalkForwardResult {
|
||||
/// The chosen params of the `window`-th outcome paired with their names — a
|
||||
/// derived view over the carried param-space (reuses [`zip_params`]); the
|
||||
/// walk-forward mirror of [`SweepFamily::named_params`](crate::SweepFamily).
|
||||
pub fn named_params(&self, window: usize) -> Vec<(String, Scalar)> {
|
||||
zip_params(&self.space, &self.windows[window].run.chosen_params)
|
||||
}
|
||||
}
|
||||
|
||||
/// Roll the windows, run `run_window` on each disjointly in parallel (C1, via the
|
||||
/// shared [`run_indexed`](crate::sweep) core), then stitch the OOS equity into one
|
||||
/// continuous curve. The varying dimension is the *data window* (C12 axis 3).
|
||||
@@ -437,6 +446,48 @@ mod tests {
|
||||
assert_eq!(stab[0].mean, 0.75);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn named_params_pairs_each_name_with_the_chosen_window_value() {
|
||||
// #76: WalkForwardResult::named_params(w) is the typed/named view — it
|
||||
// pairs each param-space NAME with window `w`'s chosen VALUE, in slot
|
||||
// order, reading the right window. Mirror of SweepFamily::named_params.
|
||||
// Expected vectors are spelled out explicitly (not via zip_params) so the
|
||||
// assertion pins the observable pairing, not the implementation.
|
||||
let mk = |fast: i64, scale: f64| WindowOutcome {
|
||||
bounds: WindowBounds {
|
||||
is: (Timestamp(0), Timestamp(0)),
|
||||
oos: (Timestamp(0), Timestamp(0)),
|
||||
},
|
||||
run: WindowRun {
|
||||
chosen_params: vec![Cell::from_i64(fast), Cell::from_f64(scale)],
|
||||
oos_equity: vec![],
|
||||
oos_report: dummy_report(),
|
||||
},
|
||||
};
|
||||
let result = WalkForwardResult {
|
||||
space: vec![
|
||||
ParamSpec { name: "sma.fast".to_string(), kind: ScalarKind::I64 },
|
||||
ParamSpec { name: "exposure.scale".to_string(), kind: ScalarKind::F64 },
|
||||
],
|
||||
windows: vec![mk(8, 0.25), mk(13, 0.75)],
|
||||
stitched_oos_equity: vec![],
|
||||
};
|
||||
assert_eq!(
|
||||
result.named_params(0),
|
||||
vec![
|
||||
("sma.fast".to_string(), Scalar::i64(8)),
|
||||
("exposure.scale".to_string(), Scalar::f64(0.25)),
|
||||
],
|
||||
);
|
||||
assert_eq!(
|
||||
result.named_params(1),
|
||||
vec![
|
||||
("sma.fast".to_string(), Scalar::i64(13)),
|
||||
("exposure.scale".to_string(), Scalar::f64(0.75)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roller_rolling_emits_consecutive_oos_windows() {
|
||||
// spec §Testing 1: rolling, origin=0, is_len=10, oos_len=5, step=5, end=24.
|
||||
|
||||
Reference in New Issue
Block a user