Skip to main content

A Python package for quantitative portfolio metrics calculations, including Deflated Sharpe Ratio (DSR)

Project description

Quant Metrics

Code Coverage

A Python package for quantitative portfolio metrics calculations, designed for portfolio management and algorithmic trading strategy evaluation.

Overview

Quant Metrics provides tools for calculating various quantitative metrics used in portfolio management and algorithmic trading. The package supports calculating metrics for multiple strategies simultaneously from CSV files or programmatically.

Currently supported metrics:

  • Deflated Sharpe Ratio (DSR): Accounts for multiple testing and non-normal return distributions when evaluating multiple strategies.
  • Sharpe Ratio: Risk-adjusted return metric
  • Probabilistic Sharpe Ratio (PSR): Probability that Sharpe ratio is positive
  • Skewness: Measure of asymmetry in return distribution
  • Kurtosis: Measure of tail heaviness in return distribution
  • Volatility (Sharpe): Adjusted volatility accounting for skewness and kurtosis
  • SR*: Sharpe Ratio* accounting for multiple testing
  • Variance Across Trials: Variance of Sharpe ratios across all strategies

Installation

pip install optego-quant-metrics

Or using uv:

uv pip install optego-quant-metrics

Features

  • Deflated Sharpe Ratio (DSR): Adjusts the Sharpe ratio to account for:

    • Multiple testing concerns (testing many strategies)
    • Non-normal return distributions (skewness and kurtosis)
    • Automatically determines number of trials from your data
  • Comprehensive Metrics: Calculate multiple metrics for portfolio strategies

Usage

Deflated Sharpe Ratio (DSR)

The Deflated Sharpe Ratio is essential when testing multiple strategies, as it corrects for the inflation of the Sharpe ratio due to multiple testing.

From CSV file:

from pathlib import Path
from quant_metrics import calculate_dsr_from_formula

# Load strategy returns from CSV file
# Number of trials is automatically determined from the number of strategies in the CSV
csv_path = Path("strategy_returns.csv")
dsr_results = calculate_dsr_from_formula(csv_path=csv_path)

# DSR results are returned as percentages
for strategy, dsr_value in dsr_results.items():
    print(f"{strategy}: {dsr_value:.2f}")

From dictionary:

from quant_metrics import calculate_dsr_from_formula

strategy_returns = {
    "Strategy 1": [0.01, 0.02, -0.01, 0.03, ...],
    "Strategy 2": [0.015, 0.025, -0.005, 0.02, ...],
}

# Number of trials is automatically determined from the number of strategies in the dictionary
dsr_results = calculate_dsr_from_formula(
    strategy_returns=strategy_returns,
    annual_rate=4.0,
    periods_per_year=12
)

Other Metrics

Sharpe Ratio:

from quant_metrics import calculate_sharpe_ratio
from pathlib import Path

sharpe_ratios = calculate_sharpe_ratio(csv_path=Path("strategy_returns.csv"))

Probabilistic Sharpe Ratio (PSR):

from quant_metrics import calculate_psr
from pathlib import Path

psr_results = calculate_psr(csv_path=Path("strategy_returns.csv"))
# Returns percentages

Risk-free Rate:

from quant_metrics import calculate_risk_free_rate

# Calculate monthly risk-free rate from 4 annual rate
monthly_rf = calculate_risk_free_rate(4.0, 12)
print(f"Monthly risk-free rate: {monthly_rf:.6f}")

CSV File Format

The CSV file should follow this format:

Structure

  • First row (Header): Column names representing strategy names
    • The first column can be a date/time identifier (e.g., "Month", "Date") - this column is ignored
    • Subsequent columns represent strategy names (e.g., "Strategy 1", "Strategy 2", "Strategy 3", ...)
  • Subsequent rows: Each row represents a time period (e.g., monthly returns)
  • Values: Returns as percentages
    • Can be formatted with symbol (e.g., `2.10`, `-0.96`) - the will be automatically stripped
    • Or as plain numbers (e.g., 2.10, -0.96) representing percentages

Requirements

  • All strategies must have the same number of data points (rows)
  • Returns should be in percentage format (not decimal format like 0.021 for 2.1)
  • Missing values are not supported - ensure all cells have valid numeric values
  • The number of strategies (columns excluding the first date column) is automatically detected and used as the number of trials

Example CSV File

Format 1: With date column and symbols

Month,Strategy 1,Strategy 2,Strategy 3,Strategy 4
1/1/2012,2.10,5.31,7.20,-0.36
1/2/2012,-0.96,3.91,-3.94,-0.19
1/3/2012,3.63,5.86,0.01,0.31
...

Format 2: Without date column, plain numbers

Strategy 1,Strategy 2,Strategy 3,Strategy 4
2.10,5.31,7.20,-0.36
-0.96,3.91,-3.94,-0.19
3.63,5.86,0.01,0.31
...

Notes

  • If the first column header is not a strategy name (e.g., "Month", "Date", "Period"), it will be automatically skipped
  • Percentage symbols (``) in values are automatically stripped during parsing
  • Values like 2.10 or 2.10 both represent 2.10 return
  • Negative values represent losses (e.g., -0.96 means -0.96 return)

Loading CSV Files

When you load a CSV file, the package will:

  1. Read the header row to identify strategy names (skipping the first column if it's not a strategy)
  2. Count the number of strategy columns to determine the number of trials
  3. Parse all return values, automatically handling `` symbols if present
  4. Convert percentage values to decimals for internal calculations
  5. Calculate metrics for each strategy automatically

Development

Setup

# Install dependencies
make dep

# Run tests
make tests

# Format and lint
make fmt

# Format, lint, and test
make ft

Running Tests

pytest tests/

Why DSR?

In portfolio management and algorithmic trading, it's common to test a wide range of strategies before settling on the best-performing one. This multiple testing inflates the Sharpe ratio, making strategies appear better than they actually are. The Deflated Sharpe Ratio (DSR) corrects for:

  1. Multiple Testing: Accounts for the fact that testing many strategies increases the chance of finding a strategy that appears good by chance
  2. Non-Normal Distributions: Adjusts for skewness and kurtosis in return distributions

The DSR formula used is:

DSR = NORM.S.DIST((Sharpe - SR*) / Volatility (Sharpe))

Where:

  • SR* accounts for multiple testing using variance across trials
  • Volatility (Sharpe) adjusts for skewness and kurtosis effects

License

See LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

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

optego_quant_metrics-1.0.1.tar.gz (40.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

optego_quant_metrics-1.0.1-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file optego_quant_metrics-1.0.1.tar.gz.

File metadata

  • Download URL: optego_quant_metrics-1.0.1.tar.gz
  • Upload date:
  • Size: 40.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for optego_quant_metrics-1.0.1.tar.gz
Algorithm Hash digest
SHA256 7850a537ec3e43bf5cf5a371cb409aacb97de5cf24a2ff4ff2fd8d00e5b977fa
MD5 2be565d7a973953138b79439d2c6d999
BLAKE2b-256 673e64fde975dfd16ae6c62875b761c439785888e566a1b9a74e286934da0042

See more details on using hashes here.

File details

Details for the file optego_quant_metrics-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for optego_quant_metrics-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ffc784349e71e160475c37e4035f03e8c223c596d5b7816377ff4b174e2dc586
MD5 302a99ebab5d167ee02f93db7ddfa4ca
BLAKE2b-256 3f99f09a15c91bfbbee4ebd353698669130ee967ad16afbcd2b6e758d7f0950e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page