#pragma once #include "core/types.hpp" #include "core/order_book.hpp" #include "risk/risk_manager.hpp" #include "journal/journal.hpp" #include "strategy/strategy.hpp" #include #include #include #include #include #include namespace hft { struct BacktestResult { std::string strategy_name; int64_t ticks_processed = 0; int64_t orders_submitted = 0; int64_t orders_filled = 0; int64_t orders_rejected = 0; int64_t trades_count = 0; double total_pnl = 0; double realized_pnl = 0; double unrealized_pnl = 0; double max_drawdown = 0; double sharpe = 0; LatencyStats order_latency; LatencyStats tick_latency; double throughput_eps = 0; std::vector equity_curve; std::vector trades; }; class ExchangeSimulator { public: explicit ExchangeSimulator(RiskLimits limits = {}); void add_symbol(const std::string& symbol); struct SubmitResult { bool approved; std::string reject_reason; std::vector trades; }; // Fix: Takes const reference to avoid scope expiration SubmitResult submit_order(const Order& order, double market_price = 0.0); bool cancel_order(const std::string& symbol, OrderId id); bool modify_order(const std::string& symbol, OrderId id, Price new_price, Quantity new_qty); void on_tick(const MarketDataTick& tick); OrderBookSnapshot get_snapshot(const std::string& symbol, int depth = 10) const; std::vector symbols() const; Position get_position(const std::string& symbol) const; std::unordered_map all_positions() const; double total_pnl() const; RiskManager& risk() { return risk_; } void set_trade_callback(TradeCallback cb) { trade_cb_ = std::move(cb); } void set_order_callback(OrderCallback cb) { order_cb_ = std::move(cb); } LatencyStats& order_latency() { return order_lat_; } LatencyStats& tick_latency() { return tick_lat_; } int64_t total_orders() const { return total_orders_.load(std::memory_order_relaxed); } int64_t total_trades() const { return total_trades_.load(std::memory_order_relaxed); } int64_t total_rejects() const { return total_rejects_.load(std::memory_order_relaxed); } OrderId next_order_id() { return ++next_oid_; } private: std::unordered_map> books_; // Fix: Correct key type and properly controls memory lifetime std::unordered_map> order_store_; RiskManager risk_; BinaryJournal journal_; mutable std::mutex mtx_; TradeCallback trade_cb_; OrderCallback order_cb_; std::atomic next_oid_{1000}; LatencyStats order_lat_, tick_lat_; // Fix: Atomic counters for thread-safe operations in main.cpp std::atomic total_orders_{0}; std::atomic total_trades_{0}; std::atomic total_rejects_{0}; }; class Backtester { public: explicit Backtester(RiskLimits limits = {}); void set_strategy(std::unique_ptr strategy); void add_symbol(const std::string& symbol); BacktestResult run(const std::vector& ticks, bool enable_journal = true, const std::string& journal_path = "replay.journal"); private: std::unique_ptr strategy_; std::unique_ptr sim_; RiskLimits limits_; std::vector symbols_; void process_signals(const std::vector& sigs, const MarketDataTick& tick, BacktestResult& result, std::unordered_map& live_orders); }; } // namespace hft