2727 StrategyRuntimeAdapter ,
2828 apply_runtime_policy_to_runtime_config ,
2929 build_execution_timing_metadata ,
30+ build_account_state_from_portfolio_snapshot ,
31+ build_portfolio_snapshot_from_account_state ,
3032 build_strategy_context_from_available_inputs ,
3133 build_strategy_evaluation_inputs ,
3234)
@@ -355,6 +357,47 @@ def _market_history_symbols(self) -> tuple[str, ...]:
355357 )
356358 )
357359
360+ def _configured_strategy_symbols (self , * , include_ranking_pool : bool = False ) -> tuple [str , ...]:
361+ candidates : list [str ] = []
362+ raw_managed = self .merged_runtime_config .get ("managed_symbols" , ())
363+ if isinstance (raw_managed , str ):
364+ raw_managed = raw_managed .replace (";" , "," ).split ("," )
365+ candidates .extend (str (symbol ) for symbol in raw_managed or ())
366+ if include_ranking_pool :
367+ raw_pool = self .merged_runtime_config .get ("ranking_pool" , ())
368+ if isinstance (raw_pool , str ):
369+ raw_pool = raw_pool .replace (";" , "," ).split ("," )
370+ candidates .extend (str (symbol ) for symbol in raw_pool or ())
371+ safe_haven_symbol = str (self .merged_runtime_config .get ("safe_haven" ) or "" ).strip ()
372+ if safe_haven_symbol and candidates :
373+ candidates .append (safe_haven_symbol )
374+ return tuple (
375+ dict .fromkeys (
376+ symbol .strip ().upper ()
377+ for symbol in candidates
378+ if symbol .strip ()
379+ )
380+ )
381+
382+ def _project_portfolio_snapshot (self , portfolio_snapshot : Any | None , strategy_symbols ) -> Any | None :
383+ if portfolio_snapshot is None or not strategy_symbols :
384+ return portfolio_snapshot
385+ if not hasattr (portfolio_snapshot , "positions" ):
386+ return portfolio_snapshot
387+ account_state = build_account_state_from_portfolio_snapshot (
388+ portfolio_snapshot ,
389+ strategy_symbols = strategy_symbols ,
390+ )
391+ account_state ["total_strategy_equity" ] = float (account_state ["available_cash" ]) + sum (
392+ float (value ) for value in dict (account_state ["market_values" ]).values ()
393+ )
394+ return build_portfolio_snapshot_from_account_state (
395+ account_state ,
396+ strategy_symbols = strategy_symbols ,
397+ as_of = getattr (portfolio_snapshot , "as_of" , None ),
398+ metadata = getattr (portfolio_snapshot , "metadata" , {}) or {},
399+ )
400+
358401 def _build_market_history_inputs (
359402 self ,
360403 ib ,
@@ -481,6 +524,10 @@ def _evaluate_market_data_strategy(
481524 ib ,
482525 required = requires_portfolio ,
483526 )
527+ portfolio_snapshot = self ._project_portfolio_snapshot (
528+ portfolio_snapshot ,
529+ self ._configured_strategy_symbols (include_ranking_pool = True ),
530+ )
484531 portfolio_snapshot = self ._attach_strategy_plugin_metadata (portfolio_snapshot , strategy_plugin_signals )
485532 option_chains = self ._fetch_option_chains_for_runtime (ib , runtime_config , portfolio_snapshot )
486533 if option_chains :
@@ -550,7 +597,9 @@ def _evaluate_value_target_strategy(
550597 runtime_config = dict (self .runtime_config )
551598 runtime_config .setdefault ("translator" , translator )
552599 apply_runtime_policy_to_runtime_config (runtime_config , self .runtime_adapter )
600+ managed_symbols = self ._configured_strategy_symbols ()
553601 portfolio_snapshot = self ._fetch_portfolio_snapshot_for_context (ib , required = True )
602+ portfolio_snapshot = self ._project_portfolio_snapshot (portfolio_snapshot , managed_symbols )
554603 portfolio_snapshot = self ._attach_strategy_plugin_metadata (portfolio_snapshot , strategy_plugin_signals )
555604 option_chains = self ._fetch_option_chains_for_runtime (ib , runtime_config , portfolio_snapshot )
556605 if option_chains :
@@ -571,9 +620,6 @@ def _evaluate_value_target_strategy(
571620 ib = ib ,
572621 )
573622 decision = self .entrypoint .evaluate (ctx )
574- managed_symbols = tuple (
575- str (symbol ) for symbol in self .merged_runtime_config .get ("managed_symbols" , ())
576- )
577623 safe_haven_symbol = next (
578624 (position .symbol for position in decision .positions if position .role == "safe_haven" ),
579625 None ,
0 commit comments