Enhanced drop-in replacement for QuantStats — portfolio analytics for quants
Project description
QuantStats Pro: Portfolio analytics for quants
QuantStats Pro is an enhanced, actively maintained drop-in replacement for QuantStats by Ran Aroussi. It performs portfolio profiling, allowing quants and portfolio managers to understand their performance with in-depth analytics and risk metrics.
pip install quantstats-pro # replaces: pip install quantstats
import quantstats as qs # import unchanged
Note: QuantStats Pro cannot coexist with the original
quantstatspackage in the same environment — both provide thequantstatsimport namespace. Uninstallquantstatsbefore installingquantstats-pro(pip uninstall quantstats).
Changelog » · Upstream » · Contributing »
Why QuantStats Pro?
This fork fixes known bugs, improves reliability, and evolves reports and visualizations — while keeping the same import quantstats as qs API.
What's new in Pro (beyond upstream):
quantstats.montecarlo— multi-model Monte Carlo engine (GBM, GARCH, Heston, bootstraps, Bayesian, …) with cross-model analytics and an institutional HTML tearsheetquantstats.alphadecay— rolling-window alpha-decay monitor with z-score traffic lights, CUSUM, and time-underwater diagnostics- New HTML tearsheets —
html_simple,html_montecarlo,html_alpha_decay(plus the classic fullhtmlreport) - Visual redesign — updated branding and chart palette on the classic tearsheet (v0.2.0+)
Package modules
| Module | Purpose |
|---|---|
quantstats.stats |
50+ performance metrics (Sharpe, Sortino, drawdown, VaR, …) |
quantstats.plots |
Performance visualizations (returns, drawdown, heatmaps, rolling stats, …) |
quantstats.reports |
HTML tearsheets and metrics tables |
quantstats.montecarlo |
Multi-model forward simulation engine and analytics |
quantstats.alphadecay |
Short-horizon rolling risk analysis and decay detection |
quantstats.utils |
Data prep, download_returns, pandas helpers |
Legacy shuffle-based Monte Carlo remains at qs.stats.montecarlo() for backward compatibility. The new engine lives under quantstats.montecarlo and powers qs.reports.html_montecarlo().
Crypto and 24/7 markets
For daily crypto data, pass periods_per_year=365 to reports and stats that annualize:
import quantstats as qs
qs.extend_pandas()
returns = qs.utils.download_returns("BTC-USD")
# Tearsheet with 365 trading days per year
qs.reports.html(returns, periods_per_year=365, output="btc_report.html")
# Individual metrics
qs.stats.sharpe(returns, periods=365)
qs.stats.rar(returns, periods=365)
qs.stats.rar(returns, periods=365)
---
## HTML Tearsheets
QuantStats Pro ships **four** HTML report types. All open in the browser by default, or save to disk with `output="path.html"`.
| Function | Use case |
|----------|----------|
| `qs.reports.html(...)` | Full classic tearsheet (metrics + all charts) |
| `qs.reports.html_simple(...)` | Lean equity-curve tearsheet — core metrics and charts only |
| `qs.reports.html_montecarlo(...)` | Multi-model Monte Carlo risk analysis (1y forward horizon by default) |
| `qs.reports.html_alpha_decay(...)` | Short-window alpha-decay health monitor (7/15/30d) |
```python
import quantstats as qs
returns = qs.utils.download_returns("QQQ")
# Classic full report vs benchmark
qs.reports.html(returns, benchmark="SPY", output="qqq_full.html")
# Simplified equity-curve view
qs.reports.html_simple(returns, benchmark="SPY", output="qqq_simple.html")
# Multi-model Monte Carlo (median consensus + stress envelope)
qs.reports.html_montecarlo(
returns,
bust=-0.25, # P(Bust): drawdown threshold
goal=0.50, # P(Goal): terminal return target
sims=500,
seed=42,
output="qqq_montecarlo.html",
)
# Alpha decay monitor
qs.reports.html_alpha_decay(
returns,
windows=(7, 15, 30),
output="qqq_alpha_decay.html",
)
View sample classic tearsheet · Monte Carlo docs
Monte Carlo Engine
quantstats.montecarlo characterises an asset with several stochastic models, simulates forward paths from each, and compares the distribution of outcomes (CAGR, max drawdown, bust/goal probabilities, CVaR).
Built-in models
| Model | Name | Category |
|---|---|---|
| GBM | gbm |
Monte Carlo |
| Shuffle (legacy) | shuffle |
Monte Carlo |
| Bootstrap | bootstrap |
Monte Carlo |
| Block Bootstrap | block_bootstrap |
Monte Carlo |
| Jump Diffusion (Merton) | jump_diffusion |
Monte Carlo |
| GARCH(1,1)-t | garch |
Monte Carlo |
| Heston (SV) | heston |
Monte Carlo |
| Bayesian (NIG) | bayesian |
Monte Carlo |
| Bayesian Bootstrap | bayesian_bootstrap |
Monte Carlo |
| Trimmed Bootstrap (top 1%) | trimmed_1pct |
Stress |
Programmatic API
from quantstats.montecarlo import run_models, available_models
from quantstats.montecarlo import analytics as mca
print(available_models())
# ['bayesian', 'bayesian_bootstrap', 'block_bootstrap', 'bootstrap', ...]
results = run_models(
returns,
models=["gbm", "garch", "bootstrap"],
horizon=252, # 1 year (default: periods_per_year)
sims=1000,
bust=-0.25,
goal=0.50,
seed=42,
)
# Per-model summary row
gbm = results["gbm"]
print(gbm.summary) # cagr_p5, cagr_median, maxdd_p95, prob_loss, cvar_5, …
print(gbm.sim_returns.shape) # (horizon, sims)
# Cross-model consensus and stress envelope
median = mca.model_median_summary(results)
envelope = mca.conservative_envelope(results)
hist = mca.historical_summary(returns, horizon=252)
Legacy shuffle Monte Carlo
The original upstream API still works — random permutation of historical returns:
mc = qs.stats.montecarlo(returns, sims=1000, bust=-0.20, goal=0.50, seed=42)
print(f"Bust probability: {mc.bust_probability:.1%}")
print(f"Goal probability: {mc.goal_probability:.1%}")
mc.plot()
Full Monte Carlo documentation »
Alpha Decay Monitor
quantstats.alphadecay tracks whether a strategy's short-term risk profile is drifting from its historical norm. It computes 10 rolling metrics over configurable windows (default 7/15/30 days):
CAGR · Volatility · Downside Vol · Max Drawdown · Mean Drawdown · Win Rate · VaR 95% · Expected Shortfall 95% · Payoff Ratio · Skew
Each metric-window cell gets a traffic-light status (Excellent / Good / Warning / Critical) based on z-scores computed on a per-metric analysis scale (log transforms for skewed metrics). The tearsheet also includes:
- Health score — count of Good/Excellent cells
- CUSUM return-decay detector
- Time underwater duration analysis
- Per-metric distribution charts with current observation vs historical mean
Programmatic API
from quantstats.alphadecay import analyze, available_metrics
print(available_metrics())
# ['cagr', 'volatility', 'downside_vol', 'max_drawdown', ...]
result = analyze(
returns,
windows=(7, 15, 30),
rf=0.0,
periods=252,
)
print(f"Health: {result.score}/{result.total} ({result.score_pct:.0f}%)")
for metric in result.metrics:
wr = metric.windows[30] # latest 30-day window
print(f"{metric.spec.label}: z={wr.z_score:+.2f} → {wr.status}")
Generate the full HTML tearsheet with qs.reports.html_alpha_decay(returns).
Quick Start
%matplotlib inline
import quantstats as qs
# extend pandas functionality with metrics, etc.
qs.extend_pandas()
# fetch the daily returns for a stock
stock = qs.utils.download_returns('META')
# show sharpe ratio
qs.stats.sharpe(stock)
# or using extend_pandas() :)
stock.sharpe()
Output:
0.7604779884378278
Visualize stock performance
qs.plots.snapshot(stock, title='Facebook Performance', show=True)
# can also be called via:
# stock.plot_snapshot(title='Facebook Performance', show=True)
Output:
Creating a report
The classic full tearsheet compares a strategy against an optional benchmark:
# benchmark can be a pandas Series or ticker
qs.reports.html(stock, "SPY", output="meta_report.html")
Output will generate something like this:
See HTML Tearsheets above for html_simple, html_montecarlo, and html_alpha_decay.
Available methods
To view a complete list of available methods, run:
[f for f in dir(qs.stats) if f[0] != '_']
['avg_loss',
'avg_return',
'avg_win',
'best',
'cagr',
'calmar',
'common_sense_ratio',
'comp',
'compare',
'compsum',
'conditional_value_at_risk',
'consecutive_losses',
'consecutive_wins',
'cpc_index',
'cvar',
'drawdown_details',
'expected_return',
'expected_shortfall',
'exposure',
'gain_to_pain_ratio',
'geometric_mean',
'ghpr',
'greeks',
'implied_volatility',
'information_ratio',
'kelly_criterion',
'kurtosis',
'max_drawdown',
'monthly_returns',
'montecarlo',
'montecarlo_cagr',
'montecarlo_drawdown',
'montecarlo_sharpe',
'outlier_loss_ratio',
'outlier_win_ratio',
'outliers',
'payoff_ratio',
'profit_factor',
'profit_ratio',
'r2',
'r_squared',
'rar',
'recovery_factor',
'remove_outliers',
'risk_of_ruin',
'risk_return_ratio',
'rolling_greeks',
'ror',
'sharpe',
'skew',
'sortino',
'adjusted_sortino',
'tail_ratio',
'to_drawdown_series',
'ulcer_index',
'ulcer_performance_index',
'upi',
'value_at_risk',
'var',
'volatility',
'win_loss_ratio',
'win_rate',
'worst']
[f for f in dir(qs.plots) if f[0] != '_']
['daily_returns',
'distribution',
'drawdown',
'drawdowns_periods',
'earnings',
'histogram',
'log_returns',
'monthly_heatmap',
'montecarlo',
'montecarlo_distribution',
'returns',
'rolling_beta',
'rolling_sharpe',
'rolling_sortino',
'rolling_volatility',
'snapshot',
'yearly_returns']
See Monte Carlo documentation and help(qs.stats.<method>) for parameter details.
Console / notebook helpers:
qs.reports.metrics(returns, mode="full") # metrics table
qs.reports.plots(returns, mode="full") # all plots
qs.reports.basic(returns) # basic metrics + plots
qs.reports.full(returns) # full metrics + plots
Important: Period-Based vs Trade-Based Metrics
QuantStats analyzes return series (daily, weekly, monthly returns), not discrete trade data. This means:
- Win Rate = percentage of periods with positive returns
- Consecutive Wins/Losses = consecutive positive/negative return periods
- Payoff Ratio = average winning period return / average losing period return
- Profit Factor = sum of positive returns / sum of negative returns
These metrics are valid and useful for:
- Systematic/algorithmic strategies with regular rebalancing
- Analyzing return-series behavior over time
- Comparing strategies on a period-by-period basis
For discretionary traders with multi-day trades, these period-based metrics may differ from trade-level statistics. A single 5-day trade might span 3 positive days and 2 negative days - QuantStats would count these as 3 "wins" and 2 "losses" at the daily level.
This is consistent with how all return-based analytics work (Sharpe ratio, Sortino ratio, drawdown analysis, etc.) - they operate on return periods, not discrete trade entries/exits.
In the meantime, you can get insights as to optional parameters for each method, by using Python's help method:
help(qs.stats.conditional_value_at_risk)
Help on function conditional_value_at_risk in module quantstats.stats:
conditional_value_at_risk(returns, sigma=1, confidence=0.99)
calculates the conditional daily value-at-risk (aka expected shortfall)
quantifies the amount of tail risk an investment
Installation
Install using pip:
pip install quantstats-pro --upgrade
Requirements
- Python >= 3.10
- pandas >= 1.5.0
- numpy >= 1.24.0
- scipy >= 1.11.0
- matplotlib >= 3.7.0
- seaborn >= 0.13.0
- tabulate >= 0.9.0
- yfinance >= 0.2.40
- arch >= 6.0 (GARCH calibration for Monte Carlo)
- plotly >= 5.0.0 (optional, for using
plots.to_plotly())
Questions?
If you find a bug, please open an issue.
Contributions welcome — check open issues or upstream QuantStats issues for bugs we're tracking.
Known Issues
For some reason, I couldn't find a way to tell seaborn not to return the
monthly returns heatmap when instructed to save - so even if you save the plot (by passing savefig={...}) it will still show the plot.
Legal Stuff
QuantStats Pro is a fork of QuantStats by Ran Aroussi, distributed under the Apache Software License. See LICENSE.txt for details.
Credits
QuantStats Pro — maintained by Diego Alvarez
QuantStats (original) — Ran Aroussi
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quantstats_pro-0.4.1.tar.gz.
File metadata
- Download URL: quantstats_pro-0.4.1.tar.gz
- Upload date:
- Size: 130.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31fbe407c8be6cdb685d00115c161f3beeee3c15a0925abd9295116d69946a46
|
|
| MD5 |
34d041ff13f4d7ae673f96b01ee2e43a
|
|
| BLAKE2b-256 |
a6e71edadcc5000c8511ae5984c42334b7b8d18aaceeb148de06a9f5519e4b8d
|
Provenance
The following attestation bundles were made for quantstats_pro-0.4.1.tar.gz:
Publisher:
python-publish.yml on diegoalvarezmgl/quantstats-pro
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quantstats_pro-0.4.1.tar.gz -
Subject digest:
31fbe407c8be6cdb685d00115c161f3beeee3c15a0925abd9295116d69946a46 - Sigstore transparency entry: 2073213464
- Sigstore integration time:
-
Permalink:
diegoalvarezmgl/quantstats-pro@ef59f04ae20263fd4589d734f05ece81aa0561cd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/diegoalvarezmgl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@ef59f04ae20263fd4589d734f05ece81aa0561cd -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file quantstats_pro-0.4.1-py3-none-any.whl.
File metadata
- Download URL: quantstats_pro-0.4.1-py3-none-any.whl
- Upload date:
- Size: 144.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2dddea52ccc18ad1c15290869ce74c08c3f011648a8289d27083f17514d6271d
|
|
| MD5 |
db5917f481c1c52fdba860abefccbf75
|
|
| BLAKE2b-256 |
1015b1a85c0c9f1c16d234a12eb011d0bba6c5ee861837c58f7bd22f003f0920
|
Provenance
The following attestation bundles were made for quantstats_pro-0.4.1-py3-none-any.whl:
Publisher:
python-publish.yml on diegoalvarezmgl/quantstats-pro
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quantstats_pro-0.4.1-py3-none-any.whl -
Subject digest:
2dddea52ccc18ad1c15290869ce74c08c3f011648a8289d27083f17514d6271d - Sigstore transparency entry: 2073213478
- Sigstore integration time:
-
Permalink:
diegoalvarezmgl/quantstats-pro@ef59f04ae20263fd4589d734f05ece81aa0561cd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/diegoalvarezmgl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@ef59f04ae20263fd4589d734f05ece81aa0561cd -
Trigger Event:
workflow_dispatch
-
Statement type: