#pragma once #include #include #include #include #include #include #include "portfolio.hpp" struct PerfReport { double total_return; double cagr; double sharpe; double max_drawdown; double volatility; double calmar; }; inline PerfReport compute_performance( const std::vector& eq, double initial_capital) { int n = static_cast(eq.size()); if (n < 2) return {}; // daily returns std::vector rets; rets.reserve(n - 1); for (int i = 1; i < n; ++i) rets.push_back((eq[i].value - eq[i-1].value) / eq[i-1].value); double mean_r = 0.0; for (double r : rets) mean_r += r; mean_r /= rets.size(); double var = 0.0; for (double r : rets) var += (r - mean_r) * (r - mean_r); var /= rets.size(); double std_r = std::sqrt(var); double total_return = (eq.back().value / initial_capital) - 1.0; // approximate years from bar count (252 trading days/year) double years = static_cast(n) / 252.0; double cagr = std::pow(eq.back().value / initial_capital, 1.0 / years) - 1.0; double sharpe = (std_r > 0) ? (mean_r / std_r) * std::sqrt(252.0) : 0.0; // max drawdown double peak = eq[0].value; double max_dd = 0.0; for (const auto& p : eq) { peak = std::max(peak, p.value); double dd = (p.value - peak) / peak; max_dd = std::min(max_dd, dd); } double vol = std_r * std::sqrt(252.0); double calmar = (max_dd != 0.0) ? cagr / std::abs(max_dd) : 0.0; return { total_return, cagr, sharpe, max_dd, vol, calmar }; } inline void print_report(const PerfReport& r) { auto pct = [](double v) { std::ostringstream s; s << std::fixed << std::setprecision(2) << v * 100.0 << "%"; return s.str(); }; auto f2 = [](double v) { std::ostringstream s; s << std::fixed << std::setprecision(2) << v; return s.str(); }; std::printf("── Performance ──────────────────────────\n"); std::printf(" %-22s %s\n", "Total return", pct(r.total_return).c_str()); std::printf(" %-22s %s\n", "CAGR", pct(r.cagr).c_str()); std::printf(" %-22s %s\n", "Sharpe ratio", f2(r.sharpe).c_str()); std::printf(" %-22s %s\n", "Max drawdown", pct(r.max_drawdown).c_str()); std::printf(" %-22s %s\n", "Volatility ann.", pct(r.volatility).c_str()); std::printf(" %-22s %s\n", "Calmar ratio", f2(r.calmar).c_str()); std::printf("─────────────────────────────────────────\n"); }