Report Format Specification¶
Field definitions and data structures for JSON, PNG, HTML, and Markdown reports.
analyze_returns Metrics Dictionary¶
For the return value of result = run_backtest(...) or run_strategy:
from eqlib import analyze_returns
m = analyze_returns(result, risk_free_rate=0.03, trading_days=252)
When result["recorded_values"] is insufficient to construct a daily NAV series, the function may return None, in which case some metrics will also be missing from the HTML report.
| Key | Description |
|---|---|
total_return |
Total return over the full period (based on start/end portfolio value) |
annual_return |
Annualized return derived from geometric annualization of daily returns |
annual_volatility |
Daily return standard deviation × √252 |
sharpe_ratio |
Sharpe ratio (annualized, net of risk-free rate) |
sortino_ratio |
Sortino ratio |
max_drawdown |
Max drawdown (negative number) |
calmar_ratio |
Annualized return / |max drawdown| |
alpha |
Annualized Alpha (relative to benchmark) |
beta |
Beta |
information_ratio |
Information ratio |
win_rate_daily |
Daily win rate |
win_rate_trade |
Paired-trade win rate |
trade_count |
Number of completed paired trades |
win_count / loss_count |
Number of profitable / losing trades |
profit_loss_ratio |
Profit/loss ratio |
annual_turnover |
Annualized turnover (relative trade volume) |
total_commission |
Total commissions (for reporting; NAV already reflects costs) |
net_return |
Same meaning as total_return (see source code comments) |
excess_return |
Strategy total return − benchmark total return |
benchmark_return |
Benchmark total return |
excess_return_max_drawdown |
Max drawdown of the excess return series |
excess_return_sharpe |
Excess return Sharpe |
daily_excess_return |
Annualized mean daily excess return |
benchmark_volatility |
Benchmark annualized volatility |
max_drawdown_start |
Start date of the maximum drawdown |
max_drawdown_end |
End date of the maximum drawdown |
trading_days |
Number of trading days |
num_trades |
Total fills (one-sided) |
monthly_returns |
Monthly returns dict ({"2024-01": 0.03, ...}) |
rolling_sharpe_60d |
60-day rolling Sharpe series ([{"date": "...", "value": ...}]) |
rolling_volatility_60d |
60-day rolling volatility series |
daily_returns_stats |
Daily return statistics (mean, std, skewness, kurtosis, best/worst day, histogram) |
per_stock_pnl |
Per-stock P&L dict (FIFO matching, {"000001": 5000.0, ...}) |
drawdown_periods |
Top 5 drawdown periods (start/trough/recovery dates, depth, duration days) |
The risk-free rate defaults to risk_free_rate=0.03 (annualized 3%) and can be adjusted as needed.
Markdown / JSON Reports¶
- Markdown: Suitable for pasting into notes or version control; provides a quick summary and trade log.
- JSON: Suitable for scripting batch comparisons across parameter sets, plotting custom charts, and integrating with dashboards.
JSON Top-Level Fields (Agent-First Schema)¶
| Field | Type | Description |
|---|---|---|
verdict |
object |
Overall grade (S/A/B/C/D), score, strongest/weakest dimension |
targets |
object |
Target metric values and pass/fail status |
diagnostics |
array |
Diagnostic findings (max drawdown, Sharpe, win rate, Alpha violations) |
recommendations |
array |
Parameter tuning suggestions (priority, parameter, current/suggested value) |
grade |
object |
6-dimension score breakdown (return, risk, risk-adjusted, trade quality, excess, stability) |
metrics |
object |
Full metrics (same as analyze_returns output; inf/nan serialized as null) |
time_series |
object |
Monthly returns, rolling Sharpe, rolling volatility, drawdown periods |
daily_returns_stats |
object |
Daily return statistics (mean, std, skewness, kurtosis) |
per_stock_pnl |
object |
Per-stock P&L (FIFO matching) |
summary |
object |
Backtest period, capital, P&L, trade count, benchmark |
trades |
array |
Individual fill records |
positions |
object |
End-of-period holdings |
chart_data |
object |
Candlestick, volume, cumulative return, drawdown chart data (nested) |
factor_analysis |
object |
Factor analysis (simplified Fama-French) |
brinson_attribution |
object |
Brinson attribution |
risk_metrics |
object |
Backward-compat: flat metrics dict (Sharpe, drawdown, Alpha, etc.) |
cumulative_returns |
array |
Backward-compat: daily NAV series [{date, total_value, cumulative_return}] |
strategy_params |
object |
(optional) Current parameters and parameter ranges |
iteration |
object |
(optional) Iteration context (run_id, changes, score delta) |
JSON top-level fields may be extended in future versions; refer to the generated file for the authoritative schema.
Note when reading JSON: summary.num_trades is typically the one-sided fill count, which differs from the paired trade count — see FAQ.