A quantitative portfolio optimisation and risk analysis system built in Python.
Uses historical market data to analyse asset returns, volatility and correlations, construct portfolios under investment constraints, optimise allocations, and evaluate performance both in-sample and out-of-sample.
Historical price data is downloaded using yfinance.
Current analysis covers data from 2020 onwards.
Portfolio constraints include:
- Long-only positions
- Maximum 40% allocation to an individual asset
A 4% risk-free rate is used for Sharpe ratio calculations.
- Download historical adjusted prices using yfinance
- Handle missing data
- Store downloaded price and return data locally
- Daily returns
- Annualised returns
- Annualised volatility
- Correlation matrix
- Annualised covariance matrix
- Expected portfolio return
- Portfolio volatility
- Sharpe ratio
- Maximum drawdown
- Asset return contributions
- Portfolio risk contributions
The system currently supports:
- Minimum-volatility portfolio
- Maximum-Sharpe portfolio
- Target-return portfolio
- Efficient frontier generation
The project includes a static out-of-sample backtesting framework.
Historical data is divided into a training period and testing period.
Portfolio statistics and optimised weights are calculated using the training period data. The resulting portfolios are then evaluated using previously unseen test-period data.
An equal-weight portfolio is also included as a benchmark.
- Python
- NumPy
- Pandas
- SciPy
- Matplotlib
- yfinance