Skip to main content

PortPy

Portfolio analysis that explains itself.

PortPy is a Python library for portfolio performance measurement and risk analysis, built around one object — Portfolio — and one idea: every number it gives you can explain, in plain language, what it is, how to read it, and whether it's good or bad.

CI License: MIT Python 3.10+

import pandas as pd
from portpy import Portfolio

prices = pd.read_csv("prices.csv", index_col=0, parse_dates=True)  # columns = tickers

portfolio = Portfolio(
    prices,
    weights={"AAPL": 0.4, "MSFT": 0.35, "GOOGL": 0.25},
    name="Tech Portfolio",
    risk_free_rate=0.04,
)

portfolio.metrics.sharpe_ratio(as_result=True).explain()
sharpe_ratio (metric)
=====================

What it is:
  Measures excess return earned per unit of total volatility taken, using the risk-free rate as the return hurdle.

Formula:
  mean(r - rf) / std(r - rf, ddof=1) * sqrt(periods_per_year)

How to read it:
  A Sharpe of 1.0 means the strategy generated approximately one unit of excess return for each unit of volatility. Higher values indicate better risk-adjusted performance.

Good vs. bad:
  Higher is generally better. Values above 1 are commonly considered strong, but interpretation depends on the asset class, time period, and strategy complexity.

Caveats:
  Sharpe treats all volatility as bad, including upside volatility. It can also overstate strategies with asymmetric downside risk, illiquidity, or short backtests. The sqrt(periods_per_year) annualization assumes i.i.d., serially uncorrelated returns - positive autocorrelation (illiquid/infrequently-priced assets) means the annualized figure is overstated (Lo, 2002).

This result:
  very good

Why PortPy

  • One object, one namespace. portfolio.metrics.<name>() auto-fills returns, weights, risk-free rate, and annualization frequency from the portfolio itself — no re-threading the same five arguments through every call.
  • A real portfolio, not just a return stream. Weights (negative/short included), asset-class tags, and explicit calendar-alignment / currency-conversion helpers for combining assets that don't trade on the same schedule (crypto, equities, bonds) or in the same currency.
  • Explains itself. .explain() on any result — a plain-language card covering what it is, how to read it, good vs. bad, and known caveats.
  • Numerically validated. Cross-checked against empyrical and quantstats for metrics, and PyPortfolioOpt, Riskfolio-Lib, and skfolio for every optimizer — including negative-weight (short) solutions, not just long-only — on real market data, see tests/validation/.
  • Builds portfolios, not just measures them. portfolio.models estimates expected returns/covariance, solves for weights (mean-variance, max Sharpe, risk parity, hierarchical risk parity, Black-Litterman, ...), and manages a book afterward (rebalancing, drift monitoring, before/after comparisons) — every result explains itself the same way metrics do.

Install

pip install portpy-quant               # core: numpy, pandas, scipy, statsmodels
pip install "portpy-quant[viz]"        # + plotly, matplotlib, seaborn
pip install "portpy-quant[data]"       # + yfinance, alpaca-py (for the examples)
pip install "portpy-quant[all]"        # everything

Documentation

  • Getting Started
  • User Guide — the Portfolio object, weights & shorts, calendar/currency alignment, the explainability layer
  • API Reference — every function, by module
  • Roadmap — what's implemented today vs. planned (visualization and strategies are not yet built)
  • examples/ — runnable scripts, metrics_debug.ipynb/metrics_tutorial.ipynb exercising every metric against live Alpaca + Fed (FRED) data, and models_debug.ipynb/models_tutorial.ipynb doing the same for .models

Status

PortPy is pre-1.0 (Development Status :: 4 - Beta). Metrics and core (calendar/currency alignment, weights, the explainability layer) and .models (estimators, optimization, construction, management) are implemented and tested. Visualization and strategies/backtesting are designed but not yet built — see the Roadmap.

License

MIT © Arthur Faugeron

Metadata

Release files for portpy-quant 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for portpy-quant 0.2.0
File Size Uploaded
portpy_quant-0.2.0.tar.gz 306.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for portpy-quant 0.2.0
File Interpreter ABI Platform
portpy_quant-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 419.2 kB

Release files / portpy_quant-0.2.0.tar.gz

Download URL portpy_quant-0.2.0.tar.gz
Size 306.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e8be53a290ccdf2a5ebf4debfbd10afa3635f2cf4c272c578055d9c1e86aa80f
BLAKE2b-256 checksum
How to use checksums
7dd9971668667f15a8775b7f33ccd039f4158e9433b8f8b04e8df667a74da419
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / portpy_quant-0.2.0-py3-none-any.whl

Download URL portpy_quant-0.2.0-py3-none-any.whl
Size 113.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
21a91659e5dce0e3c8960c16250fc93dd581afc4b416b53788b300554c41fcf1
BLAKE2b-256 checksum
How to use checksums
8d36c349a084763edd1853329bd1d4eaffcbf01db6e240268f95c0e9d02ea345
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page