FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
oms.hpp File Reference

Order management (5.8): a Pool<Order> + OpenHashMap<ClientOrderId, Handle> + a ring of recently terminal ids used to classify late venue messages. More...

#include "fastmm/core/book/book_view.hpp"
#include "fastmm/core/config_macros.hpp"
#include "fastmm/core/containers/open_hash_map.hpp"
#include "fastmm/core/containers/pool.hpp"
#include "fastmm/core/containers/recent_map.hpp"
#include "fastmm/core/containers/ring_buffer.hpp"
#include "fastmm/core/containers/static_vector.hpp"
#include "fastmm/core/enums.hpp"
#include "fastmm/core/instrument.hpp"
#include "fastmm/core/messages.hpp"
#include "fastmm/core/order.hpp"
#include "fastmm/core/result.hpp"
#include <cstdint>
#include <limits>
#include <memory>
#include <optional>

Go to the source code of this file.

Classes

struct  fastmm::OmsUpdate
 
struct  fastmm::OmsStats
 
class  fastmm::Oms
 

Namespaces

namespace  fastmm
 

Enumerations

enum class  fastmm::OmsAction : std::uint8_t {
  fastmm::None = 0 , fastmm::Ignored , fastmm::Duplicate , fastmm::CancelUnknown ,
  fastmm::LateFill , fastmm::UnknownFill , fastmm::ReconcileNeeded
}
 
enum class  fastmm::OrderClass : std::uint8_t { fastmm::Open , fastmm::RecentlyTerminal , fastmm::Unknown }
 

Variables

constexpr std::size_t fastmm::kMaxOpenOrders = 4096
 
constexpr std::size_t fastmm::kRecentlyTerminal = 4096
 
constexpr std::size_t fastmm::kMaxSyntheticFills = 64
 Fills booked from a cumulative quantity and never named by an execution.
 
constexpr std::uint64_t fastmm::kMaxSeq = 0xFFFF'FFFFULL
 Client order ids per session: the wire form is 48 bits, epoch(16) << 32 | seq(32).
 

Detailed Description

Order management (5.8): a Pool<Order> + OpenHashMap<ClientOrderId, Handle> + a ring of recently terminal ids used to classify late venue messages.

State machine (terminal states free the slot and go to the recently-terminal ring): submit -> PendingNew ack PendingNew -> Live; PendingReplace -> Live/PartiallyFilled (replace ok) reject PendingNew -> Rejected; PendingReplace -> back to previous working state cancel request Live/PartiallyFilled -> PendingCancel cancel ack any open -> Canceled (unsolicited if we did not ask); Filled when the venue's cum_qty covers the order cancel reject PendingCancel -> back; >3 rejects -> ReconcileNeeded; VenueUnknownOrder -> Canceled fill cum >= qty -> Filled, else PartiallyFilled (pending states keep pending) expired any open -> Expired; Filled when the venue's cum_qty covers the order A cum_qty a venue reports that no fill message covered (a cancel ack, an expiry or a reconciliation snapshot) becomes OmsUpdate::missed_qty for the engine to book. That booking is an estimate - the order's own price, no fee - so it is remembered here until an execution names it: one from the venue's trade history (OrderFillMsg::kReplayed), or a live one that arrives after the cum_qty covering it (its cum_qty - qty lies below the booked cum_qty; order and execution topics are not ordered on every venue). The execution then corrects the price and the fee (OmsUpdate::corrected_qty) instead of the quantity being counted twice. Races: fill after cancel ack -> LateFill (position still updated from the terminal record's instrument and side; the record takes the fill's quantity, and a Canceled or Expired order the fill completes becomes Filled, so the order's last update agrees with its fills); cancel-reject after fill -> ignored; ack for unknown id -> CancelUnknown (never leave an unknown live order); ack for an order reconciliation marked cancelled -> CancelUnknown; duplicate exec_id -> Duplicate; duplicate ack -> Ignored (also for the original id while a replace to a new id is pending: only the new id's ack completes the replace). Reconciliation (per venue): a cancel or replace still in flight stays pending; orders sent after the snapshot was requested (above the Begin's sent watermark) are not marked cancelled.