Welcome to Py-vAllocation
Py-vAllocation is a modular toolkit for single-period portfolio construction. It exposes a consistent Python API for mean-variance, mean-CVaR and robust optimisation, integrates view-based Bayesian updates, and ships with portfolio ensembling utilities so research portfolios can become investable allocations.
Key capabilities
Multiple risk models, one wrapper - switch between mean-variance, CVaR, and robust formulations without changing how you declare constraints or transaction costs.
Investor views made actionable - entropy pooling and Black-Litterman helpers transform qualitative views into posterior distributions.
Scenario-aware statistics - shrinkage estimators, Bayesian updates and scenario bootstrapping reduce estimation error out of the box.
Portfolio ensembling - average exposures, stack frontiers, and discretise weights to bridge the gap between optimisation outputs and tradeable lists.
Stress testing made easy - probability tilts, linear shocks, and PnL summaries reuse the same scenario machinery to keep analyses consistent.
Where to start
Getting Started for installation and a minimal efficient frontier example.
<no title> for the end-to-end multi-asset ETF walkthrough with stress tests and horizon projections.
Tutorials for all interactive notebooks covering mean-variance, CVaR, risk parity, stress testing, views, repricing, and ensembles.
Examples & Notebooks for a catalog of runnable scripts and notebooks.
The examples/ directory offers runnable scripts that mirror the tutorials - try
python examples/stress_and_pnl.pyfor probability tilts and performance summaries.
Install & quickstart
# Clone and install the library (full instructions in :doc:`getting_started`)
git clone https://github.com/enexqnt/py-vallocation.git
cd py-vallocation
python -m pip install -e .[robust]
import numpy as np
from pyvallocation.portfolioapi import PortfolioWrapper
wrapper = PortfolioWrapper.from_scenarios(np.random.normal(0, 0.01, size=(252, 4)))
frontier = wrapper.variance_frontier(num_portfolios=11)
weights, ret, risk = frontier.tangency(risk_free_rate=0.01)
print(weights.round(3))
Tutorials & Examples
API Reference
Background