|
| | Oms (std::uint16_t session_epoch=1, std::uint64_t max_seq=kMaxSeq) noexcept |
| | max_seq is the highest client order id sequence this session may issue; only tests lower it from kMaxSeq (reaching it takes 4.3 billion orders).
|
| |
| | Oms (const Oms &)=delete |
| |
| Oms & | operator= (const Oms &)=delete |
| |
| std::uint16_t | session_epoch () const noexcept |
| |
| ClientOrderId | next_cl_ord_id () noexcept |
| | An invalid id once the session's 32-bit sequence is used up: the wire form carries 48 bits (epoch 16 + seq 32), so reusing a sequence would repeat a ClientOrderId within the session and let a late venue message match the wrong order.
|
| |
| std::uint64_t | ids_left () const noexcept |
| | Client order ids left in this session.
|
| |
| const OmsStats & | stats () const noexcept |
| |
| std::uint32_t | open_count () const noexcept |
| |
| std::uint32_t | open_count (InstrumentId id) const noexcept |
| |
| Qty | open_qty (InstrumentId id, Side s) const noexcept |
| | Sum of leaves of open orders on (instrument, side): "in-flight same-side exposure".
|
| |
| Price | best_own_px (InstrumentId id, Side s) const noexcept |
| | Best price among our own open orders on (instrument, side); Price{} if none. For STP.
|
| |
| Result< Handle< Order >, RejectReason > | submit (const NewOrderRequest &req, ClientOrderId id, Timestamp now) noexcept |
| |
| Result< void, RejectReason > | request_cancel (Handle< Order > h) noexcept |
| |
| Result< void, RejectReason > | request_cancel_unacked (Handle< Order > h) noexcept |
| | Cancel of an order that is still waiting for its ack (the ack-timeout sweep only).
|
| |
| Result< void, RejectReason > | request_replace (Handle< Order > h, ClientOrderId new_id, Price px, Qty qty, Timestamp now={}) noexcept |
| | new_id may equal the current id for venues that amend in place.
|
| |
| OmsUpdate | on_ack (const OrderAckMsg &m) noexcept |
| |
| OmsUpdate | on_reject (const OrderRejectMsg &m) noexcept |
| |
| OmsUpdate | on_cancel_ack (const OrderCancelAckMsg &m) noexcept |
| |
| OmsUpdate | on_cancel_reject (const OrderCancelRejectMsg &m) noexcept |
| |
| OmsUpdate | on_fill (const OrderFillMsg &m) noexcept |
| |
| OmsUpdate | on_expired (const OrderExpiredMsg &m) noexcept |
| |
| void | reconcile_begin (VenueId venue=VenueId::invalid(), std::optional< ClientOrderId > sent_watermark=std::nullopt) noexcept |
| | Starts reconciling venue's orders (an invalid venue: every venue).
|
| |
| OmsUpdate | reconcile_open_order (const ReconcileMsg &m) noexcept |
| | Venue reports an open order. Unknown -> CancelUnknown (engine cancels by venue id).
|
| |
| template<class F > |
| void | reconcile_end (F &&f, VenueId venue=VenueId::invalid()) noexcept |
| | Every open order of venue (invalid: every venue) the snapshot did not report is marked Canceled, except orders sent after the snapshot was requested (see reconcile_begin).
|
| |
| template<class F > |
| std::size_t | sweep_pending (Timestamp now, Duration timeout, F &&f) noexcept |
| | Orders still PendingNew timeout after they were submitted: the request or its ack was lost, and nothing else ever frees them.
|
| |
| const Order & | get (Handle< Order > h) const noexcept |
| |
| Order & | get (Handle< Order > h) noexcept |
| |
| bool | is_live (Handle< Order > h) const noexcept |
| |
| const OrderTimes & | times (Handle< Order > h) const noexcept |
| | Send and ack times of an open order.
|
| |
| Handle< Order > | find (ClientOrderId id) const noexcept |
| |
| OrderClass | classify (ClientOrderId id) const noexcept |
| |
| template<class F > |
| void | for_each_open_order (F &&f) const noexcept |
| | Ascending handle order (deterministic). F(Handle<Order>, const Order&).
|
| |
| template<class F > |
| void | for_each_open_order (InstrumentId id, F &&f) const noexcept |
| |
| void | warm_up () noexcept |
| |
< a live order we do not know: cancel it
Reconciliation took it for gone, yet the venue has it (the snapshot missed an order still in flight). Nothing tracks it any more: cancel it rather than leave it live.
< late ack for a terminal order
Only the replacement's ack completes it (the same id for an in-place amend). An ack that repeats the current id while a replace to a new id is in flight is a duplicate of the original ack (Binance sends one from the WS API response and one from the user stream): applying it would take the replace for confirmed, leave the new id mapped after the order ends and let the new leg's ack read a freed slot while that order stays live untracked.
An in-place amend keeps the venue's order even when it is given a new client id (Binance Spot keepPriority), so the fills booked against it stay.
< duplicate ack
A venue that answers twice (API response and user stream) may put its time on either.
A replayed execution may be one the venue already counted into a cum_qty the engine booked as a synthetic fill. Taking that quantity out of the pool here is what keeps it from being booked twice, whether the order is still open, recently terminal or gone.
A live execution can also arrive after the cum_qty that covers it: venues that publish order states and executions on separate topics (Bybit's order and execution) may end an order with its cumulative quantity first. The quantity was booked then as a synthetic fill; the part of this execution at or below that cum_qty (this execution spans cum_qty - qty to cum_qty on the venue's count) is the estimate being named, not new quantity. Without a cum_qty (Deribit's trades) only an order that has ended can tell: the venue's final cum_qty was all it will ever fill, so the execution is within the estimate.
Only the part the position does not already hold moves the order forward: a replayed execution carries no cumulative quantity of its own.
< out-of-order cum: never go backwards
Every open order of venue (invalid: every venue) the snapshot did not report is marked Canceled, except orders sent after the snapshot was requested (see reconcile_begin).
F(const OmsUpdate&) runs after each order ends and outside the pool iteration, so it may place or cancel orders.
< not sent yet
Working quantity nobody accounted for: the snapshot proves the order is over, not how it ended. Treating it as cancelled is a guess, so report it instead of hiding it.
Orders still PendingNew timeout after they were submitted: the request or its ack was lost, and nothing else ever frees them.
They hold a pool slot, a max_open_orders slot and same-side open quantity that feeds max_position, so the engine force-cancels them (the venue may know the order even though we never saw its ack). F(Handle<Order>, const Order&) runs outside the pool iteration, so it may send. Returns the number reported.