The size vector is the lossless source of display status
Display Status is derived from the full Size Vector
{ requested, matched, remaining, lapsed, cancelled, voided } and is never collapsed to a single
remainder disposition. When a partially-matched order's remainder is split across dispositions —
e.g. part cancelled by the user, part lapsed by the exchange, both nonzero on the same Betfair order —
the derivation carries every nonzero part (remainder: { working, lapsed, cancelled, voided }) and
the UI renders all of them ("₹25 cancelled · ₹15 lapsed"), never dropping any.
Considered options
- Fixed precedence — pick one disposition (e.g. cancelled > lapsed) and show a single label. Rejected: the moment a remainder is genuinely split, it hides where a user's stake went — a loss of information that is unacceptable in a financial ledger.
- Lossless structured breakdown (chosen): every nonzero part is carried and shown.
The reconciliation invariant (no guesswork)
matched + remaining + lapsed + cancelled + voided must never exceed requested (within a
2dp/dust tolerance). Two cases:
- Over-sum (
sum > requested + dust) or any internal inconsistency → throwFINANCIAL_INTEGRITY. A thrown error beats a wrong number. - Under-sum / deficit (
requested − sum > dust) → the deficit is the not-yet-reported portion (e.g. at placement Betfair returns onlysizeMatched). It is surfaced aspending/ unresolved, never fabricated as lapsed/cancelled. It reconciles exactly once the provider reports the full breakdown via sync/stream/settlement (ADR-0006).
This is the guard that makes "lossless" and "no-guesswork" coexist: an unreported amount is pending, never guessed; an impossible amount throws.