Skip to content

a Rust library that generates QuantStats-style HTML performance tear sheets from return time series.

License

Notifications You must be signed in to change notification settings

netcan/quantstats-rs

Repository files navigation

quantstats-rs

Crates.io Docs.rs License: MIT

quantstats-rs is a Rust library that generates QuantStats-style HTML performance tear sheets from return time series. It aims to closely match the behaviour and visuals of the original Python QuantStats project.

Preview of the benchmark tear sheet: Quantstats-rs demo tear sheet with benchmark

Features

  • Generate full HTML tear sheets from:
    • A single strategy return series; or
    • A strategy + benchmark pair.
  • Metrics table (see PerformanceMetrics), including:
    • CAGR, Sharpe, Sortino, Calmar
    • Max / average drawdown, longest drawdown
    • Gain-to-Pain and related ratios
  • Charts (SVG, embedded in the HTML):
    • Cumulative Returns / Cumulative Returns vs Benchmark (including log-scaled and volatility-matched variants)
    • Daily Returns (Cumulative Sum)
    • Rolling Volatility / Rolling Sharpe / Rolling Sortino / Rolling Beta
    • Drawdown (Underwater) (average drawdown red dashed line, filled area below 0%)
    • Strategy – Worst 5 Drawdown Periods
    • EOY Returns / EOY Returns vs Benchmark (with red dashed mean line)
    • Monthly Returns Heatmap
    • Returns Distribution / Monthly Distribution
  • Visual alignment with Python QuantStats:
    • Matching colour scheme (strategy #348dc1, benchmark #ff9933, etc.)
    • Proportional grid, labelled y-axis, bottom time axis
    • Dashed zero / mean lines and filled areas (e.g. Underwater Plot)

Repository Layout

  • src/
    • lib.rs – public API: html, HtmlReportOptions, ReturnSeries, PerformanceMetrics.
    • reports.rs – report assembly, metrics table rendering, and template filling.
    • stats.rs – performance statistics and drawdown segment logic.
    • plots.rs – all SVG chart generation.
    • report_template.html – HTML template, roughly mirroring QuantStats’ report.html.
  • examples/
    • html_report.rs – strategy only; writes tearsheet.html.
    • html_with_benchmark.rs – strategy + benchmark; writes tearsheet_with_benchmark.html.
    • common.rs – shared demo data, generated from data/ by the script.
  • data/ – CSVs / time series used to build the example report.
  • scripts/gen_examples_common.py – generates examples/common.rs from data/.

Build & Run

From the repository root:

cargo build

# Strategy-only demo report (writes `tearsheet.html`)
cargo run --example html_report

# Strategy + benchmark demo report (writes `tearsheet_with_benchmark.html`)
cargo run --example html_with_benchmark

# Tests (if present)
cargo test

The generated HTML files can be opened directly in a browser and visually compared against reports produced by the Python QuantStats library.

Library Usage

Add a dependency from crates.io:

[dependencies]
quantstats-rs = "0.1"

Basic usage in Rust:

use chrono::NaiveDate;
use quantstats_rs::{ReturnSeries, HtmlReportOptions, html};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Prepare dates and returns (e.g. daily returns)
    let dates: Vec<NaiveDate> = /* ... */;
    let values: Vec<f64> = /* ... */; // e.g. 0.01 means +1%

    let strategy = ReturnSeries::new(dates, values, Some("Strategy".to_string()))?;

    // 2. Configure report options
    let options = HtmlReportOptions::default()
        .with_title("My Strategy Tearsheet")
        .with_strategy_title("My Strategy")
        .with_output("tearsheet.html");

    // 3. Generate HTML string and write to file (if `output` is set)
    let html_string = html(&strategy, options)?;

    println!("Report generated ({} bytes)", html_string.len());
    Ok(())
}

With a benchmark:

let strategy: ReturnSeries = /* ... */;
let benchmark: ReturnSeries = /* ... */;

let options = HtmlReportOptions::default()
    .with_benchmark(&benchmark)
    .with_title("Strategy vs Benchmark")
    .with_strategy_title("Strategy")
    .with_benchmark_title("Benchmark")
    .with_output("tearsheet_with_benchmark.html");

let html_string = html(&strategy, options)?;

Example Data & Regeneration

The example binaries use examples/common.rs, which is generated from data/:

python3 scripts/gen_examples_common.py

After changing the data under data/, re-run the script and then rerun the examples to regenerate tearsheet.html and tearsheet_with_benchmark.html.

Alignment with Python QuantStats

This implementation uses the vendored Python QuantStats code and its HTML output as the reference. The following aspects are intentionally aligned:

  • Rolling Vol / Sharpe / Sortino / Beta:
    • Axis ranges, grid density, and line styles (including red dashed mean lines).
  • Underwater Plot:
    • Filled area below 0% in strategy colour.
    • Red dashed line at the average drawdown.
    • Solid underwater curve.
  • Strategy – Worst 5 Drawdown Periods:
    • Y-axis and grid styling.
    • Label positions for the “N: Xd” drawdown annotations.
  • EOY Returns vs Benchmark:
    • Bar layout and colours.
    • Red dashed mean line for strategy returns.
  • Time axis handling:
    • Bottom-aligned date labels for all time-series charts.
    • Label thinning to avoid overlap (e.g. around dense months like 2025‑10 / 2025‑11).

If you notice discrepancies compared to a Python QuantStats report (especially in a specific chart such as “Rolling Sortino” or “Underwater Plot”), please open an issue or PR and mention:

  • Which chart (title),
  • Which part differs (axis range, grid, colours, etc.),
  • Optionally, a snippet or screenshot from the Python-generated HTML.

About

a Rust library that generates QuantStats-style HTML performance tear sheets from return time series.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published