refactor: split the aura-std roster into C28 layer crates
Phase 4 of the Stratification milestone. aura-std held four C28 ladder layers in one roster; this cuts them into layer-aligned, aura-core-only node crates so the import direction is enforced by the crate graph: - aura-std — engine nodes only (arithmetic/logic/rolling + sinks) - aura-market — session, resample - aura-strategy — bias, stops, sizer, cost-model machinery - aura-backtest — sim_broker, position_management - aura-vocabulary — the relocated closed std_vocabulary roster Node modules move verbatim (byte-identical renames); consumers are rewired by import path only. A new structural test (aura-vocabulary/tests/c28_layering.rs) asserts each node crate's [dependencies] stay within its C28-permitted inner set, catching the acyclic-but-outward violation the compiler misses. Behaviour byte-identical: full workspace suite green (1448 tests), no golden edited, clippy -D warnings clean. C28 Status block updated. closes #288
This commit is contained in:
Generated
+51
@@ -105,6 +105,13 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aura-backtest"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"aura-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aura-bench"
|
name = "aura-bench"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -139,6 +146,7 @@ dependencies = [
|
|||||||
name = "aura-cli"
|
name = "aura-cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aura-backtest",
|
||||||
"aura-campaign",
|
"aura-campaign",
|
||||||
"aura-composites",
|
"aura-composites",
|
||||||
"aura-core",
|
"aura-core",
|
||||||
@@ -147,6 +155,8 @@ dependencies = [
|
|||||||
"aura-registry",
|
"aura-registry",
|
||||||
"aura-research",
|
"aura-research",
|
||||||
"aura-std",
|
"aura-std",
|
||||||
|
"aura-strategy",
|
||||||
|
"aura-vocabulary",
|
||||||
"clap",
|
"clap",
|
||||||
"data-server",
|
"data-server",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -162,9 +172,11 @@ dependencies = [
|
|||||||
name = "aura-composites"
|
name = "aura-composites"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aura-backtest",
|
||||||
"aura-core",
|
"aura-core",
|
||||||
"aura-engine",
|
"aura-engine",
|
||||||
"aura-std",
|
"aura-std",
|
||||||
|
"aura-strategy",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -181,8 +193,12 @@ name = "aura-engine"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aura-analysis",
|
"aura-analysis",
|
||||||
|
"aura-backtest",
|
||||||
"aura-core",
|
"aura-core",
|
||||||
|
"aura-market",
|
||||||
"aura-std",
|
"aura-std",
|
||||||
|
"aura-strategy",
|
||||||
|
"aura-vocabulary",
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
"rayon",
|
"rayon",
|
||||||
@@ -194,15 +210,27 @@ dependencies = [
|
|||||||
name = "aura-ingest"
|
name = "aura-ingest"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aura-backtest",
|
||||||
"aura-core",
|
"aura-core",
|
||||||
"aura-engine",
|
"aura-engine",
|
||||||
|
"aura-market",
|
||||||
"aura-std",
|
"aura-std",
|
||||||
|
"aura-strategy",
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
"data-server",
|
"data-server",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aura-market"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"aura-core",
|
||||||
|
"chrono",
|
||||||
|
"chrono-tz",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aura-registry"
|
name = "aura-registry"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -211,6 +239,8 @@ dependencies = [
|
|||||||
"aura-engine",
|
"aura-engine",
|
||||||
"aura-research",
|
"aura-research",
|
||||||
"aura-std",
|
"aura-std",
|
||||||
|
"aura-strategy",
|
||||||
|
"aura-vocabulary",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
@@ -229,11 +259,32 @@ dependencies = [
|
|||||||
name = "aura-std"
|
name = "aura-std"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aura-backtest",
|
||||||
"aura-core",
|
"aura-core",
|
||||||
|
"aura-strategy",
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aura-strategy"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"aura-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aura-vocabulary"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"aura-backtest",
|
||||||
|
"aura-core",
|
||||||
|
"aura-market",
|
||||||
|
"aura-std",
|
||||||
|
"aura-strategy",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ resolver = "3"
|
|||||||
members = [
|
members = [
|
||||||
"crates/aura-core",
|
"crates/aura-core",
|
||||||
"crates/aura-std",
|
"crates/aura-std",
|
||||||
|
"crates/aura-vocabulary",
|
||||||
|
"crates/aura-market",
|
||||||
|
"crates/aura-strategy",
|
||||||
|
"crates/aura-backtest",
|
||||||
"crates/aura-engine",
|
"crates/aura-engine",
|
||||||
"crates/aura-analysis",
|
"crates/aura-analysis",
|
||||||
"crates/aura-composites",
|
"crates/aura-composites",
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "aura-backtest"
|
||||||
|
edition.workspace = true
|
||||||
|
version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
aura-core = { path = "../aura-core" }
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
//! `aura-backtest` — the backtest-execution node layer (C28): simulated execution
|
||||||
|
//! without money (the `SimBroker` pip yardstick, position management), measured in
|
||||||
|
//! R. Depends only on `aura-core`.
|
||||||
|
|
||||||
|
mod position_management;
|
||||||
|
mod sim_broker;
|
||||||
|
|
||||||
|
pub use position_management::{
|
||||||
|
ExitReason, FIELD_NAMES as PM_FIELD_NAMES, PositionManagement,
|
||||||
|
RECORD_KINDS as PM_RECORD_KINDS, WIDTH as PM_WIDTH,
|
||||||
|
};
|
||||||
|
pub use sim_broker::SimBroker;
|
||||||
@@ -22,6 +22,9 @@ aura-research = { path = "../aura-research" }
|
|||||||
# and renders its outcome (#198).
|
# and renders its outcome (#198).
|
||||||
aura-campaign = { path = "../aura-campaign" }
|
aura-campaign = { path = "../aura-campaign" }
|
||||||
aura-std = { path = "../aura-std" }
|
aura-std = { path = "../aura-std" }
|
||||||
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
|
aura-vocabulary = { path = "../aura-vocabulary" }
|
||||||
aura-ingest = { path = "../aura-ingest" }
|
aura-ingest = { path = "../aura-ingest" }
|
||||||
# data-server: the local M1 archive `aura run --real` streams from. Mirrors the
|
# data-server: the local M1 archive `aura run --real` streams from. Mirrors the
|
||||||
# git line in crates/aura-ingest/Cargo.toml verbatim (same source of truth).
|
# git line in crates/aura-ingest/Cargo.toml verbatim (same source of truth).
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ use aura_research::{
|
|||||||
campaign_to_json, content_id_of, parse_campaign, parse_process, validate_campaign,
|
campaign_to_json, content_id_of, parse_campaign, parse_process, validate_campaign,
|
||||||
validate_process, CampaignDoc, CostSpec, DocRef,
|
validate_process, CampaignDoc, CostSpec, DocRef,
|
||||||
};
|
};
|
||||||
use aura_std::{CarryCost, ConstantCost, VolSlippageCost};
|
use aura_strategy::{CarryCost, ConstantCost, VolSlippageCost};
|
||||||
|
|
||||||
use crate::project::Env;
|
use crate::project::Env;
|
||||||
use crate::research_docs::{
|
use crate::research_docs::{
|
||||||
@@ -1358,7 +1358,8 @@ mod tests {
|
|||||||
/// (bind_axes surfaces THAT case as its own named fault once the
|
/// (bind_axes surfaces THAT case as its own named fault once the
|
||||||
/// reopened space is built downstream).
|
/// reopened space is built downstream).
|
||||||
fn raw_bound_overrides_of_selects_axes_naming_a_bound_param() {
|
fn raw_bound_overrides_of_selects_axes_naming_a_bound_param() {
|
||||||
use aura_std::{Bias, Sma};
|
use aura_strategy::Bias;
|
||||||
|
use aura_std::Sma;
|
||||||
let raw_signal = Composite::new(
|
let raw_signal = Composite::new(
|
||||||
"fixture",
|
"fixture",
|
||||||
vec![
|
vec![
|
||||||
@@ -1555,9 +1556,9 @@ mod tests {
|
|||||||
/// variant reconstruction with no compiler error; this pin makes it loud.
|
/// variant reconstruction with no compiler error; this pin makes it loud.
|
||||||
fn every_cost_builder_declares_exactly_one_distinct_knob() {
|
fn every_cost_builder_declares_exactly_one_distinct_knob() {
|
||||||
let knobs: Vec<String> = [
|
let knobs: Vec<String> = [
|
||||||
aura_std::ConstantCost::builder(),
|
aura_strategy::ConstantCost::builder(),
|
||||||
aura_std::VolSlippageCost::builder(),
|
aura_strategy::VolSlippageCost::builder(),
|
||||||
aura_std::CarryCost::builder(),
|
aura_strategy::CarryCost::builder(),
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|b| {
|
.map(|b| {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
//! JSON op-list document deserializes into the `OpDoc` DTO (so the engine `Op`
|
//! JSON op-list document deserializes into the `OpDoc` DTO (so the engine `Op`
|
||||||
//! stays serde-free), which maps 1:1 into `aura_engine::Op`. The `aura graph
|
//! stays serde-free), which maps 1:1 into `aura_engine::Op`. The `aura graph
|
||||||
//! build` / `aura graph introspect` subcommands here drive these ops through the
|
//! build` / `aura graph introspect` subcommands here drive these ops through the
|
||||||
//! injected `aura_std::std_vocabulary`.
|
//! injected `aura_vocabulary::std_vocabulary`.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@@ -16,7 +16,7 @@ use serde::Deserialize;
|
|||||||
// `std_vocabulary` is now only reached through `crate::project::Env::resolve` in
|
// `std_vocabulary` is now only reached through `crate::project::Env::resolve` in
|
||||||
// production code; tests still exercise it directly.
|
// production code; tests still exercise it directly.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use aura_std::std_vocabulary;
|
use aura_vocabulary::std_vocabulary;
|
||||||
|
|
||||||
/// The wire DTO for one construction op — the document's by-identifier shape,
|
/// The wire DTO for one construction op — the document's by-identifier shape,
|
||||||
/// internally tagged by `"op"`, mapped into the serde-free engine `Op`. Bind
|
/// internally tagged by `"op"`, mapped into the serde-free engine `Op`. Bind
|
||||||
|
|||||||
@@ -30,16 +30,16 @@ use aura_registry::{
|
|||||||
FamilyMember, Generalization, NameKind, PlateauMode, Registry, RunTraces,
|
FamilyMember, Generalization, NameKind, PlateauMode, Registry, RunTraces,
|
||||||
DEFLATION_BLOCK_LEN, DEFLATION_N_RESAMPLES,
|
DEFLATION_BLOCK_LEN, DEFLATION_N_RESAMPLES,
|
||||||
};
|
};
|
||||||
|
use aura_backtest::{SimBroker, PM_FIELD_NAMES, PM_RECORD_KINDS};
|
||||||
use aura_std::{
|
use aura_std::{
|
||||||
cost_port, GatedRecorder, LinComb, Recorder, RollingMax, RollingMin,
|
GatedRecorder, LinComb, Recorder, RollingMax, RollingMin, SeriesReducer, Sub,
|
||||||
SeriesReducer, SimBroker, Sub, GEOMETRY_WIDTH, PM_FIELD_NAMES,
|
|
||||||
PM_RECORD_KINDS,
|
|
||||||
};
|
};
|
||||||
|
use aura_strategy::{cost_port, GEOMETRY_WIDTH};
|
||||||
// `std_vocabulary` is now only reached through `project::Env::resolve` in production
|
// `std_vocabulary` is now only reached through `project::Env::resolve` in production
|
||||||
// code; the test module still builds reference blueprints against it directly, so
|
// code; the test module still builds reference blueprints against it directly, so
|
||||||
// the import is test-only.
|
// the import is test-only.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use aura_std::std_vocabulary;
|
use aura_vocabulary::std_vocabulary;
|
||||||
// `Delay` is now only used by the test-only `r_breakout_signal` carve (#159 cut 2's
|
// `Delay` is now only used by the test-only `r_breakout_signal` carve (#159 cut 2's
|
||||||
// fused-builder retirement dropped the production caller); the import is test-only.
|
// fused-builder retirement dropped the production caller); the import is test-only.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -61,9 +61,11 @@ use aura_engine::ColumnarTrace;
|
|||||||
// `Bias`/`Ema`/`Sma` are only reached from the test module; the imports are
|
// `Bias`/`Ema`/`Sma` are only reached from the test module; the imports are
|
||||||
// test-only, mirroring `Delay`/`Scale` above.
|
// test-only, mirroring `Delay`/`Scale` above.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use aura_std::{Bias, Ema, Sma};
|
use aura_strategy::Bias;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use aura_std::{ConstantCost, VolSlippageCost};
|
use aura_std::{Ema, Sma};
|
||||||
|
#[cfg(test)]
|
||||||
|
use aura_strategy::{ConstantCost, VolSlippageCost};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use aura_core::project::{
|
|||||||
};
|
};
|
||||||
use aura_engine::ProjectProvenance;
|
use aura_engine::ProjectProvenance;
|
||||||
use aura_registry::{Registry, TraceStore};
|
use aura_registry::{Registry, TraceStore};
|
||||||
use aura_std::{std_vocabulary, std_vocabulary_types};
|
use aura_vocabulary::{std_vocabulary, std_vocabulary_types};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|||||||
@@ -4336,7 +4336,7 @@ fn sweep_and_walkforward_refuse_trace_with_a_forward_pointer() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn aura_sweep_persists_the_canonical_blueprint_keyed_by_topology_hash() {
|
fn aura_sweep_persists_the_canonical_blueprint_keyed_by_topology_hash() {
|
||||||
use aura_engine::{blueprint_from_json, blueprint_to_json};
|
use aura_engine::{blueprint_from_json, blueprint_to_json};
|
||||||
use aura_std::std_vocabulary;
|
use aura_vocabulary::std_vocabulary;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
let cwd = temp_cwd("blueprint-sweep-store");
|
let cwd = temp_cwd("blueprint-sweep-store");
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ publish.workspace = true
|
|||||||
aura-core = { path = "../aura-core" }
|
aura-core = { path = "../aura-core" }
|
||||||
aura-engine = { path = "../aura-engine" }
|
aura-engine = { path = "../aura-engine" }
|
||||||
aura-std = { path = "../aura-std" }
|
aura-std = { path = "../aura-std" }
|
||||||
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# serde_json: the risk_executor fixture round-trips a folded RunMetrics through
|
# serde_json: the risk_executor fixture round-trips a folded RunMetrics through
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
//! what C19/C23 DCE deletes), so it appears nowhere here.
|
//! what C19/C23 DCE deletes), so it appears nowhere here.
|
||||||
use aura_core::{PrimitiveBuilder, Scalar};
|
use aura_core::{PrimitiveBuilder, Scalar};
|
||||||
use aura_engine::{Composite, GraphBuilder, NodeHandle};
|
use aura_engine::{Composite, GraphBuilder, NodeHandle};
|
||||||
use aura_std::{
|
use aura_backtest::{PositionManagement, PM_FIELD_NAMES};
|
||||||
cost_port, intern_port, CostSum, Delay, Ema, FixedStop, LinComb, Mul,
|
use aura_std::{Delay, Ema, LinComb, Mul, Sqrt, Sub};
|
||||||
PositionManagement, Sizer, Sqrt, Sub, VolTfStop, COST_FIELD_NAMES, GEOMETRY_WIDTH,
|
use aura_strategy::{
|
||||||
PM_FIELD_NAMES,
|
cost_port, intern_port, CostSum, FixedStop, Sizer, VolTfStop, COST_FIELD_NAMES,
|
||||||
|
GEOMETRY_WIDTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The volatility stop as a composition of primitives:
|
/// The volatility stop as a composition of primitives:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use aura_composites::cost_graph;
|
use aura_composites::cost_graph;
|
||||||
use aura_core::Scalar;
|
use aura_core::Scalar;
|
||||||
use aura_std::{ConstantCost, VolSlippageCost};
|
use aura_strategy::{ConstantCost, VolSlippageCost};
|
||||||
|
|
||||||
/// Two heterogeneous cost nodes: ConstantCost (no extras, index 0) and
|
/// Two heterogeneous cost nodes: ConstantCost (no extras, index 0) and
|
||||||
/// VolSlippageCost (one extra `volatility`, index 1). The composite exposes the 4
|
/// VolSlippageCost (one extra `volatility`, index 1). The composite exposes the 4
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ use aura_core::{
|
|||||||
};
|
};
|
||||||
use aura_composites::{risk_executor, StopRule};
|
use aura_composites::{risk_executor, StopRule};
|
||||||
use aura_engine::{summarize_r, GraphBuilder, RunMetrics, VecSource};
|
use aura_engine::{summarize_r, GraphBuilder, RunMetrics, VecSource};
|
||||||
use aura_std::{Recorder, PM_FIELD_NAMES, PM_RECORD_KINDS};
|
use aura_backtest::{PM_FIELD_NAMES, PM_RECORD_KINDS};
|
||||||
|
use aura_std::Recorder;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
|
||||||
// The dense-record columns this fixture reads, named in lockstep with the sibling
|
// The dense-record columns this fixture reads, named in lockstep with the sibling
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ rayon = "1"
|
|||||||
# positionally, by index), so aura-std stays out of [dependencies] and the engine is
|
# positionally, by index), so aura-std stays out of [dependencies] and the engine is
|
||||||
# `-> aura-core` only. The node-naming composite-builders live in `aura-composites`.
|
# `-> aura-core` only. The node-naming composite-builders live in `aura-composites`.
|
||||||
aura-std = { path = "../aura-std" }
|
aura-std = { path = "../aura-std" }
|
||||||
|
aura-market = { path = "../aura-market" }
|
||||||
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
|
aura-vocabulary = { path = "../aura-vocabulary" }
|
||||||
# chrono / chrono-tz build the Berlin-local-wall-clock epoch-ns timestamps the
|
# chrono / chrono-tz build the Berlin-local-wall-clock epoch-ns timestamps the
|
||||||
# GER40 session-breakout E2E fixture (tests/ger40_breakout.rs) feeds the engine,
|
# GER40 session-breakout E2E fixture (tests/ger40_breakout.rs) feeds the engine,
|
||||||
# exactly as `Session`'s own unit test does. Pinned to aura-std's versions (the
|
# exactly as `Session`'s own unit test does. Pinned to aura-std's versions (the
|
||||||
|
|||||||
@@ -1384,7 +1384,9 @@ mod tests {
|
|||||||
use crate::test_fixtures::{composite_sma_cross_harness, synthetic_prices};
|
use crate::test_fixtures::{composite_sma_cross_harness, synthetic_prices};
|
||||||
use crate::{f64_field, summarize, ParamRange, RandomSpace, RunManifest, VecSource};
|
use crate::{f64_field, summarize, ParamRange, RandomSpace, RunManifest, VecSource};
|
||||||
use aura_core::{Cell, Ctx, FieldSpec, Firing, NodeSchema, Timestamp};
|
use aura_core::{Cell, Ctx, FieldSpec, Firing, NodeSchema, Timestamp};
|
||||||
use aura_std::{Bias, Ema, LinComb, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Ema, LinComb, Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
/// One knob fanning into two sibling open params passes the gate; the
|
/// One knob fanning into two sibling open params passes the gate; the
|
||||||
@@ -3122,7 +3124,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn param_space_reflects_only_open_knobs() {
|
fn param_space_reflects_only_open_knobs() {
|
||||||
use aura_std::{Bias, Sma};
|
use aura_strategy::Bias;
|
||||||
|
use aura_std::Sma;
|
||||||
// "sma2_entry": Sma "bias" with length bound to 2 (a structural constant)
|
// "sma2_entry": Sma "bias" with length bound to 2 (a structural constant)
|
||||||
// plus Bias "exp" whose `scale` stays open. The bound knob must be
|
// plus Bias "exp" whose `scale` stays open. The bound knob must be
|
||||||
// absent from param_space; only the open one remains.
|
// absent from param_space; only the open one remains.
|
||||||
@@ -3148,7 +3151,8 @@ mod tests {
|
|||||||
/// order — the bound value becomes a default an axis may override.
|
/// order — the bound value becomes a default an axis may override.
|
||||||
#[test]
|
#[test]
|
||||||
fn reopen_returns_a_bound_knob_to_param_space() {
|
fn reopen_returns_a_bound_knob_to_param_space() {
|
||||||
use aura_std::{Bias, Sma};
|
use aura_strategy::Bias;
|
||||||
|
use aura_std::Sma;
|
||||||
let strat = Composite::new(
|
let strat = Composite::new(
|
||||||
"sma2_entry",
|
"sma2_entry",
|
||||||
vec![
|
vec![
|
||||||
@@ -3169,7 +3173,8 @@ mod tests {
|
|||||||
/// error, not a silent no-op — open axes pass through without reopen.
|
/// error, not a silent no-op — open axes pass through without reopen.
|
||||||
#[test]
|
#[test]
|
||||||
fn reopen_unknown_or_open_path_errors() {
|
fn reopen_unknown_or_open_path_errors() {
|
||||||
use aura_std::{Bias, Sma};
|
use aura_strategy::Bias;
|
||||||
|
use aura_std::Sma;
|
||||||
let strat = Composite::new(
|
let strat = Composite::new(
|
||||||
"sma2_entry",
|
"sma2_entry",
|
||||||
vec![
|
vec![
|
||||||
@@ -3190,7 +3195,8 @@ mod tests {
|
|||||||
/// carries the bound value (the default the CLI renders in --list-axes).
|
/// carries the bound value (the default the CLI renders in --list-axes).
|
||||||
#[test]
|
#[test]
|
||||||
fn bound_param_space_is_path_qualified_with_values() {
|
fn bound_param_space_is_path_qualified_with_values() {
|
||||||
use aura_std::{Bias, Sma};
|
use aura_strategy::Bias;
|
||||||
|
use aura_std::Sma;
|
||||||
let strat = Composite::new(
|
let strat = Composite::new(
|
||||||
"sma2_entry",
|
"sma2_entry",
|
||||||
vec![
|
vec![
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ fn reconstruct(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Load a blueprint from canonical JSON, resolving each primitive's type identity
|
/// Load a blueprint from canonical JSON, resolving each primitive's type identity
|
||||||
/// through the injected `resolve` (e.g. `aura_std::std_vocabulary`). The version
|
/// through the injected `resolve` (e.g. `aura_vocabulary::std_vocabulary`). The version
|
||||||
/// envelope is checked before the payload is reconstructed.
|
/// envelope is checked before the payload is reconstructed.
|
||||||
pub fn blueprint_from_json(
|
pub fn blueprint_from_json(
|
||||||
data: &str,
|
data: &str,
|
||||||
@@ -267,7 +267,8 @@ mod tests {
|
|||||||
use crate::harness::{Edge, Target};
|
use crate::harness::{Edge, Target};
|
||||||
use crate::VecSource; // crate-root re-export (blueprint.rs tests import it the same way, e.g. :923)
|
use crate::VecSource; // crate-root re-export (blueprint.rs tests import it the same way, e.g. :923)
|
||||||
use aura_core::{Scalar, ScalarKind, Timestamp};
|
use aura_core::{Scalar, ScalarKind, Timestamp};
|
||||||
use aura_std::{Bias, Recorder, Sma, Sub};
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
// Open param point for the sink-free signal (fast.length is bound): [slow.length, bias.scale].
|
// Open param point for the sink-free signal (fast.length is bound): [slow.length, bias.scale].
|
||||||
@@ -303,7 +304,7 @@ mod tests {
|
|||||||
fn serialized_blueprint_runs_bit_identical_to_rust_built() {
|
fn serialized_blueprint_runs_bit_identical_to_rust_built() {
|
||||||
let rust_built = crate::test_fixtures::sink_free_sma_cross_signal();
|
let rust_built = crate::test_fixtures::sink_free_sma_cross_signal();
|
||||||
let json = blueprint_to_json(&rust_built).expect("serializes");
|
let json = blueprint_to_json(&rust_built).expect("serializes");
|
||||||
let loaded = blueprint_from_json(&json, &|t| aura_std::std_vocabulary(t)).expect("loads");
|
let loaded = blueprint_from_json(&json, &|t| aura_vocabulary::std_vocabulary(t)).expect("loads");
|
||||||
|
|
||||||
let trace_rust = run_recording(rust_built);
|
let trace_rust = run_recording(rust_built);
|
||||||
let trace_loaded = run_recording(loaded);
|
let trace_loaded = run_recording(loaded);
|
||||||
@@ -316,7 +317,7 @@ mod tests {
|
|||||||
fn serializer_and_loader_are_inverse() {
|
fn serializer_and_loader_are_inverse() {
|
||||||
let original = crate::test_fixtures::sink_free_sma_cross_signal();
|
let original = crate::test_fixtures::sink_free_sma_cross_signal();
|
||||||
let json = blueprint_to_json(&original).expect("serializes");
|
let json = blueprint_to_json(&original).expect("serializes");
|
||||||
let loaded = blueprint_from_json(&json, &|t| aura_std::std_vocabulary(t)).expect("loads");
|
let loaded = blueprint_from_json(&json, &|t| aura_vocabulary::std_vocabulary(t)).expect("loads");
|
||||||
// serialize -> load -> serialize is byte-stable (canonical round-trip identity)
|
// serialize -> load -> serialize is byte-stable (canonical round-trip identity)
|
||||||
assert_eq!(json, blueprint_to_json(&loaded).expect("re-serializes"));
|
assert_eq!(json, blueprint_to_json(&loaded).expect("re-serializes"));
|
||||||
}
|
}
|
||||||
@@ -339,7 +340,7 @@ mod tests {
|
|||||||
vec![OutField { node: 0, field: 0, name: "bias".into() }],
|
vec![OutField { node: 0, field: 0, name: "bias".into() }],
|
||||||
);
|
);
|
||||||
let json = blueprint_to_json(&outer).expect("serializes");
|
let json = blueprint_to_json(&outer).expect("serializes");
|
||||||
let loaded = blueprint_from_json(&json, &|t| aura_std::std_vocabulary(t)).expect("loads");
|
let loaded = blueprint_from_json(&json, &|t| aura_vocabulary::std_vocabulary(t)).expect("loads");
|
||||||
assert_eq!(json, blueprint_to_json(&loaded).expect("re-serializes"));
|
assert_eq!(json, blueprint_to_json(&loaded).expect("re-serializes"));
|
||||||
// the nested composite survived as a composite, not flattened
|
// the nested composite survived as a composite, not flattened
|
||||||
assert!(json.contains(r#"{"composite":{"name":"sma_cross""#), "nested composite preserved");
|
assert!(json.contains(r#"{"composite":{"name":"sma_cross""#), "nested composite preserved");
|
||||||
@@ -370,7 +371,7 @@ mod tests {
|
|||||||
assert_ne!(plain_json, doced_json, "the doc is canonical-byte-bearing");
|
assert_ne!(plain_json, doced_json, "the doc is canonical-byte-bearing");
|
||||||
assert!(doced_json.contains("why this graph"), "doc serialized: {doced_json}");
|
assert!(doced_json.contains("why this graph"), "doc serialized: {doced_json}");
|
||||||
assert!(!plain_json.contains("\"doc\""), "absent doc emits no key: {plain_json}");
|
assert!(!plain_json.contains("\"doc\""), "absent doc emits no key: {plain_json}");
|
||||||
let loaded = blueprint_from_json(&doced_json, &|t| aura_std::std_vocabulary(t)).expect("loads");
|
let loaded = blueprint_from_json(&doced_json, &|t| aura_vocabulary::std_vocabulary(t)).expect("loads");
|
||||||
assert_eq!(loaded.doc(), Some("why this graph: the spread detects trend turns"));
|
assert_eq!(loaded.doc(), Some("why this graph: the spread detects trend turns"));
|
||||||
assert_eq!(doced_json, blueprint_to_json(&loaded).expect("re-serializes"), "round-trip byte-stable");
|
assert_eq!(doced_json, blueprint_to_json(&loaded).expect("re-serializes"), "round-trip byte-stable");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -395,7 +396,7 @@ mod tests {
|
|||||||
let tapped_json = blueprint_to_json(&tapped).expect("serializes");
|
let tapped_json = blueprint_to_json(&tapped).expect("serializes");
|
||||||
assert_ne!(plain_json, tapped_json, "taps are canonical-byte-bearing");
|
assert_ne!(plain_json, tapped_json, "taps are canonical-byte-bearing");
|
||||||
assert!(!plain_json.contains("\"taps\""), "absent taps emit no key: {plain_json}");
|
assert!(!plain_json.contains("\"taps\""), "absent taps emit no key: {plain_json}");
|
||||||
let loaded = blueprint_from_json(&tapped_json, &|t| aura_std::std_vocabulary(t)).expect("loads");
|
let loaded = blueprint_from_json(&tapped_json, &|t| aura_vocabulary::std_vocabulary(t)).expect("loads");
|
||||||
assert_eq!(loaded.taps(), tapped.taps());
|
assert_eq!(loaded.taps(), tapped.taps());
|
||||||
assert_eq!(tapped_json, blueprint_to_json(&loaded).expect("re-serializes"), "round-trip byte-stable");
|
assert_eq!(tapped_json, blueprint_to_json(&loaded).expect("re-serializes"), "round-trip byte-stable");
|
||||||
}
|
}
|
||||||
@@ -431,14 +432,14 @@ mod tests {
|
|||||||
let json = r#"{"format_version":1,"blueprint":{"name":"x","nodes":[{"primitive":{"type":"NoSuchNode"}}]}}"#;
|
let json = r#"{"format_version":1,"blueprint":{"name":"x","nodes":[{"primitive":{"type":"NoSuchNode"}}]}}"#;
|
||||||
// `.err().unwrap()` (not `.unwrap_err()`): the Ok type `Composite` holds a
|
// `.err().unwrap()` (not `.unwrap_err()`): the Ok type `Composite` holds a
|
||||||
// build closure and is not `Debug`, which `unwrap_err`'s bound would require.
|
// build closure and is not `Debug`, which `unwrap_err`'s bound would require.
|
||||||
let err = blueprint_from_json(json, &|t| aura_std::std_vocabulary(t)).err().unwrap();
|
let err = blueprint_from_json(json, &|t| aura_vocabulary::std_vocabulary(t)).err().unwrap();
|
||||||
assert!(matches!(err, LoadError::UnknownNodeType(t) if t == "NoSuchNode"));
|
assert!(matches!(err, LoadError::UnknownNodeType(t) if t == "NoSuchNode"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unsupported_version_fails_named() {
|
fn unsupported_version_fails_named() {
|
||||||
let json = r#"{"format_version":2,"blueprint":{"name":"x","nodes":[]}}"#;
|
let json = r#"{"format_version":2,"blueprint":{"name":"x","nodes":[]}}"#;
|
||||||
let err = blueprint_from_json(json, &|t| aura_std::std_vocabulary(t)).err().unwrap();
|
let err = blueprint_from_json(json, &|t| aura_vocabulary::std_vocabulary(t)).err().unwrap();
|
||||||
assert!(matches!(err, LoadError::UnsupportedVersion { found: 2, supported: 1 }));
|
assert!(matches!(err, LoadError::UnsupportedVersion { found: 2, supported: 1 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,7 +467,7 @@ mod tests {
|
|||||||
assert_ne!(with_unknown, canonical, "probe must actually inject unknown keys");
|
assert_ne!(with_unknown, canonical, "probe must actually inject unknown keys");
|
||||||
|
|
||||||
// tolerated, not refused
|
// tolerated, not refused
|
||||||
let loaded = blueprint_from_json(&with_unknown, &|t| aura_std::std_vocabulary(t))
|
let loaded = blueprint_from_json(&with_unknown, &|t| aura_vocabulary::std_vocabulary(t))
|
||||||
.expect("an unknown optional field is tolerated, not refused");
|
.expect("an unknown optional field is tolerated, not refused");
|
||||||
|
|
||||||
// the unknown keys did not leak into the graph: re-serialization equals the
|
// the unknown keys did not leak into the graph: re-serialization equals the
|
||||||
@@ -474,7 +475,7 @@ mod tests {
|
|||||||
assert_eq!(blueprint_to_json(&loaded).expect("re-serializes"), canonical);
|
assert_eq!(blueprint_to_json(&loaded).expect("re-serializes"), canonical);
|
||||||
|
|
||||||
// and the loaded graph runs bit-identically to the plain canonical one (C1).
|
// and the loaded graph runs bit-identically to the plain canonical one (C1).
|
||||||
let plain = blueprint_from_json(&canonical, &|t| aura_std::std_vocabulary(t)).expect("loads");
|
let plain = blueprint_from_json(&canonical, &|t| aura_vocabulary::std_vocabulary(t)).expect("loads");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
run_recording(loaded),
|
run_recording(loaded),
|
||||||
run_recording(plain),
|
run_recording(plain),
|
||||||
@@ -655,9 +656,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The resolver used by the gang-serde tests below (mirrors the inline
|
// The resolver used by the gang-serde tests below (mirrors the inline
|
||||||
// `&|t| aura_std::std_vocabulary(t)` closure the rest of this module uses).
|
// `&|t| aura_vocabulary::std_vocabulary(t)` closure the rest of this module uses).
|
||||||
fn fixture_resolver() -> impl Fn(&str) -> Option<PrimitiveBuilder> {
|
fn fixture_resolver() -> impl Fn(&str) -> Option<PrimitiveBuilder> {
|
||||||
|t: &str| aura_std::std_vocabulary(t)
|
|t: &str| aura_vocabulary::std_vocabulary(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shared topology: two open SMAs feeding a `Sub`. `ganged_fixture_named`
|
// Shared topology: two open SMAs feeding a `Sub`. `ganged_fixture_named`
|
||||||
|
|||||||
@@ -344,7 +344,9 @@ mod tests {
|
|||||||
use crate::test_fixtures::sma_cross as hand_sma_cross;
|
use crate::test_fixtures::sma_cross as hand_sma_cross;
|
||||||
use crate::{Composite, OutField, Role, Target};
|
use crate::{Composite, OutField, Role, Target};
|
||||||
use aura_core::{Firing, ScalarKind};
|
use aura_core::{Firing, ScalarKind};
|
||||||
use aura_std::{Bias, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
/// The `sma_cross` sub-composite authored through the builder.
|
/// The `sma_cross` sub-composite authored through the builder.
|
||||||
|
|||||||
@@ -472,7 +472,7 @@ pub fn replay(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::{GraphSession, Op, OpError};
|
use super::{GraphSession, Op, OpError};
|
||||||
use aura_core::{BindOpError, Scalar, ScalarKind};
|
use aura_core::{BindOpError, Scalar, ScalarKind};
|
||||||
use aura_std::std_vocabulary;
|
use aura_vocabulary::std_vocabulary;
|
||||||
|
|
||||||
fn session(name: &str) -> GraphSession<'static> {
|
fn session(name: &str) -> GraphSession<'static> {
|
||||||
GraphSession::new(name, &std_vocabulary)
|
GraphSession::new(name, &std_vocabulary)
|
||||||
@@ -736,7 +736,7 @@ mod tests {
|
|||||||
Op::Tap { from: "fast.value".into(), as_name: "fast_ma".into() },
|
Op::Tap { from: "fast.value".into(), as_name: "fast_ma".into() },
|
||||||
Op::Expose { from: "sub.value".into(), as_name: "bias".into() },
|
Op::Expose { from: "sub.value".into(), as_name: "bias".into() },
|
||||||
];
|
];
|
||||||
let flat = super::replay("g", ops, &aura_std::std_vocabulary)
|
let flat = super::replay("g", ops, &aura_vocabulary::std_vocabulary)
|
||||||
.expect("replays")
|
.expect("replays")
|
||||||
.compile_with_params(&[Scalar::i64(2), Scalar::i64(4)])
|
.compile_with_params(&[Scalar::i64(2), Scalar::i64(4)])
|
||||||
.expect("compiles");
|
.expect("compiles");
|
||||||
@@ -949,7 +949,7 @@ mod tests {
|
|||||||
let finalize = ops.len();
|
let finalize = ops.len();
|
||||||
// `.err()` not `.unwrap_err()`: the Ok arm `Composite` holds build closures
|
// `.err()` not `.unwrap_err()`: the Ok arm `Composite` holds build closures
|
||||||
// and is not `Debug`.
|
// and is not `Debug`.
|
||||||
let (idx, _err) = super::replay("g", ops, &aura_std::std_vocabulary)
|
let (idx, _err) = super::replay("g", ops, &aura_vocabulary::std_vocabulary)
|
||||||
.err()
|
.err()
|
||||||
.expect("a cyclic op-list must be rejected (DAG invariant 5 / C9)");
|
.expect("a cyclic op-list must be rejected (DAG invariant 5 / C9)");
|
||||||
// An eager realisation attributes the fault to the closing connect op; a
|
// An eager realisation attributes the fault to the closing connect op; a
|
||||||
@@ -976,7 +976,7 @@ mod tests {
|
|||||||
Op::Expose { from: "s.value".into(), as_name: "out".into() },
|
Op::Expose { from: "s.value".into(), as_name: "out".into() },
|
||||||
];
|
];
|
||||||
assert!(
|
assert!(
|
||||||
super::replay("g", ops, &aura_std::std_vocabulary).is_err(),
|
super::replay("g", ops, &aura_vocabulary::std_vocabulary).is_err(),
|
||||||
"a self-loop op-list must be rejected (DAG invariant 5 / C9)"
|
"a self-loop op-list must be rejected (DAG invariant 5 / C9)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -990,7 +990,7 @@ mod tests {
|
|||||||
];
|
];
|
||||||
// `.err().unwrap()` rather than `.unwrap_err()`: the Ok arm `Composite` is
|
// `.err().unwrap()` rather than `.unwrap_err()`: the Ok arm `Composite` is
|
||||||
// not `Debug` (it holds build closures), which `unwrap_err` would require.
|
// not `Debug` (it holds build closures), which `unwrap_err` would require.
|
||||||
let err = super::replay("g", ops, &aura_std::std_vocabulary).err().unwrap();
|
let err = super::replay("g", ops, &aura_vocabulary::std_vocabulary).err().unwrap();
|
||||||
assert_eq!(err, (1, OpError::UnknownNodeType("Nope".into())));
|
assert_eq!(err, (1, OpError::UnknownNodeType("Nope".into())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1004,7 +1004,8 @@ mod tests {
|
|||||||
fn replay_built_signal_compiles_identically_to_graphbuilder() {
|
fn replay_built_signal_compiles_identically_to_graphbuilder() {
|
||||||
use crate::GraphBuilder;
|
use crate::GraphBuilder;
|
||||||
use aura_core::Scalar;
|
use aura_core::Scalar;
|
||||||
use aura_std::{Bias, Sma, Sub};
|
use aura_std::{Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
|
||||||
// param space of the flat root: fast.length(i64), slow.length(i64),
|
// param space of the flat root: fast.length(i64), slow.length(i64),
|
||||||
// bias.scale(f64) — same vector applied to both sides, so it cancels.
|
// bias.scale(f64) — same vector applied to both sides, so it cancels.
|
||||||
@@ -1023,7 +1024,7 @@ mod tests {
|
|||||||
Op::Connect { from: "sub.value".into(), to: "bias.signal".into() },
|
Op::Connect { from: "sub.value".into(), to: "bias.signal".into() },
|
||||||
Op::Expose { from: "bias.bias".into(), as_name: "bias".into() },
|
Op::Expose { from: "bias.bias".into(), as_name: "bias".into() },
|
||||||
];
|
];
|
||||||
let replay_flat = super::replay("root", ops, &aura_std::std_vocabulary)
|
let replay_flat = super::replay("root", ops, &aura_vocabulary::std_vocabulary)
|
||||||
.expect("replay resolves")
|
.expect("replay resolves")
|
||||||
.compile_with_params(¶ms)
|
.compile_with_params(¶ms)
|
||||||
.expect("replay compiles");
|
.expect("replay compiles");
|
||||||
|
|||||||
@@ -321,7 +321,8 @@ mod tests {
|
|||||||
use aura_core::{
|
use aura_core::{
|
||||||
Cell, FieldSpec, Node, NodeSchema, PortSpec, PrimitiveBuilder, Scalar,
|
Cell, FieldSpec, Node, NodeSchema, PortSpec, PrimitiveBuilder, Scalar,
|
||||||
};
|
};
|
||||||
use aura_std::{Bias, Recorder, Sma, Sub};
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
/// A bare node whose only purpose is to back a `PrimitiveBuilder` in a test.
|
/// A bare node whose only purpose is to back a `PrimitiveBuilder` in a test.
|
||||||
|
|||||||
@@ -676,7 +676,9 @@ mod tests {
|
|||||||
// PortSpec / NodeSchema name the fixtures' declared signatures, brought in here
|
// PortSpec / NodeSchema name the fixtures' declared signatures, brought in here
|
||||||
// (production code reads them via the carried signatures, never naming the types).
|
// (production code reads them via the carried signatures, never naming the types).
|
||||||
use aura_core::{FieldSpec, NodeSchema, PortSpec};
|
use aura_core::{FieldSpec, NodeSchema, PortSpec};
|
||||||
use aura_std::{Bias, Recorder, Sma, SimBroker, Sub, When};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub, When};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
/// Build an f64 source stream from (timestamp, value) points.
|
/// Build an f64 source stream from (timestamp, value) points.
|
||||||
|
|||||||
@@ -312,7 +312,9 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::{Edge, FlatGraph, Harness, SourceSpec, Target, VecSource};
|
use crate::{Edge, FlatGraph, Harness, SourceSpec, Target, VecSource};
|
||||||
use aura_core::{Firing, NodeSchema, PortSpec, ScalarKind};
|
use aura_core::{Firing, NodeSchema, PortSpec, ScalarKind};
|
||||||
use aura_std::{Bias, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
use crate::{BlueprintNode, Composite, Edge, OutField, Role, Target};
|
use crate::{BlueprintNode, Composite, Edge, OutField, Role, Target};
|
||||||
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_std::{Bias, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
/// Seven synthetic F64 ticks driving the harness; deterministic input fixture.
|
/// Seven synthetic F64 ticks driving the harness; deterministic input fixture.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//! End-to-end coverage for blueprint serialization (C24, cycle 0087): a
|
//! End-to-end coverage for blueprint serialization (C24, cycle 0087): a
|
||||||
//! param-generic `Composite` is projected to canonical, versioned JSON
|
//! param-generic `Composite` is projected to canonical, versioned JSON
|
||||||
//! (`blueprint_to_json`) and reconstructed from it (`blueprint_from_json`) through
|
//! (`blueprint_to_json`) and reconstructed from it (`blueprint_from_json`) through
|
||||||
//! an **injected** node-vocabulary resolver (`aura_std::std_vocabulary`).
|
//! an **injected** node-vocabulary resolver (`aura_vocabulary::std_vocabulary`).
|
||||||
//!
|
//!
|
||||||
//! The in-module tests in `blueprint_serde.rs` reach into crate internals
|
//! The in-module tests in `blueprint_serde.rs` reach into crate internals
|
||||||
//! (`crate::test_fixtures::sink_free_sma_cross_signal`, the crate-private
|
//! (`crate::test_fixtures::sink_free_sma_cross_signal`, the crate-private
|
||||||
@@ -19,7 +19,9 @@ use aura_engine::{
|
|||||||
blueprint_from_json, blueprint_identity_json, blueprint_to_json, BlueprintNode, Composite,
|
blueprint_from_json, blueprint_identity_json, blueprint_to_json, BlueprintNode, Composite,
|
||||||
Edge, LoadError, OutField, Role, Target, VecSource, BLUEPRINT_FORMAT_VERSION,
|
Edge, LoadError, OutField, Role, Target, VecSource, BLUEPRINT_FORMAT_VERSION,
|
||||||
};
|
};
|
||||||
use aura_std::{std_vocabulary, Bias, Recorder, Sma, Sub};
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
use aura_vocabulary::std_vocabulary;
|
||||||
|
|
||||||
/// Seven synthetic F64 ticks (mirrors the crate-private `synthetic_prices`):
|
/// Seven synthetic F64 ticks (mirrors the crate-private `synthetic_prices`):
|
||||||
/// short enough that the fast (2) and slow (4) SMA windows warm up within the
|
/// short enough that the fast (2) and slow (4) SMA windows warm up within the
|
||||||
@@ -102,7 +104,7 @@ fn run_recording(signal: Composite) -> Vec<(Timestamp, Vec<Scalar>)> {
|
|||||||
|
|
||||||
/// Property (C24 acceptance, through the public seam): a blueprint authored via the
|
/// Property (C24 acceptance, through the public seam): a blueprint authored via the
|
||||||
/// exported `Composite` builder, serialized to JSON, then loaded back through
|
/// exported `Composite` builder, serialized to JSON, then loaded back through
|
||||||
/// `blueprint_from_json` + the injected `aura_std::std_vocabulary` and run, records
|
/// `blueprint_from_json` + the injected `aura_vocabulary::std_vocabulary` and run, records
|
||||||
/// a `bias` trace **byte-identical** to the Rust-built twin's run — proven entirely
|
/// a `bias` trace **byte-identical** to the Rust-built twin's run — proven entirely
|
||||||
/// through `aura_engine`/`aura_std` public exports (the World/cdylib seam C24
|
/// through `aura_engine`/`aura_std` public exports (the World/cdylib seam C24
|
||||||
/// serves). The serialization round-trip is behaviour-preserving (C1): same input,
|
/// serves). The serialization round-trip is behaviour-preserving (C1): same input,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
//! (`crate::GraphBuilder`, `crate::CompileError`, `super::replay`). These tests
|
//! (`crate::GraphBuilder`, `crate::CompileError`, `super::replay`). These tests
|
||||||
//! use only the **exported** surface — `aura_engine::{replay, Op, OpError,
|
//! use only the **exported** surface — `aura_engine::{replay, Op, OpError,
|
||||||
//! GraphBuilder, Composite, FlatGraph, Scalar, ScalarKind}` plus the injected
|
//! GraphBuilder, Composite, FlatGraph, Scalar, ScalarKind}` plus the injected
|
||||||
//! `aura_std::std_vocabulary` — the exact seam the iteration-2 CLI (`aura graph
|
//! `aura_vocabulary::std_vocabulary` — the exact seam the iteration-2 CLI (`aura graph
|
||||||
//! build`/`introspect`) and the World consume. A refactor that made `Op`,
|
//! build`/`introspect`) and the World consume. A refactor that made `Op`,
|
||||||
//! `OpError`, `replay`, or a needed re-export (`ScalarKind`, `Scalar`)
|
//! `OpError`, `replay`, or a needed re-export (`ScalarKind`, `Scalar`)
|
||||||
//! unreachable across the crate boundary would break that consumer while leaving
|
//! unreachable across the crate boundary would break that consumer while leaving
|
||||||
@@ -15,7 +15,9 @@
|
|||||||
//! addition to the per-property invariants below.
|
//! addition to the per-property invariants below.
|
||||||
|
|
||||||
use aura_engine::{replay, GraphBuilder, Op, OpError, Scalar, ScalarKind};
|
use aura_engine::{replay, GraphBuilder, Op, OpError, Scalar, ScalarKind};
|
||||||
use aura_std::{std_vocabulary, Bias, Sma, Sub};
|
use aura_std::{Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
use aura_vocabulary::std_vocabulary;
|
||||||
|
|
||||||
/// The flat root's open param point: fast.length(i64), slow.length(i64),
|
/// The flat root's open param point: fast.length(i64), slow.length(i64),
|
||||||
/// bias.scale(f64), in param-space traversal order. The same vector is applied to
|
/// bias.scale(f64), in param-space traversal order. The same vector is applied to
|
||||||
@@ -45,7 +47,7 @@ fn signal_ops() -> Vec<Op> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Property (C24 acceptance-1, through the public seam): an op-script replayed via
|
/// Property (C24 acceptance-1, through the public seam): an op-script replayed via
|
||||||
/// the exported `replay` + the injected `aura_std::std_vocabulary` compiles to a
|
/// the exported `replay` + the injected `aura_vocabulary::std_vocabulary` compiles to a
|
||||||
/// `FlatGraph` whose index-wired topology (`edges`) and lowered bound sources
|
/// `FlatGraph` whose index-wired topology (`edges`) and lowered bound sources
|
||||||
/// (`sources`) are **identical** to the same signal hand-wired on the exported
|
/// (`sources`) are **identical** to the same signal hand-wired on the exported
|
||||||
/// `GraphBuilder` surface and compiled with the same param point. The two
|
/// `GraphBuilder` surface and compiled with the same param point. The two
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ use std::sync::mpsc;
|
|||||||
|
|
||||||
use aura_core::{NodeSchema, Scalar, ScalarKind, Timestamp};
|
use aura_core::{NodeSchema, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_engine::{Edge, FlatGraph, Harness, Source, SourceSpec, Target, VecSource};
|
use aura_engine::{Edge, FlatGraph, Harness, Source, SourceSpec, Target, VecSource};
|
||||||
use aura_std::{And, Delay, EqConst, Gt, Latch, Recorder, Resample, Session, SimBroker};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_market::{Resample, Session};
|
||||||
|
use aura_std::{And, Delay, EqConst, Gt, Latch, Recorder};
|
||||||
use chrono::TimeZone;
|
use chrono::TimeZone;
|
||||||
use chrono_tz::Europe::Berlin;
|
use chrono_tz::Europe::Berlin;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ use aura_engine::{
|
|||||||
f64_field, summarize, sweep, BlueprintNode, Composite, Edge, ListSpace, OutField, ParamSpec,
|
f64_field, summarize, sweep, BlueprintNode, Composite, Edge, ListSpace, OutField, ParamSpec,
|
||||||
Role, RunManifest, RunReport, Scalar, SweepError, Target, VecSource,
|
Role, RunManifest, RunReport, Scalar, SweepError, Target, VecSource,
|
||||||
};
|
};
|
||||||
use aura_std::{Bias, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
|
||||||
/// Seven synthetic F64 ticks — the same fixture shape as `random_sweep_e2e.rs`,
|
/// Seven synthetic F64 ticks — the same fixture shape as `random_sweep_e2e.rs`,
|
||||||
/// short enough that small SMA windows warm up deterministically.
|
/// short enough that small SMA windows warm up deterministically.
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ use std::sync::mpsc;
|
|||||||
|
|
||||||
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_engine::{blueprint_from_json, BlueprintNode, Composite, Edge, Role, Target, VecSource};
|
use aura_engine::{blueprint_from_json, BlueprintNode, Composite, Edge, Role, Target, VecSource};
|
||||||
use aura_std::{std_vocabulary, Recorder};
|
use aura_std::Recorder;
|
||||||
|
use aura_vocabulary::std_vocabulary;
|
||||||
|
|
||||||
// value = (high - low) + (close - open): every column is load-bearing, so any
|
// value = (high - low) + (close - open): every column is load-bearing, so any
|
||||||
// mis-pairing of roles to sources (or a wrong merge tie-break) changes the
|
// mis-pairing of roles to sources (or a wrong merge tie-break) changes the
|
||||||
|
|||||||
@@ -27,10 +27,8 @@
|
|||||||
|
|
||||||
use aura_core::{AnyColumn, Ctx, Node, Scalar, ScalarKind, Timestamp};
|
use aura_core::{AnyColumn, Ctx, Node, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_engine::{PositionAction, RMetrics, derive_position_events, summarize_r};
|
use aura_engine::{PositionAction, RMetrics, derive_position_events, summarize_r};
|
||||||
use aura_std::{
|
use aura_backtest::{PM_FIELD_NAMES, PM_RECORD_KINDS, PM_WIDTH, PositionManagement};
|
||||||
ConstantCost, CostSum, FixedStop, PM_FIELD_NAMES, PM_RECORD_KINDS, PM_WIDTH,
|
use aura_strategy::{ConstantCost, CostSum, FixedStop, VolSlippageCost};
|
||||||
PositionManagement, VolSlippageCost,
|
|
||||||
};
|
|
||||||
|
|
||||||
// The indices `report.rs::summarize_r` reads the dense record by. Re-declared here
|
// The indices `report.rs::summarize_r` reads the dense record by. Re-declared here
|
||||||
// (the consumer's `r_col` module is private to `aura-engine`) so the guard test can
|
// (the consumer's `r_col` module is private to `aura-engine`) so the guard test can
|
||||||
@@ -267,7 +265,7 @@ fn net_of_cost_is_charged_per_r_so_a_wider_stop_dilutes_it() {
|
|||||||
assert!(tight_cost > wide_cost, "a tighter stop must pay more R per fixed price-unit cost");
|
assert!(tight_cost > wide_cost, "a tighter stop must pay more R per fixed price-unit cost");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drive the REAL `aura_std::ConstantCost(c)` node over a recorded PM `ledger`,
|
/// Drive the REAL `aura_strategy::ConstantCost(c)` node over a recorded PM `ledger`,
|
||||||
/// node-by-node off the producer's own `closed`/`open`/`entry_price`/`stop_price`
|
/// node-by-node off the producer's own `closed`/`open`/`entry_price`/`stop_price`
|
||||||
/// columns — the actual cost producer the run-path graph taps (not an algebraic stand-in
|
/// columns — the actual cost producer the run-path graph taps (not an algebraic stand-in
|
||||||
/// like `const_cost_stream`). Returns the node's 3-wide `[cost_in_r, cum_cost_in_r,
|
/// like `const_cost_stream`). Returns the node's 3-wide `[cost_in_r, cum_cost_in_r,
|
||||||
@@ -336,7 +334,7 @@ fn net_r_equity_final_sample_agrees_with_summarize_r_net_total() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drive the REAL `aura_std::VolSlippageCost(k)` node over a recorded PM `ledger`
|
/// Drive the REAL `aura_strategy::VolSlippageCost(k)` node over a recorded PM `ledger`
|
||||||
/// with a constant `vol` per cycle — the run-path's vol-slippage producer. Returns
|
/// with a constant `vol` per cycle — the run-path's vol-slippage producer. Returns
|
||||||
/// the node's 3-wide `[cost_in_r, cum_cost_in_r, open_cost_in_r]` rows, co-temporal
|
/// the node's 3-wide `[cost_in_r, cum_cost_in_r, open_cost_in_r]` rows, co-temporal
|
||||||
/// 1:1 with `ledger`.
|
/// 1:1 with `ledger`.
|
||||||
@@ -367,7 +365,7 @@ fn vol_slippage_node_stream(
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drive the REAL `aura_std::CostSum(n)` aggregator over `n` co-temporal cost
|
/// Drive the REAL `aura_strategy::CostSum(n)` aggregator over `n` co-temporal cost
|
||||||
/// streams, summing them per-field — the run-path's cost-graph output node.
|
/// streams, summing them per-field — the run-path's cost-graph output node.
|
||||||
fn cost_sum_node_stream(streams: &[&[(Timestamp, Vec<Scalar>)]]) -> Vec<(Timestamp, Vec<Scalar>)> {
|
fn cost_sum_node_stream(streams: &[&[(Timestamp, Vec<Scalar>)]]) -> Vec<(Timestamp, Vec<Scalar>)> {
|
||||||
let n = streams.len();
|
let n = streams.len();
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ use aura_engine::{
|
|||||||
f64_field, summarize, sweep, BlueprintNode, Composite, Edge, OutField, ParamRange, ParamSpec,
|
f64_field, summarize, sweep, BlueprintNode, Composite, Edge, OutField, ParamRange, ParamSpec,
|
||||||
RandomSpace, Role, RunManifest, RunReport, Scalar, Space, SweepError, Target, VecSource,
|
RandomSpace, Role, RunManifest, RunReport, Scalar, Space, SweepError, Target, VecSource,
|
||||||
};
|
};
|
||||||
use aura_std::{Bias, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
|
||||||
/// Seven synthetic F64 ticks (mirrors the crate-private `synthetic_prices`):
|
/// Seven synthetic F64 ticks (mirrors the crate-private `synthetic_prices`):
|
||||||
/// short enough that small SMA windows warm up, so every run yields finite,
|
/// short enough that small SMA windows warm up, so every run yields finite,
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
use aura_core::{Scalar, ScalarKind};
|
use aura_core::{Scalar, ScalarKind};
|
||||||
use aura_engine::{Composite, Role, Target};
|
use aura_engine::{Composite, Role, Target};
|
||||||
use aura_std::{Bias, Sma};
|
use aura_std::Sma;
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
|
||||||
/// A single bound `Sma`, wired from a root role so it compiles standalone.
|
/// A single bound `Sma`, wired from a root role so it compiles standalone.
|
||||||
fn one_bound_sma() -> Composite {
|
fn one_bound_sma() -> Composite {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//! Acceptance proof for issue #236: an **RSI-class** signal — the classic
|
//! Acceptance proof for issue #236: an **RSI-class** signal — the classic
|
||||||
//! gain/loss split of the price change and the smoothed **ratio** of average gain
|
//! gain/loss split of the price change and the smoothed **ratio** of average gain
|
||||||
//! to average loss — composes *purely from blueprint data* through the injected
|
//! to average loss — composes *purely from blueprint data* through the injected
|
||||||
//! `aura_std::std_vocabulary` and runs to hand-computable RS values. This is the
|
//! `aura_vocabulary::std_vocabulary` and runs to hand-computable RS values. This is the
|
||||||
//! property that pins the four std-vocabulary gaps the issue names as a single
|
//! property that pins the four std-vocabulary gaps the issue names as a single
|
||||||
//! honest behaviour: `Div`, a `Const` source, `Abs`, and pairwise `Max`/`Min`.
|
//! honest behaviour: `Div`, a `Const` source, `Abs`, and pairwise `Max`/`Min`.
|
||||||
//!
|
//!
|
||||||
@@ -24,7 +24,8 @@ use std::sync::mpsc;
|
|||||||
|
|
||||||
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_engine::{blueprint_from_json, BlueprintNode, Composite, Edge, Role, Target, VecSource};
|
use aura_engine::{blueprint_from_json, BlueprintNode, Composite, Edge, Role, Target, VecSource};
|
||||||
use aura_std::{std_vocabulary, Recorder};
|
use aura_std::Recorder;
|
||||||
|
use aura_vocabulary::std_vocabulary;
|
||||||
|
|
||||||
// The RSI-class signal as blueprint data. Raw price fans out to a zero `Const`
|
// The RSI-class signal as blueprint data. Raw price fans out to a zero `Const`
|
||||||
// (its clock is the price role), a `Delay[1]`, and a `Sub`; `delta = price - prev`
|
// (its clock is the price role), a `Delay[1]`, and a `Sub`; `delta = price - prev`
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
use aura_core::{AnyColumn, Ctx, Node, Scalar, ScalarKind, Timestamp};
|
use aura_core::{AnyColumn, Ctx, Node, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_engine::{summarize, summarize_r};
|
use aura_engine::{summarize, summarize_r};
|
||||||
use aura_std::{GatedRecorder, SeriesReducer, PM_RECORD_KINDS, PM_WIDTH};
|
use aura_backtest::{PM_RECORD_KINDS, PM_WIDTH};
|
||||||
|
use aura_std::{GatedRecorder, SeriesReducer};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
const CLOSED: usize = 0;
|
const CLOSED: usize = 0;
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
use aura_core::{AnyColumn, Ctx, Node, Scalar, ScalarKind, Timestamp};
|
use aura_core::{AnyColumn, Ctx, Node, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_std::{GatedRecorder, PM_RECORD_KINDS, PM_WIDTH};
|
use aura_backtest::{PM_RECORD_KINDS, PM_WIDTH};
|
||||||
|
use aura_std::GatedRecorder;
|
||||||
|
|
||||||
struct CountingAlloc;
|
struct CountingAlloc;
|
||||||
static LIVE: AtomicUsize = AtomicUsize::new(0);
|
static LIVE: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ use std::sync::mpsc;
|
|||||||
|
|
||||||
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
|
||||||
use aura_engine::{GraphBuilder, VecSource};
|
use aura_engine::{GraphBuilder, VecSource};
|
||||||
use aura_std::{Abs, Gt, Recorder, Resample, When};
|
use aura_market::Resample;
|
||||||
|
use aura_std::{Abs, Gt, Recorder, When};
|
||||||
|
|
||||||
/// A deterministic `f64` tick stream, no timestamps/randomness beyond a fixed
|
/// A deterministic `f64` tick stream, no timestamps/randomness beyond a fixed
|
||||||
/// literal sequence.
|
/// literal sequence.
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ aura-engine = { path = "../aura-engine" }
|
|||||||
zip = "2"
|
zip = "2"
|
||||||
# the integration tests bootstrap a sample harness + fold a RunReport
|
# the integration tests bootstrap a sample harness + fold a RunReport
|
||||||
aura-std = { path = "../aura-std" }
|
aura-std = { path = "../aura-std" }
|
||||||
|
aura-market = { path = "../aura-market" }
|
||||||
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
# chrono / chrono-tz build the Berlin-local-wall-clock window bounds + the
|
# chrono / chrono-tz build the Berlin-local-wall-clock window bounds + the
|
||||||
# Session node's timezone for the real GER40 session-breakout example/test
|
# Session node's timezone for the real GER40 session-breakout example/test
|
||||||
# (examples/ger40_breakout_real.rs, tests/ger40_breakout_real.rs). Pinned to
|
# (examples/ger40_breakout_real.rs, tests/ger40_breakout_real.rs). Pinned to
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ use aura_engine::{
|
|||||||
join_on_ts, summarize, Composite, Edge, FlatGraph, GraphBuilder, Harness, RunManifest,
|
join_on_ts, summarize, Composite, Edge, FlatGraph, GraphBuilder, Harness, RunManifest,
|
||||||
RunReport, SourceSpec, Target,
|
RunReport, SourceSpec, Target,
|
||||||
};
|
};
|
||||||
use aura_std::{And, Delay, EqConst, Gt, Latch, Recorder, Resample, Session, SimBroker};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_market::{Resample, Session};
|
||||||
|
use aura_std::{And, Delay, EqConst, Gt, Latch, Recorder};
|
||||||
use chrono::TimeZone;
|
use chrono::TimeZone;
|
||||||
use chrono_tz::Europe::Berlin;
|
use chrono_tz::Europe::Berlin;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ use aura_engine::{
|
|||||||
VecSource,
|
VecSource,
|
||||||
};
|
};
|
||||||
use aura_ingest::load_m1_window;
|
use aura_ingest::load_m1_window;
|
||||||
use aura_std::{Bias, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use data_server::{DataServer, DEFAULT_DATA_PATH};
|
use data_server::{DataServer, DEFAULT_DATA_PATH};
|
||||||
|
|
||||||
/// Bootstrap the cycle-0007 two-sink signal-quality harness (mirrors
|
/// Bootstrap the cycle-0007 two-sink signal-quality harness (mirrors
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ use aura_engine::{
|
|||||||
Target,
|
Target,
|
||||||
};
|
};
|
||||||
use aura_ingest::{M1Field, M1FieldSource};
|
use aura_ingest::{M1Field, M1FieldSource};
|
||||||
use aura_std::{Bias, Recorder, SimBroker, Sma, Sub};
|
use aura_backtest::SimBroker;
|
||||||
|
use aura_std::{Recorder, Sma, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
use data_server::loader::CHUNK_SIZE;
|
use data_server::loader::CHUNK_SIZE;
|
||||||
use data_server::{DataServer, DEFAULT_DATA_PATH};
|
use data_server::{DataServer, DEFAULT_DATA_PATH};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "aura-market"
|
||||||
|
edition.workspace = true
|
||||||
|
version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
aura-core = { path = "../aura-core" }
|
||||||
|
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
||||||
|
chrono-tz = { version = "0.10", default-features = false }
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
//! `aura-market` — the market-vocabulary node layer (C28): session anchoring and
|
||||||
|
//! bar resampling over market data streams. Depends only on `aura-core`.
|
||||||
|
|
||||||
|
mod resample;
|
||||||
|
mod session;
|
||||||
|
|
||||||
|
pub use resample::Resample;
|
||||||
|
pub use session::{Session, SessionFrankfurt};
|
||||||
@@ -24,3 +24,5 @@ serde_json = { workspace = true }
|
|||||||
# the referential-tier test's generic param-space fixture (a real vocabulary
|
# the referential-tier test's generic param-space fixture (a real vocabulary
|
||||||
# resolver + a zero-arg node, not hand-rolled).
|
# resolver + a zero-arg node, not hand-rolled).
|
||||||
aura-std = { path = "../aura-std" }
|
aura-std = { path = "../aura-std" }
|
||||||
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
|
aura-vocabulary = { path = "../aura-vocabulary" }
|
||||||
|
|||||||
@@ -1799,7 +1799,7 @@ mod tests {
|
|||||||
use aura_research::{Axis, DocRef};
|
use aura_research::{Axis, DocRef};
|
||||||
|
|
||||||
let reg = Registry::open(temp_family_dir("referential_tier"));
|
let reg = Registry::open(temp_family_dir("referential_tier"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
|
|
||||||
// A minimal fixture composite with one OPEN param, built from a
|
// A minimal fixture composite with one OPEN param, built from a
|
||||||
// zero-arg `aura-std` node (`Bias`) so `std_vocabulary` can actually
|
// zero-arg `aura-std` node (`Bias`) so `std_vocabulary` can actually
|
||||||
@@ -1812,7 +1812,7 @@ mod tests {
|
|||||||
// vocabulary-loadable composite" the test needs.
|
// vocabulary-loadable composite" the test needs.
|
||||||
let composite = Composite::new(
|
let composite = Composite::new(
|
||||||
"fixture",
|
"fixture",
|
||||||
vec![aura_std::Bias::builder().named("b").into()],
|
vec![aura_strategy::Bias::builder().named("b").into()],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
@@ -1942,7 +1942,7 @@ mod tests {
|
|||||||
fn bias_fixture() -> aura_engine::Composite {
|
fn bias_fixture() -> aura_engine::Composite {
|
||||||
aura_engine::Composite::new(
|
aura_engine::Composite::new(
|
||||||
"fixture",
|
"fixture",
|
||||||
vec![aura_std::Bias::builder().named("b").into()],
|
vec![aura_strategy::Bias::builder().named("b").into()],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
@@ -1966,7 +1966,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn identity_index_lookup_backfills_and_resolves() {
|
fn identity_index_lookup_backfills_and_resolves() {
|
||||||
let reg = Registry::open(temp_family_dir("identity_backfill"));
|
let reg = Registry::open(temp_family_dir("identity_backfill"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
let (blueprint_json, content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
let (blueprint_json, content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
||||||
|
|
||||||
// no index yet: the lookup answers via the scan fallback...
|
// no index yet: the lookup answers via the scan fallback...
|
||||||
@@ -1983,7 +1983,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn identity_index_verified_hit_answers_without_a_store_walk() {
|
fn identity_index_verified_hit_answers_without_a_store_walk() {
|
||||||
let reg = Registry::open(temp_family_dir("identity_hit_no_walk"));
|
let reg = Registry::open(temp_family_dir("identity_hit_no_walk"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
let (blueprint_json, _content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
let (blueprint_json, _content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
||||||
|
|
||||||
// backfill the index, then poison the store: a DIRECTORY named like
|
// backfill the index, then poison the store: a DIRECTORY named like
|
||||||
@@ -2003,7 +2003,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn identity_index_legacy_store_backfills_in_one_pass() {
|
fn identity_index_legacy_store_backfills_in_one_pass() {
|
||||||
let reg = Registry::open(temp_family_dir("identity_legacy_backfill"));
|
let reg = Registry::open(temp_family_dir("identity_legacy_backfill"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
let (_json_a, content_a, identity_a) = seed_blueprint(®, &bias_fixture());
|
let (_json_a, content_a, identity_a) = seed_blueprint(®, &bias_fixture());
|
||||||
let (_json_b, content_b, identity_b) = seed_blueprint(®, &delay_fixture());
|
let (_json_b, content_b, identity_b) = seed_blueprint(®, &delay_fixture());
|
||||||
assert_ne!(identity_a, identity_b, "fixtures must be identity-distinct");
|
assert_ne!(identity_a, identity_b, "fixtures must be identity-distinct");
|
||||||
@@ -2023,7 +2023,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn identity_index_stale_lines_degrade_to_scan_and_heal() {
|
fn identity_index_stale_lines_degrade_to_scan_and_heal() {
|
||||||
let reg = Registry::open(temp_family_dir("identity_stale_heals"));
|
let reg = Registry::open(temp_family_dir("identity_stale_heals"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
let (json_a, content_a, identity_a) = seed_blueprint(®, &bias_fixture());
|
let (json_a, content_a, identity_a) = seed_blueprint(®, &bias_fixture());
|
||||||
let (_json_b, content_b, _identity_b) = seed_blueprint(®, &delay_fixture());
|
let (_json_b, content_b, _identity_b) = seed_blueprint(®, &delay_fixture());
|
||||||
|
|
||||||
@@ -2052,7 +2052,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn identity_index_unloadable_under_roster_stays_unmatched() {
|
fn identity_index_unloadable_under_roster_stays_unmatched() {
|
||||||
let reg = Registry::open(temp_family_dir("identity_unloadable"));
|
let reg = Registry::open(temp_family_dir("identity_unloadable"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
let (_json, _content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
let (_json, _content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
||||||
reg.find_blueprint_by_identity(&identity_id, &resolve).expect("backfill");
|
reg.find_blueprint_by_identity(&identity_id, &resolve).expect("backfill");
|
||||||
|
|
||||||
@@ -2067,7 +2067,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn identity_index_garbage_line_does_not_break_resolution() {
|
fn identity_index_garbage_line_does_not_break_resolution() {
|
||||||
let reg = Registry::open(temp_family_dir("identity_garbage_line"));
|
let reg = Registry::open(temp_family_dir("identity_garbage_line"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
let (blueprint_json, _content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
let (blueprint_json, _content_id, identity_id) = seed_blueprint(®, &bias_fixture());
|
||||||
|
|
||||||
// a wholly-garbage index file must not break resolution (a
|
// a wholly-garbage index file must not break resolution (a
|
||||||
@@ -2089,7 +2089,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn identity_index_twin_store_converges_and_stops_growing() {
|
fn identity_index_twin_store_converges_and_stops_growing() {
|
||||||
let reg = Registry::open(temp_family_dir("identity_twin_converges"));
|
let reg = Registry::open(temp_family_dir("identity_twin_converges"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
|
|
||||||
// Two same-identity twins: the one-node Bias composite, built with
|
// Two same-identity twins: the one-node Bias composite, built with
|
||||||
// different debug names. Debug symbols are identity-blind, so the two
|
// different debug names. Debug symbols are identity-blind, so the two
|
||||||
@@ -2097,7 +2097,7 @@ mod tests {
|
|||||||
let (_json_a, content_a, identity) = seed_blueprint(®, &bias_fixture());
|
let (_json_a, content_a, identity) = seed_blueprint(®, &bias_fixture());
|
||||||
let twin = aura_engine::Composite::new(
|
let twin = aura_engine::Composite::new(
|
||||||
"fixture_twin",
|
"fixture_twin",
|
||||||
vec![aura_std::Bias::builder().named("b_twin").into()],
|
vec![aura_strategy::Bias::builder().named("b_twin").into()],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
@@ -2145,7 +2145,7 @@ mod tests {
|
|||||||
use aura_std::Sma;
|
use aura_std::Sma;
|
||||||
|
|
||||||
let reg = Registry::open(temp_family_dir("bound_axis_tier"));
|
let reg = Registry::open(temp_family_dir("bound_axis_tier"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
|
|
||||||
// A fixture composite with ONE bound param and NO open param, so the
|
// A fixture composite with ONE bound param and NO open param, so the
|
||||||
// reverse full-coverage check (every OPEN param must be bound by an
|
// reverse full-coverage check (every OPEN param must be bound by an
|
||||||
@@ -2234,7 +2234,7 @@ mod tests {
|
|||||||
use aura_engine::{blueprint_to_json, Composite};
|
use aura_engine::{blueprint_to_json, Composite};
|
||||||
|
|
||||||
let reg = Registry::open(temp_family_dir("coverage_tier"));
|
let reg = Registry::open(temp_family_dir("coverage_tier"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
|
|
||||||
// A fixture composite with TWO open params, from two zero-arg `Bias`
|
// A fixture composite with TWO open params, from two zero-arg `Bias`
|
||||||
// nodes so `std_vocabulary` can load it on round-trip (the sibling test
|
// nodes so `std_vocabulary` can load it on round-trip (the sibling test
|
||||||
@@ -2243,8 +2243,8 @@ mod tests {
|
|||||||
let composite = Composite::new(
|
let composite = Composite::new(
|
||||||
"fixture",
|
"fixture",
|
||||||
vec![
|
vec![
|
||||||
aura_std::Bias::builder().named("b1").into(),
|
aura_strategy::Bias::builder().named("b1").into(),
|
||||||
aura_std::Bias::builder().named("b2").into(),
|
aura_strategy::Bias::builder().named("b2").into(),
|
||||||
],
|
],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
@@ -2307,14 +2307,14 @@ mod tests {
|
|||||||
use aura_engine::{blueprint_to_json, Composite, Role, Target};
|
use aura_engine::{blueprint_to_json, Composite, Role, Target};
|
||||||
|
|
||||||
let reg = Registry::open(temp_family_dir("binding_keys"));
|
let reg = Registry::open(temp_family_dir("binding_keys"));
|
||||||
let resolve = |t: &str| aura_std::std_vocabulary(t);
|
let resolve = |t: &str| aura_vocabulary::std_vocabulary(t);
|
||||||
|
|
||||||
// The referential fixture composite (see
|
// The referential fixture composite (see
|
||||||
// referential_tier_resolves_refs_and_checks_axes), plus ONE input
|
// referential_tier_resolves_refs_and_checks_axes), plus ONE input
|
||||||
// role so a binding key has something to name.
|
// role so a binding key has something to name.
|
||||||
let composite = Composite::new(
|
let composite = Composite::new(
|
||||||
"fixture",
|
"fixture",
|
||||||
vec![aura_std::Bias::builder().named("b").into()],
|
vec![aura_strategy::Bias::builder().named("b").into()],
|
||||||
vec![],
|
vec![],
|
||||||
vec![Role {
|
vec![Role {
|
||||||
name: "price".to_string(),
|
name: "price".to_string(),
|
||||||
|
|||||||
@@ -14,3 +14,7 @@ aura-core = { path = "../aura-core" }
|
|||||||
# zone + DST transitions.
|
# zone + DST transitions.
|
||||||
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
||||||
chrono-tz = { version = "0.10", default-features = false }
|
chrono-tz = { version = "0.10", default-features = false }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
|
|||||||
@@ -20,12 +20,7 @@
|
|||||||
mod abs;
|
mod abs;
|
||||||
mod add;
|
mod add;
|
||||||
mod and;
|
mod and;
|
||||||
mod bias;
|
|
||||||
mod carry_cost;
|
|
||||||
mod const_node;
|
mod const_node;
|
||||||
mod constant_cost;
|
|
||||||
mod cost;
|
|
||||||
mod cost_sum;
|
|
||||||
mod cumsum;
|
mod cumsum;
|
||||||
mod delay;
|
mod delay;
|
||||||
mod div;
|
mod div;
|
||||||
@@ -35,42 +30,24 @@ mod gated_recorder;
|
|||||||
mod gt;
|
mod gt;
|
||||||
mod latch;
|
mod latch;
|
||||||
mod lincomb;
|
mod lincomb;
|
||||||
mod longonly;
|
|
||||||
mod max;
|
mod max;
|
||||||
mod min;
|
mod min;
|
||||||
mod mul;
|
mod mul;
|
||||||
mod position_management;
|
|
||||||
mod recorder;
|
mod recorder;
|
||||||
mod resample;
|
|
||||||
mod rolling_max;
|
mod rolling_max;
|
||||||
mod rolling_min;
|
mod rolling_min;
|
||||||
mod scale;
|
mod scale;
|
||||||
mod select;
|
mod select;
|
||||||
mod series_reducer;
|
mod series_reducer;
|
||||||
mod session;
|
|
||||||
mod sign;
|
mod sign;
|
||||||
mod sim_broker;
|
|
||||||
mod sizer;
|
|
||||||
mod sma;
|
mod sma;
|
||||||
mod sqrt;
|
mod sqrt;
|
||||||
mod stop_rule;
|
|
||||||
mod sub;
|
mod sub;
|
||||||
mod vocabulary;
|
|
||||||
mod vol_slippage_cost;
|
|
||||||
mod vol_tf_stop;
|
|
||||||
mod when;
|
mod when;
|
||||||
pub use abs::Abs;
|
pub use abs::Abs;
|
||||||
pub use add::Add;
|
pub use add::Add;
|
||||||
pub use and::And;
|
pub use and::And;
|
||||||
pub use bias::Bias;
|
|
||||||
pub use carry_cost::CarryCost;
|
|
||||||
pub use const_node::Const;
|
pub use const_node::Const;
|
||||||
pub use constant_cost::ConstantCost;
|
|
||||||
pub use cost::{
|
|
||||||
cost_node_builder, cost_port, intern_port, ChargeMode, CostNode, CostRunner,
|
|
||||||
COST_FIELD_NAMES, COST_WIDTH, GEOMETRY_WIDTH,
|
|
||||||
};
|
|
||||||
pub use cost_sum::CostSum;
|
|
||||||
pub use cumsum::CumSum;
|
pub use cumsum::CumSum;
|
||||||
pub use delay::Delay;
|
pub use delay::Delay;
|
||||||
pub use div::Div;
|
pub use div::Div;
|
||||||
@@ -80,30 +57,17 @@ pub use gated_recorder::GatedRecorder;
|
|||||||
pub use gt::Gt;
|
pub use gt::Gt;
|
||||||
pub use latch::Latch;
|
pub use latch::Latch;
|
||||||
pub use lincomb::LinComb;
|
pub use lincomb::LinComb;
|
||||||
pub use longonly::LongOnly;
|
|
||||||
pub use max::Max;
|
pub use max::Max;
|
||||||
pub use min::Min;
|
pub use min::Min;
|
||||||
pub use mul::Mul;
|
pub use mul::Mul;
|
||||||
pub use position_management::{
|
|
||||||
ExitReason, FIELD_NAMES as PM_FIELD_NAMES, PositionManagement, RECORD_KINDS as PM_RECORD_KINDS,
|
|
||||||
WIDTH as PM_WIDTH,
|
|
||||||
};
|
|
||||||
pub use recorder::Recorder;
|
pub use recorder::Recorder;
|
||||||
pub use resample::Resample;
|
|
||||||
pub use rolling_max::RollingMax;
|
pub use rolling_max::RollingMax;
|
||||||
pub use rolling_min::RollingMin;
|
pub use rolling_min::RollingMin;
|
||||||
pub use scale::Scale;
|
pub use scale::Scale;
|
||||||
pub use select::Select;
|
pub use select::Select;
|
||||||
pub use series_reducer::SeriesReducer;
|
pub use series_reducer::SeriesReducer;
|
||||||
pub use session::{Session, SessionFrankfurt};
|
|
||||||
pub use sign::Sign;
|
pub use sign::Sign;
|
||||||
pub use sim_broker::SimBroker;
|
|
||||||
pub use sizer::Sizer;
|
|
||||||
pub use sma::Sma;
|
pub use sma::Sma;
|
||||||
pub use sqrt::Sqrt;
|
pub use sqrt::Sqrt;
|
||||||
pub use stop_rule::FixedStop;
|
|
||||||
pub use sub::Sub;
|
pub use sub::Sub;
|
||||||
pub use vocabulary::{std_vocabulary, std_vocabulary_types};
|
|
||||||
pub use vol_slippage_cost::VolSlippageCost;
|
|
||||||
pub use vol_tf_stop::VolTfStop;
|
|
||||||
pub use when::When;
|
pub use when::When;
|
||||||
|
|||||||
@@ -202,7 +202,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn labels_carry_identifying_params() {
|
fn labels_carry_identifying_params() {
|
||||||
use crate::{Add, Bias, LinComb, Recorder, SimBroker, Sub};
|
use crate::{Add, LinComb, Recorder, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
use aura_backtest::SimBroker;
|
||||||
use aura_core::{Firing, ScalarKind};
|
use aura_core::{Firing, ScalarKind};
|
||||||
|
|
||||||
// the load-bearing payoff: two SMAs disambiguate by window
|
// the load-bearing payoff: two SMAs disambiguate by window
|
||||||
@@ -221,7 +223,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nodes_declare_expected_params() {
|
fn nodes_declare_expected_params() {
|
||||||
use crate::{Add, Bias, LinComb, Recorder, SimBroker, Sub};
|
use crate::{Add, LinComb, Recorder, Sub};
|
||||||
|
use aura_strategy::Bias;
|
||||||
|
use aura_backtest::SimBroker;
|
||||||
use aura_core::{Firing, ParamSpec, ScalarKind};
|
use aura_core::{Firing, ParamSpec, ScalarKind};
|
||||||
// single scalar knobs (declared on the param-generic builder, pre-build)
|
// single scalar knobs (declared on the param-generic builder, pre-build)
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "aura-strategy"
|
||||||
|
edition.workspace = true
|
||||||
|
version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
aura-core = { path = "../aura-core" }
|
||||||
@@ -91,7 +91,7 @@ pub enum ChargeMode {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use aura_core::Ctx;
|
/// use aura_core::Ctx;
|
||||||
/// use aura_std::{CostNode, CostRunner};
|
/// use aura_strategy::{CostNode, CostRunner};
|
||||||
///
|
///
|
||||||
/// pub struct HalfSpreadCost {
|
/// pub struct HalfSpreadCost {
|
||||||
/// half_spread: f64,
|
/// half_spread: f64,
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//! `aura-strategy` — the strategy-definition node layer (C28): bias, stop rules,
|
||||||
|
//! sizing, and the cost-model machinery (measured in R). Depends only on
|
||||||
|
//! `aura-core`.
|
||||||
|
|
||||||
|
mod bias;
|
||||||
|
mod carry_cost;
|
||||||
|
mod constant_cost;
|
||||||
|
mod cost;
|
||||||
|
mod cost_sum;
|
||||||
|
mod longonly;
|
||||||
|
mod sizer;
|
||||||
|
mod stop_rule;
|
||||||
|
mod vol_slippage_cost;
|
||||||
|
mod vol_tf_stop;
|
||||||
|
|
||||||
|
pub use bias::Bias;
|
||||||
|
pub use carry_cost::CarryCost;
|
||||||
|
pub use constant_cost::ConstantCost;
|
||||||
|
pub use cost::{
|
||||||
|
cost_node_builder, cost_port, intern_port, ChargeMode, CostNode, CostRunner,
|
||||||
|
COST_FIELD_NAMES, COST_WIDTH, GEOMETRY_WIDTH,
|
||||||
|
};
|
||||||
|
pub use cost_sum::CostSum;
|
||||||
|
pub use longonly::LongOnly;
|
||||||
|
pub use sizer::Sizer;
|
||||||
|
pub use stop_rule::FixedStop;
|
||||||
|
pub use vol_slippage_cost::VolSlippageCost;
|
||||||
|
pub use vol_tf_stop::VolTfStop;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "aura-vocabulary"
|
||||||
|
edition.workspace = true
|
||||||
|
version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
aura-core = { path = "../aura-core" }
|
||||||
|
aura-std = { path = "../aura-std" }
|
||||||
|
aura-market = { path = "../aura-market" }
|
||||||
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
toml = "0.8"
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
//! The closed, compiled-in dispatch from a serialized node **type identity** to
|
//! The closed, compiled-in dispatch from a serialized node **type identity** to
|
||||||
//! its `aura-std` builder factory — the load-side counterpart to the type label
|
//! its node-crate builder factory — the load-side counterpart to the type label
|
||||||
//! a blueprint serializes (`PrimitiveBuilder::label`). This is **not** a dynamic
|
//! a blueprint serializes (`PrimitiveBuilder::label`). This is **not** a dynamic
|
||||||
//! registry (domain invariant 9): it is a `match` the crate that *owns* the
|
//! registry (domain invariant 9): it is a `match` the crate that *owns* the
|
||||||
//! nodes writes, over its own closed, compiled-in vocabulary (C24 — nodes are
|
//! nodes writes, over its own closed, compiled-in vocabulary (C24 — nodes are
|
||||||
//! referenced "by compiled-in type identity", never a by-name marketplace). The
|
//! referenced "by compiled-in type identity", never a by-name marketplace). The
|
||||||
//! engine cannot hold this table (it does not depend on `aura-std`); a loader
|
//! engine cannot hold this table (it does not depend on the node crates); a loader
|
||||||
//! takes it as an injected resolver, and a project `cdylib` later supplies its
|
//! takes it as an injected resolver, and a project `cdylib` later supplies its
|
||||||
//! own (C16) through the same seam.
|
//! own (C16) through the same seam.
|
||||||
//!
|
//!
|
||||||
@@ -17,11 +17,13 @@
|
|||||||
//! rather than guessing. Serialising structural-axis construction args is a
|
//! rather than guessing. Serialising structural-axis construction args is a
|
||||||
//! later, additive extension (#156/C20).
|
//! later, additive extension (#156/C20).
|
||||||
|
|
||||||
use crate::{
|
use aura_backtest::PositionManagement;
|
||||||
Abs, Add, And, Bias, CarryCost, Const, ConstantCost, CumSum, Delay, Div, Ema, EqConst,
|
use aura_market::{Resample, SessionFrankfurt};
|
||||||
FixedStop, Gt, Latch, LongOnly, Max, Min, Mul, PositionManagement, Resample, RollingMax,
|
use aura_std::{
|
||||||
RollingMin, Scale, Select, SessionFrankfurt, Sign, Sizer, Sma, Sqrt, Sub, VolSlippageCost, When,
|
Abs, Add, And, Const, CumSum, Delay, Div, Ema, EqConst, Gt, Latch, Max, Min, Mul, RollingMax,
|
||||||
|
RollingMin, Scale, Select, Sign, Sma, Sqrt, Sub, When,
|
||||||
};
|
};
|
||||||
|
use aura_strategy::{Bias, CarryCost, ConstantCost, FixedStop, LongOnly, Sizer, VolSlippageCost};
|
||||||
use aura_core::PrimitiveBuilder;
|
use aura_core::PrimitiveBuilder;
|
||||||
|
|
||||||
/// The single roster source (#160): one `"TypeId" => Type` line per zero-arg
|
/// The single roster source (#160): one `"TypeId" => Type` line per zero-arg
|
||||||
@@ -37,7 +39,7 @@ macro_rules! std_vocabulary_roster {
|
|||||||
($($type_id:literal => $ty:ty),+ $(,)?) => {
|
($($type_id:literal => $ty:ty),+ $(,)?) => {
|
||||||
/// Resolve a serialized node type identity (the `PrimitiveBuilder::label`,
|
/// Resolve a serialized node type identity (the `PrimitiveBuilder::label`,
|
||||||
/// e.g. `"SMA"`) to a fresh, unbound builder from the node's own factory.
|
/// e.g. `"SMA"`) to a fresh, unbound builder from the node's own factory.
|
||||||
/// Returns `None` for any identity outside the zero-arg `aura-std`
|
/// Returns `None` for any identity outside the zero-arg node
|
||||||
/// vocabulary.
|
/// vocabulary.
|
||||||
pub fn std_vocabulary(type_id: &str) -> Option<PrimitiveBuilder> {
|
pub fn std_vocabulary(type_id: &str) -> Option<PrimitiveBuilder> {
|
||||||
Some(match type_id {
|
Some(match type_id {
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
//! C28 structural fitness: the node crates obey the ladder import direction.
|
||||||
|
//! The compiler only rejects import cycles; an acyclic-but-outward dependency
|
||||||
|
//! (e.g. `aura-std` -> `aura-market`) would compile silently. This test reads
|
||||||
|
//! each node crate's `[dependencies]` table and asserts its intra-workspace edges
|
||||||
|
//! stay within the inner set C28 permits for that layer. `[dev-dependencies]` are
|
||||||
|
//! C28-exempt (tests may cross layers) and are deliberately not inspected.
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn workspace_root() -> PathBuf {
|
||||||
|
// aura-vocabulary/ + /../.. = workspace root (the repo idiom for reaching it).
|
||||||
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..").join("..")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `aura-*` keys under `[dependencies]` (NOT `[dev-dependencies]`) of a crate.
|
||||||
|
fn prod_intra_workspace_deps(crate_name: &str) -> Vec<String> {
|
||||||
|
let manifest = workspace_root()
|
||||||
|
.join("crates")
|
||||||
|
.join(crate_name)
|
||||||
|
.join("Cargo.toml");
|
||||||
|
let text = std::fs::read_to_string(&manifest)
|
||||||
|
.unwrap_or_else(|e| panic!("read {}: {e}", manifest.display()));
|
||||||
|
let doc: toml::Value = toml::from_str(&text).expect("Cargo.toml parses as TOML");
|
||||||
|
match doc.get("dependencies").and_then(|d| d.as_table()) {
|
||||||
|
Some(deps) => deps
|
||||||
|
.keys()
|
||||||
|
.filter(|k| k.starts_with("aura-"))
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
None => Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn node_crates_obey_the_c28_import_direction() {
|
||||||
|
// (crate, the intra-workspace [dependencies] C28 permits for its layer)
|
||||||
|
let allowed: &[(&str, &[&str])] = &[
|
||||||
|
("aura-std", &["aura-core"]), // engine
|
||||||
|
("aura-market", &["aura-core"]), // market
|
||||||
|
("aura-strategy", &["aura-core"]), // strategy
|
||||||
|
("aura-backtest", &["aura-core"]), // backtest (may gain aura-strategy when it imports one)
|
||||||
|
(
|
||||||
|
"aura-vocabulary",
|
||||||
|
&[
|
||||||
|
"aura-core",
|
||||||
|
"aura-std",
|
||||||
|
"aura-market",
|
||||||
|
"aura-strategy",
|
||||||
|
"aura-backtest",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (crate_name, permitted) in allowed {
|
||||||
|
for dep in prod_intra_workspace_deps(crate_name) {
|
||||||
|
assert!(
|
||||||
|
permitted.contains(&dep.as_str()),
|
||||||
|
"C28 import-direction violation: `{crate_name}` [dependencies] on `{dep}`, \
|
||||||
|
outside its permitted inner set {permitted:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-12
@@ -2684,23 +2684,29 @@ cleanly by layer, so the layering is realized only partially:
|
|||||||
The stratification supplies the *second* metric consumer (measurement) that the
|
The stratification supplies the *second* metric consumer (measurement) that the
|
||||||
deferral was waiting on, so retiring #147 and cutting this edge are one coupled
|
deferral was waiting on, so retiring #147 and cutting this edge are one coupled
|
||||||
decision — reserved to the user, since it reverses a ratified deferral.
|
decision — reserved to the user, since it reverses a ratified deferral.
|
||||||
- The interweaving is mostly *inside* crates. `aura-std` holds four layers in one
|
- The `aura-std` four-layer roster is now cut by layer (phase 4, #288): `aura-std`
|
||||||
roster: engine (arithmetic/logic/rolling + the generic sinks), market
|
holds the engine nodes only (arithmetic/logic/rolling + the generic sinks);
|
||||||
(`session.rs`, `resample.rs`), strategy (`bias.rs`/`stop_rule.rs`/`sizer.rs` +
|
`aura-market` (`session`, `resample`), `aura-strategy` (`bias`/`stop_rule`/
|
||||||
the cost nodes) and backtest (`sim_broker.rs`, `position_management.rs`);
|
`sizer` + the cost nodes) and `aura-backtest` (`sim_broker`,
|
||||||
`aura-analysis` holds backtest reductions and generic hurdle math together. No
|
`position_management`) carry the outer rungs, each depending only on `aura-core`;
|
||||||
crate exists yet for *measurement* (its run verb is the additive shape dispatch,
|
the closed node roster moved to `aura-vocabulary`. The remaining in-crate
|
||||||
#286) or *execution* (unbuilt — the C10/C13 edge only). Under this model the
|
interweave is `aura-analysis`, which still holds backtest reductions and generic
|
||||||
`aura-registry → aura-research` edge is column-internal and legal.
|
hurdle math together (phase 5). No crate exists yet for *measurement* (its run
|
||||||
|
verb is the additive shape dispatch, #286) or *execution* (unbuilt — the C10/C13
|
||||||
|
edge only). Under this model the `aura-registry → aura-research` edge is
|
||||||
|
column-internal and legal.
|
||||||
- Phased realization (each independently shippable; behaviour byte-identical
|
- Phased realization (each independently shippable; behaviour byte-identical
|
||||||
except the purely additive shape dispatch): (1) this contract; (2) cut the
|
except the purely additive shape dispatch): (1) this contract; (2) cut the
|
||||||
`engine → analysis` edge — coupled to the #147 decision above; (3) the #286
|
`engine → analysis` edge — coupled to the #147 decision above; (3) the #286
|
||||||
shape dispatch plus the per-run scaffold as a library (seeds an `aura-backtest`
|
shape dispatch plus the per-run scaffold as a library (seeds an `aura-backtest`
|
||||||
crate, gives *measurement* its run verb, removes the measured O(cycles) run-time
|
crate, gives *measurement* its run verb, removes the measured O(cycles) run-time
|
||||||
retention); (4) split the `aura-std` roster along engine / market /
|
retention); (4) split the `aura-std` roster along engine / market / strategy /
|
||||||
strategy+backtest; (5) split `aura-analysis` into generic statistics and
|
backtest — **done** (#288: four `aura-core`-only node crates, the closed roster
|
||||||
backtest metrics; (6) generify the column's metric interface (demand-driven —
|
moved to `aura-vocabulary`, the ladder direction enforced by a structural test);
|
||||||
this is #147). Crate names provisional; full evidence on #286 and the milestone.
|
(5) split `aura-analysis` into generic statistics and backtest metrics; (6)
|
||||||
|
generify the column's metric interface (demand-driven — this is #147). Crate
|
||||||
|
names now realized (`aura-market`/`aura-strategy`/`aura-backtest`/
|
||||||
|
`aura-vocabulary`); full evidence on #288, #286 and the milestone.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user