@@ -223,6 +223,60 @@ def accountValues(self):
223223 assert summary ["orders_submitted" ][1 ]["quantity" ] == 2
224224
225225
226+ def test_execute_rebalance_keeps_safe_haven_cash_when_only_risk_target_is_unbuyable (tmp_path , monkeypatch ):
227+ class FakeIB :
228+ def openTrades (self ):
229+ return []
230+
231+ def fills (self ):
232+ return []
233+
234+ def accountValues (self ):
235+ return [SimpleNamespace (tag = "AvailableFunds" , currency = "USD" , value = "1294.00" )]
236+
237+ prices = {"SOXL" : 175.0 , "SOXX" : 525.0 , "BOXX" : 116.83 }
238+ submitted = []
239+ monkeypatch .setattr ("application.execution_service.time.sleep" , lambda _seconds : None )
240+
241+ _trade_logs , summary = execute_rebalance (
242+ FakeIB (),
243+ {},
244+ {},
245+ {"equity" : 1294.0 , "buying_power" : 1294.0 },
246+ fetch_quote_snapshots = lambda _ib , symbols : {
247+ symbol : SimpleNamespace (last_price = prices [symbol ]) for symbol in symbols
248+ },
249+ submit_order_intent = lambda _ib , intent : submitted .append (intent ) or SimpleNamespace (
250+ broker_order_id = "dry-run" ,
251+ status = "Submitted" ,
252+ ),
253+ order_intent_cls = OrderIntent ,
254+ translator = translate ,
255+ strategy_symbols = ["SOXL" , "SOXX" , "BOXX" ],
256+ strategy_profile = "soxl_soxx_trend_income" ,
257+ signal_metadata = _signal_metadata (
258+ {"SOXL" : 0.0 , "SOXX" : 0.15 , "BOXX" : 0.85 },
259+ risk_symbols = ("SOXL" , "SOXX" ),
260+ safe_haven_symbols = ("BOXX" ,),
261+ trade_date = "2026-05-26" ,
262+ ),
263+ dry_run_only = True ,
264+ cash_reserve_ratio = 0.03 ,
265+ rebalance_threshold_ratio = 0.01 ,
266+ limit_buy_premium = 1.0 ,
267+ quantity_step = 1.0 ,
268+ sell_settle_delay_sec = 0 ,
269+ execution_lock_dir = tmp_path ,
270+ return_summary = True ,
271+ )
272+
273+ assert submitted == []
274+ assert summary ["small_account_whole_share_substituted_symbols" ] == ["SOXX" ]
275+ assert summary ["small_account_safe_haven_cash_substituted_symbols" ] == ["BOXX" ]
276+ boxx_row = next (row for row in summary ["target_vs_current" ] if row ["symbol" ] == "BOXX" )
277+ assert boxx_row ["target_weight" ] == 0.0
278+
279+
226280def test_execute_rebalance_routes_order_to_single_account_id (monkeypatch , tmp_path ):
227281 class FakeIB :
228282 def openTrades (self ):
0 commit comments