Tracker sweep + executor robustness: net-R chain, archive inventory, std::grid, per-cell fault isolation (12 issues) #270
@@ -121,8 +121,8 @@ fn graph_introspect_vocabulary_lists_exactly_the_closed_roster_count() {
|
||||
let lines: Vec<&str> = stdout.lines().filter(|l| !l.is_empty()).collect();
|
||||
assert_eq!(
|
||||
lines.len(),
|
||||
28,
|
||||
"the std-only (no project) vocabulary has exactly the roster's 28 entries: {stdout}"
|
||||
29,
|
||||
"the std-only (no project) vocabulary has exactly the roster's 29 entries: {stdout}"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ pub use rolling_max::RollingMax;
|
||||
pub use rolling_min::RollingMin;
|
||||
pub use scale::Scale;
|
||||
pub use series_reducer::SeriesReducer;
|
||||
pub use session::Session;
|
||||
pub use session::{Session, SessionFrankfurt};
|
||||
pub use sim_broker::SimBroker;
|
||||
pub use sizer::Sizer;
|
||||
pub use sma::Sma;
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
//!
|
||||
//! **Cold guard.** If the trigger column is empty (not yet fired) → `None`.
|
||||
|
||||
use aura_core::{Cell, Ctx, FieldSpec, Firing, Node, NodeSchema, PortSpec, PrimitiveBuilder, ScalarKind};
|
||||
use aura_core::{
|
||||
Cell, Ctx, FieldSpec, Firing, Node, NodeSchema, ParamSpec, PortSpec, PrimitiveBuilder, ScalarKind,
|
||||
};
|
||||
use chrono::{TimeZone, Timelike};
|
||||
|
||||
/// Frankfurt-session bar indexer. Holds the open offset (minutes past local
|
||||
@@ -76,6 +78,33 @@ impl Session {
|
||||
}
|
||||
}
|
||||
|
||||
/// The zero-arg `SessionFrankfurt` roster preset (#261): the Frankfurt open
|
||||
/// (09:00 `Europe/Berlin`) baked as a literal, so the closed `std_vocabulary`
|
||||
/// roster can reach a `Session` without a structural construction argument
|
||||
/// (`Session::builder` itself stays absent from the roster — #155 scope).
|
||||
/// The one remaining knob, `period_minutes` (i64, conventionally 15 — the
|
||||
/// resampler's bar width), is declared as the node's sole `ParamSpec` and
|
||||
/// bound through it via the single-knob `CarryCost`/`ConstantCost`/
|
||||
/// `VolSlippageCost` pattern. This is additive: `Session::builder` is
|
||||
/// untouched and stays the vehicle for other timezones/opens.
|
||||
pub struct SessionFrankfurt;
|
||||
|
||||
impl SessionFrankfurt {
|
||||
/// The param-generic recipe: one `period_minutes` I64 knob, the Frankfurt
|
||||
/// open/timezone baked in the closure.
|
||||
pub fn builder() -> PrimitiveBuilder {
|
||||
PrimitiveBuilder::new(
|
||||
"SessionFrankfurt",
|
||||
NodeSchema {
|
||||
inputs: vec![PortSpec { kind: ScalarKind::F64, firing: Firing::Any, name: "trigger".into() }],
|
||||
output: vec![FieldSpec { name: "bars_since_open".into(), kind: ScalarKind::I64 }],
|
||||
params: vec![ParamSpec { name: "period_minutes".into(), kind: ScalarKind::I64 }],
|
||||
},
|
||||
|p| Box::new(Session::new(9, 0, chrono_tz::Europe::Berlin, p[0].i64())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for Session {
|
||||
fn lookbacks(&self) -> Vec<usize> {
|
||||
vec![1]
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
use crate::{
|
||||
Abs, Add, And, Bias, CarryCost, Const, ConstantCost, Delay, Div, Ema, EqConst, FixedStop, Gt,
|
||||
Latch, LongOnly, Max, Min, Mul, PositionManagement, Resample, RollingMax, RollingMin, Scale,
|
||||
Sizer, Sma, Sqrt, Sub, VolSlippageCost,
|
||||
SessionFrankfurt, Sizer, Sma, Sqrt, Sub, VolSlippageCost,
|
||||
};
|
||||
use aura_core::PrimitiveBuilder;
|
||||
|
||||
@@ -81,6 +81,7 @@ std_vocabulary_roster! {
|
||||
"RollingMax" => RollingMax,
|
||||
"RollingMin" => RollingMin,
|
||||
"Scale" => Scale,
|
||||
"SessionFrankfurt" => SessionFrankfurt,
|
||||
"Sizer" => Sizer,
|
||||
"SMA" => Sma,
|
||||
"Sqrt" => Sqrt,
|
||||
@@ -129,7 +130,7 @@ mod tests {
|
||||
assert!(!std_vocabulary_types().contains(&"LinComb")); // construction-arg node
|
||||
assert!(!std_vocabulary_types().contains(&"Recorder")); // sink
|
||||
assert!(!std_vocabulary_types().contains(&"nope"));
|
||||
// count guard: pins the roster at exactly 28 entries
|
||||
assert_eq!(std_vocabulary_types().len(), 28);
|
||||
// count guard: pins the roster at exactly 29 entries
|
||||
assert_eq!(std_vocabulary_types().len(), 29);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user