{"record":{"id":"9abea2300c7489f1","repo":"HKUDS/Vibe-Trading","slug":"binance-usd-m-account-totals-are-incoherent","errorCode":null,"errorMessage":"Binance USD-M account totals are incoherent","messagePattern":"Binance USD-M account totals are incoherent","errorType":"exception","errorClass":"UsdMObservationError","httpStatus":null,"severity":"critical","filePath":"agent/src/trading/connectors/binance/usdm.py","lineNumber":281,"sourceCode":"        (\n            account[\"total_unrealized_pnl\"],\n            sum(row[\"unrealized_pnl\"] for row in positions),\n        ),\n        (\n            account[\"total_initial_margin\"],\n            sum(row[\"initial_margin\"] for row in positions),\n        ),\n        (\n            account[\"total_maintenance_margin\"],\n            sum(row[\"maintenance_margin\"] for row in positions),\n        ),\n        (\n            account[\"margin_balance\"],\n            account[\"wallet_balance\"] + account[\"total_unrealized_pnl\"],\n        ),\n    )\n    if any(not close_enough(reported, derived) for reported, derived in comparisons):\n        raise UsdMObservationError(\"Binance USD-M account totals are incoherent\")\n\n\ndef _mapping_rows(value: Any, name: str) -> list[Mapping[str, Any]]:\n    if not isinstance(value, list) or any(not isinstance(row, Mapping) for row in value):\n        raise UsdMObservationError(f\"Binance USD-M {name} payload is invalid\")\n    return value\n\n\ndef _require_one_way(rows: list[Mapping[str, Any]]) -> None:\n    if any(str(row.get(\"positionSide\") or \"\").upper() != \"BOTH\" for row in rows):\n        raise UsdMObservationError(\"Binance USD-M Shadow Account requires one-way position mode\")\n\n\ndef _active_by_symbol(rows: list[Mapping[str, Any]], source: str) -> dict[str, Mapping[str, Any]]:\n    active: dict[str, Mapping[str, Any]] = {}\n    for row in rows:\n        quantity = _number(row.get(\"positionAmt\"), \"positionAmt\")\n        if quantity == 0:","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/binance/usdm.py#L263-L299","documentation":"Raised by _require_coherent_totals when reported account totals do not match derived values within tolerance: margin_balance must equal wallet_balance + total_unrealized_pnl (and similar comparisons checked via close_enough). This guards against partially-read or inconsistent snapshots from the exchange. The error indicates the account payload is internally contradictory, so risk computations would be wrong.","triggerScenarios":"read_account_observation receives an account dict where margin_balance deviates from wallet_balance + total_unrealized_pnl beyond absolute_tolerance, typically because balances and positions were fetched at different times or from different endpoints.","commonSituations":"Active positions changing between the balance and positionRisk REST calls; using absolute_tolerance too small for large accounts (floating point noise); mocks with hand-picked inconsistent numbers; exchange during settlement/funding events reporting transiently inconsistent totals.","solutions":["Retry the observation — transient incoherence from concurrent position updates usually resolves","Fetch account balances and positions atomically (same snapshot / Binance userData stream instead of two REST calls)","Increase absolute_tolerance in the connector configuration if the account is large and discrepancies are float noise","Fix mock/fixture numbers so margin_balance == wallet_balance + total_unrealized_pnl"],"exampleFix":"// before\n{\"wallet_balance\": 1000.0, \"total_unrealized_pnl\": 5.0, \"margin_balance\": 1010.0}\n// after\n{\"wallet_balance\": 1000.0, \"total_unrealized_pnl\": 5.0, \"margin_balance\": 1005.0}","handlingStrategy":"retry","validationCode":"def totals_coherent(acc: dict, tol: float) -> bool:\n    return abs(acc[\"margin_balance\"] - (acc[\"wallet_balance\"] + acc[\"total_unrealized_pnl\"])) <= tol\n\nif not totals_coherent(acc, tol):\n    acc = refetch_account()","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        obs = connector.read_account_observation(...)\n        break\n    except UsdMObservationError as exc:\n        if \"incoherent\" not in str(exc) or attempt == 2:\n            raise\n        sleep(0.5)","preventionTips":["Fetch balances and positions from the same snapshot (user-data stream)","Size absolute_tolerance to the account magnitude","Retry transiently before treating incoherence as fatal","Keep mock numbers internally consistent"],"tags":["binance","usdm","consistency-check","floating-point","account-validation"],"backgroundTag":"data-consistency-validation","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}