FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
result.hpp
Go to the documentation of this file.
1#pragma once
2// BacktestResult (8.4): structure-of-arrays rows (numpy-friendly: each column is one
3// contiguous vector) plus the summary Metrics and the raw counters of every component.
4// Prices, quantities and notionals are raw 1e-8 fixed-point int64; the CSV/JSON writers
5// format them as exact decimals.
7#include "fastmm/core/engine_runner.hpp"
8#include "fastmm/sim/sim_transport.hpp"
9#include "fastmm/sim/sim_treasury.hpp"
11
12#include <cstdint>
13#include <string>
14#include <vector>
15
16namespace fastmm::bt {
17
18struct FillRows {
19 std::vector<std::int64_t> ts; // venue time of the execution
20 std::vector<std::uint32_t> instrument;
21 std::vector<std::int8_t> side; // 0 buy / 1 sell
22 std::vector<std::int64_t> price; // raw 1e-8
23 std::vector<std::int64_t> qty;
24 std::vector<std::int64_t> fee; // raw notional, negative == rebate
25 std::vector<std::uint64_t> cl_ord_id;
26 std::vector<std::uint8_t> liquidity; // Liquidity: 1 maker, 2 taker
27 std::vector<std::int64_t> mid; // venue mid at fill time (raw)
28 std::vector<std::int64_t> best_bid; // venue touch at fill time (raw); 0 when that side is empty
29 std::vector<std::int64_t> best_ask;
30 // Displayed quantity still ahead of the order when it filled (raw); -1 when the fill model
31 // does not track a queue position (FillModel::Matching).
32 std::vector<std::int64_t> queue_ahead;
33 // Markout horizons, in nanoseconds of simulated time, and the venue mid of the fill's
34 // instrument at fill ts + horizon (raw). markout_mid[h][i] is 0 when the run ended before the
35 // horizon or the book had no two sides there: that fill is excluded from the horizon, never
36 // marked at a substitute price.
37 std::vector<std::int64_t> markout_horizon_ns;
38 std::vector<std::vector<std::int64_t>> markout_mid;
40 [[nodiscard]] std::size_t size() const noexcept { return ts.size(); }
41 void reserve(std::size_t n);
42};
44// One instrument's columns of EquityRows, one row per bar.
46 std::vector<std::int64_t> pnl; // raw notional, realized + unrealized - fees, settlement ccy
47 std::vector<std::int64_t> position; // raw qty
48 std::vector<std::int64_t> mid; // raw price, venue mid
49 std::vector<std::uint8_t> quoted; // bit 0 bid resting, bit 1 ask resting
50};
52struct EquityRows {
53 std::vector<std::int64_t> ts; // bar end
54 std::vector<std::int64_t> realized; // raw notional, all instruments
55 std::vector<std::int64_t> unrealized;
56 std::vector<std::int64_t> fees;
57 std::vector<std::int64_t> position; // raw qty, net over all instruments
58 std::vector<std::int64_t> mid; // raw price, instrument 0
59 std::vector<std::uint8_t> quoted; // bit 0 bid resting, bit 1 ask resting (instrument 0)
60 std::vector<InstrumentEquityRows> by_instrument; // indexed by instrument id
61 [[nodiscard]] std::size_t size() const noexcept { return ts.size(); }
62 [[nodiscard]] std::int64_t equity(std::size_t i) const noexcept {
63 return realized[i] + unrealized[i] - fees[i];
64 }
65 void reserve(std::size_t n);
66};
68inline constexpr std::uint8_t kOrderKindNew = 0;
69inline constexpr std::uint8_t kOrderKindCancel = 1;
70inline constexpr std::uint8_t kOrderKindReplace = 2;
72struct OrderRows {
73 std::vector<std::int64_t> ts; // engine send time (virtual)
74 std::vector<std::int64_t> venue_ts; // arrival at the venue; 0 when dropped
75 std::vector<std::int64_t> trigger_ts; // T0 of the event that caused the order (0 unknown)
76 std::vector<std::uint64_t> cl_ord_id;
77 std::vector<std::uint32_t> instrument;
78 std::vector<std::int8_t> side; // 0 buy / 1 sell / -1 n/a (cancel, replace)
79 std::vector<std::int64_t> price;
80 std::vector<std::int64_t> qty;
81 std::vector<std::uint8_t> kind; // kOrderKindNew / Cancel / Replace
82 std::vector<std::uint8_t> type; // OrderType (new orders)
83 [[nodiscard]] std::size_t size() const noexcept { return ts.size(); }
84 void reserve(std::size_t n);
85};
87// Wall time of one slow method of a Python strategy over a backtest.
88struct SlowMethodTiming {
89 std::string name;
90 std::uint64_t calls = 0;
91 std::uint64_t wall_p50_ns = 0;
92 std::uint64_t wall_p99_ns = 0;
93 std::uint64_t wall_max_ns = 0;
94};
96// The pool treasuries of a run ([venues.<primary>.treasury]), summed over the pools, and every
97// transfer the simulated venue carried out or refused.
98struct BacktestTreasury {
99 std::uint32_t pools = 0;
100 std::uint64_t sent = 0;
101 std::uint64_t done = 0;
102 std::uint64_t failed = 0;
103 std::uint64_t timed_out = 0;
104 std::uint64_t limited = 0; // plans the limits held back
105 std::uint64_t dry_run_plans = 0;
106 std::vector<sim::SimTransferRecord> transfers;
107 // The amount the carried-out transfers moved in `asset` (raw).
108 [[nodiscard]] std::int64_t moved(std::string_view asset) const noexcept;
109};
111struct BacktestResult {
112 std::string strategy;
114 std::uint64_t seed = 0;
119 RunnerStats engine; // the engine's own counters and positions
120 sim::SimTransportStats transport;
121 std::string outbound_sha256;
122 std::uint64_t outbound_messages = 0;
123 std::uint64_t md_events = 0; // market-data messages delivered to the engine
124 // Recorded events the venue took ahead of one recorded before them (venue-time order), and those
125 // that still came after a later-stamped one (received more than reorder_window_ms late).
126 std::uint64_t md_reordered = 0;
127 std::uint64_t md_late = 0;
128 std::uint64_t engine_steps = 0;
129 std::int64_t start_ts = 0;
130 std::int64_t end_ts = 0;
131 double wall_seconds = 0.0;
132 // Slow methods of a Python strategy (the Python package fills this in; empty otherwise).
133 std::vector<SlowMethodTiming> slow_methods;
134 // The pool treasuries; `pools` is 0 without one.
136
137 [[nodiscard]] const Metrics& summary() const noexcept { return metrics; }
138 // Whether the global kill switch stopped the run ([risk] max_loss, a failing hook, ...), and
139 // when: seconds of simulated time after start_ts.
140 [[nodiscard]] bool killed() const noexcept { return engine.kill_reason != KillReason::None; }
141 [[nodiscard]] double kill_at_s() const noexcept {
142 return static_cast<double>(engine.kill_ts_ns - start_ts) / 1e9;
144 // Human-readable table, one metric per line.
145 [[nodiscard]] std::string summary_table() const;
146 [[nodiscard]] std::string summary_json() const;
147 [[nodiscard]] std::string equity_csv() const;
148 [[nodiscard]] std::string fills_csv() const;
149 [[nodiscard]] std::string orders_csv() const;
150 // One row per simulated transfer: ts_ns,from,to,asset,amount,state,client_id.
151 [[nodiscard]] std::string transfers_csv() const;
152 // Writes equity.csv, fills.csv, orders.csv and summary.json into `dir` (created if needed), and
153 // transfers.csv with a pool treasury.
154 // Returns false on I/O failure.
155 [[nodiscard]] bool write_all(const std::string& dir) const;
156};
158} // namespace fastmm::bt
Metrics (8.4) computed from the result rows: equity bars (1 s by default), fills and orders.
Definition backtest_config.hpp:39
constexpr std::uint8_t kOrderKindCancel
Definition result.hpp:71
constexpr std::uint8_t kOrderKindReplace
Definition result.hpp:72
constexpr std::uint8_t kOrderKindNew
Definition result.hpp:70
std::map< std::string, std::string > ParamMap
Definition params.hpp:119
Strategy parameter schema (8.6, ADR-0012).
Definition result.hpp:113
std::uint64_t md_events
market-data messages delivered to the engine
Definition result.hpp:125
std::string summary_table() const
Human-readable table, one metric per line.
std::string outbound_sha256
Definition result.hpp:123
std::string fills_csv() const
Metrics metrics
Definition result.hpp:120
std::uint64_t md_reordered
Recorded events the venue took ahead of one recorded before them (venue-time order),...
Definition result.hpp:128
std::int64_t start_ts
Definition result.hpp:131
std::uint64_t engine_steps
Definition result.hpp:130
const Metrics & summary() const noexcept
Definition result.hpp:139
std::uint64_t md_late
Definition result.hpp:129
bool killed() const noexcept
Whether the global kill switch stopped the run ([risk] max_loss, a failing hook, ....
Definition result.hpp:142
bool write_all(const std::string &dir) const
Writes equity.csv, fills.csv, orders.csv and summary.json into dir (created if needed),...
FillRows fills
Definition result.hpp:117
std::string summary_json() const
EquityRows equity
Definition result.hpp:118
std::string orders_csv() const
std::string strategy
Definition result.hpp:114
BacktestTreasury treasury
The pool treasuries; pools is 0 without one.
Definition result.hpp:137
RunnerStats engine
the engine's own counters and positions
Definition result.hpp:121
double kill_at_s() const noexcept
Definition result.hpp:143
sim::SimTransportStats transport
Definition result.hpp:122
std::int64_t end_ts
Definition result.hpp:132
std::string equity_csv() const
std::vector< SlowMethodTiming > slow_methods
Slow methods of a Python strategy (the Python package fills this in; empty otherwise).
Definition result.hpp:135
std::uint64_t outbound_messages
Definition result.hpp:124
ParamMap params
Definition result.hpp:115
OrderRows orders
Definition result.hpp:119
std::string transfers_csv() const
One row per simulated transfer: ts_ns,from,to,asset,amount,state,client_id.
std::uint64_t seed
Definition result.hpp:116
double wall_seconds
Definition result.hpp:133
The pool treasuries of a run ([venues.
Definition result.hpp:100
std::uint64_t failed
Definition result.hpp:104
std::uint64_t timed_out
Definition result.hpp:105
std::uint64_t done
Definition result.hpp:103
std::uint32_t pools
Definition result.hpp:101
std::vector< sim::SimTransferRecord > transfers
Definition result.hpp:108
std::uint64_t limited
plans the limits held back
Definition result.hpp:106
std::uint64_t sent
Definition result.hpp:102
std::uint64_t dry_run_plans
Definition result.hpp:107
std::int64_t moved(std::string_view asset) const noexcept
The amount the carried-out transfers moved in asset (raw).
Definition result.hpp:54
std::vector< std::int64_t > unrealized
Definition result.hpp:57
std::size_t size() const noexcept
Definition result.hpp:63
std::vector< InstrumentEquityRows > by_instrument
indexed by instrument id
Definition result.hpp:62
std::vector< std::int64_t > realized
raw notional, all instruments
Definition result.hpp:56
void reserve(std::size_t n)
std::vector< std::int64_t > ts
bar end
Definition result.hpp:55
std::vector< std::int64_t > position
raw qty, net over all instruments
Definition result.hpp:59
std::vector< std::int64_t > fees
Definition result.hpp:58
std::vector< std::uint8_t > quoted
bit 0 bid resting, bit 1 ask resting (instrument 0)
Definition result.hpp:61
std::vector< std::int64_t > mid
raw price, instrument 0
Definition result.hpp:60
std::int64_t equity(std::size_t i) const noexcept
Definition result.hpp:64
Definition result.hpp:20
std::vector< std::int64_t > qty
Definition result.hpp:25
std::vector< std::int64_t > best_bid
venue touch at fill time (raw); 0 when that side is empty
Definition result.hpp:30
std::vector< std::int64_t > price
raw 1e-8
Definition result.hpp:24
std::vector< std::uint8_t > liquidity
Liquidity: 1 maker, 2 taker.
Definition result.hpp:28
std::vector< std::int64_t > queue_ahead
Displayed quantity still ahead of the order when it filled (raw); -1 when the fill model does not tra...
Definition result.hpp:34
std::vector< std::uint32_t > instrument
Definition result.hpp:22
void reserve(std::size_t n)
std::size_t size() const noexcept
Definition result.hpp:42
std::vector< std::uint64_t > cl_ord_id
Definition result.hpp:27
std::vector< std::int64_t > ts
venue time of the execution
Definition result.hpp:21
std::vector< std::int64_t > fee
raw notional, negative == rebate
Definition result.hpp:26
std::vector< std::vector< std::int64_t > > markout_mid
Definition result.hpp:40
std::vector< std::int64_t > best_ask
Definition result.hpp:31
std::vector< std::int64_t > markout_horizon_ns
Markout horizons, in nanoseconds of simulated time, and the venue mid of the fill's instrument at fil...
Definition result.hpp:39
std::vector< std::int64_t > mid
venue mid at fill time (raw)
Definition result.hpp:29
std::vector< std::int8_t > side
0 buy / 1 sell
Definition result.hpp:23
One instrument's columns of EquityRows, one row per bar.
Definition result.hpp:47
std::vector< std::int64_t > position
raw qty
Definition result.hpp:49
std::vector< std::int64_t > mid
raw price, venue mid
Definition result.hpp:50
std::vector< std::int64_t > pnl
raw notional, realized + unrealized - fees, settlement ccy
Definition result.hpp:48
std::vector< std::uint8_t > quoted
bit 0 bid resting, bit 1 ask resting
Definition result.hpp:51
Definition metrics.hpp:70
Definition result.hpp:74
std::vector< std::int64_t > price
Definition result.hpp:81
std::vector< std::uint32_t > instrument
Definition result.hpp:79
std::vector< std::int64_t > qty
Definition result.hpp:82
std::vector< std::int64_t > venue_ts
arrival at the venue; 0 when dropped
Definition result.hpp:76
std::vector< std::int8_t > side
0 buy / 1 sell / -1 n/a (cancel, replace)
Definition result.hpp:80
std::vector< std::int64_t > trigger_ts
T0 of the event that caused the order (0 unknown)
Definition result.hpp:77
void reserve(std::size_t n)
std::vector< std::uint8_t > kind
kOrderKindNew / Cancel / Replace
Definition result.hpp:83
std::vector< std::uint8_t > type
OrderType (new orders)
Definition result.hpp:84
std::vector< std::int64_t > ts
engine send time (virtual)
Definition result.hpp:75
std::size_t size() const noexcept
Definition result.hpp:85
std::vector< std::uint64_t > cl_ord_id
Definition result.hpp:78
Wall time of one slow method of a Python strategy over a backtest.
Definition result.hpp:90
std::uint64_t calls
Definition result.hpp:92
std::string name
Definition result.hpp:91
std::uint64_t wall_p99_ns
Definition result.hpp:94
std::uint64_t wall_max_ns
Definition result.hpp:95
std::uint64_t wall_p50_ns
Definition result.hpp:93