@@ -126,6 +126,8 @@ def _build_runtime_settings(
126126 dca_mode : str | None = None ,
127127 dca_base_investment_usd : float | None = None ,
128128 runtime_execution_window_trading_days : int | None = None ,
129+ reserved_cash_floor_usd : float = 0.0 ,
130+ reserved_cash_ratio : float = 0.0 ,
129131) -> PlatformRuntimeSettings :
130132 return PlatformRuntimeSettings (
131133 project_id = None ,
@@ -141,6 +143,8 @@ def _build_runtime_settings(
141143 tg_token = None ,
142144 tg_chat_id = None ,
143145 dry_run_only = False ,
146+ reserved_cash_floor_usd = reserved_cash_floor_usd ,
147+ reserved_cash_ratio = reserved_cash_ratio ,
144148 income_threshold_usd = income_threshold_usd ,
145149 qqqi_income_ratio = qqqi_income_ratio ,
146150 income_layer_enabled = income_layer_enabled ,
@@ -329,6 +333,29 @@ def test_load_strategy_runtime_applies_dca_overrides_from_settings(self):
329333 self .assertTrue (runtime .merged_runtime_config ["smart_multiplier_enabled" ])
330334 self .assertEqual (runtime .merged_runtime_config ["base_investment_usd" ], 500.0 )
331335
336+ def test_load_strategy_runtime_applies_reserved_cash_policy_overrides_from_settings (self ):
337+ entrypoint = _SemiconductorEntrypoint ()
338+
339+ with patch .object (strategy_runtime_module , "load_strategy_entrypoint_for_profile" , return_value = entrypoint ):
340+ with patch .object (
341+ strategy_runtime_module ,
342+ "load_strategy_runtime_adapter_for_profile" ,
343+ return_value = StrategyRuntimeAdapter (portfolio_input_name = "portfolio_snapshot" ),
344+ ):
345+ runtime = strategy_runtime_module .load_strategy_runtime (
346+ "soxl_soxx_trend_income" ,
347+ runtime_settings = _build_runtime_settings (
348+ "soxl_soxx_trend_income" ,
349+ reserved_cash_floor_usd = 150.0 ,
350+ reserved_cash_ratio = 0.03 ,
351+ ),
352+ )
353+
354+ self .assertEqual (runtime .runtime_overrides ["reserved_cash_floor_usd" ], 150.0 )
355+ self .assertEqual (runtime .runtime_overrides ["reserved_cash_ratio" ], 0.03 )
356+ self .assertEqual (runtime .merged_runtime_config ["reserved_cash_floor_usd" ], 150.0 )
357+ self .assertEqual (runtime .merged_runtime_config ["reserved_cash_ratio" ], 0.03 )
358+
332359 def test_load_strategy_runtime_applies_tech_execution_window_overrides_from_settings (self ):
333360 entrypoint = _TechEntrypoint ()
334361
0 commit comments