fix(paper): ETH 5m allineato al tick + hardening GUI/compose

Bug principale: in scripts/run_paper_trading.py il fetch usava
end = now.replace(minute=0,...), troncando sempre all'ora. ETH è
dichiarato timeframe=5m (commit 23b7273) ma di fatto veniva
valutato 1 volta ogni 60 min — 502 poll del run 39e027df hanno
prodotto solo 43 evaluazioni/asset, tutte a HH:00. Il commento
in load_assets segnala esplicitamente che a 1h la strategia
perde -33% su 7y: regressione vs backtest.

Fix: helper _align_end_to_timeframe(now, timeframe) snappa end
al boundary nativo dell'asset. Mappa 1m/5m/15m/30m/1h/4h/1d.
Test regression in src/strategy_crypto/tests con 9 casi.

Hardening accessorio incluso nello stesso commit:
- docker-compose.yml: state/ in RW per strategy-crypto-gui
  (SQLite WAL richiede SHM writable anche da reader).
- multi_swarm_core/dashboard/nicegui_app.py: ui.timer ora
  deactivate on_disconnect su 3 pagine (index/convergence/genomes)
  per evitare leak di timer dopo client disconnect.
- strategy_crypto/frontend/data.py: retry 5s su sqlite.connect
  per cold-start race quando GUI parte prima del paper writer.
- state/validation-hardened-001.json: output WFA tooling
  multi-fold del run phase1-hardened-001.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-05-18 17:04:15 +00:00
parent 23b7273e71
commit 6655e425fa
6 changed files with 451 additions and 11 deletions
+324
View File
@@ -0,0 +1,324 @@
{
"run_id": "7f65bd1832d94c638b588aab02fb223e",
"run_name": "phase1-hardened-001",
"n_folds": 4,
"top_k_requested": 5,
"top_k_evaluated": 5,
"symbol": "BTC-PERPETUAL",
"timeframe": "1h",
"start": "2018-09-01T00:00:00+00:00",
"end": "2026-01-01T00:00:00+00:00",
"ohlcv_bars": 64297,
"results": [
{
"genome_id": "9cf506b83bec55f6",
"fitness_is": 0.2847465321576384,
"sharpe_is": 0.6809931251900289,
"folds": [
{
"fold": 0,
"fitness": 0.4454407113532186,
"sharpe": 0.940612398713799,
"dsr": 0.09856838950479485,
"dsr_pvalue": 0.9014316104952051,
"return": 0.12691347502077277,
"max_dd": 0.08467873586477132,
"n_trades": 50,
"test_start": "2022-05-02 12:00:00+00:00",
"test_end": "2023-04-02 08:00:00+00:00"
},
{
"fold": 1,
"fitness": 0.3348901947844796,
"sharpe": 0.6215567075501345,
"dsr": 0.05615871498414856,
"dsr_pvalue": 0.9438412850158514,
"return": 0.1669550204052912,
"max_dd": 0.2425926649805225,
"n_trades": 60,
"test_start": "2023-04-02 09:00:00+00:00",
"test_end": "2024-03-02 05:00:00+00:00"
},
{
"fold": 2,
"fitness": 0.08496628060413243,
"sharpe": -0.291593157960215,
"dsr": 0.006828013272159182,
"dsr_pvalue": 0.9931719867278408,
"return": -0.06496567446731383,
"max_dd": 0.1933746053658072,
"n_trades": 72,
"test_start": "2024-03-02 06:00:00+00:00",
"test_end": "2025-01-31 02:00:00+00:00"
},
{
"fold": 3,
"fitness": 0.10547685784422405,
"sharpe": -0.04385303190774091,
"dsr": 0.013045759744378084,
"dsr_pvalue": 0.986954240255622,
"return": -0.003908970230222186,
"max_dd": 0.05825300658307936,
"n_trades": 31,
"test_start": "2025-01-31 03:00:00+00:00",
"test_end": "2025-12-31 23:00:00+00:00"
}
],
"fitness_oos_mean": 0.24269351114651366,
"fitness_oos_min": 0.08496628060413243,
"fitness_oos_max": 0.4454407113532186,
"fitness_oos_std": 0.15273583802070415,
"sharpe_oos_mean": 0.3066807290989944,
"sharpe_oos_min": -0.291593157960215,
"robust_score": 0.08496628060413243
},
{
"genome_id": "9f1f7ffa40b4900a",
"fitness_is": 0.2653851546757454,
"sharpe_is": 0.7183647852569522,
"folds": [
{
"fold": 0,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2022-05-02 12:00:00+00:00",
"test_end": "2023-04-02 08:00:00+00:00"
},
{
"fold": 1,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2023-04-02 09:00:00+00:00",
"test_end": "2024-03-02 05:00:00+00:00"
},
{
"fold": 2,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2024-03-02 06:00:00+00:00",
"test_end": "2025-01-31 02:00:00+00:00"
},
{
"fold": 3,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2025-01-31 03:00:00+00:00",
"test_end": "2025-12-31 23:00:00+00:00"
}
],
"fitness_oos_mean": 0.0,
"fitness_oos_min": 0.0,
"fitness_oos_max": 0.0,
"fitness_oos_std": 0.0,
"sharpe_oos_mean": 0.0,
"sharpe_oos_min": 0.0,
"robust_score": 0.0
},
{
"genome_id": "aff702f86c30e30f",
"fitness_is": 0.22070023288031862,
"sharpe_is": 0.49220575419744833,
"folds": [
{
"fold": 0,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2022-05-02 12:00:00+00:00",
"test_end": "2023-04-02 08:00:00+00:00"
},
{
"fold": 1,
"fitness": 0.0,
"sharpe": -1.3160615555061568,
"dsr": 2.0480110912755528e-14,
"dsr_pvalue": 0.9999999999999796,
"return": -0.004197667464114874,
"max_dd": 0.004197667464114874,
"n_trades": 1,
"test_start": "2023-04-02 09:00:00+00:00",
"test_end": "2024-03-02 05:00:00+00:00"
},
{
"fold": 2,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2024-03-02 06:00:00+00:00",
"test_end": "2025-01-31 02:00:00+00:00"
},
{
"fold": 3,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2025-01-31 03:00:00+00:00",
"test_end": "2025-12-31 23:00:00+00:00"
}
],
"fitness_oos_mean": 0.0,
"fitness_oos_min": 0.0,
"fitness_oos_max": 0.0,
"fitness_oos_std": 0.0,
"sharpe_oos_mean": -0.3290153888765392,
"sharpe_oos_min": -1.3160615555061568,
"robust_score": 0.0
},
{
"genome_id": "43236904205071d5",
"fitness_is": 0.22070023288031862,
"sharpe_is": 0.49220575419744833,
"folds": [
{
"fold": 0,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2022-05-02 12:00:00+00:00",
"test_end": "2023-04-02 08:00:00+00:00"
},
{
"fold": 1,
"fitness": 0.0,
"sharpe": -1.3160615555061568,
"dsr": 2.0480110912755528e-14,
"dsr_pvalue": 0.9999999999999796,
"return": -0.004197667464114874,
"max_dd": 0.004197667464114874,
"n_trades": 1,
"test_start": "2023-04-02 09:00:00+00:00",
"test_end": "2024-03-02 05:00:00+00:00"
},
{
"fold": 2,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2024-03-02 06:00:00+00:00",
"test_end": "2025-01-31 02:00:00+00:00"
},
{
"fold": 3,
"fitness": 0.0,
"sharpe": 0.0,
"dsr": 0.0,
"dsr_pvalue": 1.0,
"return": 0.0,
"max_dd": 0.0,
"n_trades": 0,
"test_start": "2025-01-31 03:00:00+00:00",
"test_end": "2025-12-31 23:00:00+00:00"
}
],
"fitness_oos_mean": 0.0,
"fitness_oos_min": 0.0,
"fitness_oos_max": 0.0,
"fitness_oos_std": 0.0,
"sharpe_oos_mean": -0.3290153888765392,
"sharpe_oos_min": -1.3160615555061568,
"robust_score": 0.0
},
{
"genome_id": "78a445d3043e0771",
"fitness_is": 0.20950868586433583,
"sharpe_is": 0.2940379509455447,
"folds": [
{
"fold": 0,
"fitness": 0.07182313189843528,
"sharpe": -0.5971649832941454,
"dsr": 0.0029614586254508167,
"dsr_pvalue": 0.9970385413745492,
"return": -0.10657245144370586,
"max_dd": 0.17076725093180228,
"n_trades": 14,
"test_start": "2022-05-02 12:00:00+00:00",
"test_end": "2023-04-02 08:00:00+00:00"
},
{
"fold": 1,
"fitness": 0.04914620786914511,
"sharpe": -0.7350195766937807,
"dsr": 0.0007433210570883239,
"dsr_pvalue": 0.9992566789429117,
"return": -0.03472119511680272,
"max_dd": 0.060780295013844174,
"n_trades": 20,
"test_start": "2023-04-02 09:00:00+00:00",
"test_end": "2024-03-02 05:00:00+00:00"
},
{
"fold": 2,
"fitness": 0.0,
"sharpe": 1.2071345821102195,
"dsr": 0.14855640183813817,
"dsr_pvalue": 0.8514435981618618,
"return": 0.12296871148346566,
"max_dd": 0.05065940776643054,
"n_trades": 9,
"test_start": "2024-03-02 06:00:00+00:00",
"test_end": "2025-01-31 02:00:00+00:00"
},
{
"fold": 3,
"fitness": 0.0,
"sharpe": -1.6874561123211371,
"dsr": 9.510326955509528e-06,
"dsr_pvalue": 0.9999904896730445,
"return": -0.03197955364502458,
"max_dd": 0.032239270519921044,
"n_trades": 7,
"test_start": "2025-01-31 03:00:00+00:00",
"test_end": "2025-12-31 23:00:00+00:00"
}
],
"fitness_oos_mean": 0.0302423349418951,
"fitness_oos_min": 0.0,
"fitness_oos_max": 0.07182313189843528,
"fitness_oos_std": 0.03128704497338385,
"sharpe_oos_mean": -0.4531265225497109,
"sharpe_oos_min": -1.6874561123211371,
"robust_score": 0.0
}
]
}