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.3.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.3-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: optego_quant_metrics-1.0.3.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.3.tar.gz
Algorithm Hash digest
SHA256 9e6ad3c5de593932ddb1097285ebb42b30e3b1db9fed8be6c7d2d8e4569fbb02
MD5 9a4af5d47a5442f99ef818b545c0293d
BLAKE2b-256 1a1ae12334fbd6d8c7c878d4dbba675065187d38aff33360d9ed47c4799e2f3a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for optego_quant_metrics-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3e47a6d5512453291d286f1f2ec7ee9ce19f3cd0884db0de770c497654024066
MD5 b6b5c8f23dd59fb11d3258421d0987da
BLAKE2b-256 f936a39eb55ee2a52d5524bde7f1cae110e6f4236376059e547ea186b37fb94c

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