plan: 0066 stage1-r primitives + spec correction (VolStop -> composition)
VolStop was a design error (a fused node justified by a missing primitive). A node is a primitive only if not DAG-expressible from other primitives; a missing primitive is added, not fused away. Adds Mul + Sqrt primitives, removes the fused VolStop, expresses the vol stop as a composition (rolling EWMA stddev = k * Sqrt(Ema(Mul(d,d), length))). Spec 0065 b gets a correction note; full record on #117. refs #117 #119
This commit is contained in:
@@ -157,15 +157,31 @@ field is renamed to `bias_sign_flips` **with `#[serde(alias = "exposure_sign_fli
|
||||
historical `runs.jsonl` still deserialises (the planner pins the exact sites; ~311
|
||||
`exposure` / 82 `Exposure` references across `crates/`).
|
||||
|
||||
**(b) `VolStop` + `FixedStop` stop-rule nodes (#119) — new, `aura-std`.**
|
||||
**(b) Stop-rule (#119).**
|
||||
|
||||
> **CORRECTION (2026-06-24, #117).** The "fused `VolStop` node (no Abs/Mul
|
||||
> primitive exists, so fuse)" below was a design error. A node is a PRIMITIVE only
|
||||
> if it is **not** DAG-expressible from other primitives; a missing primitive is
|
||||
> **added**, not fused away. The vol stop is pure feed-forward arithmetic → a
|
||||
> **composition**, not a primitive. Corrected design:
|
||||
> - add primitives `Mul` (two-stream f64 product) + `Sqrt` to `aura-std`;
|
||||
> - the vol stop is a **rolling stddev (EWMA volatility)**: `stop_distance =
|
||||
> k · Sqrt(Ema(Mul(Δ,Δ), length))`, `Δ = Sub(price, Delay(price,1))`, scaled
|
||||
> `k·σ` via the existing `LinComb` (k a param weight). `Sqrt` is mandatory
|
||||
> (variance is price², `stop_distance` must be price so R is dimensionless);
|
||||
> `Abs` is **not** added (Δ² not |Δ|);
|
||||
> - this `vol_stop(length, k) → Composite` lives in `aura-engine` (composites need
|
||||
> `GraphBuilder`); the fused `VolStop` node is removed;
|
||||
> - `FixedStop` is **kept** as a legitimate primitive (a param constant gated on
|
||||
> its price input — a source-less `Const` has no firing trigger in the push model).
|
||||
>
|
||||
> The block below is the superseded pre-correction shape, retained for ancestry.
|
||||
|
||||
```rust
|
||||
// VolStop: one fused node (no Abs/Mul primitive exists, so abs+delta+EMA must fuse).
|
||||
// SUPERSEDED (see CORRECTION above): the fused-node shape, not the shipped design.
|
||||
pub struct VolStop { length: usize, k: f64, prev_price: Option<f64>, ema: f64, comp: f64, count: usize, out: [Cell; 1] }
|
||||
// eval: d = |price - prev_price|; ema = EMA_length(d) (Kahan, like Sma); out = k * ema.
|
||||
// None until warm (count < length). Input "price" (f64, Any). Output "stop_distance" (f64).
|
||||
// Params length:i64, k:f64. prev_price updated AFTER use (intra-node z⁻¹, C2-clean).
|
||||
pub struct FixedStop { distance: f64, out: [Cell; 1] } // out = distance, constant; test fixture + axis sibling
|
||||
pub struct FixedStop { distance: f64, out: [Cell; 1] } // KEPT: out = distance, constant (a triggered-constant primitive)
|
||||
```
|
||||
|
||||
**(c) `PositionManagement` node (#127) — new, `aura-std`. The dense R-record.**
|
||||
|
||||
Reference in New Issue
Block a user