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

QuoteManager (5.6): diffs the strategy's DesiredQuotes against the orders resting at the venue and emits the minimal set of New / Cancel / Replace actions. More...

#include "fastmm/core/config_macros.hpp"
#include "fastmm/core/containers/ring_buffer.hpp"
#include "fastmm/core/containers/static_vector.hpp"
#include "fastmm/core/instrument.hpp"
#include "fastmm/core/messages.hpp"
#include "fastmm/core/oms.hpp"
#include "fastmm/core/time.hpp"
#include <array>
#include <cstddef>
#include <cstdint>

Go to the source code of this file.

Classes

struct  fastmm::DesiredQuotes
 
struct  fastmm::QuoteParams
 
struct  fastmm::QuoteAction
 
struct  fastmm::QuoteStats
 
class  fastmm::QuoteManager
 

Namespaces

namespace  fastmm
 

Enumerations

enum class  fastmm::QuoteActionKind : std::uint8_t { fastmm::New , fastmm::Cancel , fastmm::Replace }
 

Variables

constexpr std::size_t fastmm::kMaxQuoteLevels = 8
 

Detailed Description

QuoteManager (5.6): diffs the strategy's DesiredQuotes against the orders resting at the venue and emits the minimal set of New / Cancel / Replace actions.

Rules:

  • level i of a side maps to slot i (one order per slot);
  • hysteresis: keep an order whose price is within min_requote_ticks of the desired price and whose leaves cover min_qty_bps of the desired quantity;
  • never re-quote a slot within min_requote_interval of its last change;
  • orders in a Pending* state are never touched: the slot records the target instead and applies it when the order's ack or terminal update arrives via on_order_update() (dropped if the instrument is pulled first);
  • a slot only counts an order as its own if it is live and carries the slot's tag (order slots are reused, and a replace changes the order's id);
  • while an instrument is pulled, an order that becomes working late (its ack arrived after the pull) is cancelled at once;
  • a New rejected by the venue (other than a post-only cross) blocks new orders on that side for reject_backoff, doubling on each further reject up to reject_backoff_max and reset by an ack on that side, so an unfundable side is not resent on every requote;
  • an instrument whose venue supports replace (set_replace(), with supports_replace) gets a single Replace; otherwise Cancel now and New only once the cancel's terminal update arrives via on_order_update() (cancel-then-new keeps momentary exposure down and never double-quotes a level, and the New is checked against the balance once the old order's hold is released);
  • such a deferred New (QuoteAction::deferred) that the balance no longer covers -- the order it replaced filled instead of cancelling -- is withheld (QuoteAction::withheld, kept_balance) rather than refused by risk: the target predates the fill, the strategy's next quotes decide;
  • pull_quotes(keep_desired) pauses an instrument (the engine during reconciliation): resume() re-applies the last desired quotes unless the instrument was pulled for good meanwhile;
  • a New or Replace the placer holds back for want of an order token (QuoteAction::rate_limited) is neither a reject nor a backoff: the instrument joins a FIFO of starved instruments, and the engine re-applies their last desired quotes (retry()) in that order as tokens come back, so a burst of requotes on many instruments is served in turn instead of refused event by event.

Actions are executed by the caller through a Placer callable so the QuoteManager stays independent of risk/OMS/transport wiring: bool place(QuoteAction& a); // New: sets a.handle on success; returns false on reject