FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
backtest_runner.hpp
Go to the documentation of this file.
1#pragma once
2// BacktestRunner (8.4): wires Engine<S, SimClock, SimTransport, InlineFeed> to a SimDriver
3// and collects a BacktestResult. Two entry points share one BacktestSession:
4//
5// run_backtest<MyStrategy>(cfg, source) // template: no registration needed
6// run_backtest(cfg, "basic_mm", source) // registry: apps, Python, sweeps
7//
8// `source == nullptr` selects the synthetic market: with the matching fill model the
9// MarketGenerator is coupled to the venue (strategy orders rest in the same book as the
10// synthetic flow); with the L2 queue model a SyntheticSource stream is replayed exactly like
11// historical data. A non-null source is read from its current position (reset() it first to
12// reuse one).
17#include "fastmm/core/engine_runner.hpp"
18#include "fastmm/sim/sim_backend.hpp"
20
21#include <memory>
22#include <string_view>
23
24namespace fastmm::bt {
25
26class BacktestSession {
27 public:
28 // `schema`: the strategy's parameters, recorded in cfg.journal_out (may be null).
29 // `strategy_meta`: `key=value` lines recorded in cfg.journal_out (Python strategies).
31 MdSource* source,
32 const ParamSchema* schema = nullptr,
33 std::string_view strategy_meta = {});
35 BacktestSession(const BacktestSession&) = delete;
38 [[nodiscard]] RunnerDeps& deps() noexcept { return deps_; }
39 [[nodiscard]] sim::SimBackend& backend() noexcept { return *backend_; }
40 // Parameter updates delivered at simulated times during run() (not owned; may be null).
41 void set_param_schedule(sim::ParamSchedule* schedule) noexcept { params_ = schedule; }
42 // Code run at simulated times during run() (sim::SimDriver::set_slow_hooks).
43 void set_slow_hooks(const sim::SlowHooks& hooks) noexcept { slow_ = hooks; }
44 // Runs to the end of the data / horizon. `runner` (may be null) supplies engine stats and, with
45 // [strategy] state_file, the strategy's state to write at the end.
46 BacktestResult run(const sim::EngineHooks& hooks,
47 IEngineRunner* runner,
48 std::string_view strategy_name);
49
50 private:
51 struct Impl;
52 BacktestConfig cfg_;
53 MdSource* source_;
54 std::unique_ptr<SyntheticSource> synthetic_;
55 std::unique_ptr<sim::MarketGenerator> generator_;
56 std::unique_ptr<sim::SimBackend> backend_;
57 // initial_state = journal: the positions the recorded session started with, and where they and
58 // the strategy's state came from.
59 std::vector<ReconcileMsg> start_positions_;
60 std::string start_note_;
61 // params_from_journal: the session's updates on this strategy's schema, and the schedule they go
62 // to when the caller sets none.
63 std::vector<ParamUpdateMsg> journal_params_;
64 std::unique_ptr<sim::ParamSchedule> own_params_;
65 std::unique_ptr<Impl> impl_;
66 RunnerDeps deps_;
67 sim::ParamSchedule* params_ = nullptr;
68 sim::SlowHooks slow_{};
69};
70
71template <StrategyLike S>
72BacktestResult run_backtest(const BacktestConfig& cfg, MdSource* source = nullptr) {
73 BacktestSession session(cfg, source, &S::schema());
74 std::unique_ptr<IEngineRunner> runner = session.backend().template make_runner<S>(session.deps());
75 return session.run(session.backend().hooks, runner.get(), S::name());
76}
77
78// Registry path (registers the built-in strategies first). Throws std::invalid_argument for
79// an unknown strategy or bad parameters.
80BacktestResult run_backtest(const BacktestConfig& cfg,
81 std::string_view strategy,
82 MdSource* source = nullptr);
83
84// Convenience wrapper that owns the config.
85template <StrategyLike S>
86class BacktestRunner {
87 public:
88 explicit BacktestRunner(BacktestConfig cfg) : cfg_(std::move(cfg)) {}
89 [[nodiscard]] BacktestConfig& config() noexcept { return cfg_; }
90 [[nodiscard]] const BacktestConfig& config() const noexcept { return cfg_; }
91 BacktestResult run(MdSource* source = nullptr) { return run_backtest<S>(cfg_, source); }
93 private:
94 BacktestConfig cfg_;
95};
96
97// The SyntheticSource a run with `source == nullptr` replays under the L2 queue fill model.
99
100// Resolves `--data` through the data-source registry (data_registry.hpp): "<name>:<args>",
101// or a bare *.fmj / *.csv path. "synthetic" (and "") open to nullptr, which selects the market
102// generator. `instruments` lets a source map its symbols onto instrument ids; it may be null.
103// Throws std::runtime_error for an unknown source, bad options or unreadable files.
104[[nodiscard]] std::unique_ptr<MdSource> open_data(std::string_view spec,
105 const InstrumentTable* instruments = nullptr);
106// Source for [backtest] source / path. `source` is a whole spec ("binance:BTCUSDT:2024-03-27");
107// a bare name plus `path` ("journal" + "x.fmj") is the same thing written as two keys.
108[[nodiscard]] std::unique_ptr<MdSource> open_source(const BacktestConfig& cfg);
109
110} // namespace fastmm::bt
BacktestResult (8.4): structure-of-arrays rows (numpy-friendly: each column is one contiguous vector)...
BacktestConfig: everything a run needs, assembled from the TOML sections [engine] [[instruments]] [st...
Dense-by-id table built at startup; symbol lookup is a sorted FlatMap keyed by (venue,...
Definition instrument.hpp:141
Definition params.hpp:102
Convenience wrapper that owns the config.
Definition backtest_runner.hpp:88
BacktestResult run(MdSource *source=nullptr)
Definition backtest_runner.hpp:93
BacktestConfig & config() noexcept
Definition backtest_runner.hpp:91
Definition backtest_runner.hpp:28
void set_slow_hooks(const sim::SlowHooks &hooks) noexcept
Code run at simulated times during run() (sim::SimDriver::set_slow_hooks).
Definition backtest_runner.hpp:45
RunnerDeps & deps() noexcept
Definition backtest_runner.hpp:40
BacktestResult run(const sim::EngineHooks &hooks, IEngineRunner *runner, std::string_view strategy_name)
Runs to the end of the data / horizon.
BacktestSession & operator=(const BacktestSession &)=delete
sim::SimBackend & backend() noexcept
Definition backtest_runner.hpp:41
void set_param_schedule(sim::ParamSchedule *schedule) noexcept
Parameter updates delivered at simulated times during run() (not owned; may be null).
Definition backtest_runner.hpp:43
Definition param_schedule.hpp:33
DataSource (8.4): a timestamp-ordered stream of normalized market-data events consumed by the simulat...
Definition backtest_config.hpp:39
std::unique_ptr< MdSource > open_data(std::string_view spec, const InstrumentTable *instruments=nullptr)
Resolves --data through the data-source registry (data_registry.hpp): "<name>:<args>",...
SyntheticSourceConfig synthetic_source_config(const BacktestConfig &cfg)
The SyntheticSource a run with source == nullptr replays under the L2 queue fill model.
BacktestResult run_backtest(const BacktestConfig &cfg, MdSource *source=nullptr)
Definition backtest_runner.hpp:74
std::unique_ptr< MdSource > open_source(const BacktestConfig &cfg)
Source for [backtest] source / path.
Strategy registry (8.6, ADR-0012): name -> parameter schema + one factory per transport kind,...
Everything a factory needs that is backend-independent.
Definition registry.hpp:51
Definition backtest_config.hpp:48
Definition result.hpp:113
Definition synthetic_source.hpp:20
SyntheticSource: a MarketGenerator run against its own MatchingEngine, published through MdAggregator...