{% extends "base.html" %} {% block title %}Methodology{% endblock %} {% block page_title %}Methodology{% endblock %} {% block head %} {% endblock %} {% block content %}
AI Portfolio Stress Testing
This platform combines machine learning forecasting, Hidden Markov Model regime detection, Mean-Variance Optimisation, and SHAP explainability to deliver a fully integrated risk analytics workflow. The pipeline processes macroeconomic and market data end-to-end — from raw ingestion through to plain-English portfolio narratives.
ElasticNet XGBoost HMM Regime Ledoit-Wolf Max-Sharpe MVO SHAP scikit-learn FastAPI pandas / numpy Chart.js
01
Data Ingestion
Macroeconomic & Market Data Pipeline
Raw data is sourced from FRED (Federal Reserve), ECB, and Yahoo Finance. The pipeline collects US and European macroeconomic indicators alongside asset price series for S&P 500, Nasdaq 100, Gold, and Bitcoin.
pandas_datareader yfinance FRED API
02
Feature Engineering
Macro & Technical Feature Construction
Transforms raw series into predictive features used by the ML models.
feature_t = f(macro_{t-1..t-3}, price_momentum_{1m,3m,6m}, rolling_vol_{3m,6m})
03
Regime Detection
Hidden Markov Model — Market State Classification
A Gaussian Hidden Markov Model classifies monthly market states. States are labelled by their return/volatility characteristics.
P(regime_t | regime_{t-1}) via transition matrix A observation prob: N(μ_k, Σ_k) per state k
hmmlearn GaussianHMM Baum-Welch
04–05
Macro Model Training
Macro Index Construction & Asset Model Training
Two complementary steps. Phase 4 builds composite macro indices via PCA; Phase 5 trains asset-level linear models as a warm-up for Phase 6.
PCA OLS statsmodels
06
ML Ensemble Forecasting
ElasticNet + XGBoost Return Forecasting
Two-model ensemble trained per asset on lagged macro + technical features. A two-pass training strategy handles BTC's shorter data history.
ŷ_t = 0.5 · ŷ_EN(X_{t-1}) + 0.5 · ŷ_XGB(X_{t-1})
ElasticNet XGBoost walk-forward CV
06.1
Hyperparameter Tuning
Grid Search + Rolling Validation
Extended hyperparameter search to find optimal model configurations.
07
Portfolio Optimisation
Mean-Variance Optimisation + Regime Tilts + Stress Testing
Uses ensemble expected returns and Ledoit-Wolf shrinkage covariance to solve for the Maximum-Sharpe tangency portfolio, then applies regime-based tilts.
max_w (μᵀw) / √(wᵀΣ̂w) s.t. Σ wᵢ = 1, wᵢ ≥ 0 REGIME_TILT: w_adjusted = clip(w_base + tilt_Δ, 0, 1), renormalised
Ledoit-Wolf Max-Sharpe scipy.optimize SLSQP
08
Explainability
SHAP Feature Attribution + ElasticNet Coefficients
Decomposes model predictions into feature-level contributions for transparency.
Portfolio factor exposure_f = Σ_i weight_i · mean_k |SHAP_i(x_k, f)|
SHAP TreeExplainer LinearExplainer
09–10
API & Dashboard
FastAPI REST Layer + Server-Rendered Analytics Dashboard
Phase 9 exposes all pipeline outputs as REST endpoints with a NarrativeEngine for plain-English explanations. Phase 10 delivers this full-screen dashboard.
FastAPI Jinja2 Chart.js 4.4 Uvicorn
Risk Metrics Glossary
MetricFormula / DefinitionInterpretation
VaR 95% 5th percentile of return distribution Maximum monthly loss not exceeded 95% of the time
CVaR 95% E[r | r < VaR₉₅] Expected loss in the worst 5% of outcomes (tail risk)
Sharpe Ratio (μ_p − r_f) / σ_p Risk-adjusted return per unit of total volatility
Diversification Ratio Σ(w_i · σ_i) / σ_portfolio How much diversification reduces portfolio volatility; >1 is good
Max Drawdown min(cumret_t / max(cumret_{0..t}) − 1) Worst peak-to-trough loss over the observed period
Ledoit-Wolf Σ̂ = (1−δ)·S + δ·μ̂·I Shrinkage estimator; δ chosen analytically to minimise MSE
Scope note: The core portfolio universe is limited to SPX, NDX, Gold and BTC. FTSE 100 and FX series (EUR/USD, GBP/USD, DXY) are ingested as macro conditioning variables and feature inputs only; they do not currently enter the portfolio allocation or stress test return calculations. Extending the investable universe to include FTSE or FX instruments would require additional asset-level sensitivity models and covariance matrix expansion.
{% endblock %}