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.2.tar.gz (42.8 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.2-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: optego_quant_metrics-1.0.2.tar.gz
  • Upload date:
  • Size: 42.8 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.2.tar.gz
Algorithm Hash digest
SHA256 66ea99ef6f646b7aedf4e079f9d75c91f4130ad336a3bdd7225b9975647db6ad
MD5 ad10090ae1f616a2b70e97930f274aee
BLAKE2b-256 4b3494f02885011f5f3916a57920db503e77a450b0ac695d077c9b1885a215db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for optego_quant_metrics-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4e6d56fdda3781d2585365412099cb0926671773a66b85ab6b96e856b3ac0784
MD5 54d568c37920f803413601fd957dcae6
BLAKE2b-256 54b5f047fa7711ceae8347c5783306fe2c9b6011c641f5c4faa3280fd34b4c11

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