Skip to content

marketbyorder-bot: snapshot orders associated by snapshot_id, which is per-instrument not per-channel #30

Description

@armcconnell

marketbyorder-bot associates SnapshotOrder records with an instrument by snapshot_id alone, but Snapshot ID is scoped per instrument, not per channel.

Spec (market-by-order, 0x20): "Monotonically increasing per (channel_id, instrument_id) within the current Reset Count era." The association rule is "discard any SnapshotOrder whose Snapshot ID does not match the currently-open SnapshotBegin"snapshot_id validates the match, it isn't the key.

Two places assume channel-wide uniqueness:

  • shard.go:164-176applySnapshotOrder scans s.instruments and inserts into the first instrument whose OpenSnapshot.SnapshotID matches. Go map iteration is randomized, so with two matching instruments the target is arbitrary.
  • shard.go:24-27,420snapCtx is keyed {channel_id, snapshot_id}, so two instruments sharing an id collide and the later snapshot_begin overwrites the earlier context. wire_snapshots rows can then be written with the wrong instrument_id/symbol.

Publishers must not interleave snapshot groups, which normally leaves one group open at a time. The gap is when a SnapshotEnd is lost: that instrument's OpenSnapshot is never cleared and lingers. Because each instrument's counter advances once per cycle, instruments in the same cycle typically sit at the same snapshot_id — so a stale open snapshot is likely to collide with the next instrument's rather than unlikely. #20 measured ~3.7% of snapshots arriving short on the Tokyo feed, so lingering open snapshots are not hypothetical.

Effects are bounded but real: misattributed orders land in a shadow that fails its count check and is discarded (snapshot_discarded_total), so live books are not corrupted — but recovery for the affected instrument is delayed a cycle, and mis-keyed wire_snapshots rows are persisted.

Fix: key the association on the currently-open snapshot for a known (channel_id, instrument_id) and use snapshot_id only to validate. snapCtx needs the instrument in its key.

Found while writing marketbyprice-parser (#29) — the market-by-price spec scopes Snapshot ID identically. Not verified against a live feed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions