FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
replay.hpp
Go to the documentation of this file.
1#pragma once
2// Deterministic replay (5.11): runs Engine<S, SimClock, ReplayTransport, JournalFeed> over a
3// session journal recorded by fastmm-live, a sim or a backtest run (BacktestConfig::journal_out)
4// and proves that the engine reproduces the recorded outbound stream bit for bit.
5//
6// A format v2 journal carries what a replay needs besides the events: the engine clock of every
7// event, the session epoch, quoting enabled (dry run), the RNG seed, per-venue cancel-replace and
8// the effective configuration. replay_journal(path) uses all of it; replay_journal(path, cfg)
9// takes the engine and strategy configuration from `cfg` (what-if runs) and still restores the
10// session settings from the header.
11//
12// journal (inbound events + Out* copies) --JournalFeed--> engine --ReplayTransport--> sha256
13//
14// A replay passes when the replayed and recorded message counts and SHA-256 hashes are equal
15// and no message differed (ReplayResult::ok()). A different strategy or parameters turn the
16// same call into a what-if run (ok() is then expected to be false).
18#include "fastmm/core/engine_runner.hpp"
21
22#include <cstdint>
23#include <functional>
24#include <memory>
25#include <string>
26
27namespace fastmm::bt {
28
29struct ReplayOptions {
30 std::string strategy; // empty -> the strategy recorded in the journal header
31 bool verify = true; // compare every outbound message with the journal's Out* records
32 // Restore session epoch, quoting enabled, RNG seed and per-venue cancel-replace from a v2
33 // header (a journal without them replays with the given configuration's values).
34 bool session_from_journal = true;
35 // Apply the journal's ParamUpdate records, their fields matched to the strategy's parameters by
36 // name (false: skip them and keep the configured parameters, a what-if run).
37 bool param_updates = true;
38 // Replay a journal whose writer never closed it (no trailer) or whose last block is corrupt.
39 // The events before the damage are intact, so a replay of them runs and the outbound comparison
40 // stops early; by default such a file is refused rather than compared against a stream that was
41 // cut off. fastmm-replay --allow-incomplete sets it and warns instead.
42 bool allow_incomplete = false;
43};
45struct ReplayResult {
46 std::string strategy;
47 std::string outbound_sha256; // what the replayed engine sent
48 std::string recorded_sha256; // the journal's Out* records
49 std::uint64_t outbound_messages = 0;
50 std::uint64_t recorded_messages = 0;
51 std::uint64_t events = 0; // inbound events replayed
52 std::int64_t first_mismatch = -1; // index of the first differing message (verify only)
53 std::string expected_message; // summaries at first_mismatch ("(none)" past the end)
54 std::string actual_message;
55 bool session_restored = false; // the header's session settings were applied
56 bool incomplete = false; // the journal has no trailer or a damaged tail block
57 [[nodiscard]] bool ok() const noexcept {
63struct JournalInfo {
64 // The file was closed cleanly: it ends in a trailer and no block was discarded. False means the
65 // writer died or ran out of space and the tail of the session is missing.
66 bool complete = true;
67 std::string strategy;
68 std::uint32_t version = 0;
69 std::uint64_t rng_seed = 0;
70 std::uint64_t config_hash = 0;
71 std::int64_t start_ts = 0;
72 std::uint64_t messages = 0;
73 std::uint64_t outbound_messages = 0; // > 0 == session journal, 0 == market data only
74 std::uint64_t dropped_outbound = 0; // of which the transport did not accept
75 std::uint64_t market_data_messages = 0;
76 bool has_session = false; // v2 session settings below are valid
77 std::uint16_t session_epoch = 0;
78 bool quoting_enabled = true;
79 std::uint64_t replace_venues = 0;
80 bool engine_time = false; // the events carry the engine clock
81 std::string config_toml; // embedded effective configuration (empty: none)
82 std::string strategy_meta; // `key=value` lines about the strategy (empty: none)
83};
85// A strategy outside the registry (a Python hot strategy): the name for the result, the parameter
86// schema that ParamUpdate fields are matched against, and a factory that builds the runner on the
87// sim::ReplayBackend that `deps.backend` points at.
88struct ReplayStrategy {
89 std::string name;
90 const ParamSchema* schema = nullptr;
91 std::function<std::unique_ptr<IEngineRunner>(RunnerDeps& deps)> make;
92};
94// Throws std::runtime_error when the file cannot be opened / validated.
95[[nodiscard]] JournalInfo inspect_journal(const std::string& path);
96
97// The configuration embedded in the journal. Throws std::runtime_error when there is none (v1
98// journals, market-data journals, hand-built backtest configurations) or it does not parse.
99[[nodiscard]] BacktestConfig journal_config(const std::string& path);
100
101// One-line description of an Out* message (type, ids, side, price, quantity, stamp).
102[[nodiscard]] std::string describe_outbound(const EventHeader& h);
103
104// `cfg` supplies the engine configuration and strategy parameters (it must match the
105// recording run for a verifying replay); the instrument table is taken from the journal.
106// Throws std::runtime_error / std::invalid_argument on unreadable journals or unknown
107// strategies.
108[[nodiscard]] ReplayResult replay_journal(const std::string& path,
109 const BacktestConfig& cfg,
110 const ReplayOptions& opt = {});
111// Replays `strategy` instead of a registered one (opt.strategy is ignored).
112[[nodiscard]] ReplayResult replay_journal(const std::string& path,
113 const BacktestConfig& cfg,
114 const ReplayOptions& opt,
115 const ReplayStrategy& strategy);
116// Replays with the journal's embedded configuration (journal_config(path)).
117[[nodiscard]] ReplayResult replay_journal(const std::string& path, const ReplayOptions& opt = {});
118
119} // namespace fastmm::bt
BacktestConfig: everything a run needs, assembled from the TOML sections [engine] [[instruments]] [st...
Definition params.hpp:102
Definition backtest_config.hpp:39
JournalInfo inspect_journal(const std::string &path)
Throws std::runtime_error when the file cannot be opened / validated.
std::string describe_outbound(const EventHeader &h)
One-line description of an Out* message (type, ids, side, price, quantity, stamp).
BacktestConfig journal_config(const std::string &path)
The configuration embedded in the journal.
ReplayResult replay_journal(const std::string &path, const BacktestConfig &cfg, const ReplayOptions &opt={})
cfg supplies the engine configuration and strategy parameters (it must match the recording run for a ...
Strategy parameter schema (8.6, ADR-0012).
Strategy registry (8.6, ADR-0012): name -> parameter schema + one factory per transport kind,...
Definition messages.hpp:37
Everything a factory needs that is backend-independent.
Definition registry.hpp:51
Definition backtest_config.hpp:48
Definition replay.hpp:65
std::uint16_t session_epoch
Definition replay.hpp:79
std::uint64_t outbound_messages
> 0 == session journal, 0 == market data only
Definition replay.hpp:75
std::string strategy
Definition replay.hpp:69
std::uint64_t replace_venues
Definition replay.hpp:81
std::uint32_t version
Definition replay.hpp:70
std::uint64_t messages
Definition replay.hpp:74
std::uint64_t market_data_messages
Definition replay.hpp:77
std::string strategy_meta
key=value lines about the strategy (empty: none)
Definition replay.hpp:84
bool complete
The file was closed cleanly: it ends in a trailer and no block was discarded.
Definition replay.hpp:68
bool has_session
v2 session settings below are valid
Definition replay.hpp:78
bool engine_time
the events carry the engine clock
Definition replay.hpp:82
std::int64_t start_ts
Definition replay.hpp:73
std::uint64_t rng_seed
Definition replay.hpp:71
bool quoting_enabled
Definition replay.hpp:80
std::uint64_t config_hash
Definition replay.hpp:72
std::string config_toml
embedded effective configuration (empty: none)
Definition replay.hpp:83
std::uint64_t dropped_outbound
of which the transport did not accept
Definition replay.hpp:76
Definition replay.hpp:31
bool param_updates
Apply the journal's ParamUpdate records, their fields matched to the strategy's parameters by name (f...
Definition replay.hpp:39
bool allow_incomplete
Replay a journal whose writer never closed it (no trailer) or whose last block is corrupt.
Definition replay.hpp:44
bool verify
compare every outbound message with the journal's Out* records
Definition replay.hpp:33
bool session_from_journal
Restore session epoch, quoting enabled, RNG seed and per-venue cancel-replace from a v2 header (a jou...
Definition replay.hpp:36
std::string strategy
empty -> the strategy recorded in the journal header
Definition replay.hpp:32
Definition replay.hpp:47
std::string expected_message
summaries at first_mismatch ("(none)" past the end)
Definition replay.hpp:55
bool incomplete
the journal has no trailer or a damaged tail block
Definition replay.hpp:58
bool session_restored
the header's session settings were applied
Definition replay.hpp:57
std::string strategy
Definition replay.hpp:48
std::uint64_t events
inbound events replayed
Definition replay.hpp:53
std::string outbound_sha256
what the replayed engine sent
Definition replay.hpp:49
bool ok() const noexcept
Definition replay.hpp:59
std::string recorded_sha256
the journal's Out* records
Definition replay.hpp:50
std::uint64_t outbound_messages
Definition replay.hpp:51
std::int64_t first_mismatch
index of the first differing message (verify only)
Definition replay.hpp:54
std::string actual_message
Definition replay.hpp:56
std::uint64_t recorded_messages
Definition replay.hpp:52
A strategy outside the registry (a Python hot strategy): the name for the result, the parameter schem...
Definition replay.hpp:90
std::string name
Definition replay.hpp:91
const ParamSchema * schema
Definition replay.hpp:92
std::function< std::unique_ptr< IEngineRunner >(RunnerDeps &deps)> make
Definition replay.hpp:93