test: declare historical audit assumptions in non-liquidity fixtures

This commit is contained in:
boris
2026-09-12 06:39:34 +08:00
parent 4d3a9e0e5b
commit 053f880e34
7 changed files with 124 additions and 78 deletions
+58 -38
View File
@@ -1484,8 +1484,6 @@ where
) -> Result<BrokerExecutionReport, BacktestError> {
if self.volume_limit {
self.volume_rate.map_err(|error| BacktestError::Execution(error.to_string()))?;
self.volume_capacity_mode.validate(true, self.matching_type_uses_intraday_quotes())
.map_err(|error| BacktestError::Execution(error.to_string()))?;
}
let mut session = std::mem::take(&mut *self.execution_session.borrow_mut());
session.activate(date);
@@ -4252,12 +4250,8 @@ where
.saturating_sub(self.reserved_open_sell_quantity(symbol, None));
match self.market_fillable_quantity(
snapshot,
OrderSide::Sell,
sellable.min(current_qty),
minimum_order_quantity,
order_step_size,
0,
sellable >= current_qty,
false,
) {
Ok(quantity) => {
let quantity = quantity.min(sellable).min(current_qty);
@@ -4300,11 +4294,7 @@ where
}
match self.market_fillable_quantity(
snapshot,
OrderSide::Buy,
u32::MAX,
minimum_order_quantity,
order_step_size,
0,
false,
) {
Ok(quantity) => {
@@ -4573,14 +4563,12 @@ where
} else {
None
};
self.volume_capacity_mode.validate(self.volume_limit, algo_request.is_some() || self.matching_type_uses_intraday_quotes())
.map_err(|error| BacktestError::Execution(error.to_string()))?;
let market_limited_qty = self.market_fillable_quantity(
snapshot,
OrderSide::Sell,
requested_qty.min(sellable),
self.minimum_order_quantity(data, symbol),
self.order_step_size(data, symbol),
*intraday_turnover.get(symbol).unwrap_or(&0),
requested_qty >= position.quantity && sellable >= position.quantity,
algo_request.is_some(),
);
let fillable_qty = match market_limited_qty {
Ok(quantity) => {
@@ -6382,14 +6370,12 @@ where
}
let mut partial_fill_reason = None;
self.volume_capacity_mode.validate(self.volume_limit, algo_request.is_some() || self.matching_type_uses_intraday_quotes())
.map_err(|error| BacktestError::Execution(error.to_string()))?;
let market_limited_qty = self.market_fillable_quantity(
snapshot,
OrderSide::Buy,
requested_qty,
self.minimum_order_quantity(data, symbol),
self.order_step_size(data, symbol),
*intraday_turnover.get(symbol).unwrap_or(&0),
false,
algo_request.is_some(),
);
let constrained_qty = match market_limited_qty {
Ok(quantity) => {
@@ -7286,20 +7272,15 @@ where
fn market_fillable_quantity(
&self,
snapshot: &crate::data::DailyMarketSnapshot,
side: OrderSide,
requested_qty: u32,
minimum_order_quantity: u32,
order_step_size: u32,
consumed_turnover: u32,
allow_odd_lot_sell: bool,
algorithmic_order: bool,
) -> Result<u32, String> {
if requested_qty == 0 {
return Ok(0);
}
let _ = (side, minimum_order_quantity, order_step_size, consumed_turnover, allow_odd_lot_sell);
if self.inactive_limit && snapshot.paused { return Err("paused".into()); }
self.volume_capacity_mode.validate(self.volume_limit, self.matching_type_uses_intraday_quotes())
self.volume_capacity_mode.validate(self.volume_limit, algorithmic_order || self.matching_type_uses_intraday_quotes())
.map_err(|error| error.to_string())?;
// Per-observation limits are applied to each actual quote below. The
// session-audit model must never size this order from the day's total.
@@ -9412,7 +9393,42 @@ mod tests {
}
#[test]
fn current_bar_close_volume_limit_uses_daily_volume_when_minute_volume_missing() {
fn daily_session_volume_changes_only_audit_not_opening_fills() {
use crate::execution_capacity::VolumeCapacityMode;
let run = |volume: u64, mode: VolumeCapacityMode| {
let mut market = limit_test_snapshot();
market.volume = volume;
let date = market.date;
let data = DataSet::from_components_with_actions_and_quotes(
vec![limit_test_instrument()], vec![market], vec![],
vec![limit_test_candidate(true, true)], vec![limit_test_benchmark()], vec![], vec![],
).unwrap();
let mut portfolio = PortfolioState::new(100_000.0);
let broker = BrokerSimulator::new(ChinaAShareCostModel::default(), ChinaEquityRuleHooks)
.with_volume_capacity_mode(mode).with_liquidity_limit(false);
let decision = StrategyDecision { order_intents: vec![OrderIntent::Shares {
symbol: "000001.SZ".into(), quantity: 1_000, reason: "capacity_test".into(),
}], ..StrategyDecision::default() };
let before = portfolio.cash();
let outcome = broker.execute(date, &mut portfolio, &data, &decision);
if outcome.is_err() { assert_eq!(portfolio.cash(), before); }
let audit = broker.audit_completed_session_capacity(date, &data).unwrap();
(outcome, portfolio.cash(), audit)
};
let (strict, _, _) = run(1_000_000, VolumeCapacityMode::ExecutionObservation);
assert!(strict.unwrap_err().to_string().contains("execution-time capacity is missing"));
let (a, cash_a, audit_a) = run(100, VolumeCapacityMode::SessionCapacityAudit);
let (b, cash_b, audit_b) = run(1_000_000, VolumeCapacityMode::SessionCapacityAudit);
let a = a.unwrap(); let b = b.unwrap();
assert_eq!(a.fill_events.len(), 1);
assert_eq!(serde_json::to_value(&a.fill_events).unwrap(), serde_json::to_value(&b.fill_events).unwrap());
assert_eq!(cash_a, cash_b);
assert_eq!(audit_a[0].filled_shares, 1_000);
assert!(!audit_a[0].passed); assert!(audit_b[0].passed);
}
#[test]
fn daily_capacity_requires_a_timed_observation_instead_of_falling_back_to_total_volume() {
let mut snapshot = limit_test_snapshot();
snapshot.minute_volume = 0;
snapshot.volume = 1_000_000;
@@ -9428,13 +9444,13 @@ mod tests {
.with_liquidity_limit(true);
let fillable =
broker.market_fillable_quantity(&snapshot, OrderSide::Buy, 5_000, 100, 100, 0, false);
broker.market_fillable_quantity(&snapshot, 5_000, false);
assert_eq!(fillable, Ok(5_000));
assert!(fillable.unwrap_err().contains("daily session volume cannot size an earlier fill"));
}
#[test]
fn volume_limit_uses_floor_for_odd_lot_sell() {
fn session_capacity_audit_never_caps_an_early_odd_lot_sell() {
let mut snapshot = limit_test_snapshot();
snapshot.minute_volume = 0;
snapshot.volume = 3;
@@ -9444,18 +9460,19 @@ mod tests {
PriceField::Close,
)
.with_matching_type(MatchingType::CurrentBarClose)
.with_volume_capacity_mode(crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_volume_limit(true)
.with_volume_percent(0.5)
.with_liquidity_limit(false);
let fillable =
broker.market_fillable_quantity(&snapshot, OrderSide::Sell, 10, 100, 100, 0, true);
broker.market_fillable_quantity(&snapshot, 10, false);
assert_eq!(fillable, Ok(1));
assert_eq!(fillable, Ok(10));
}
#[test]
fn current_bar_close_volume_limit_rejects_daily_zero_volume() {
fn session_audit_does_not_infer_an_opening_suspension_from_future_zero_volume() {
let mut snapshot = limit_test_snapshot();
snapshot.minute_volume = 0;
snapshot.volume = 0;
@@ -9465,13 +9482,16 @@ mod tests {
PriceField::Close,
)
.with_matching_type(MatchingType::CurrentBarClose)
.with_volume_capacity_mode(crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_volume_limit(true)
.with_liquidity_limit(false);
let fillable =
broker.market_fillable_quantity(&snapshot, OrderSide::Buy, 5_000, 100, 100, 0, false);
broker.market_fillable_quantity(&snapshot, 5_000, false);
assert_eq!(fillable, Err("daily no volume".to_string()));
assert_eq!(fillable, Ok(5_000));
snapshot.paused = true;
assert_eq!(broker.market_fillable_quantity(&snapshot, 5_000, false), Err("paused".into()));
}
#[test]
@@ -9492,7 +9512,7 @@ mod tests {
.with_liquidity_limit(false);
let fillable =
broker.market_fillable_quantity(&snapshot, OrderSide::Buy, 5_000, 100, 100, 0, false);
broker.market_fillable_quantity(&snapshot, 5_000, false);
assert_eq!(fillable, Ok(5_000));
}
@@ -14527,6 +14527,7 @@ mod tests {
active_datetime: None, order_events: &[], fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = symbol.to_string();
cfg.max_positions = 1;
cfg.refresh_rate = 1;
@@ -14560,6 +14561,7 @@ mod tests {
active_datetime: None, order_events: &[], fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::generic();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = symbol.into();
cfg.stock_filter_expr = "close > 0".into();
cfg.hold_until_exit_enabled = true;
@@ -15175,6 +15177,7 @@ mod tests {
}
let data = DataSet::from_components(parts.instruments, parts.market, parts.factors, parts.candidates, parts.benchmarks).unwrap();
let mut config = PlatformExprStrategyConfig::generic();
config.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
config.universe_include = Some(BTreeSet::from(["000001.SZ".to_owned()]));
config.signal_symbol = "000001.SZ".to_owned();
config.benchmark_symbol = "000852.SH".to_owned();
@@ -15419,6 +15422,7 @@ mod tests {
fills: &[],
};
let mut config = PlatformExprStrategyConfig::microcap_rotation();
config.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
config.signal_symbol = symbol.to_string();
config.refresh_rate = 1;
config.max_positions = 1;
@@ -15670,6 +15674,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 1;
cfg.max_positions = 3;
@@ -22375,6 +22380,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = symbol.to_string();
cfg.exposure_expr = "1.0".to_string();
cfg.selection_limit_expr = "40".to_string();
@@ -22749,6 +22755,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.rotation_enabled = false;
cfg.daily_top_up_enabled = false;
cfg.signal_symbol = symbol.to_string();
@@ -23705,6 +23712,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = symbol.to_string();
cfg.exposure_expr = "0.5".to_string();
cfg.selection_limit_expr = "40".to_string();
@@ -24961,6 +24969,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.intraday_execution_time = Some(NaiveTime::from_hms_opt(9, 33, 0).unwrap());
cfg.signal_symbol = signal.to_string();
cfg.max_positions = 1;
@@ -27428,6 +27437,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 2;
@@ -27569,6 +27579,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 2;
@@ -28359,6 +28370,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 2;
@@ -28678,6 +28690,7 @@ mod tests {
.expect("dataset");
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 20;
cfg.max_positions = 2;
@@ -28726,6 +28739,7 @@ mod tests {
);
let mut dynamic_cfg = PlatformExprStrategyConfig::microcap_rotation();
dynamic_cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
dynamic_cfg.signal_symbol = "000001.SZ".to_string();
dynamic_cfg.refresh_rate = 20;
dynamic_cfg.refresh_rate_expr = "year >= 2024 ? 5 : 20".to_string();
@@ -28751,6 +28765,7 @@ mod tests {
);
let mut signal_dates_cfg = PlatformExprStrategyConfig::microcap_rotation();
signal_dates_cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
signal_dates_cfg.signal_symbol = "000001.SZ".to_string();
signal_dates_cfg.refresh_rate = 20;
signal_dates_cfg.max_positions = 2;
@@ -28786,6 +28801,7 @@ mod tests {
);
let mut no_retry_cfg = PlatformExprStrategyConfig::microcap_rotation();
no_retry_cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
no_retry_cfg.signal_symbol = "000001.SZ".to_string();
no_retry_cfg.refresh_rate = 15;
no_retry_cfg.max_positions = 2;
@@ -28953,6 +28969,7 @@ mod tests {
.expect("dataset");
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 10;
cfg.max_positions = 2;
@@ -29130,6 +29147,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 20;
cfg.max_positions = 2;
@@ -30343,6 +30361,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.rotation_enabled = false;
cfg.hold_until_exit_enabled = true;
cfg.signal_symbol = symbol.to_string();
@@ -31605,6 +31624,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 2;
@@ -31758,6 +31778,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 2;
@@ -31922,6 +31943,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 2;
@@ -33943,6 +33965,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 1;
@@ -34120,6 +34143,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.refresh_rate = 99;
cfg.max_positions = 1;
@@ -34162,6 +34186,7 @@ mod tests {
);
let mut filtered_cfg = PlatformExprStrategyConfig::microcap_rotation();
filtered_cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
filtered_cfg.signal_symbol = "000001.SZ".to_string();
filtered_cfg.refresh_rate = 99;
filtered_cfg.max_positions = 1;
@@ -36485,6 +36510,7 @@ mod tests {
fills: &[],
};
let mut cfg = PlatformExprStrategyConfig::microcap_rotation();
cfg.volume_capacity_mode = crate::execution_capacity::VolumeCapacityMode::SessionCapacityAudit;
cfg.signal_symbol = "000001.SZ".to_string();
cfg.rotation_enabled = false;
cfg.benchmark_short_ma_days = 1;
@@ -119,7 +119,7 @@ fn run(policy: AutomaticTradeProtection) -> fidc_core::BacktestResult {
action("-100", "decision_date >= \"2026-09-14\""),
];
config.matching_type = MatchingType::CurrentBarClose;
let broker = BrokerSimulator::new(ChinaAShareCostModel::default(), ChinaEquityRuleHooks)
let broker = BrokerSimulator::new(ChinaAShareCostModel::default(), ChinaEquityRuleHooks).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::CurrentBarClose);
BacktestEngine::new(
data(),
@@ -294,7 +294,7 @@ fn locked_holding_keeps_its_slot_even_when_cash_can_buy_the_next_candidate() {
}],
..Default::default()
};
let broker = BrokerSimulator::new(ChinaAShareCostModel::default(), ChinaEquityRuleHooks)
let broker = BrokerSimulator::new(ChinaAShareCostModel::default(), ChinaEquityRuleHooks).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::CurrentBarClose);
let result = BacktestEngine::new(
dataset,
+2 -2
View File
@@ -394,7 +394,7 @@ fn engine_reinvests_dividend_receivable_in_round_lots() {
.with_minimum_commission(0.0),
ChinaEquityRuleHooks::default(),
PriceField::Open,
),
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit),
BacktestConfig {
initial_cash: 11_008.0,
benchmark_code: "000300.SH".to_string(),
@@ -475,7 +475,7 @@ fn engine_settles_same_day_dividend_after_split_for_aiquant_semantics() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
),
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit),
BacktestConfig {
initial_cash: 11_008.0,
benchmark_code: "000300.SH".to_string(),
@@ -170,7 +170,7 @@ fn engine_uses_preplanned_decision_symbols_without_recomputing_strategy_plan() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks,
PriceField::Close,
)
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::CurrentBarClose);
let config = BacktestConfig {
initial_cash: 10_000.0,
@@ -235,7 +235,7 @@ fn engine_skips_decision_quote_symbol_plan_without_loader() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks,
PriceField::Close,
)
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::CurrentBarClose);
let config = BacktestConfig {
initial_cash: 10_000.0,
@@ -391,7 +391,7 @@ fn engine_preloads_declared_decision_quotes_for_current_positions() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks,
PriceField::Last,
)
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::MinuteLast)
.with_intraday_execution_start_time(t(10, 40, 0));
let config = BacktestConfig {
@@ -590,7 +590,7 @@ fn engine_reuses_preloaded_decision_quotes_without_loader_call() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks,
PriceField::Last,
)
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::MinuteLast)
.with_intraday_execution_start_time(t(10, 40, 0));
let config = BacktestConfig {
@@ -796,7 +796,7 @@ fn engine_loads_distinct_decision_quote_times_on_same_day() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks,
PriceField::Last,
)
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::MinuteLast)
.with_intraday_execution_start_time(t(10, 40, 0));
let config = BacktestConfig {
+2 -2
View File
@@ -295,7 +295,7 @@ fn engine_keeps_unresolved_delisted_position_without_fabricating_a_fill() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
BuyThenHoldStrategy,
@@ -548,7 +548,7 @@ fn engine_applies_successor_conversion_before_unresolved_delisting_audit() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
BuyThenHoldStrategy,
+29 -29
View File
@@ -1219,7 +1219,7 @@ fn engine_runs_strategy_hooks_in_daily_order() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -1260,7 +1260,7 @@ fn engine_runs_strategy_hooks_in_daily_order() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut compact_engine = BacktestEngine::new(
compact_data,
compact_strategy,
@@ -1401,7 +1401,7 @@ fn engine_executes_open_auction_decisions_before_on_day() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::DayOpen,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -1497,7 +1497,7 @@ fn engine_executes_futures_order_intents_against_future_account() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
FuturesOrderStrategy,
@@ -1569,7 +1569,7 @@ fn platform_runtime_actions_execute_generic_futures_open_and_close() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
two_day_futures_data(),
PlatformExprStrategy::new(cfg),
@@ -1609,7 +1609,7 @@ fn engine_settles_configured_futures_expiration_at_settlement() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
single_day_anchor_data(date),
FuturesOrderStrategy,
@@ -1657,7 +1657,7 @@ fn engine_aggregates_futures_account_into_nav_and_metrics() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
single_day_anchor_data(date),
FuturesOrderStrategy,
@@ -1700,7 +1700,7 @@ fn engine_matches_pending_futures_limit_order_with_data_driven_costs() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
two_day_futures_data(),
FuturesLimitOrderStrategy,
@@ -1753,7 +1753,7 @@ fn engine_reports_pending_futures_order_at_backtest_boundary() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
two_day_futures_data(),
FuturesLimitOrderStrategy,
@@ -1805,7 +1805,7 @@ fn engine_rejects_futures_limit_orders_not_aligned_to_tick() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
two_day_futures_data(),
FuturesInvalidTickLimitStrategy,
@@ -1836,7 +1836,7 @@ fn engine_allows_disabling_futures_limit_tick_validation() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
two_day_futures_data(),
FuturesInvalidTickLimitStrategy,
@@ -1883,7 +1883,7 @@ fn engine_rejects_futures_limit_orders_outside_price_limits() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
two_day_futures_data(),
FuturesAboveUpperLimitStrategy,
@@ -1958,7 +1958,7 @@ fn engine_rejects_futures_orders_when_trading_phase_is_closed() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
FuturesClosedPhaseOrderStrategy,
@@ -2066,7 +2066,7 @@ fn engine_sweeps_futures_order_book_depth_when_available() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Last,
)
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit)
.with_matching_type(MatchingType::MinuteBestCounterparty);
let mut engine = BacktestEngine::new(
data,
@@ -2111,7 +2111,7 @@ fn strategy_context_exposes_advanced_data_helpers() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
two_day_futures_data(),
AdvancedDataApiProbeStrategy {
@@ -2265,7 +2265,7 @@ fn engine_runs_minute_hooks_and_executes_minute_orders() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Last,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let loader_requests = Arc::new(Mutex::new(Vec::<ExecutionQuoteRequest>::new()));
let loader_requests_for_callback = Arc::clone(&loader_requests);
let mut engine = BacktestEngine::new(
@@ -2381,7 +2381,7 @@ fn engine_skips_empty_platform_style_minute_callbacks_between_schedule_times() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Last,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -2579,7 +2579,7 @@ fn strategy_context_exposes_engine_native_data_helpers() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -2683,7 +2683,7 @@ fn strategy_context_exposes_final_order_runtime_view() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Close,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -2959,7 +2959,7 @@ fn engine_applies_account_cash_flow_and_financing_intents() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Close,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
AccountFlowStrategy,
@@ -3157,7 +3157,7 @@ fn engine_expires_pending_day_limit_orders_at_market_close() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let strategy = LimitCarryStrategy { issued: false };
let mut engine = BacktestEngine::new(
data,
@@ -3394,7 +3394,7 @@ fn engine_runs_scheduled_rules_for_daily_weekly_and_monthly_triggers() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::DayOpen,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -3649,7 +3649,7 @@ fn engine_dispatches_process_events_to_external_bus_listeners() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::DayOpen,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -3741,7 +3741,7 @@ fn engine_installs_process_mods_on_event_bus() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::DayOpen,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
HookProbeStrategy {
@@ -3778,7 +3778,7 @@ fn engine_installs_enabled_process_mods_from_loader() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::DayOpen,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
HookProbeStrategy {
@@ -3981,7 +3981,7 @@ fn engine_applies_dynamic_universe_and_subscription_directives() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -4105,7 +4105,7 @@ fn engine_exposes_current_process_context_to_strategies() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Last,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
strategy,
@@ -4215,7 +4215,7 @@ fn engine_rejects_an_unexplained_missing_holding_close() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
BuyMissingRowThenHoldStrategy,
@@ -4314,7 +4314,7 @@ fn platform_strategy_cannot_hide_missing_valuation_by_skipping_stop_take() {
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks::default(),
PriceField::Open,
);
).with_volume_capacity_mode(fidc_core::execution_capacity::VolumeCapacityMode::SessionCapacityAudit);
let mut engine = BacktestEngine::new(
data,
PlatformExprStrategy::new(config),