diff --git a/application/account_facts_publisher.py b/application/account_facts_publisher.py index 5be61e8..c91cad2 100644 --- a/application/account_facts_publisher.py +++ b/application/account_facts_publisher.py @@ -207,6 +207,10 @@ def build_firstrade_account_snapshot( raise AccountFactsPublishError("snapshot_time_invalid") cash_balance = balances.get("cash_balance") + # Use exact available_cash only when cash_balance is absent — still a real + # provider cash figure, never synthesized from equity or buying power. + if cash_balance is None: + cash_balance = balances.get("available_cash") cash: list[dict[str, str]] = [] if cash_balance is not None: cash.append({ diff --git a/tests/test_account_facts_publisher.py b/tests/test_account_facts_publisher.py index 127e5ae..0c1d8f1 100644 --- a/tests/test_account_facts_publisher.py +++ b/tests/test_account_facts_publisher.py @@ -116,6 +116,7 @@ def test_rejects_qrs_amounts_outside_exact_decimal_contract(value): def test_allows_cash_to_be_absent_without_synthesizing_it(): data = observation() data["balances"]["cash_balance"] = None + data["balances"]["available_cash"] = None payload = build_firstrade_account_snapshot( data, load_account_facts_publish_config(config()), account_scope="us" @@ -124,6 +125,22 @@ def test_allows_cash_to_be_absent_without_synthesizing_it(): assert payload["cash"] == [] +def test_falls_back_to_available_cash_when_cash_balance_absent(): + data = observation() + data["balances"]["cash_balance"] = None + data["balances"]["available_cash"] = "240.00" + + payload = build_firstrade_account_snapshot( + data, load_account_facts_publish_config(config()), account_scope="us" + ) + + assert payload["cash"] == [{ + "currency": "USD", + "cash_balance": "240.00", + "source_tag": "provider.cash_balance", + }] + + @pytest.mark.parametrize( ("overrides", "reason"), [