refactor(cli): cut wrap_r's dead cost-graph branch (#221)
Behaviour-preserving removal of the unreachable single-run cost seam: no caller ever passed Some(cost). Drops the cost parameter from wrap_r (the compiler enumerated 8 sites, all passing None), the dead branch, the vol_proxy arm, CostConfig, SLIP_VOL_LENGTH, and the 4 inert cost imports; RollingMax/RollingMin/Sub move to #[cfg(test)] (last production caller gone). The cost_graph composite stays alive in aura-composites; the campaign/sweep reduce path (C10) is untouched. Decision + rationale on the issue. Suite green unchanged (62 groups), clippy clean. closes #221
This commit is contained in:
@@ -579,9 +579,9 @@ fn present_campaign(
|
||||
/// campaign trace re-run. The routing mirrors `persist_traces_r` (main.rs):
|
||||
/// equity <- the SimBroker equity recorder (tx_eq), exposure <- the Bias
|
||||
/// recorder (tx_ex), r_equity <- the cum_realized_r + unrealized_r recorder
|
||||
/// (tx_req). `net_r_equity` has no channel here: the campaign runner wires
|
||||
/// no cost leg (`wrap_r(.., cost: None)`), so a net curve is not produced
|
||||
/// by this run's configuration.
|
||||
/// (tx_req). `net_r_equity` has no channel here: `wrap_r` no longer builds a
|
||||
/// cost leg at all (#221), so a net curve is not produced by this run's
|
||||
/// configuration.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum TapChannel {
|
||||
Equity,
|
||||
@@ -764,7 +764,7 @@ fn persist_campaign_traces(
|
||||
let (tx_ex, rx_ex) = mpsc::channel();
|
||||
let (tx_r, rx_r) = mpsc::channel();
|
||||
let (tx_req, rx_req) = mpsc::channel();
|
||||
let mut h = crate::wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, false, None)
|
||||
let mut h = crate::wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, false)
|
||||
.bootstrap_with_cells(&point)
|
||||
.expect("the nominee's point re-bootstraps (it already ran this realization)");
|
||||
let sources: Vec<Box<dyn aura_engine::Source>> = vec![Box::new(source)];
|
||||
|
||||
+14
-99
@@ -13,7 +13,7 @@ mod verb_sugar;
|
||||
use render::{ChartData, ChartMeta, ChartMode, ReduceKind, Series};
|
||||
|
||||
use aura_core::{zip_params, Cell, Firing, ParamSpec, Scalar, ScalarKind, Timestamp};
|
||||
use aura_composites::{cost_graph, risk_executor, StopRule};
|
||||
use aura_composites::{risk_executor, StopRule};
|
||||
use aura_engine::{
|
||||
blueprint_from_json, blueprint_to_json, f64_field, join_on_ts, monte_carlo, param_stability,
|
||||
r_metrics_from_rs, summarize, summarize_r, walk_forward, window_of, BindError, BlueprintNode,
|
||||
@@ -29,8 +29,8 @@ use aura_registry::{
|
||||
DEFLATION_BLOCK_LEN, DEFLATION_N_RESAMPLES,
|
||||
};
|
||||
use aura_std::{
|
||||
CarryCost, ConstantCost, GatedRecorder, LinComb, Recorder, RollingMax,
|
||||
RollingMin, SeriesReducer, SimBroker, Sub, VolSlippageCost, PM_FIELD_NAMES,
|
||||
GatedRecorder, LinComb, Recorder,
|
||||
SeriesReducer, SimBroker, PM_FIELD_NAMES,
|
||||
PM_RECORD_KINDS,
|
||||
};
|
||||
// `std_vocabulary` is now only reached through `project::Env::resolve` in production
|
||||
@@ -59,6 +59,12 @@ use aura_std::{Add, Gt, Latch, Mul, Sqrt};
|
||||
use aura_engine::ColumnarTrace;
|
||||
#[cfg(test)]
|
||||
use aura_std::{Bias, Ema, Sma};
|
||||
// `RollingMax`/`RollingMin`/`Sub` are now only reached from the test-only
|
||||
// `r_breakout_signal`/`r_meanrev_signal` carves: #221's `wrap_r` cost-graph
|
||||
// removal dropped the last production caller (the vol-slippage proxy), mirroring
|
||||
// `Delay`/`Scale` above.
|
||||
#[cfg(test)]
|
||||
use aura_std::{RollingMax, RollingMin, Sub};
|
||||
use std::sync::mpsc;
|
||||
use std::sync::LazyLock;
|
||||
use std::collections::HashSet;
|
||||
@@ -1098,7 +1104,7 @@ fn reproduce_family_in(
|
||||
let (tx_r, _) = mpsc::channel();
|
||||
let (tx_req, _) = mpsc::channel();
|
||||
let space =
|
||||
wrap_r(reload(), tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true, None).param_space();
|
||||
wrap_r(reload(), tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true).param_space();
|
||||
let point = point_from_params(&space, &stored.manifest.params);
|
||||
// A MonteCarlo member carries no tuning params (the params-join is empty), so its
|
||||
// reproduce line would print a BLANK member label; the seed IS its realization
|
||||
@@ -1182,20 +1188,6 @@ pub(crate) const R_SMA_STOP_LENGTH: i64 = 3;
|
||||
/// `StopRule::Vol` and its manifest record, like [`R_SMA_STOP_LENGTH`].
|
||||
pub(crate) const R_SMA_STOP_K: f64 = 2.0;
|
||||
|
||||
/// Short-horizon realized-range window for vol-scaled slippage. Deliberately
|
||||
/// distinct from `R_SMA_STOP_LENGTH` (3): scaling slippage by the stop's own
|
||||
/// vol would collapse cost-in-R to a constant (spec 0082). Short enough to warm
|
||||
/// within the synthetic smoke fixture so the run path exercises non-zero slippage.
|
||||
const SLIP_VOL_LENGTH: i64 = 5;
|
||||
|
||||
/// Which cost nodes the run-path cost graph builds. At least one field is `Some`
|
||||
/// (the carrier `Option` is `None` when no cost flag was given).
|
||||
struct CostConfig {
|
||||
const_cost: Option<f64>, // --cost-per-trade
|
||||
slip_vol_mult: Option<f64>, // --slip-vol-mult
|
||||
carry_per_cycle: Option<f64>, // --carry-per-cycle
|
||||
}
|
||||
|
||||
/// Which data a `run` drives a harness on: the built-in synthetic stream, or real M1
|
||||
/// close bars for a vetted symbol over an optional window.
|
||||
#[derive(Debug)]
|
||||
@@ -1254,11 +1246,6 @@ fn wrap_r(
|
||||
tx_req: mpsc::Sender<(Timestamp, Vec<Scalar>)>,
|
||||
stop: StopRule,
|
||||
reduce: bool,
|
||||
cost: Option<(
|
||||
CostConfig,
|
||||
mpsc::Sender<(Timestamp, Vec<Scalar>)>,
|
||||
mpsc::Sender<(Timestamp, Vec<Scalar>)>,
|
||||
)>,
|
||||
) -> Composite {
|
||||
let mut g = GraphBuilder::new("r_sma");
|
||||
// SMA-cross signal → Bias, nested as a serializable `price`→`bias` leg.
|
||||
@@ -1292,30 +1279,12 @@ fn wrap_r(
|
||||
} else {
|
||||
g.add(Recorder::builder(PM_RECORD_KINDS.to_vec(), Firing::Any, tx_r))
|
||||
};
|
||||
// Hoisted above the single main feed: the short-horizon vol proxy iff a
|
||||
// vol-slippage cost is actually wired (run path, non-reduce), so its `price`
|
||||
// inputs join the one `price_targets` array (no second feed call).
|
||||
let vol_proxy = match &cost {
|
||||
Some((cfg, _, _)) if !reduce && cfg.slip_vol_mult.is_some() => {
|
||||
let vhi = g.add(RollingMax::builder().named("slip_vol_hi").bind("length", Scalar::i64(SLIP_VOL_LENGTH)));
|
||||
let vlo = g.add(RollingMin::builder().named("slip_vol_lo").bind("length", Scalar::i64(SLIP_VOL_LENGTH)));
|
||||
let vrange = g.add(Sub::builder().named("slip_vol_range"));
|
||||
g.connect(vhi.output("value"), vrange.input("lhs"));
|
||||
g.connect(vlo.output("value"), vrange.input("rhs"));
|
||||
Some((vhi, vlo, vrange))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let price = g.source_role("price", ScalarKind::F64);
|
||||
let mut price_targets = vec![
|
||||
let price_targets = vec![
|
||||
sig.input("price"),
|
||||
broker.input("price"),
|
||||
exec.input("price"),
|
||||
];
|
||||
if let Some((vhi, vlo, _)) = vol_proxy {
|
||||
price_targets.push(vhi.input("series"));
|
||||
price_targets.push(vlo.input("series"));
|
||||
}
|
||||
g.feed(price, price_targets);
|
||||
g.connect(sig.output("bias"), broker.input("exposure"));
|
||||
g.connect(sig.output("bias"), ex.input("col[0]"));
|
||||
@@ -1335,59 +1304,6 @@ fn wrap_r(
|
||||
g.connect(exec.output("cum_realized_r"), r_equity.input("term[0]"));
|
||||
g.connect(exec.output("unrealized_r"), r_equity.input("term[1]"));
|
||||
g.connect(r_equity.output("value"), req.input("col[0]"));
|
||||
if let Some((cfg, tx_net, tx_cost)) = cost {
|
||||
// Build the active cost nodes (same conditional order), tracking the vol
|
||||
// node's index so its `cost[k].volatility` role can be fed below.
|
||||
let mut cost_nodes = Vec::new();
|
||||
let mut vol_slot = None;
|
||||
if let Some(cpt) = cfg.const_cost {
|
||||
cost_nodes.push(ConstantCost::builder().bind("cost_per_trade", Scalar::f64(cpt)));
|
||||
}
|
||||
if let Some(svm) = cfg.slip_vol_mult {
|
||||
vol_slot = Some(cost_nodes.len());
|
||||
cost_nodes.push(VolSlippageCost::builder().bind("slip_vol_mult", Scalar::f64(svm)));
|
||||
}
|
||||
if let Some(cpc) = cfg.carry_per_cycle {
|
||||
cost_nodes.push(CarryCost::builder().bind("carry_per_cycle", Scalar::f64(cpc)));
|
||||
}
|
||||
// A single cost_graph composite fans the shared PM-geometry into the active
|
||||
// cost nodes and sums their per-field charges into the run's cost streams.
|
||||
let cg = g.add(cost_graph(cost_nodes));
|
||||
g.connect(exec.output("closed_this_cycle"), cg.input("closed"));
|
||||
g.connect(exec.output("open"), cg.input("open"));
|
||||
g.connect(exec.output("entry_price"), cg.input("entry_price"));
|
||||
g.connect(exec.output("stop_price"), cg.input("stop_price"));
|
||||
if let Some(k) = vol_slot {
|
||||
let (_, _, vrange) = vol_proxy.expect("vol proxy is built whenever slip_vol_mult is set");
|
||||
let role: &'static str = format!("cost[{k}].volatility").leak();
|
||||
g.connect(vrange.output("value"), cg.input(role));
|
||||
}
|
||||
|
||||
// net_r_equity = cum_realized_r + unrealized_r - Σcum_cost_in_r - Σopen_cost_in_r
|
||||
let net_eq = g.add(
|
||||
LinComb::builder(4)
|
||||
.bind("weights[0]", Scalar::f64(1.0))
|
||||
.bind("weights[1]", Scalar::f64(1.0))
|
||||
.bind("weights[2]", Scalar::f64(-1.0))
|
||||
.bind("weights[3]", Scalar::f64(-1.0)),
|
||||
);
|
||||
g.connect(exec.output("cum_realized_r"), net_eq.input("term[0]"));
|
||||
g.connect(exec.output("unrealized_r"), net_eq.input("term[1]"));
|
||||
g.connect(cg.output("cum_cost_in_r"), net_eq.input("term[2]"));
|
||||
g.connect(cg.output("open_cost_in_r"), net_eq.input("term[3]"));
|
||||
let net_rec = g.add(Recorder::builder(vec![ScalarKind::F64], Firing::Any, tx_net));
|
||||
g.connect(net_eq.output("value"), net_rec.input("col[0]"));
|
||||
|
||||
// The aggregate cost record summarize_r folds (col 0 per-close, col 2 window-end).
|
||||
let cost_rec = g.add(Recorder::builder(
|
||||
vec![ScalarKind::F64, ScalarKind::F64, ScalarKind::F64],
|
||||
Firing::Any,
|
||||
tx_cost,
|
||||
));
|
||||
g.connect(cg.output("cost_in_r"), cost_rec.input("col[0]"));
|
||||
g.connect(cg.output("cum_cost_in_r"), cost_rec.input("col[1]"));
|
||||
g.connect(cg.output("open_cost_in_r"), cost_rec.input("col[2]"));
|
||||
}
|
||||
}
|
||||
g.build().expect("r_sma wiring resolves")
|
||||
}
|
||||
@@ -1439,7 +1355,7 @@ fn run_signal_r(
|
||||
// The req tap (r_equity recorder) is wired but not persisted on this path; keep the
|
||||
// receiver alive so the sink's sends do not fail, but do not drain it.
|
||||
let (tx_req, _rx_req) = mpsc::channel();
|
||||
let wrapped = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, false, None);
|
||||
let wrapped = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, false);
|
||||
let flat = wrapped
|
||||
.compile_with_params(params)
|
||||
.expect("signal binds + wraps to a valid harness");
|
||||
@@ -1483,7 +1399,7 @@ fn run_blueprint_member(
|
||||
let (tx_ex, rx_ex) = mpsc::channel();
|
||||
let (tx_r, rx_r) = mpsc::channel();
|
||||
let (tx_req, _rx_req) = mpsc::channel();
|
||||
let mut h = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, true, None)
|
||||
let mut h = wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, stop, true)
|
||||
.bootstrap_with_cells(point)
|
||||
.expect("member bootstraps (point kind-checked against param_space)");
|
||||
h.run(sources);
|
||||
@@ -1530,7 +1446,7 @@ fn blueprint_axis_probe(doc: &str, env: &project::Env) -> Composite {
|
||||
let (tx_ex, _) = mpsc::channel();
|
||||
let (tx_r, _) = mpsc::channel();
|
||||
let (tx_req, _) = mpsc::channel();
|
||||
wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true, None)
|
||||
wrap_r(signal, tx_eq, tx_ex, tx_r, tx_req, StopRule::Vol { length: R_SMA_STOP_LENGTH, k: R_SMA_STOP_K }, true)
|
||||
}
|
||||
|
||||
/// `aura sweep <blueprint.json> --list-axes`: one `<name>:<kind>` line per open
|
||||
@@ -3355,7 +3271,6 @@ mod tests {
|
||||
tx_req,
|
||||
StopRule::Vol { length: 3, k: 2.0 },
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.compile_with_params(&[])
|
||||
.expect("r-meanrev signal wraps to a valid harness");
|
||||
|
||||
Reference in New Issue
Block a user