From c3ab279d7d721d9b6768dfa9f263b387526a72cb Mon Sep 17 00:00:00 2001 From: boris Date: Mon, 6 Jul 2026 08:44:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=86=E9=92=9F=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E4=BB=B7=E6=88=90=E4=BA=A4=E9=87=8F=E9=A2=84=E8=BF=87?= =?UTF-8?q?=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/fidc-core/src/broker.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/crates/fidc-core/src/broker.rs b/crates/fidc-core/src/broker.rs index ebda0de..0db5dd7 100644 --- a/crates/fidc-core/src/broker.rs +++ b/crates/fidc-core/src/broker.rs @@ -5275,7 +5275,11 @@ where "daily volume limit" }; - if self.inactive_limit && (snapshot.paused || available_market_volume == 0) { + let mut max_fill = requested_qty; + + if self.inactive_limit + && (snapshot.paused || (!uses_intraday_quantity && available_market_volume == 0)) + { return Err(if snapshot.paused { "paused".to_string() } else { @@ -5283,7 +5287,10 @@ where }); } - let mut max_fill = requested_qty; + if uses_intraday_quantity { + return Ok(max_fill); + } + if self.liquidity_limit && uses_intraday_quantity && !self.is_open_auction_matching() { let top_level_liquidity = match side { OrderSide::Buy => snapshot.liquidity_for_buy(), @@ -6680,6 +6687,29 @@ mod tests { assert_eq!(fillable, Err("daily no volume".to_string())); } + #[test] + fn minute_last_prefilter_does_not_use_snapshot_minute_volume() { + let mut snapshot = limit_test_snapshot(); + snapshot.minute_volume = 0; + snapshot.volume = 1_000_000; + snapshot.bid1_volume = 0; + snapshot.ask1_volume = 0; + let broker = BrokerSimulator::new_with_execution_price( + ChinaAShareCostModel::default(), + ChinaEquityRuleHooks, + PriceField::Last, + ) + .with_matching_type(MatchingType::MinuteLast) + .with_volume_limit(true) + .with_volume_percent(0.25) + .with_liquidity_limit(false); + + let fillable = + broker.market_fillable_quantity(&snapshot, OrderSide::Buy, 5_000, 100, 100, 0, false); + + assert_eq!(fillable, Ok(5_000)); + } + #[test] fn target_value_valuation_uses_daily_snapshot_but_value_order_sizing_uses_intraday_minute() { let date = chrono::NaiveDate::from_ymd_opt(2025, 1, 2).expect("valid date");