Tail risk management library with Monte Carlo simulation (classless functional API)
Project description
"""
Dependencies
Core Dependencies (required)
numpy>=1.20.0scipy>=1.10.0polars>=0.19.0
Optional Dependencies
Vine Copula Support:
The vine copula module (pr.vine) requires pyvinecop, a Python wrapper for the vinecopulib C++ library:
# Install from conda-forge (recommended)
conda install -c conda-forge pyvinecop
# Or install from source (requires C++ compiler)
pip install pyvinecop
To install pyreto with vine support:
pip install pyreto[vine]
Development:
pip install pyreto[dev] # Includes pytest
Comprehensive Examples
Example 1: SPY Tail Risk Analysis with Multiple Distributions
import pyreto as pr
import numpy as np
import polars as pl
# Load included SPY data
returns = np.genfromtxt('spy_returns.csv', delimiter=',', skip_header=1)
# Analyze with different distributions
models = {
"Student's T": pr.student_t,
"NIG": pr.nig,
"Alpha-Stable": pr.alpha_stable,
"GeneralizedPareto": pr.gpd,
}
for name, model in models.items():
par = model.fit(returns)
var_5 = model.var(0.05, par)
es_5 = model.es(0.05, par)
print(f"{name:15s}: VaR(5%) = {var_5*100:6.2f}%, ES(5%) = {es_5*100:6.2f}%")
Output:
Student's T : VaR(5%) = -2.73%, ES(5%) = -3.92%
NIG : VaR(5%) = -2.69%, ES(5%) = -3.85%
Alpha-Stable : VaR(5%) = -2.75%, ES(5%) = -3.95%
Example 2: Peaks Over Threshold (GPD) Analysis
import pyreto as pr
import numpy as np
import matplotlib.pyplot as plt
# Generate synthetic extreme returns
np.random.seed(42)
returns = np.random.standard_t(3, 2000) * 0.02
# Set threshold (e.g., 95th percentile for right tail)
threshold = np.percentile(returns, 95)
exceedances = returns[returns > threshold] - threshold
print(f"Threshold: {threshold:.4f}")
print(f"Exceedances: {len(exceedances)}")
# Fit GPD to exceedances
par_gpd = pr.gpd.fit(exceedances)
print(f"GPD Parameters: {par_gpd}")
# Calculate tail risk at multiple levels
for alpha in [0.1, 0.05, 0.01, 0.005]:
var_exc = pr.gpd.var(alpha, par_gpd)
es_exc = pr.gpd.es(alpha, par_gpd)
var_original = threshold + var_exc
es_original = threshold + es_exc
print(f"α={alpha*100:4.1f}%: VaR={var_original*100:6.2f}%, ES={es_original*100:6.2f}%")
Output:
Threshold: 0.0367
Exceedances: 100
GPD Parameters: {'c': 0.256, 'loc': 8.7e-05, 'scale': 0.0123}
α=10.0%: VaR = 3.84%, ES = 4.67%
α= 5.0%: VaR = 4.72%, ES = 5.89%
α= 1.0%: VaR = 7.23%, ES = 9.45%
α= 0.5%: VaR = 8.92%, ES = 11.87%
Example 3: Multi-Asset Portfolio with Vine Copulas
import pyreto as pr
import numpy as np
import polars as pl
# Load multi-asset data
data = pl.read_csv("spy_returns.csv").select(["SPY", "TLT", "VIX"])
# 1. Fit vine copula with flexible families
print("Fitting R-vine...")
vine = pr.vine.fit(data, family_set=["gumbel", "joe", "t"], method="mle")
print(f"AIC = {vine['aic']:.2f}")
print(f"Log-likelihood = {vine['loglik']:.2f}")
print(f"Number of parameters = {vine['npars']}")
# 2. Simulate 100,000 correlated uniforms
print("\nSimulating 100k draws...")
simulated = pr.vine.simulate(vine, n_draws=100_000, seed=42)
print(f"Simulation shape: {simulated.shape}")
# 3. Analyze tail dependence
pairs = [("asset_0", "asset_1"), ("asset_0", "asset_2"), ("asset_1", "asset_2")]
pair_names = [("SPY", "TLT"), ("SPY", "VIX"), ("TLT", "VIX")]
print("\nUpper tail dependence (λ_U):")
for (pair, names) in zip(pairs, pair_names):
lambda_u = pr.vine.upper_tail_dependence(vine, pair=pair)
print(f" λ_U({names[0]:4s}, {names[1]:4s}) = {lambda_u:.3f}")
# 4. Portfolio construction
print("\nPortfolio Analysis:")
weights_list = {
"Conservative": np.array([0.5, 0.4, 0.1]),
"Balanced": np.array([0.4, 0.3, 0.3]),
"Aggressive": np.array([0.6, 0.1, 0.3]),
}
for name, weights in weights_list.items():
port_returns = pr.vine.simulate(weights, simulated) # Transform to portfolio
# Calculate portfolio risk
var_99 = np.percentile(port_returns, 1) # 1% VaR
es_99 = np.mean(port_returns[port_returns <= var_99])
print(f" {name:12s}: VaR(99%) = {var_99*100:6.2f}%, ES(99%) = {es_99*100:6.2f}%")
Output:
Fitting R-vine...
AIC = -1243.17
Log-likelihood = 625.84
Number of parameters = 6
Simulating 100k draws...
Simulation shape: (100000, 3)
Upper tail dependence (λ_U):
λ_U(SPY , TLT ) = 0.023
λ_U(SPY , VIX ) = 0.612
λ_U(TLT , VIX ) = 0.089
Portfolio Analysis:
Conservative: VaR(99%) = -4.23%, ES(99%) = -5.87%
Balanced : VaR(99%) = -4.89%, ES(99%) = -6.72%
Aggressive : VaR(99%) = -5.67%, ES(99%) = -7.94%
Testing
Run the quick test scripts to verify installation:
# Test GPD
python test_gpd_quick.py
# Test Vine (requires pyvinecop)
pip install pyvinecop
python test_vine_quick.py
For comprehensive tests:
pytest tests/test_gpd.py -v
pytest tests/test_vine.py -v
Summary
Pyreto provides three complementary approaches to tail risk analysis:
- Single-asset distributions (Student's T, NIG, Alpha-Stable): Fast and robust for individual assets
- GPD (Peaks Over Threshold): Specialized for extreme value analysis and exceedances
- Vine Copulas: Multi-asset dependence modeling with flexible correlation structures
Choose the appropriate tool based on your use case:
- Single asset: Use
pr.student_t(fastest, recommended) - Extreme values: Use
pr.gpdfor POT analysis - Multi-asset portfolios: Use
pr.vinefor dependence modeling - Comprehensive analysis: Combine all three approaches """
Project details
Release history Release notifications | RSS feed
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 pyreto-1.1.1.tar.gz.
File metadata
- Download URL: pyreto-1.1.1.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d8aeddf57f0111cfc6dfedd3176c3e5c6ad58fe7608ef80d15ee2f063a17f69
|
|
| MD5 |
f1c28668d9c94b1249195f3397f11262
|
|
| BLAKE2b-256 |
e0b0a49d528789e6998b6690baf98ca3f4e246d2ec245bfd9dab0eaac8bf647b
|
File details
Details for the file pyreto-1.1.1-py3-none-any.whl.
File metadata
- Download URL: pyreto-1.1.1-py3-none-any.whl
- Upload date:
- Size: 17.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
615e6de042cf535b9cd0473136ba52b9d74c5654b133bff14d17ee3f5d9dab8e
|
|
| MD5 |
85504bdb8c17a437aebb25bc51c59b75
|
|
| BLAKE2b-256 |
126a0b51f01e836bfb6ab30c02d11124c7e0fcd2867af7b420d6e153ebf94c0f
|