Skip to content

BinanceOrderBook

Maintains a live, local Binance SPOT order book for a configurable set of currency pairs, per Binance's documented local-order-book- maintenance algorithm (not linked here -- its status page returns inconsistent HTTP status codes to automated checks; search Binance's spot API docs for "How to manage a local order book correctly"): bootstrap from a REST depth snapshot, then apply WS update-deltas whose U (first update id) brackets the book's current lastUpdateId, resyncing on any gap.

Property Value
Project Virtufin.Worker.BinanceOrderBook
Base class Virtufin.Worker.DevKit.WorkerBase<JsonNode, JsonObject>
Engine application/x-dotnet-dll (Managed only)

One instance, many pairs

One worker instance tracks a configurable set of pairs (default: every pair it sees) rather than one instance per pair -- one-worker-per-pair was judged operationally heavy for Binance spot's 50+ actively-traded pairs. Internally, a Dictionary<string, OrderBook> holds one state machine per pair.

The worker subscribes to two flat, un-suffixed topics -- act.exchange.binance.orderbook.update and act.exchange.binance.orderbook.snapshot -- rather than the pubsub-topics spec's per-pair pattern for these two input topics. The pair for an update-delta event is parsed from Binance's own combined-stream envelope (payload.stream); the pair for a snapshot event is read from the CloudEvent's currencypair extension attribute (Binance's raw REST response has no symbol field of its own). The worker's output -- state key, changed/gap topics -- stays genuinely per-pair, matching the spec.

Snapshot delivery

This worker doesn't call Binance's REST snapshot endpoint itself. HttpGetWorker (virtufin-workers/HttpGetWorker) is deployed once per tracked pair (Binance's depth endpoint is single-symbol), and a platform Trigger (Dapr Jobs, the same primitive the TUI's Triggers page exposes) fires periodically to invoke it. Post-gap recovery latency is therefore bounded by the polling interval (default @every 30s), not instant -- a deliberate tradeoff paired with dropping (not buffering) updates received while the book isn't Live.

State

Key act\|hyp.<name>.exchange.<venue>.orderbook.<pair>
Value { bids, asks, last_update_id, updated_at }

Events published

Action Topic Payload
Book updated ...orderbook.changed.<pair> { pair, last_update_id }
Gap detected ...orderbook.changed.<pair>.error { pair, expected, got }

Configuration

Key Default Purpose
currencypairs (all pairs seen) Comma-separated allowlist.
venue binance Multi-venue future-proofing.
world act act or hyp.<name>.
stateservice workmanager SaveStateRequest.service.
apihost localhost:5002 Gateway host:port.

See the repo README for the full deploy sequence and known-gaps list.