A quantitative risk model that calculates Value at Risk (VaR) for a multi-stock portfolio using Monte Carlo simulation — built from raw market data through to a production-grade risk report.
This project simulates 10,000 market scenarios across a $1,000,000 hypothetical portfolio to answer one critical question:
"With 95% confidence, what is the maximum this portfolio can lose in a single day?"
That number is Value at Risk (VaR) — the core risk metric used by every major bank, hedge fund, and asset manager on Wall Street.
var-model/
│
├── data/
│ └── prices.csv # Historical closing prices (5 years, 5 stocks)
│
├── notebooks/
│ └── var_analysis.ipynb # Full walkthrough with charts & commentary
│
├── src/
│ ├── data_pull.py # Yahoo Finance data extraction
│ ├── returns.py # Daily returns & volatility calculations
│ ├── covariance.py # Covariance matrix construction
│ ├── monte_carlo.py # 10,000-scenario Monte Carlo simulation
│ └── var_report.py # VaR output & visualisations
│
├── requirements.txt
├── .gitignore
├── LICENSE
└── README.md
A $1,000,000 portfolio is built across 5 stocks spanning uncorrelated sectors:
| Ticker | Company | Sector | Weight |
|---|---|---|---|
| AAPL | Apple | Technology | 25% |
| XOM | ExxonMobil | Energy | 20% |
| JPM | JPMorgan | Financials | 20% |
| NVDA | Nvidia | Semiconductors | 20% |
| JNJ | J&J | Healthcare | 15% |
5 years of daily closing prices pulled from Yahoo Finance via yfinance.
# Daily log returns
returns = np.log(prices / prices.shift(1)).dropna()
# Volatility (annualised standard deviation)
volatility = returns.std() * np.sqrt(252)
# Covariance matrix — how stocks move relative to each other
cov_matrix = returns.cov() * 252Using Cholesky decomposition to preserve the real-world correlation structure between assets, the model generates 10,000 independent 1-day portfolio return scenarios.
# Cholesky decomposition preserves covariance structure
L = np.linalg.cholesky(cov_matrix)
simulated_returns = (L @ np.random.normal(size=(n_assets, n_simulations))).T95% 1-Day VaR: -$XX,XXX (portfolio will not lose more than this 95% of days)
99% 1-Day VaR: -$XX,XXX (tail risk — the worst 1% of scenarios)
Expected Shortfall (CVaR): -$XX,XXX (average loss beyond VaR threshold)
Python 3.10+# 1. Clone the repo
git clone https://github.com/YOUR_USERNAME/var-model.git
cd var-model
# 2. Create a virtual environment
python -m venv venv
source venv/bin/activate # Mac/Linux
venv\Scripts\activate # Windows
# 3. Install dependencies
pip install -r requirements.txt
# 4. Run the model
python src/monte_carlo.pyjupyter notebook notebooks/var_analysis.ipynbThe model produces:
- VaR figure at 95% and 99% confidence intervals
- Return distribution histogram with VaR threshold marked
- Correlation heatmap of the portfolio's asset relationships
- Portfolio simulation fan chart across 10,000 scenarios
| Tool | Purpose |
|---|---|
| Python | Core language |
| NumPy | Matrix algebra & simulation |
| Pandas | Data wrangling |
| yfinance | Market data extraction |
| Matplotlib | Visualisation |
| SciPy | Statistical functions |
| Jupyter | Interactive analysis notebook |
MIT — see LICENSE