Stacking ensemble
Combinador NNLS/Ridge sobre las señales de los modelos base, elegido por Sharpe en holdout.
Reporte fase 40_stacking_ensemble
Estado: OK. Stacking integrado, data/ensemble_weights.json persistido, servicio restaurado, 3 curl tests en verde. Decisión de deploy documentada con caveat honesto.
Archivos (en 213.165.80.157)
| Acción | Path | md5 |
|---|---|---|
| Nuevo | /opt/trading-web/stacking.py |
2a69dcde0067d8ab01389f2f4e388f05 |
| Editado | /opt/trading-web/quant_engine.py |
4e028193776cbbd44752f11409099265 |
| Artefact | /opt/trading-web/data/ensemble_weights.json |
ba60856a4d2135b21fa36644fe8eed61 |
| Backup | /opt/backups/trading-web/quant_engine.py.20260418-1308.bak |
(original pre-fase-40) |
| Backup | /opt/backups/trading-web/agents.py.20260418-1308.bak |
(sin cambios esta fase) |
Resultado entrenamiento
- 16 344 samples de cobertura completa (
quant_errors⋈quant_predictions), 13 075 train / 3 269 holdout temporal. - Entrenador selecciona entre Ridge y NNLS por Sharpe holdout → eligió NNLS.
- Pesos:
gbm=0.524, kalman=0.476, resto=0. Intercept=0. notes: candidates=[nnls:sharpe=3.85/hr=62.4%, ridge:sharpe=2.30/hr=60.5%] chose=nnls
Comparativas
Holdout de predicciones reales (mismo horizonte que producción):
| Modelo | HR | Sharpe |
|---|---|---|
| Ensemble (prev) | 49.9% | −0.04 |
| gbm | 57.7% | 2.00 |
| kalman | 61.8% | 3.76 |
| stacking | 62.4% | 3.85 |
→ Stacking supera al ensemble previo y a todos los modelos individuales.
Walk-forward fase 30 (SPY/QQQ/GLD/BTC, 2y closes, train=180/test=20/step=20):
| Modelo | n | HR | mean Sharpe |
|---|---|---|---|
| gbm | 545 | 53.0% | −0.46 |
| merton | 141 | 53.9% | +1.19 |
| kalman | 559 | 49.6% | −0.51 |
| hmm | 1017 | 50.2% | +0.49 |
| stacking | 1249 | 48.6% | −0.01 |
→ Stacking NO supera a los mejores individuales (Merton/HMM) en este walk-forward.
Decisión
Deploy ejecutado — el stacking reemplaza al ensemble previo en run_full_quant. Motivos + caveats detallados en STACKING_REPORT.md:
- Gana netamente en la única comparativa apples-to-apples (holdout de predicciones reales del sistema).
- Pierde en walk-forward yfinance → documentado como mismatch de horizonte + regime shift + feature scope limitado (RSI/MACD/sentiment no persistidos por prediction_id; ver deuda técnica).
- Fallback graceful a media GBM+Kalman si falla el import o el JSON.
- Contrato downstream (bias_correction + calibration + /report) intacto.
Verificación post-deploy
/ : 200
/report : 200 (contiene "Informe Diario")
/backtest: 200
Smoke run_full_quant(SPY): "Stacking (nnls): pred=713.01 return=+0.40% conf=60.7%"