From a3415095a754bd138e43e2ceccea1b2e064601e5 Mon Sep 17 00:00:00 2001 From: boris Date: Mon, 6 Jul 2026 07:26:20 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=88=86=E9=92=9F=E4=B9=B0?= =?UTF-8?q?=E5=85=A5=E6=8A=95=E5=BD=B1=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fidc-core/src/platform_expr_strategy.rs | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index c5bbbee..73c9370 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -8687,7 +8687,18 @@ impl Strategy for PlatformExprStrategy { let market = ctx.data.market(projection_date, symbol); let candidate = ctx.data.candidate(projection_date, symbol); let factor = ctx.data.factor(selection_factor_date, symbol); - let quote_count = ctx.data.execution_quotes_on(projection_date, symbol).len(); + let quotes = ctx.data.execution_quotes_on(projection_date, symbol); + let quote_count = quotes.len(); + let quote_cursor = self.projected_execution_start_cursor( + ctx, + projection_date, + symbol, + &projected_execution_state, + ); + let latest_quote = quotes + .iter() + .filter(|quote| quote.timestamp <= quote_cursor) + .max_by_key(|quote| quote.timestamp); let sizing_price = market.map(|market| { let raw = if self.config.aiquant_transaction_cost { self.aiquant_scheduled_last_price(ctx, projection_date, symbol) @@ -8699,8 +8710,35 @@ impl Strategy for PlatformExprStrategy { }; self.projected_apply_slippage(market, OrderSide::Buy, raw, None) }); + let projected_qty = sizing_price + .map(|price| { + self.value_buy_quantity( + buy_cash, + price, + self.projected_minimum_order_quantity(ctx, symbol), + self.projected_order_step_size(ctx, symbol), + ) + }) + .unwrap_or_default(); + let fillable_qty = market + .and_then(|market| { + self.projected_market_fillable_quantity( + market, + latest_quote, + symbol, + OrderSide::Buy, + projected_qty, + self.projected_round_lot(ctx, symbol), + self.projected_minimum_order_quantity(ctx, symbol), + self.projected_order_step_size(ctx, symbol), + false, + 0, + &projected_execution_state, + ) + }) + .unwrap_or_default(); projection_debug_notes.push(format!( - "periodic_buy_project_zero symbol={} buy_cash={:.4} target_cash={:.4} available_cash={:.4} projection_date={} execution_date={} market={} factor={} candidate={} has_day_quotes={} quote_count={} sizing_price={:.4} market_volume={} minute_volume={} paused={} allow_buy={} is_kcb={} upper_limit={:.4} lower_limit={:.4}", + "periodic_buy_project_zero symbol={} buy_cash={:.4} target_cash={:.4} available_cash={:.4} projection_date={} execution_date={} market={} factor={} candidate={} has_day_quotes={} quote_count={} quote_cursor={} quote_ts={} quote_last={:.4} quote_volume_delta={} quote_bid1_volume={} quote_ask1_volume={} sizing_price={:.4} projected_qty={} fillable_qty={} quote_quantity_limit={} volume_limit={} liquidity_limit={} volume_percent={:.4} market_volume={} minute_volume={} paused={} allow_buy={} is_kcb={} upper_limit={:.4} lower_limit={:.4}", symbol, buy_cash, target_cash, @@ -8712,7 +8750,28 @@ impl Strategy for PlatformExprStrategy { candidate.is_some(), ctx.data.has_execution_quotes_on_date(projection_date), quote_count, + quote_cursor, + latest_quote + .map(|quote| quote.timestamp.to_string()) + .unwrap_or_else(|| "-".to_string()), + latest_quote + .map(|quote| quote.last_price) + .unwrap_or(f64::NAN), + latest_quote + .map(|quote| quote.volume_delta) + .unwrap_or_default(), + latest_quote.map(|quote| quote.bid1_volume).unwrap_or_default(), + latest_quote.map(|quote| quote.ask1_volume).unwrap_or_default(), sizing_price.unwrap_or(f64::NAN), + projected_qty, + fillable_qty, + self.config.quote_quantity_limit, + self.config.risk_config.trading_constraints.volume_limit_enabled, + self.config + .risk_config + .trading_constraints + .liquidity_limit_enabled, + self.config.risk_config.trading_constraints.volume_percent, market.map(|item| item.volume).unwrap_or(0), market.map(|item| item.minute_volume).unwrap_or(0), market.map(|item| item.paused).unwrap_or(false),