Interactive Backtest Report Demo¶
Below is an interactive backtest report generated by AKQuant. You can interact directly with the charts on this page to view detailed backtest data.
Benchmark Comparison¶
BacktestResult.viz.report accepts a benchmark return series:
benchmark_returns = (
benchmark_df.set_index("date")["close"].pct_change().fillna(0.0)
)
result.viz.report(
filename="akquant_report.html",
benchmark=benchmark_returns,
show=False,
)
When benchmark is provided, the HTML report adds a benchmark comparison section with strategy/benchmark/excess cumulative curves and relative metrics (total excess, annual excess, tracking error, information ratio, beta, alpha).
Structured Benchmark Analysis¶
AKQuant now exposes the benchmark comparison logic as a structured analysis payload that can be reused by web frontends, APIs, and offline pipelines instead of relying on HTML parsing.
benchmark_returns = (
benchmark_df.set_index("date")["close"].pct_change().fillna(0.0)
)
payload = result.benchmark_analysis(
benchmark=benchmark_returns,
curve_freq="D",
)
print(payload["schema_version"])
print(payload["summary"]["annual_excess"])
print(payload["series"][0])
The payload includes:
schema_version: contract version for downstream consumersavailable: whether benchmark analysis is availablereason: validation or alignment message when analysis is unavailablebenchmark.label: display label of the selected benchmarksummary: aggregate metrics such astotal_excess,annual_excess,tracking_error,information_ratio,beta, andalphaseries: aligned daily points with strategy, benchmark, excess, and cumulative seriesmeta: sample count, start/end date, and annualization settings
Recommended practice:
- Prepare the benchmark return series on the backend
- Call
result.benchmark_analysis(...)once after the backtest - Let the frontend render
summary + series + meta - Reuse the same analysis payload for both
result.viz.report(..., benchmark=...)and the frontend view
Export for Frontend or Archival¶
You can persist the benchmark analysis as part of the backtest artifacts:
result.export_benchmark_analysis(
path="artifacts/benchmark_analysis.json",
benchmark=benchmark_returns,
format="json",
curve_freq="D",
)
format="parquet" is also supported and writes:
series.parquet: aligned benchmark time seriesmetadata.json: summary metrics and metadata
Interactive LWC Trade Review¶
result.viz.review() renders an offline, self-contained single-file HTML powered by TradingView Lightweight Charts, overlaying buy/sell markers on the K-line for large-volume or intraday trade review.
It complements result.viz.report() rather than replacing it: analytical charts (equity curve, drawdown, heatmaps, attribution) stay with report()'s plotly output; review() only fills the "interactive candlesticks + trade markers" gap for bar-by-bar timing review.
# market_data is a single DataFrame or a {symbol: df} dict
path = result.viz.review(
market_data=df,
title="AKQuant Trade Review",
theme="dark", # initial theme "light" / "dark"; toggled in-page
filename="akquant_review.html",
show=False, # True opens the browser automatically
)
Notes:
- The HTML inlines lightweight-charts with no CDN dependency, so it opens and archives offline.
- A light/dark toggle button sits in the top bar;
themeonly sets the initial theme. Switching recolors instantly with no file regeneration. - Multi-symbol input (
{symbol: df}) adds a symbol selector at the top;initial_symbolsets which one is shown first. - Column names are case-insensitive and Chinese names are supported (
开盘/最高/最低/收盘/成交量/日期, etc.). - Daily data uses a
YYYY-MM-DDaxis; intraday data automatically switches to a time-of-day axis. - Optimized for large / intraday datasets: the payload is built with vectorized ops and timestamps are de-duplicated, so tens of thousands of candles stay smooth (the core advantage over the plotly analytical charts).
See examples/67_lwc_trade_review.py for a full example.