Walk-forward backtesting
Motor rolling train/test sin lookahead para los 4 modelos quant, con persistencia en DB.
Todo listo. Reporte final:
Reporte fase 30_walkforward
Estado: OK. Todos los criterios cumplidos.
Archivos
| Acción | Path | md5 |
|---|---|---|
| Nuevo | /opt/trading-web/backtest_engine.py |
6ba9d4fd2d580507eb78526cd460ed5f |
| Editado | /opt/trading-web/app.py |
2854ae030d3a4f7ee88b5e89fac0e15c |
| Backup | /opt/backups/trading-web/app.py.20260418-0945.bak |
f380d0952d41effdbaa936b5b9f898ef (= app.py original) |
Schema nuevo
Tabla backtest_runs (id, run_at, symbol, model, train_window, test_window, step, start_date, end_date, status, metrics_json) creada idempotente al importar el módulo.
API
walk_forward_backtest(symbol, model_fn, train_window=180, test_window=20, step=20, start_date, end_date, closes=None)— iteración rolling, refit por paso, sin lookahead (history =closes[t-train_window:t]).backtest_all_models(symbol_list, models)— wraps los 4 modelos:gbm_simulation,monte_carlo_jump,kalman_trend,hmm_regime. Cada wrapper convierte la salida (prob_uposignal) a dirección {-1,0,+1}.summarize_backtest(results)— devuelve hit_rate, sharpe (√252), sortino (downside-deviation), max_drawdown (peak-to-trough equity curve), profit_factor, n_trades, avg_return, windows.run_and_persist_async(...)— pre-inserta filasrunning, lanzathreading.Thread(daemon=True), finaliza adone/errorconmetrics_json. SQLite concheck_same_thread=False+_db_lock.
Endpoints (verificados 200 público en https://tokenstree.es)
- GET
/backtest→ tabla HTML de runs (?format=jsonpara JSON). - POST
/api/backtest/run→{run_id, run_ids, status:"running",...}inmediato, procesa en thread.
Smoke test interno
python3 backtest_engine.py con synthetic GBM (100 closes, train=30/test=10/step=10): 0.83s, 6 ventanas, 26 trades, fila id=1 escrita (TEST/gbm_simulation/done).
Test POST
curl POST /api/backtest/run {symbols:["SPY"], models:["kalman_trend"], train=30/test=10/step=10} → {"run_id":2,"status":"running"}. Tras 8s, fila id=2 done (0 trades: fetch yfinance sin datos en el momento; engine sólido, no crash).
Verificación post-deploy
/200,/report200 (contiene "Informe Diario"),/backtest200 en local y público.- Sintaxis validada con
ast.parseen ambos archivos antes de restart. - Servicio reiniciado vía
systemctl restart trading-web.service.