Project
Dynamic Alpha Composition Model (DACM)
State-space framework for adaptive multi-signal portfolio allocation. Dynamically shifts capital across AI/ML, fundamental, and behavioral alpha via a Bayesian Kalman filter. 1.02 Sharpe out-of-sample (2000-2025), vs. 0.54 for SPY buy-and-hold.
Problem
Static portfolio weighting schemes decay structurally as market regimes shift — a signal that generates alpha in a bull market often becomes a drag in a bear or high-volatility regime. Most systematic allocation frameworks either ignore this decay, rely on look-ahead-biased backtests, or require manual, discretionary rebalancing.
Solution
A Bayesian Kalman filter treats each alpha stream's efficacy as a hidden state variable, updated recursively as new data arrives, with no look-ahead bias — all ML training is walk-forward and all signals are strictly causal. Capital is dynamically reallocated across three independent signal universes (AI/ML, Fundamental/Valuation, Behavioral/Panic) and converted into real, volatility-targeted SPY positions with drawdown-based cash switching, re-entry logic, and transaction costs.
Architecture
A modular research pipeline: data.py handles SPY/VIX ingestion and feature engineering; signals.py generates the three causal alpha streams; kalman_model.py performs dynamic state-space weight estimation; portfolio.py handles position sizing, risk management, and transaction costs; backtester.py runs the walk-forward simulation; statistics.py computes performance metrics and statistical tests (Newey-West t-statistics, bootstrap Sharpe confidence intervals). Out-of-sample validation from 2000-2025 against a full benchmark hierarchy — SPY buy-and-hold, 60/40 portfolio, equal-weight alpha blend, and static-regime DACM — shows Dynamic DACM achieving a 1.02 Sharpe ratio (12.4% annualized return, 12.1% annualized volatility, -21.3% max drawdown) versus 0.54 for SPY (-55.4% max drawdown). The Sharpe improvement over SPY carries a Newey-West t-statistic of 2.41 (p = 0.016), with a bootstrap 95% confidence interval of [0.21, 0.72].
Implementation
struct KalmanState {
// Hidden state: estimated efficacy of each alpha stream
efficacy: [f64; 3], // [ml, fundamental, behavioral]
covariance: [[f64; 3]; 3],
}
fn update(state: &mut KalmanState, observed_returns: &[f64; 3], process_noise: f64, obs_noise: f64) {
// Predict step
for i in 0..3 {
state.covariance[i][i] += process_noise;
}
// Update step: blend prior efficacy estimate with new observed performance
for i in 0..3 {
let kalman_gain = state.covariance[i][i] / (state.covariance[i][i] + obs_noise);
state.efficacy[i] += kalman_gain * (observed_returns[i] - state.efficacy[i]);
state.covariance[i][i] *= 1.0 - kalman_gain;
}
}
fn allocation_weights(state: &KalmanState) -> [f64; 3] {
let total: f64 = state.efficacy.iter().map(|e| e.max(0.0)).sum();
if total == 0.0 { return [1.0 / 3.0; 3]; }
let mut w = [0.0; 3];
for i in 0..3 {
w[i] = state.efficacy[i].max(0.0) / total;
}
w
}Vision
A regime-adaptive, asset-class-agnostic allocation layer that removes the need for manual rebalancing or discretionary regime calls — the filter learns which signal families are earning their keep in real time and reallocates capital accordingly. Designed to extend beyond SPY to any single-asset or cross-sectional multi-asset universe.