refactor: split aura-analysis into statistics and backtest metrics
C28 phase 5 (Stratification): the backtest reductions - RunMetrics, RMetrics, summarize_r, r_metrics_from_rs, and the position-event table - move verbatim into aura-backtest::metrics, beside the position_management producer whose record layout they read (the r_col/cost_col lockstep contract is now intra-crate; its stale "aura-std" comment corrected). aura-analysis is reduced to the domain-free half: the multiple-comparison hurdle math (inv_norm_cdf, expected_max_of_normals) and the selection-provenance types (FamilySelection/SelectionMode - kept beside the statistics so RunManifest.selection embeds a foundation-grade type), [dependencies] = serde only. The engine re-export surface is name-unchanged (report.rs re-imports from both crates), so no indirect consumer needed a source edit; aura-backtest moves from aura-engine's dev-dependencies into [dependencies] as a commented TRANSIENT widening of the C28 violation, removed by the phase-2 edge cut on this branch. The campaign drift guard imports its pinned types from their new source crates. Behaviour-preserving: 1448/0 tests, clippy -D warnings clean, serde shapes byte-identical (C18), moved code traceable via git copy detection. closes #291
This commit is contained in:
Generated
+3
-2
@@ -100,9 +100,7 @@ dependencies = [
|
|||||||
name = "aura-analysis"
|
name = "aura-analysis"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aura-core",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -110,6 +108,8 @@ name = "aura-backtest"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aura-core",
|
"aura-core",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -133,6 +133,7 @@ name = "aura-campaign"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aura-analysis",
|
"aura-analysis",
|
||||||
|
"aura-backtest",
|
||||||
"aura-core",
|
"aura-core",
|
||||||
"aura-engine",
|
"aura-engine",
|
||||||
"aura-registry",
|
"aura-registry",
|
||||||
|
|||||||
@@ -6,15 +6,8 @@ license.workspace = true
|
|||||||
publish.workspace = true
|
publish.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aura-core = { path = "../aura-core" }
|
# serde gives the selection-provenance types (`FamilySelection`/`SelectionMode`,
|
||||||
# serde is admitted under the amended C16 per-case dependency policy (INDEX.md):
|
# embedded by the engine's `RunManifest.selection`) their typed
|
||||||
# it gives the run-report types a typed (de)serialization path for the run
|
# (de)serialization path for the run registry (C18). Deterministic output
|
||||||
# registry (cycle 0029). serde's output is deterministic (C1-safe).
|
# (C1-safe). The backtest metric types moved to aura-backtest (#291).
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
# serde_json is used only by this crate's round-trip tests (the production types
|
|
||||||
# derive serde, but JSON rendering lives in aura-engine's RunReport::to_json).
|
|
||||||
# Test-only -> dev-dependencies, so it never enters the frozen artifact's library
|
|
||||||
# link (C16 frozen-artifact scrutiny).
|
|
||||||
serde_json = { workspace = true }
|
|
||||||
|
|||||||
+10
-1045
File diff suppressed because it is too large
Load Diff
@@ -7,3 +7,13 @@ publish.workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aura-core = { path = "../aura-core" }
|
aura-core = { path = "../aura-core" }
|
||||||
|
# serde gives the backtest metric types (`RunMetrics`/`RMetrics`/`PositionEvent`)
|
||||||
|
# their typed (de)serialization path for the run registry (C18; moved with the
|
||||||
|
# types from aura-analysis, #291). Deterministic output (C1-safe).
|
||||||
|
serde = { workspace = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
# serde_json is used only by the moved metric round-trip tests (JSON rendering
|
||||||
|
# for production lives in aura-engine's RunReport::to_json). Test-only, so it
|
||||||
|
# never enters the frozen artifact's library link (C16).
|
||||||
|
serde_json = { workspace = true }
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
//! `aura-backtest` — the backtest-execution node layer (C28): simulated execution
|
//! `aura-backtest` — the backtest layer (C28): simulated execution without
|
||||||
//! without money (the `SimBroker` pip yardstick, position management), measured in
|
//! money (the `SimBroker` pip yardstick, position management), measured in R,
|
||||||
//! R. Depends only on `aura-core`.
|
//! plus the backtest metric reductions over the recorded streams
|
||||||
|
//! (`metrics`, moved from `aura-analysis` by #291). Depends only on
|
||||||
|
//! `aura-core` (+ serde for the metric types' C18 wire shapes).
|
||||||
|
|
||||||
|
mod metrics;
|
||||||
mod position_management;
|
mod position_management;
|
||||||
mod sim_broker;
|
mod sim_broker;
|
||||||
|
|
||||||
|
pub use metrics::{
|
||||||
|
derive_position_events, r_metrics_from_rs, summarize_r, PositionAction,
|
||||||
|
PositionEvent, RMetrics, RunMetrics,
|
||||||
|
};
|
||||||
pub use position_management::{
|
pub use position_management::{
|
||||||
ExitReason, FIELD_NAMES as PM_FIELD_NAMES, PositionManagement,
|
ExitReason, FIELD_NAMES as PM_FIELD_NAMES, PositionManagement,
|
||||||
RECORD_KINDS as PM_RECORD_KINDS, WIDTH as PM_WIDTH,
|
RECORD_KINDS as PM_RECORD_KINDS, WIDTH as PM_WIDTH,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -28,3 +28,9 @@ serde_json = { workspace = true }
|
|||||||
# work-stealing pool the engine's run_indexed already uses — parallelism across
|
# work-stealing pool the engine's run_indexed already uses — parallelism across
|
||||||
# sims, never within one. Direct versioned dep, mirroring aura-engine.
|
# sims, never within one. Direct versioned dep, mirroring aura-engine.
|
||||||
rayon = "1"
|
rayon = "1"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
# aura-backtest supplies RunMetrics/summarize_r for the metric-vocabulary drift
|
||||||
|
# guard's direct-source import (tests/metric_vocabulary_e2e.rs). Production
|
||||||
|
# code reaches these types via the aura-engine re-export instead.
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
//! Cross-crate guard for #190: pins `aura_research::metric_vocabulary()` (the
|
//! Cross-crate guard for #190: pins `aura_research::metric_vocabulary()` (the
|
||||||
//! hand-written 17-name declared metric roster) against the ACTUAL scalar
|
//! hand-written 17-name declared metric roster) against the ACTUAL scalar
|
||||||
//! fields the three metric-bearing `aura-analysis` types serialize — not a
|
//! fields the three metric-bearing types serialize — `RunMetrics`/`RMetrics`
|
||||||
//! second hand-list that could independently drift. `aura-campaign` is the
|
//! from `aura-backtest` (via `summarize_r`), `FamilySelection` from
|
||||||
//! one crate that already depends on both `aura-analysis` (the types) and
|
//! `aura-analysis` — not a second hand-list that could independently drift.
|
||||||
//! `aura-research` (the vocabulary), so it is the only place this pin can be
|
//! `aura-campaign` is the one crate that already depends on the type sources
|
||||||
//! written today (`aura-research` deliberately has no `aura-analysis` dep —
|
//! and `aura-research` (the vocabulary), so this pin lives here
|
||||||
|
//! (`aura-research` deliberately has no dep on either type crate —
|
||||||
//! `metric_vocabulary`'s own doc comment names this as an accepted residual).
|
//! `metric_vocabulary`'s own doc comment names this as an accepted residual).
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use aura_analysis::{summarize_r, FamilySelection, RunMetrics, SelectionMode};
|
use aura_analysis::{FamilySelection, SelectionMode};
|
||||||
|
use aura_backtest::{summarize_r, RunMetrics};
|
||||||
|
|
||||||
/// The names of every field of a serialized sample whose JSON value is a
|
/// The names of every field of a serialized sample whose JSON value is a
|
||||||
/// `Number` — i.e. a scalar metric readout, not a string/enum tag, a nested
|
/// `Number` — i.e. a scalar metric readout, not a string/enum tag, a nested
|
||||||
|
|||||||
@@ -7,11 +7,16 @@ publish.workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aura-core = { path = "../aura-core" }
|
aura-core = { path = "../aura-core" }
|
||||||
# aura-analysis holds the pure trading-domain reductions (R-metrics, the
|
# aura-analysis holds the domain-free post-run statistics and the
|
||||||
# position-event table, the multiple-comparison hurdle math) lifted out of
|
# selection-provenance types the engine's `RunManifest.selection` embeds
|
||||||
# `report` (issue #136). The engine re-exports them via `report::` so callers
|
# (#136, reduced to the domain-free half by #291). Re-exported via `report::`
|
||||||
# resolve the moved types through aura-engine unchanged (C18 byte-identity).
|
# so callers resolve the types through aura-engine unchanged (C18).
|
||||||
aura-analysis = { path = "../aura-analysis" }
|
aura-analysis = { path = "../aura-analysis" }
|
||||||
|
# aura-backtest holds the backtest metric reductions re-exported through
|
||||||
|
# `report::` (#291). TRANSIENT widening of the known C28 layer violation: the
|
||||||
|
# phase-2 edge cut (#147) removes this production edge again on the same
|
||||||
|
# branch.
|
||||||
|
aura-backtest = { path = "../aura-backtest" }
|
||||||
# serde is admitted under the amended C16 per-case dependency policy (INDEX.md):
|
# serde is admitted under the amended C16 per-case dependency policy (INDEX.md):
|
||||||
# it gives the run-report types a typed (de)serialization path for the run
|
# it gives the run-report types a typed (de)serialization path for the run
|
||||||
# registry (cycle 0029). serde's output is deterministic (C1-safe).
|
# registry (cycle 0029). serde's output is deterministic (C1-safe).
|
||||||
@@ -38,7 +43,6 @@ rayon = "1"
|
|||||||
aura-std = { path = "../aura-std" }
|
aura-std = { path = "../aura-std" }
|
||||||
aura-market = { path = "../aura-market" }
|
aura-market = { path = "../aura-market" }
|
||||||
aura-strategy = { path = "../aura-strategy" }
|
aura-strategy = { path = "../aura-strategy" }
|
||||||
aura-backtest = { path = "../aura-backtest" }
|
|
||||||
aura-vocabulary = { path = "../aura-vocabulary" }
|
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,
|
||||||
|
|||||||
@@ -11,15 +11,17 @@
|
|||||||
use aura_core::{Scalar, ScalarKind, SeriesFold, Timestamp};
|
use aura_core::{Scalar, ScalarKind, SeriesFold, Timestamp};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
// The pure trading-domain reductions (R-metrics, the position-event table, the
|
// The backtest reductions (R-metrics, the position-event table) live in
|
||||||
// multiple-comparison hurdle math) live in `aura-analysis` (issue #136); they are
|
// `aura-backtest::metrics`, the domain-free hurdle math + selection provenance
|
||||||
// re-imported here so `report::`'s namespace — and therefore `aura-engine`'s
|
// in `aura-analysis` (issues #136, #291); both are re-imported here so
|
||||||
// `lib.rs` re-export and every `crate::report::X` reference — resolves unchanged
|
// `report::`'s namespace — and therefore `aura-engine`'s `lib.rs` re-export and
|
||||||
// (C18 byte-identity). `summarize` (below) bridges trace columns into these types
|
// every `crate::report::X` reference — resolves unchanged (C18 byte-identity).
|
||||||
// at the engine boundary, so it stays here.
|
// `summarize` (below) bridges trace columns into these types at the engine
|
||||||
pub use aura_analysis::{
|
// boundary, so it stays here.
|
||||||
derive_position_events, expected_max_of_normals, inv_norm_cdf, r_metrics_from_rs, summarize_r,
|
pub use aura_analysis::{expected_max_of_normals, inv_norm_cdf, FamilySelection, SelectionMode};
|
||||||
FamilySelection, PositionAction, PositionEvent, RMetrics, RunMetrics, SelectionMode,
|
pub use aura_backtest::{
|
||||||
|
derive_position_events, r_metrics_from_rs, summarize_r, PositionAction,
|
||||||
|
PositionEvent, RMetrics, RunMetrics,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The reproducible run descriptor (C18). **Caller-supplied**: the engine
|
/// The reproducible run descriptor (C18). **Caller-supplied**: the engine
|
||||||
|
|||||||
+18
-12
@@ -2667,14 +2667,16 @@ shell", #286).** This contract states the *target*. At HEAD the crates cut by
|
|||||||
mechanical role (vocabulary / reductions / documents / orchestration / CLI), not
|
mechanical role (vocabulary / reductions / documents / orchestration / CLI), not
|
||||||
cleanly by layer, so the layering is realized only partially:
|
cleanly by layer, so the layering is realized only partially:
|
||||||
- The dependency *direction* already nearly obeys the rule. The one hard
|
- The dependency *direction* already nearly obeys the rule. The one hard
|
||||||
production violation is `aura-engine → aura-analysis`: `report.rs:20`
|
production violation is the engine's re-export of the backtest metrics —
|
||||||
re-exports the R-metrics, the position-event table, the hurdle math, and the
|
since the #291 split, `aura-engine → aura-backtest`: `report.rs` re-exports
|
||||||
selection-provenance types (`RMetrics`/`RunMetrics`/`summarize_r`/
|
the R-metrics and the position-event table (`RMetrics`/`RunMetrics`/
|
||||||
`r_metrics_from_rs`, `PositionEvent`/`PositionAction`/`derive_position_events`,
|
`summarize_r`/`r_metrics_from_rs`, `PositionEvent`/`PositionAction`/
|
||||||
`inv_norm_cdf`/`expected_max_of_normals`, `FamilySelection`/`SelectionMode`),
|
`derive_position_events`), and the generic-statistics kernel in `mc.rs`
|
||||||
and the generic-statistics kernel in `mc.rs` carries R/bias-typed fields
|
carries R/bias-typed fields (`McAggregate.bias_sign_flips`, `RBootstrap.e_r`)
|
||||||
(`McAggregate.bias_sign_flips`, `RBootstrap.e_r`) inside otherwise domain-free
|
inside otherwise domain-free structs. The `aura-engine → aura-analysis` edge
|
||||||
structs.
|
is no longer a violation: post-#291 that crate holds only domain-free
|
||||||
|
statistics + selection provenance (`FamilySelection` for
|
||||||
|
`RunManifest.selection`), foundation-grade under this contract.
|
||||||
- **That violation is the exact surface of the deliberately-deferred #147.**
|
- **That violation is the exact surface of the deliberately-deferred #147.**
|
||||||
Cutting it cleanly needs the metric genericity (`RunReport<M>` plus abstracting
|
Cutting it cleanly needs the metric genericity (`RunReport<M>` plus abstracting
|
||||||
the registry deflation vocabulary) that #136 ratified *deferring* (user-ratified
|
the registry deflation vocabulary) that #136 ratified *deferring* (user-ratified
|
||||||
@@ -2689,9 +2691,11 @@ cleanly by layer, so the layering is realized only partially:
|
|||||||
`aura-market` (`session`, `resample`), `aura-strategy` (`bias`/`stop_rule`/
|
`aura-market` (`session`, `resample`), `aura-strategy` (`bias`/`stop_rule`/
|
||||||
`sizer` + the cost nodes) and `aura-backtest` (`sim_broker`,
|
`sizer` + the cost nodes) and `aura-backtest` (`sim_broker`,
|
||||||
`position_management`) carry the outer rungs, each depending only on `aura-core`;
|
`position_management`) carry the outer rungs, each depending only on `aura-core`;
|
||||||
the closed node roster moved to `aura-vocabulary`. The remaining in-crate
|
the closed node roster moved to `aura-vocabulary`. The `aura-analysis`
|
||||||
interweave is `aura-analysis`, which still holds backtest reductions and generic
|
interweave is resolved (phase 5, #291): the backtest reductions live in
|
||||||
hurdle math together (phase 5). No crate exists yet for *measurement* (its run
|
`aura-backtest::metrics` beside their `position_management` producer, and
|
||||||
|
`aura-analysis` is reduced to domain-free statistics + selection provenance
|
||||||
|
(`[dependencies]` = serde only). No crate exists yet for *measurement* (its run
|
||||||
verb is the additive shape dispatch, #286) or *execution* (unbuilt — the C10/C13
|
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
|
edge only). Under this model the `aura-registry → aura-research` edge is
|
||||||
column-internal and legal.
|
column-internal and legal.
|
||||||
@@ -2703,7 +2707,9 @@ cleanly by layer, so the layering is realized only partially:
|
|||||||
retention); (4) split the `aura-std` roster along engine / market / strategy /
|
retention); (4) split the `aura-std` roster along engine / market / strategy /
|
||||||
backtest — **done** (#288: four `aura-core`-only node crates, the closed roster
|
backtest — **done** (#288: four `aura-core`-only node crates, the closed roster
|
||||||
moved to `aura-vocabulary`, the ladder direction enforced by a structural test);
|
moved to `aura-vocabulary`, the ladder direction enforced by a structural test);
|
||||||
(5) split `aura-analysis` into generic statistics and backtest metrics; (6)
|
(5) split `aura-analysis` into generic statistics and backtest metrics —
|
||||||
|
**done** (#291: metrics moved to `aura-backtest::metrics`, `aura-analysis`
|
||||||
|
reduced to the domain-free half, engine re-export surface name-unchanged); (6)
|
||||||
generify the column's metric interface (demand-driven — this is #147). Crate
|
generify the column's metric interface (demand-driven — this is #147). Crate
|
||||||
names now realized (`aura-market`/`aura-strategy`/`aura-backtest`/
|
names now realized (`aura-market`/`aura-strategy`/`aura-backtest`/
|
||||||
`aura-vocabulary`); full evidence on #288, #286 and the milestone.
|
`aura-vocabulary`); full evidence on #288, #286 and the milestone.
|
||||||
|
|||||||
Reference in New Issue
Block a user