@@ -18,21 +18,10 @@ def get_market_prices(
1818 symbols ,
1919 * ,
2020 fetch_quote_snapshots ,
21- dry_run_only : bool = False ,
22- snapshot_price_fallbacks : dict [str , float ] | None = None ,
2321):
2422 """Fetch market prices for multiple symbols in one pass."""
2523 quotes = fetch_quote_snapshots (ib , symbols )
26- prices = {symbol : quote .last_price for symbol , quote in quotes .items ()}
27- if dry_run_only and snapshot_price_fallbacks :
28- for symbol in symbols :
29- normalized = str (symbol ).strip ().upper ()
30- if normalized in prices :
31- continue
32- fallback_price = snapshot_price_fallbacks .get (normalized )
33- if fallback_price and float (fallback_price ) > 0 :
34- prices [normalized ] = float (fallback_price )
35- return prices
24+ return {symbol : quote .last_price for symbol , quote in quotes .items ()}
3625
3726
3827def check_order_submitted (report , * , translator ):
@@ -192,6 +181,38 @@ def _display_text(value: Any, *, fallback: str) -> str:
192181 return text or fallback
193182
194183
184+ def _apply_snapshot_price_fallbacks (
185+ prices : dict [str , float ],
186+ symbols ,
187+ * ,
188+ dry_run_only : bool ,
189+ snapshot_price_fallbacks : dict [str , float ] | None ,
190+ ) -> tuple [dict [str , float ], tuple [str , ...]]:
191+ if not dry_run_only or not snapshot_price_fallbacks :
192+ return dict (prices ), ()
193+ resolved = dict (prices )
194+ fallback_symbols : list [str ] = []
195+ for symbol in symbols :
196+ normalized = str (symbol ).strip ().upper ()
197+ if normalized in resolved :
198+ continue
199+ fallback_price = snapshot_price_fallbacks .get (normalized )
200+ if fallback_price and float (fallback_price ) > 0 :
201+ resolved [normalized ] = float (fallback_price )
202+ fallback_symbols .append (normalized )
203+ return resolved , tuple (fallback_symbols )
204+
205+
206+ def _format_symbol_preview (symbols : tuple [str , ...], * , limit : int = 3 ) -> str :
207+ if not symbols :
208+ return ""
209+ shown = [str (symbol ).strip ().upper () for symbol in symbols [:limit ]]
210+ remaining = len (symbols ) - len (shown )
211+ if remaining > 0 :
212+ shown .append (f"+{ remaining } " )
213+ return "," .join (shown )
214+
215+
195216def _resolve_execution_lock_path (
196217 * ,
197218 strategy_profile : str | None ,
@@ -364,6 +385,10 @@ def execute_rebalance(
364385 "residual_cash_estimate" : float (account_values .get ("buying_power" , 0.0 ) or 0.0 ),
365386 "current_stock_weight" : 0.0 ,
366387 "current_safe_haven_weight" : 0.0 ,
388+ "price_source_mode" : "market_quote" ,
389+ "snapshot_price_fallback_used" : False ,
390+ "snapshot_price_fallback_symbols" : [],
391+ "snapshot_price_fallback_count" : 0 ,
367392 "lock_path" : None ,
368393 }
369394 if equity <= 0 :
@@ -389,9 +414,18 @@ def execute_rebalance(
389414 ib ,
390415 all_symbols ,
391416 fetch_quote_snapshots = fetch_quote_snapshots ,
417+ )
418+ prices , snapshot_price_fallback_symbols = _apply_snapshot_price_fallbacks (
419+ prices ,
420+ all_symbols ,
392421 dry_run_only = dry_run_only ,
393422 snapshot_price_fallbacks = snapshot_price_fallbacks ,
394423 )
424+ execution_summary ["snapshot_price_fallback_used" ] = bool (snapshot_price_fallback_symbols )
425+ execution_summary ["snapshot_price_fallback_symbols" ] = list (snapshot_price_fallback_symbols )
426+ execution_summary ["snapshot_price_fallback_count" ] = len (snapshot_price_fallback_symbols )
427+ if snapshot_price_fallback_symbols :
428+ execution_summary ["price_source_mode" ] = "mixed_market_quote_snapshot_close"
395429
396430 current_mv = {}
397431 for symbol in all_symbols :
@@ -459,6 +493,14 @@ def execute_rebalance(
459493 ]
460494 )
461495 )
496+ if snapshot_price_fallback_symbols :
497+ trade_logs .append (
498+ translator (
499+ "dry_run_snapshot_prices" ,
500+ count = len (snapshot_price_fallback_symbols ),
501+ symbols = _format_symbol_preview (snapshot_price_fallback_symbols ),
502+ )
503+ )
462504 trade_logs .extend (_format_target_lines (target_weights , current_mv , equity , translator = translator ))
463505
464506 missing_price_symbols : list [str ] = []
0 commit comments