修复分钟执行价缺失档位量成交
This commit is contained in:
@@ -5596,7 +5596,8 @@ where
|
||||
if remaining_qty == 0 {
|
||||
break;
|
||||
}
|
||||
let mut available_qty = if quote_quantity_limited {
|
||||
let missing_level1_depth = Self::quote_lacks_level1_depth(quote);
|
||||
let mut available_qty = if quote_quantity_limited && !missing_level1_depth {
|
||||
let top_level_liquidity = match side {
|
||||
OrderSide::Buy => quote.ask1_volume,
|
||||
OrderSide::Sell => quote.bid1_volume,
|
||||
@@ -5785,6 +5786,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn quote_lacks_level1_depth(quote: &IntradayExecutionQuote) -> bool {
|
||||
quote.volume_delta > 0 && quote.bid1_volume == 0 && quote.ask1_volume == 0
|
||||
}
|
||||
|
||||
fn matching_type_uses_intraday_quotes(&self) -> bool {
|
||||
matches!(
|
||||
self.matching_type,
|
||||
@@ -6128,6 +6133,44 @@ mod tests {
|
||||
assert_eq!(fill.quantity, 1_200);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minute_last_uses_volume_delta_when_level1_depth_missing() {
|
||||
let date = chrono::NaiveDate::from_ymd_opt(2025, 1, 2).expect("valid date");
|
||||
let broker = BrokerSimulator::new(ChinaAShareCostModel::default(), ChinaEquityRuleHooks)
|
||||
.with_matching_type(MatchingType::MinuteLast)
|
||||
.with_volume_limit(true)
|
||||
.with_volume_percent(0.25)
|
||||
.with_liquidity_limit(true);
|
||||
let mut quote = limit_test_quote(10.0, 0.0, 0.0);
|
||||
quote.timestamp = date.and_hms_opt(10, 15, 0).expect("valid timestamp");
|
||||
quote.volume_delta = 600;
|
||||
quote.ask1_volume = 0;
|
||||
quote.bid1_volume = 0;
|
||||
|
||||
let fill = broker
|
||||
.select_execution_fill(
|
||||
&limit_test_snapshot(),
|
||||
&[quote],
|
||||
OrderSide::Buy,
|
||||
MatchingType::MinuteLast,
|
||||
Some(date.and_hms_opt(10, 15, 0).expect("valid timestamp")),
|
||||
None,
|
||||
400,
|
||||
100,
|
||||
100,
|
||||
100,
|
||||
false,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.expect("bar-derived minute quote fill");
|
||||
|
||||
assert_eq!(fill.quantity, 100);
|
||||
assert_eq!(fill.legs.len(), 1);
|
||||
assert_eq!(fill.legs[0].price, 10.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minute_last_volume_limit_rejects_sub_lot_quote_volume() {
|
||||
let date = chrono::NaiveDate::from_ymd_opt(2025, 1, 2).expect("valid date");
|
||||
|
||||
Reference in New Issue
Block a user