41#include "fastmm/core/timer_wheel.hpp"
89#define FASTMM_STRATEGY_HOOKS(X) \
90 X(Start, on_start, "start", (Ctx & ctx), (ctx), "void on_start(auto& ctx)") \
91 X(Stop, on_stop, "stop", (Ctx & ctx), (ctx), "void on_stop(auto& ctx)") \
95 (Ctx & ctx, InstrumentId id, const Book& book), \
97 "void on_book(auto& ctx, InstrumentId id, const auto& book)") \
101 (Ctx & ctx, InstrumentId id, const BookTickerMsg& m), \
103 "void on_book_ticker(auto& ctx, InstrumentId id, const BookTickerMsg& m)") \
107 (Ctx & ctx, InstrumentId id, const TradeMsg& m), \
109 "void on_trade(auto& ctx, InstrumentId id, const TradeMsg& m)") \
113 (Ctx & ctx, InstrumentId id, const OptionTickerMsg& m), \
115 "void on_option_ticker(auto& ctx, InstrumentId id, const OptionTickerMsg& m)") \
119 (Ctx & ctx, const Fill& fill), \
121 "void on_fill(auto& ctx, const Fill& fill)") \
125 (Ctx & ctx, const OmsUpdate& u), \
127 "void on_order_update(auto& ctx, const OmsUpdate& u)") \
131 (Ctx & ctx, TimerId id, std::uint64_t tag), \
133 "void on_timer(auto& ctx, TimerId id, std::uint64_t tag)") \
137 (Ctx & ctx, const ConnectionStateMsg& m), \
139 "void on_connection(auto& ctx, const ConnectionStateMsg& m)") \
143 (Ctx & ctx, bool enabled), \
145 "void on_quoting(auto& ctx, bool enabled)") \
146 X(Params, on_params, "params", (Ctx & ctx), (ctx), "void on_params(auto& ctx)") \
150 (Ctx & ctx, const BalanceMsg& m), \
152 "void on_balance(auto& ctx, const BalanceMsg& m)") \
156 (Ctx & ctx, InstrumentId id, const PerpStateMsg& m), \
158 "void on_perp_state(auto& ctx, InstrumentId id, const PerpStateMsg& m)") \
162 (Ctx & ctx, const RiskReject& r), \
164 "void on_risk_reject(auto& ctx, const RiskReject& r)") \
165 X(BatchEnd, on_batch_end, "batch_end", (Ctx & ctx), (ctx), "void on_batch_end(auto& ctx)")
176concept KeepsState =
requires(S& s, std::string_view bytes) {
177 { s.state() } -> std::convertible_to<std::string_view>;
178 { s.restore(bytes) } -> std::same_as<bool>;
182#define FASTMM_STRATEGY_HOOK_NEAR_MISSES(Y) \
183 Y(on_fills, on_fill) \
184 Y(on_reject, on_risk_reject) \
185 Y(on_risk_rejected, on_risk_reject) \
186 Y(on_execution, on_fill) \
187 Y(on_trades, on_trade) \
188 Y(on_order_book, on_book) \
189 Y(on_orderbook, on_book) \
190 Y(on_book_update, on_book) \
191 Y(on_depth, on_book) \
192 Y(on_tick, on_book) \
193 Y(on_bbo, on_book_ticker) \
194 Y(on_ticker, on_book_ticker) \
195 Y(on_options_ticker, on_option_ticker) \
196 Y(on_order, on_order_update) \
197 Y(on_order_event, on_order_update) \
198 Y(on_timer_fired, on_timer) \
199 Y(on_connection_state, on_connection) \
200 Y(on_disconnect, on_connection) \
201 Y(on_init, on_start) \
202 Y(on_shutdown, on_stop) \
203 Y(on_quote, on_quoting) \
204 Y(on_param, on_params) \
205 Y(on_parameters, on_params) \
206 Y(on_balances, on_balance) \
207 Y(on_perp, on_perp_state) \
208 Y(on_funding, on_perp_state) \
209 Y(on_mark, on_perp_state) \
212 Y(onTrade, on_trade) \
215enum class Hook : std::uint8_t {
216#define FASTMM_HOOK_ENUM(E, name, word, params, args, sig) E,
218#undef FASTMM_HOOK_ENUM
233inline constexpr std::array<HookInfo, static_cast<std::size_t>(Hook::Count)>
kHooks{{
234#define FASTMM_HOOK_INFO(E, name, word, params, args, sig) {Hook::E, #name, word, sig},
236#undef FASTMM_HOOK_INFO
239namespace detail::hooks {
241#define FASTMM_HOOK_UNPAREN(...) __VA_ARGS__
248concept probeable = std::is_class_v<S> && !std::is_final_v<S>;
250#define FASTMM_HOOK_PROBE(name) \
251 struct probe_##name { \
255 struct name_probe_##name : S, probe_##name {}; \
257 concept declares_##name = probeable<S> && (!requires { &name_probe_##name<S>::name; });
259#define FASTMM_HOOK_CALL(E, name, word, params, args, sig) \
260 FASTMM_HOOK_PROBE(name) \
261 template <class S, class Ctx, class Book> \
262 concept calls_##name = requires(S& s, FASTMM_HOOK_UNPAREN params) { \
263 { s.name args } -> std::same_as<void>; \
266#undef FASTMM_HOOK_CALL
268#define FASTMM_HOOK_NEAR_MISS(name, hook) \
269 FASTMM_HOOK_PROBE(name) \
270 template <bool Found> \
271 struct near_miss_##name { \
272 static constexpr bool value = false; \
275 struct near_miss_##name<true> { \
276 [[deprecated("fastmm: " #name " is not a hook; did you mean " #hook "?")]] \
277 static constexpr bool value = true; \
280#undef FASTMM_HOOK_NEAR_MISS
281#undef FASTMM_HOOK_PROBE
284concept allows_near_miss_names =
requires {
requires S::fastmm_allow_near_miss_names; };
287struct StandInContext {};
288struct StandInBook {};
292template <
class S,
class Ctx,
class Book>
295#define FASTMM_HOOK_STATUS(E, name, word, params, args, sig) \
297 if (detail::hooks::calls_##name<S, Ctx, Book>) return HookStatus::Ok; \
298 return detail::hooks::declares_##name<S> ? HookStatus::Mismatch : HookStatus::Absent;
300#undef FASTMM_HOOK_STATUS
308template <
class S,
class Ctx,
class Book>
316 class Ctx = detail::hooks::StandInContext,
317 class Book = detail::hooks::StandInBook>
320#define FASTMM_HOOK_ASSERT(E, name, word, params, args, sig) \
321 const bool name##_declared = detail::hooks::declares_##name<S>; \
322 const bool name##_signature_matches = detail::hooks::calls_##name<S, Ctx, Book>; \
323 static_assert(!name##_declared || name##_signature_matches, \
324 "fastmm: " #name " has the wrong signature or is not public; expected " sig);
326#undef FASTMM_HOOK_ASSERT
327 const bool near_miss_names_allowed = detail::hooks::allows_near_miss_names<S>;
328#define FASTMM_HOOK_WARN(name, hook) \
329 static_cast<void>(detail::hooks::near_miss_##name < !near_miss_names_allowed && \
330 detail::hooks::declares_##name < S >> ::value);
332#undef FASTMM_HOOK_WARN
333 constexpr bool has_state =
requires(S& s) { s.state(); };
334 constexpr bool has_restore =
requires(S& s, std::string_view b) { s.restore(b); };
335 static_assert(has_state == has_restore,
336 "fastmm: state() and restore() go together; expected std::string_view state() and "
337 "bool restore(std::string_view)");
338 static_assert(!has_state || KeepsState<S>,
339 "fastmm: expected std::string_view state() and bool restore(std::string_view)");
343namespace detail::hooks {
345 std::array<char, 160> chars{};
346 std::size_t size = 0;
348template <
class S,
class Ctx,
class Book>
349inline constexpr HookSetText hook_set_text = [] {
351 for (
const HookInfo& h :
kHooks) {
352 if (!implements_hook<S, Ctx, Book>(h.hook))
continue;
353 if (t.size != 0) t.chars[t.size++] =
' ';
354 for (
const char c : h.word) t.chars[t.size++] = c;
361template <
class S,
class Ctx,
class Book>
363 const detail::hooks::HookSetText& t = detail::hooks::hook_set_text<S, Ctx, Book>;
364 return std::string_view(t.chars.data(), t.size);
Fixed<Tag>: int64 fixed point with a global 1e-8 scale (ADR-0001).
#define FASTMM_HOOK_STATUS(E, name, word, params, args, sig)
#define FASTMM_STRATEGY_HOOK_NEAR_MISSES(Y)
Y(misspelling, hook): names that produce a "did you mean" warning.
Definition hooks.hpp:184
#define FASTMM_HOOK_ASSERT(E, name, word, params, args, sig)
#define FASTMM_HOOK_NEAR_MISS(name, hook)
#define FASTMM_HOOK_WARN(name, hook)
#define FASTMM_HOOK_CALL(E, name, word, params, args, sig)
Definition hooks.hpp:261
#define FASTMM_HOOK_INFO(E, name, word, params, args, sig)
Event bus message structs (5.5).
Definition strategy.hpp:16
OrderType
Definition enums.hpp:23
constexpr bool implements_hook(Hook h) noexcept
True when the engine calls S's hook h (the engine dispatches on this at compile time).
Definition hooks.hpp:311
RejectReason
Ordered exactly like RiskEngine::check_new evaluates them (5.7), followed by OMS / transport / venue ...
Definition enums.hpp:123
Side
Definition enums.hpp:12
HookStatus
Absent: no member with the hook's name.
Definition hooks.hpp:226
StrongId< struct InstrumentTag, std::uint32_t > InstrumentId
Dense index into the engine's instrument table.
Definition strong_id.hpp:38
constexpr HookStatus hook_status(Hook h) noexcept
Definition hooks.hpp:295
Liquidity
Definition enums.hpp:434
constexpr std::string_view implemented_hooks() noexcept
The implemented hooks as words in table order ("start book fill timer connection quoting").
Definition hooks.hpp:364
constexpr std::array< HookInfo, static_cast< std::size_t >(Hook::Count)> kHooks
Definition hooks.hpp:235
Hook
Definition hooks.hpp:217
FASTMM_HOOK_ENUM(E, name, word, params, args, sig)
constexpr bool verify_strategy() noexcept
Compile-time check of every hook of S; always returns true (failures are static_asserts),...
Definition hooks.hpp:320
Order management (5.8): a Pool<Order> + OpenHashMap<ClientOrderId, Handle> + a ring of recently termi...
Strongly typed identifiers.
InstrumentId instrument
the order's instrument, else the fill message's
Definition hooks.hpp:57
Side side
the order's side, else the fill message's
Definition hooks.hpp:58
Liquidity liquidity
Definition hooks.hpp:65
Qty position_delta
signed change of the position; differs from qty when the commission is charged in the base asset
Definition hooks.hpp:61
Qty qty
Definition hooks.hpp:60
bool known
the id matched an order, open or recently terminal (update->order)
Definition hooks.hpp:66
bool late
the order was already terminal when the fill arrived
Definition hooks.hpp:67
Notional fee
quote currency, as booked
Definition hooks.hpp:63
const OmsUpdate * update
non-null when known
Definition hooks.hpp:69
const OrderFillMsg * msg
always set by the engine
Definition hooks.hpp:70
Price price
this execution
Definition hooks.hpp:59
bool fee_converted
false: commission in a third asset, not booked (counted in stats)
Definition hooks.hpp:64
bool order_done
the order reached a terminal state with this fill
Definition hooks.hpp:68
Hook hook
Definition hooks.hpp:229
std::string_view name
"on_trade"
Definition hooks.hpp:230
std::string_view signature
"void on_trade(auto\& ctx, InstrumentId id, const TradeMsg\& m)"
Definition hooks.hpp:232
std::string_view word
"trade" (start-up log)
Definition hooks.hpp:231
Definition messages.hpp:233
A new order or replace the engine's own risk check refused (RiskEngine, [risk]): nothing was sent and...
Definition hooks.hpp:76
Side side
Definition hooks.hpp:78
Timestamp time
Definition hooks.hpp:86
ClientOrderId order
Definition hooks.hpp:85
RejectReason reason
Definition hooks.hpp:80
Qty qty
Definition hooks.hpp:84
std::uint32_t user_tag
NewOrderRequest::user_tag; a quote's is QuoteManager::make_tag.
Definition hooks.hpp:82
OrderType type
Definition hooks.hpp:79
bool replace
a replace of order; else a new order and order is invalid
Definition hooks.hpp:81
Price price
Definition hooks.hpp:83
InstrumentId instrument
Definition hooks.hpp:77