FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
fastmm::StrategyContext< Engine > Class Template Reference

#include <fastmm/core/strategy_context.hpp>

Public Types

using Book = typename Engine::Book
 

Public Member Functions

 StrategyContext (Engine *e) noexcept
 
Timestamp now () const noexcept
 
const Instrument & instrument (InstrumentId id) const noexcept
 
const InstrumentTable & instruments () const noexcept
 
bool contains (InstrumentId id) const noexcept
 
const Book & book (InstrumentId id) const noexcept
 
Qty own_qty (InstrumentId id, Side side, Price px) const noexcept
 Our resting quantity that the venue's feed shows at (id, side, px): the book and the tickers of a live venue include our own orders.
 
Qty own_qty (InstrumentId id, Side side, Price px, Timestamp at) const noexcept
 
Level best_ex_self (InstrumentId id, Side side) const noexcept
 The book's best level on one side with own_qty taken out; a level that was only ours is skipped.
 
const Position & position (InstrumentId id) const noexcept
 
Portfolio portfolio () const noexcept
 PnL totals over every instrument (a loop over all positions; not for every event).
 
bool set_quotes (InstrumentId id, const DesiredQuotes &q) noexcept
 Returns false when the quotes were ignored: quoting is disabled (control pull, kill switch, reconciliation; on_quoting reports the changes) or the instrument is not in the table.
 
void pull_quotes (InstrumentId id) noexcept
 
void note_quote (InstrumentId id, Side side, std::string_view reason, Notional budget={}) noexcept
 Why the strategy asks what it asks on a side, for the operator: a short reason ("inventory_cap", "model_off"; empty clears it, at most 23 bytes kept) and the budget it gave the side in the settlement currency.
 
void metric (std::string_view name, double value) noexcept
 A number the strategy publishes by name, for the status file (a budget split, a model's state): the first 32 names are kept, a name at most 23 bytes.
 
void pull_all_quotes () noexcept
 
const Order * working_quote (InstrumentId id, Side side, std::uint32_t level=0) const noexcept
 The open order in a quote slot (level 0 is closest to the mid), or nullptr.
 
Result< ClientOrderId, RejectReason > send (const NewOrderRequest &req) noexcept
 RejectReason::InvalidTag: user_tag lies in the QuoteManager's tag range.
 
Result< void, RejectReason > cancel (ClientOrderId id) noexcept
 
Result< void, RejectReason > replace (ClientOrderId id, Price px, Qty qty) noexcept
 
const Order * order (ClientOrderId id) const noexcept
 An open order by id, or nullptr once it is terminal. Valid until the next context call.
 
std::optional< Qty > queue_ahead (ClientOrderId id) const noexcept
 Estimated quantity resting ahead of an open order at its price: the l2_queue fill model's queue model on the market data the strategy sees, with [engine] queue_conservatism, from the order's ack.
 
const OrderTimes * order_times (ClientOrderId id) const noexcept
 Send and ack times of an open order, or nullptr (OmsUpdate::times has them in on_order_update and, through Fill::update, in on_fill).
 
Qty open_qty (InstrumentId id, Side side) const noexcept
 Unfilled quantity of our open orders (quotes included) on one side.
 
const Oms & oms () const noexcept
 
TimerId every (Duration period, std::uint64_t tag=0) noexcept
 
TimerId once (Duration delay, std::uint64_t tag=0) noexcept
 
bool cancel_timer (TimerId id) noexcept
 
bool quoting_enabled () const noexcept
 
bool reconciling () const noexcept
 A venue's orders and position are being reconciled, or have not been yet since the session started (a live session waits for every venue that replays executions; new orders are refused with NotReconciled until then).
 
bool killed () const noexcept
 
bool venue_killed (VenueId v) const noexcept
 One venue's kill switch: new orders to it are refused and set_quotes ignores its instruments.
 
void request_stop () noexcept
 
void request_batch_end () noexcept
 Asks for one on_batch_end call once the engine has handled every event that is waiting now (the feed is empty or the step's max_events_per_step is used up).
 
void trip_kill (KillReason reason) noexcept
 Trips the global kill switch: quoting stops, quotes are pulled and every working order is cancelled.
 
const FeeRates & fees (InstrumentId id) const noexcept
 Maker and taker rates of the instrument, in cbps of the notional (positive: a fee).
 
RiskHeadroom risk_headroom (InstrumentId id) const noexcept
 What each [risk] limit still admits on the instrument now: the next check uses the same inputs, so an order of exactly a room passes that limit.
 
VenueHealthView venue_health (VenueId v) const noexcept
 Feed lag and order round trip of a venue (core/venue_health.hpp), and whether the feed-lag gate ([risk] max_feed_lag_ms) holds it now.
 
OrderBudget order_budget (VenueId v) const noexcept
 What the [risk] rate limit and the venue's own limits still admit (core/order_budget.hpp): the local token bucket, and the venue's order counts and request weight by window as its connector last published them (live only; venue_known is false elsewhere).
 
Balance balance (VenueId v, std::string_view asset) const noexcept
 One asset of a venue's account: the venue's last report (on_balance) less what this engine's orders hold and its fills moved since.
 
Margin margin (VenueId v) const noexcept
 The venue's margin: its account-wide margin where it reports one, else the settlement asset of its first derivative.
 
bool balances_live () const noexcept
 A venue has reported balances (before that, balance() is unknown everywhere).
 
Qty balance_room (InstrumentId id, Side side, Price px) const noexcept
 Largest quantity of id on side at px the balance covers (a spot buy's quote with the taker fee, a spot sell's base, a derivative's initial margin), rounded down to the lot.
 
Qty balance_room (InstrumentId id, Side side, Price px, VenueId account) const noexcept
 ... on one account of the instrument's pool (its own venue when account is not one).
 
PoolMembers pool (VenueId primary) const noexcept
 The accounts that take orders for a venue's instruments ([venues.
 
VenueId pool_primary (VenueId v) const noexcept
 The venue whose instruments v takes orders for: its primary, or v itself.
 
bool account_usable (VenueId v) const noexcept
 The automatic routing would send to v now: its order link is live and its kill switch is not engaged (its balance and window are the order's to decide).
 
RefPrice mark (InstrumentId id) const noexcept
 The venue's mark and index price of a derivative (on_perp_state), with the time each arrived.
 
RefPrice index (InstrumentId id) const noexcept
 
FundingView funding (InstrumentId id) const noexcept
 The venue's funding of a perpetual: the rate it will apply at next, per interval, and over(d), the rate over a holding time d.
 
const PerpRow & perp_state (InstrumentId id) const noexcept
 Every field as last reported, open interest included, without the staleness applied.
 
Xoshiro256ss & rng () noexcept
 

Member Typedef Documentation

◆ Book

template<class Engine >
using fastmm::StrategyContext< Engine >::Book = typename Engine::Book

Constructor & Destructor Documentation

◆ StrategyContext()

template<class Engine >
fastmm::StrategyContext< Engine >::StrategyContext ( Engine *  e)
inlineexplicitnoexcept

Member Function Documentation

◆ now()

template<class Engine >
Timestamp fastmm::StrategyContext< Engine >::now ( ) const
inlinenoexcept

◆ instrument()

template<class Engine >
const Instrument & fastmm::StrategyContext< Engine >::instrument ( InstrumentId  id) const
inlinenoexcept

◆ instruments()

template<class Engine >
const InstrumentTable & fastmm::StrategyContext< Engine >::instruments ( ) const
inlinenoexcept

◆ contains()

template<class Engine >
bool fastmm::StrategyContext< Engine >::contains ( InstrumentId  id) const
inlinenoexcept

◆ book()

template<class Engine >
const Book & fastmm::StrategyContext< Engine >::book ( InstrumentId  id) const
inlinenoexcept

◆ own_qty() [1/2]

template<class Engine >
Qty fastmm::StrategyContext< Engine >::own_qty ( InstrumentId  id,
Side  side,
Price  px 
) const
inlinenoexcept

Our resting quantity that the venue's feed shows at (id, side, px): the book and the tickers of a live venue include our own orders.

As of the book's last update, or of venue time at (a BookTicker's exch_ts). An order counts from its ack's venue time to its end's, less its fills, so a depth update stamped before our cancel still includes it. Zero in the simulator, whose feed does not contain our orders.

◆ own_qty() [2/2]

template<class Engine >
Qty fastmm::StrategyContext< Engine >::own_qty ( InstrumentId  id,
Side  side,
Price  px,
Timestamp  at 
) const
inlinenoexcept

◆ best_ex_self()

template<class Engine >
Level fastmm::StrategyContext< Engine >::best_ex_self ( InstrumentId  id,
Side  side 
) const
inlinenoexcept

The book's best level on one side with own_qty taken out; a level that was only ours is skipped.

Level{} when none is left.

◆ position()

template<class Engine >
const Position & fastmm::StrategyContext< Engine >::position ( InstrumentId  id) const
inlinenoexcept

◆ portfolio()

template<class Engine >
Portfolio fastmm::StrategyContext< Engine >::portfolio ( ) const
inlinenoexcept

PnL totals over every instrument (a loop over all positions; not for every event).

◆ set_quotes()

template<class Engine >
bool fastmm::StrategyContext< Engine >::set_quotes ( InstrumentId  id,
const DesiredQuotes &  q 
)
inlinenoexcept

Returns false when the quotes were ignored: quoting is disabled (control pull, kill switch, reconciliation; on_quoting reports the changes) or the instrument is not in the table.

◆ pull_quotes()

template<class Engine >
void fastmm::StrategyContext< Engine >::pull_quotes ( InstrumentId  id)
inlinenoexcept

◆ note_quote()

template<class Engine >
void fastmm::StrategyContext< Engine >::note_quote ( InstrumentId  id,
Side  side,
std::string_view  reason,
Notional  budget = {} 
)
inlinenoexcept

Why the strategy asks what it asks on a side, for the operator: a short reason ("inventory_cap", "model_off"; empty clears it, at most 23 bytes kept) and the budget it gave the side in the settlement currency.

The status file shows it next to what the engine finds in the way (core/quote_diag.hpp); the store records each change. No allocation.

◆ metric()

template<class Engine >
void fastmm::StrategyContext< Engine >::metric ( std::string_view  name,
double  value 
)
inlinenoexcept

A number the strategy publishes by name, for the status file (a budget split, a model's state): the first 32 names are kept, a name at most 23 bytes.

No allocation.

◆ pull_all_quotes()

template<class Engine >
void fastmm::StrategyContext< Engine >::pull_all_quotes ( )
inlinenoexcept

◆ working_quote()

template<class Engine >
const Order * fastmm::StrategyContext< Engine >::working_quote ( InstrumentId  id,
Side  side,
std::uint32_t  level = 0 
) const
inlinenoexcept

The open order in a quote slot (level 0 is closest to the mid), or nullptr.

◆ send()

template<class Engine >
Result< ClientOrderId, RejectReason > fastmm::StrategyContext< Engine >::send ( const NewOrderRequest &  req)
inlinenoexcept

RejectReason::InvalidTag: user_tag lies in the QuoteManager's tag range.

◆ cancel()

template<class Engine >
Result< void, RejectReason > fastmm::StrategyContext< Engine >::cancel ( ClientOrderId  id)
inlinenoexcept

◆ replace()

template<class Engine >
Result< void, RejectReason > fastmm::StrategyContext< Engine >::replace ( ClientOrderId  id,
Price  px,
Qty  qty 
)
inlinenoexcept

◆ order()

template<class Engine >
const Order * fastmm::StrategyContext< Engine >::order ( ClientOrderId  id) const
inlinenoexcept

An open order by id, or nullptr once it is terminal. Valid until the next context call.

◆ queue_ahead()

template<class Engine >
std::optional< Qty > fastmm::StrategyContext< Engine >::queue_ahead ( ClientOrderId  id) const
inlinenoexcept

Estimated quantity resting ahead of an open order at its price: the l2_queue fill model's queue model on the market data the strategy sees, with [engine] queue_conservatism, from the order's ack.

nullopt while it is not acknowledged or once it is terminal. The engine tracks queues from the first call on (call it in on_start to cover every order from its ack); an order already resting at the first call starts at the back of its level as the book shows it.

◆ order_times()

template<class Engine >
const OrderTimes * fastmm::StrategyContext< Engine >::order_times ( ClientOrderId  id) const
inlinenoexcept

Send and ack times of an open order, or nullptr (OmsUpdate::times has them in on_order_update and, through Fill::update, in on_fill).

◆ open_qty()

template<class Engine >
Qty fastmm::StrategyContext< Engine >::open_qty ( InstrumentId  id,
Side  side 
) const
inlinenoexcept

Unfilled quantity of our open orders (quotes included) on one side.

◆ oms()

template<class Engine >
const Oms & fastmm::StrategyContext< Engine >::oms ( ) const
inlinenoexcept

◆ every()

template<class Engine >
TimerId fastmm::StrategyContext< Engine >::every ( Duration  period,
std::uint64_t  tag = 0 
)
inlinenoexcept

◆ once()

template<class Engine >
TimerId fastmm::StrategyContext< Engine >::once ( Duration  delay,
std::uint64_t  tag = 0 
)
inlinenoexcept

◆ cancel_timer()

template<class Engine >
bool fastmm::StrategyContext< Engine >::cancel_timer ( TimerId  id)
inlinenoexcept

◆ quoting_enabled()

template<class Engine >
bool fastmm::StrategyContext< Engine >::quoting_enabled ( ) const
inlinenoexcept

◆ reconciling()

template<class Engine >
bool fastmm::StrategyContext< Engine >::reconciling ( ) const
inlinenoexcept

A venue's orders and position are being reconciled, or have not been yet since the session started (a live session waits for every venue that replays executions; new orders are refused with NotReconciled until then).

Positions may be missing fills while this holds.

◆ killed()

template<class Engine >
bool fastmm::StrategyContext< Engine >::killed ( ) const
inlinenoexcept

◆ venue_killed()

template<class Engine >
bool fastmm::StrategyContext< Engine >::venue_killed ( VenueId  v) const
inlinenoexcept

One venue's kill switch: new orders to it are refused and set_quotes ignores its instruments.

◆ request_stop()

template<class Engine >
void fastmm::StrategyContext< Engine >::request_stop ( )
inlinenoexcept

◆ request_batch_end()

template<class Engine >
void fastmm::StrategyContext< Engine >::request_batch_end ( )
inlinenoexcept

Asks for one on_batch_end call once the engine has handled every event that is waiting now (the feed is empty or the step's max_events_per_step is used up).

Work a burst of events would each trigger (a requote after every balance report) is done once, after the burst. Repeated requests before the call make one call.

◆ trip_kill()

template<class Engine >
void fastmm::StrategyContext< Engine >::trip_kill ( KillReason  reason)
inlinenoexcept

Trips the global kill switch: quoting stops, quotes are pulled and every working order is cancelled.

The adapter for Python hot hooks uses KillReason::StrategyError.

◆ fees()

template<class Engine >
const FeeRates & fastmm::StrategyContext< Engine >::fees ( InstrumentId  id) const
inlinenoexcept

Maker and taker rates of the instrument, in cbps of the notional (positive: a fee).

The configuration's ([[instruments]] maker_bps / taker_bps, else [venues.<x>.fees]), or the account's own where the connector fetched them (fetch_fees). A backtest charges these.

◆ risk_headroom()

template<class Engine >
RiskHeadroom fastmm::StrategyContext< Engine >::risk_headroom ( InstrumentId  id) const
inlinenoexcept

What each [risk] limit still admits on the instrument now: the next check uses the same inputs, so an order of exactly a room passes that limit.

RiskHeadroom::kUnlimited (or the type's max()) where the limit is off.

◆ venue_health()

template<class Engine >
VenueHealthView fastmm::StrategyContext< Engine >::venue_health ( VenueId  v) const
inlinenoexcept

Feed lag and order round trip of a venue (core/venue_health.hpp), and whether the feed-lag gate ([risk] max_feed_lag_ms) holds it now.

◆ order_budget()

template<class Engine >
OrderBudget fastmm::StrategyContext< Engine >::order_budget ( VenueId  v) const
inlinenoexcept

What the [risk] rate limit and the venue's own limits still admit (core/order_budget.hpp): the local token bucket, and the venue's order counts and request weight by window as its connector last published them (live only; venue_known is false elsewhere).

◆ balance()

template<class Engine >
Balance fastmm::StrategyContext< Engine >::balance ( VenueId  v,
std::string_view  asset 
) const
inlinenoexcept

One asset of a venue's account: the venue's last report (on_balance) less what this engine's orders hold and its fills moved since.

Balance::known is false until the venue reports it, and for an asset no instrument of the venue names.

◆ margin()

template<class Engine >
Margin fastmm::StrategyContext< Engine >::margin ( VenueId  v) const
inlinenoexcept

The venue's margin: its account-wide margin where it reports one, else the settlement asset of its first derivative.

◆ balances_live()

template<class Engine >
bool fastmm::StrategyContext< Engine >::balances_live ( ) const
inlinenoexcept

A venue has reported balances (before that, balance() is unknown everywhere).

◆ balance_room() [1/2]

template<class Engine >
Qty fastmm::StrategyContext< Engine >::balance_room ( InstrumentId  id,
Side  side,
Price  px 
) const
inlinenoexcept

Largest quantity of id on side at px the balance covers (a spot buy's quote with the taker fee, a spot sell's base, a derivative's initial margin), rounded down to the lot.

Qty::max() while the venue has not reported the balance that side draws on.

◆ balance_room() [2/2]

template<class Engine >
Qty fastmm::StrategyContext< Engine >::balance_room ( InstrumentId  id,
Side  side,
Price  px,
VenueId  account 
) const
inlinenoexcept

... on one account of the instrument's pool (its own venue when account is not one).

◆ pool()

template<class Engine >
PoolMembers fastmm::StrategyContext< Engine >::pool ( VenueId  primary) const
inlinenoexcept

The accounts that take orders for a venue's instruments ([venues.

<x>] pool_of), the primary first; just the venue itself without a pool. Each has its own balance(), margin() and order_budget(); an order goes to the one NewOrderRequest::account names, else to the usable member whose balance covers it with the most order window left, and Order::venue keeps it.

◆ pool_primary()

template<class Engine >
VenueId fastmm::StrategyContext< Engine >::pool_primary ( VenueId  v) const
inlinenoexcept

The venue whose instruments v takes orders for: its primary, or v itself.

◆ account_usable()

template<class Engine >
bool fastmm::StrategyContext< Engine >::account_usable ( VenueId  v) const
inlinenoexcept

The automatic routing would send to v now: its order link is live and its kill switch is not engaged (its balance and window are the order's to decide).

◆ mark()

template<class Engine >
RefPrice fastmm::StrategyContext< Engine >::mark ( InstrumentId  id) const
inlinenoexcept

The venue's mark and index price of a derivative (on_perp_state), with the time each arrived.

stale: older than [accounting] stale_mark_ms, or never reported; usable() is neither.

◆ index()

template<class Engine >
RefPrice fastmm::StrategyContext< Engine >::index ( InstrumentId  id) const
inlinenoexcept

◆ funding()

template<class Engine >
FundingView fastmm::StrategyContext< Engine >::funding ( InstrumentId  id) const
inlinenoexcept

The venue's funding of a perpetual: the rate it will apply at next, per interval, and over(d), the rate over a holding time d.

stale against [accounting] stale_funding_ms.

◆ perp_state()

template<class Engine >
const PerpRow & fastmm::StrategyContext< Engine >::perp_state ( InstrumentId  id) const
inlinenoexcept

Every field as last reported, open interest included, without the staleness applied.

◆ rng()

template<class Engine >
Xoshiro256ss & fastmm::StrategyContext< Engine >::rng ( )
inlinenoexcept