File size: 3,947 Bytes
ba6114e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#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 <unordered_map>
#include <atomic>
#include <memory>
#include <mutex>
#include <deque>
#include <functional>

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<double> equity_curve;
    std::vector<Trade>  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<Trade> 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<std::string> symbols() const;

    Position get_position(const std::string& symbol) const;
    std::unordered_map<std::string, Position> 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<std::string, std::unique_ptr<OrderBook>> books_;
    // Fix: Correct key type and properly controls memory lifetime
    std::unordered_map<OrderId, std::unique_ptr<Order>> order_store_; 
    RiskManager risk_;
    BinaryJournal journal_;
    mutable std::mutex mtx_;

    TradeCallback trade_cb_;
    OrderCallback order_cb_;

    std::atomic<OrderId> next_oid_{1000};
    LatencyStats order_lat_, tick_lat_;
    
    // Fix: Atomic counters for thread-safe operations in main.cpp
    std::atomic<int64_t> total_orders_{0};
    std::atomic<int64_t> total_trades_{0};
    std::atomic<int64_t> total_rejects_{0};
};

class Backtester {
public:
    explicit Backtester(RiskLimits limits = {});

    void set_strategy(std::unique_ptr<IStrategy> strategy);
    void add_symbol(const std::string& symbol);

    BacktestResult run(const std::vector<MarketDataTick>& ticks,
                       bool enable_journal = true,
                       const std::string& journal_path = "replay.journal");



private:
    std::unique_ptr<IStrategy>  strategy_;
    std::unique_ptr<ExchangeSimulator> sim_;
    RiskLimits limits_;
    std::vector<std::string> symbols_;

    void process_signals(const std::vector<StrategySignal>& sigs,
                         const MarketDataTick& tick,
                         BacktestResult& result,
                         std::unordered_map<OrderId, Order>& live_orders);
};

} // namespace hft