修复策略投影成交量约束

This commit is contained in:
boris
2026-07-05 17:01:04 +08:00
parent 7189998699
commit c557656040
2 changed files with 281 additions and 21 deletions
+45 -5
View File
@@ -2034,7 +2034,6 @@ impl OmniMicroCapStrategy {
Some(fill.quantity)
}
#[allow(dead_code)]
fn projected_market_fillable_quantity(
&self,
ctx: &StrategyContext<'_>,
@@ -2046,18 +2045,19 @@ impl OmniMicroCapStrategy {
minimum_order_quantity: u32,
order_step_size: u32,
allow_odd_lot_sell: bool,
current_fill_quantity: u32,
execution_state: &ProjectedExecutionState,
) -> Option<u32> {
if requested_qty == 0 {
return Some(0);
}
let snapshot = ctx.data.market(date, symbol)?;
if snapshot.minute_volume == 0 {
let constraints = self.config.risk_config.trading_constraints;
if constraints.volume_limit_enabled && snapshot.minute_volume == 0 {
return None;
}
let mut max_fill = requested_qty;
let constraints = self.config.risk_config.trading_constraints;
if constraints.liquidity_limit_enabled {
let top_level_liquidity = match side {
OrderSide::Buy => snapshot.liquidity_for_buy(),
@@ -2079,7 +2079,12 @@ impl OmniMicroCapStrategy {
max_fill = max_fill.min(liquidity_limited);
}
let consumed_turnover = *execution_state.intraday_turnover.get(symbol).unwrap_or(&0);
let consumed_turnover = execution_state
.intraday_turnover
.get(symbol)
.copied()
.unwrap_or(0)
.saturating_add(current_fill_quantity);
if constraints.volume_limit_enabled {
let raw_limit = ((snapshot.minute_volume as f64) * constraints.volume_percent).floor()
as i64
@@ -2129,6 +2134,23 @@ impl OmniMicroCapStrategy {
return None;
}
let requested_qty = self.projected_market_fillable_quantity(
ctx,
date,
symbol,
side,
requested_qty,
round_lot,
minimum_order_quantity,
order_step_size,
allow_odd_lot_sell,
0,
execution_state,
)?;
if requested_qty == 0 {
return None;
}
if let Some(market) = ctx.data.market(date, symbol) {
let execution_price = self.projected_execution_price(market, side);
if execution_price.is_finite() && execution_price > 0.0 {
@@ -2222,7 +2244,25 @@ impl OmniMicroCapStrategy {
if remaining_qty == 0 {
break;
}
let mut take_qty = remaining_qty.min(available_qty);
let market_fillable_qty = self
.projected_market_fillable_quantity(
ctx,
date,
symbol,
side,
remaining_qty,
round_lot,
minimum_order_quantity,
order_step_size,
allow_odd_lot_sell,
filled_qty,
execution_state,
)
.unwrap_or(0);
if market_fillable_qty == 0 {
break;
}
let mut take_qty = remaining_qty.min(available_qty).min(market_fillable_qty);
if !(side == OrderSide::Sell && allow_odd_lot_sell && take_qty == remaining_qty) {
take_qty =
self.round_lot_quantity(take_qty, minimum_order_quantity, order_step_size);