Skip market buys below one lot

This commit is contained in:
boris
2026-09-06 13:35:52 +08:00
parent c5767ca272
commit f5de3a2c29
+50
View File
@@ -5796,6 +5796,9 @@ where
self.minimum_order_quantity(data, symbol),
self.order_step_size(data, symbol),
);
if requested_qty == 0 {
return Ok(());
}
self.process_buy(
date,
portfolio,
@@ -10345,6 +10348,53 @@ mod tests {
);
}
#[test]
fn market_share_buy_skips_quantity_that_rounds_below_one_lot() {
let date = chrono::NaiveDate::from_ymd_opt(2025, 1, 2).expect("valid date");
let data = DataSet::from_components_with_actions_and_quotes(
vec![limit_test_instrument()],
vec![limit_test_snapshot()],
Vec::new(),
vec![limit_test_candidate(true, true)],
vec![limit_test_benchmark()],
Vec::new(),
Vec::new(),
)
.expect("valid dataset");
let broker = BrokerSimulator::new_with_execution_price(
ChinaAShareCostModel::default(),
ChinaEquityRuleHooks,
PriceField::Open,
)
.with_volume_limit(false)
.with_liquidity_limit(false)
.with_inactive_limit(false);
let mut portfolio = PortfolioState::new(20_000.0);
let mut report = BrokerExecutionReport::default();
broker
.process_shares(
date,
&mut portfolio,
&data,
"000001.SZ",
1,
"sub_lot_target_delta",
&mut BTreeMap::new(),
&mut IntradayExecutionLedger::default(),
&mut None,
&mut BTreeMap::new(),
None,
&mut report,
)
.expect("sub-lot buy must be a no-op");
assert!(report.order_events.is_empty());
assert!(report.fill_events.is_empty());
assert!(portfolio.position("000001.SZ").is_none());
report.validate().expect("empty report remains valid");
}
#[test]
fn target_value_zero_rejects_sell_when_market_snapshot_missing() {
let trade_date = chrono::NaiveDate::from_ymd_opt(2025, 1, 2).expect("valid date");