@@ -120,6 +120,79 @@ def fetch_portfolio_snapshot(_ib, **kwargs):
120120 assert observations .open_orders [0 ]["account" ] == "U123"
121121
122122
123+ def test_cash_reconciliation_ignores_dynamic_margin_and_valuation_tags () -> None :
124+ def fetch_snapshot (_ib , * , dynamic_net_liquidation : float , dynamic_available_funds : float , ** _kwargs ):
125+ return SimpleNamespace (
126+ positions = (),
127+ metadata = {
128+ "cash_balances" : (
129+ {
130+ "account_id" : "U123" ,
131+ "currency" : "USD" ,
132+ "CashBalance" : 123.45 ,
133+ "AvailableFunds" : dynamic_available_funds ,
134+ "NetLiquidation" : dynamic_net_liquidation ,
135+ },
136+ ),
137+ "option_positions" : (),
138+ },
139+ )
140+
141+ ib = _IB ()
142+ first = collect_read_only_reconciliation_observations (
143+ ib ,
144+ account_ids = ("U123" ,),
145+ fetch_portfolio_snapshot = lambda * args , ** kwargs : fetch_snapshot (
146+ * args ,
147+ ** kwargs ,
148+ dynamic_net_liquidation = 1_000.0 ,
149+ dynamic_available_funds = 700.0 ,
150+ ),
151+ market_currency = "USD" ,
152+ cash_only_execution = True ,
153+ )
154+ second = collect_read_only_reconciliation_observations (
155+ ib ,
156+ account_ids = ("U123" ,),
157+ fetch_portfolio_snapshot = lambda * args , ** kwargs : fetch_snapshot (
158+ * args ,
159+ ** kwargs ,
160+ dynamic_net_liquidation = 1_050.0 ,
161+ dynamic_available_funds = 750.0 ,
162+ ),
163+ market_currency = "USD" ,
164+ cash_only_execution = True ,
165+ )
166+
167+ assert first .cash == second .cash == (
168+ {"account" : "U123" , "currency" : "USD" , "tags" : {"CashBalance" : 123.45 }},
169+ )
170+
171+
172+ def test_cash_reconciliation_fails_closed_without_a_cash_balance_tag () -> None :
173+ with pytest .raises (IBKRReconciliationReadError , match = "stable cash-balance tag" ):
174+ collect_read_only_reconciliation_observations (
175+ _IB (),
176+ account_ids = ("U123" ,),
177+ fetch_portfolio_snapshot = lambda * _args , ** _kwargs : SimpleNamespace (
178+ positions = (),
179+ metadata = {
180+ "cash_balances" : (
181+ {
182+ "account_id" : "U123" ,
183+ "currency" : "USD" ,
184+ "AvailableFunds" : 700.0 ,
185+ "NetLiquidation" : 1_000.0 ,
186+ },
187+ ),
188+ "option_positions" : (),
189+ },
190+ ),
191+ market_currency = "USD" ,
192+ cash_only_execution = True ,
193+ )
194+
195+
123196def test_missing_read_only_order_surface_fails_closed () -> None :
124197 class MissingOpenOrderReader (_IB ):
125198 reqAllOpenOrders = None
0 commit comments