Repository Public Research preview
1# CHANGELOG — révision scientifique complète (editorial board, 2026-10-17)23WP 12 — *Forecasting Realized Volatility Across Asset Classes* — version 0.1 (août 2026, brouillon ; pipeline jamais exécuté4jusqu'au bout) → **version 0.2** (octobre 2026). État figé avant révision : tag git `pre-revision-20261017`,5`docs/main_pre-revision-20261017.pdf` (9 p.). Rapport scientifique : `docs/REVIEW-REPORT.md`.67## 1. Corrections majeures du code (preuves dans le dépôt)89| # | Où | Avant | Après | Pourquoi / preuve |10|---|----|-------|-------|-------------------|11| C1 | `src/wp12/models_econ.py::rolling_garch_forecasts` | La prévision était tirée de l'objet `res` ajusté à la date de ré-estimation : entre deux ré-estimations (22 j) la prévision GARCH/GJR/EGARCH restait **figée**, et même à la date de ré-estimation elle conditionnait sur les rendements jusqu'à *t−1* (décalage d'un jour). | Paramètres ré-estimés tous les 22 j sur la fenêtre se terminant à l'origine *t* ; récursion de variance refiltrée **chaque jour** sur les données jusqu'à *t* (`arch_model(...).fix(params).forecast(...)`), prévision = E[σ²_{t+1..t+h} \| F_t]. | Vérifié empiriquement sur `econ_SPY.parquet` (v0.1) : seuls 3,3 % des jours consécutifs avaient une prévision GARCH différente (= 1/22). Les 25 fichiers `econ_*.parquet` ont été **ré-exécutés** (6 min 18 s, 16 workers) ; anciens fichiers conservés dans `data/processed/forecasts_pre-revision-20261017/` (non commités). |12| C2 | `src/wp12/models_econ.py::rolling_realgarch_forecasts` | Fenêtre d'estimation et filtre de l'état `log h` arrêtés à *t−1* : première prévision = E[x_t] au lieu de E[x_{t+1}]. | Fenêtre et filtre jusqu'à *t* inclus ; `mu = ω + β log h_t + γ log x_t`. | Lecture du code ; ré-exécuté avec C1. |13| C3 | `src/wp12/evaluation.py::model_confidence_set` | La statistique `t_{i·} = d_{i·}/sqrt(var_i)` était studentisée par la variance bootstrap de la perte moyenne du modèle *i* (`var(L̄_i*)`) et non par celle de l'écart à la moyenne de l'ensemble `var(d̄_{i·}*)` — incohérent avec Hansen-Lunde-Nason (2011, éq. T_max). | `var_i = var(boot_d)` avec `boot_d = L̄_i* − moyenne de l'ensemble`. | Définition HLN 2011 §3.1 ; test unitaire `tests/test_evaluation.py` toujours vert (18/18). |14| C4 | `scripts/04_evaluate.py::attach_actuals` | Pertes moyennes, DM et MCS calculés sur les dates propres à chaque modèle (LSTM/Transformer commencent 22 j plus tard ; le pooled plus tôt car il compte le calendrier-union). | **Échantillon commun** par (actif, horizon) : seules les dates où *tous* les modèles ont une prévision sont conservées (journalisé dans la sortie de 04). | Comparabilité des pertes moyennes ; standard de la littérature. |15| C5 | `src/wp12/models_ml.py::rolling_pooled_lgbm`, `scripts/03_run_models.py::run_pooled`, `scripts/05_robustness.py::part_loo` | LightGBM `n_jobs=-1` (18 threads) : 9 s par ré-estimation par sursouscription ; horizons et exclusions en série (≈ 77 min pour le pooled seul). | `n_jobs=2` (2,4 s/ré-estimation) ; un processus par horizon (pooled) et par (actif exclu, horizon) (LOO) ; `--part loo-forecast` séparé de la comparaison. | Chronométrage du 2026-10-17 (n_jobs=2 : 2,42 s ; 4 : 2,55 s ; 8 : 4,08 s ; 18 : 8,95 s). Fréquence de ré-estimation mensuelle **inchangée**. |16| C6 | `scripts/05_robustness.py::part_outliers` (nouveau) | — | Sensibilité des résultats crypto aux jours de RV implausible (> 500 % annualisé) ; sortie `results/reproduced/outlier_sensitivity.csv`, table `results/tables/outliers.tex`. | Diagnostic données : BTC 2013-04-10 (2 530 % ann.), XRP/ETH/ADA 2017 et fév. 2021 (> 1 000 %) ; cf. REVIEW-REPORT §Données. |17| C7 | `scripts/08_make_tables.py::table_sensitivity` | Table fréquence × fenêtre ; plantait sans `window_sensitivity.csv`. | Bloc fenêtre imprimé seulement si le fichier existe ; ratio à HAR ajouté par mesure ; `table_outliers` ajoutée. | — |18| C8 | `scripts/90_verify_bib.py` (nouveau) | — | Vérification Crossref de chaque entrée du `.bib` → `docs/bib-verification.csv`. | Protocole §Références. |19| C10 | `src/wp12/models_econ.py` (GARCH, GJR, EGARCH, Realized GARCH) | **Aucun filtre d'insanité** sur la famille GARCH alors que le texte l'annonçait pour « tous les modèles » : les prévisions EGARCH simulées explosaient (max 7,6·10²⁴⁸ sur TLT/EURUSD/ZN…), contaminant Comb-Mean/Comb-InvMSE et le MSE (overflow). | Filtre d'insanité (étendue de la cible réalisée sur la fenêtre, comme HAR) appliqué aux quatre modèles ; prévisions non finies ignorées. | Constaté sur `merged_forecasts.parquet` du premier passage de 04 (22:36) ; econ ré-exécuté (2 min 23 s). |20| C11 | `models_econ.py`, `models_ml.py` (tous les filtres d'insanité) | Borne inférieure = min de la cible sur la fenêtre, **y compris deux jours ADA à RV = 0** (4 et 9 janv. 2020, flux mort) → prévisions HARQ négatives tronquées à 10⁻¹² → QLIKE ≈ 10⁹ sur 19 jours ADA (QLIKE moyen HARQ h=1 : 494 075). | Borne inférieure = min des cibles **strictement positives**. | `losses_by_ticker.csv` avant/après ; HARQ h=1 overall 494 075 → 0,516 (ratio 2,01). Le pooled, les ML et deep n'ont pas été ré-exécutés avec cette borne (elle n'était contraignante que sur ADA pour HARQ ; prévisions minimales des autres modèles ≥ 3·10⁻⁷). |21| C12 | `scripts/04_evaluate.py::load_forecasts` | `pooled_loo.parquet` (4 actifs) était chargé comme un 26ᵉ modèle → l'échantillon commun s'effondrait à 766 k lignes. | Fichier LOO exclu de 04 (comparé dans 05). | Journal 04 : 4 517 493 → 766 402 lignes (bug) vs 4 483 121 → 4 432 500 (corrigé). |22| C13 | `scripts/09_build_paper.py::check_headers` | Signalait `titlepage.tex` (page titre canonique sans en-tête projet). | Fichiers `titlepage*.tex` exemptés. | HARMONISATION §3. |23| C9 | `config.yaml` | `min_intraday_bars: 30` (non lu par le code). | Commentaire corrigé : seuils effectifs 250 (equity RTH) / 700 (autres), `realized_vol.MIN_BARS`. | Incohérence config/texte. |2425## 2. Texte — avant / après2627| # | Section | Avant (v0.1) | Après (v0.2) | Raison |28|---|---------|--------------|--------------|--------|29| T1 | `introduction.tex` | **Vide** (en-tête seulement, bien que le README annonce la section « written »). | Introduction complète (motivation, désaccord de la littérature, design, aperçu des résultats généré à partir de `results/reproduced/`, contributions, plan). | Section manquante. |30| T2 | `literature.tex` | 44 références ; « five HAR variants » ; pas de résultats contradictoires ; pas de littérature crypto-données. | 16 références vérifiées ajoutées (voir §4) ; « six HAR specifications » ; évidence contradictoire (Branco-Rubesam-Zevallos 2024 vs Christensen et al. 2023 / Zhang et al. 2024) ; justification GW 2006 vs West 1996 pour le DM en fenêtre roulante ; qualité des données crypto (Alexander-Dakos 2020). | Master prompt §5-6. |31| T3 | `data.tex` | « day = calendar day in UTC » pour la crypto ; « AC(1) averages 0.70–0.82 » ; univers en liste à puces ; « roughly 94 million bars » ; README « five classes ». | Jour crypto = jour calendaire **US Eastern** (le client API ne convertit aucun fuseau : `api_client.py` ; `n_bars` max = 1 440) ; AC(1) par classe **0,70 / 0,74 / 0,77 / 0,86** (recalculé sur `panel.parquet`) ; jours de sauts par classe 3,7 / 8,2 / 10,2 / 14,8 % ; univers en prose ; 93,8 millions de barres (compte pyarrow) ; quatre classes partout ; paragraphe sur les jours de RV implausible. | Affirmations non vérifiées ou fausses. |32| T4 | `methodology.tex` | Description verbale de GARCH/GJR/EGARCH, DM, MCS, combinaisons, GR, utilité, VaR ; « fourteen additional predictors » ; facteur de conversion GARCH non formalisé ; pas d'échantillon commun ; Realized GARCH multi-pas sans formule. | Équations ajoutées : cible (eq:target), RV sous-échantillonné (eq:rvss), TQ explicité, GARCH/EGARCH (eq:garch, eq:egarch), facteur ĉ_t et mapping (eq:garch_map), forme réduite du Realized GARCH, DM avec Bartlett (eq:dm), MCS t_{i·}/T_max (eq:mcs), MZ (eq:mz), encompassing (eq:enc), poids inverse-MSE (eq:comb), statistique de fluctuation (eq:gr), poids de timing (eq:timing), gain d'utilité (eq:utility), LR de Kupiec (eq:kupiec) ; **quinze** prédicteurs supplémentaires (compte dans `ml_features`) ; sous-section « Forecast target and rolling protocol » avec l'échantillon commun ; note de bas de page sur la correction C1. | Master prompt §4. |33| T5 | `results.tex`, `robustness.tex`, `economic_value.tex`, `conclusion.tex` | Vides. | Rédigées à partir des sorties de `results/reproduced/` (voir §3) ; chaque chiffre renvoie à un CSV/table générée. | — |34| T6 | `appendix.tex` | Vide. | Table par actif, grilles d'hyperparamètres, reproductibilité et temps d'exécution. | — |35| T7 | `main.tex` | `\WPabstract` = texte provisoire « TO BE WRITTEN… » ; `\WPdate` August 2026 ; `\WPversion` 0.1. | Résumé rédigé à partir des résultats ; October 2026 ; 0.2 ; mots-clés en minuscules (sauf sigles). | Protocole. |3637## 3. Réanalyses exécutées (2026-10-17, Mac Studio M5 Max 18 c / 48 Go, Python 3.14)3839| Étape | Commande | Durée | Sortie |40|-------|----------|-------|--------|41| Famille économétrique (HAR ×6, GARCH ×3, Realized GARCH) × 25 actifs — 3 passages (après C1-C2 ; après C10 ; après C11) | `python3 scripts/03_run_models.py --family econ --workers 16` | 6 min 18 s + 2 min 23 s + 2 min 30 s | `data/processed/forecasts/econ_*.parquet` (non commités) |42| Pooled LightGBM (mensuel, 3 horizons en parallèle) | `python3 scripts/03_run_models.py --family pooled` | 23 min 54 s (en concurrence avec le LOO ; ≈ 8 min seul d'après le chronométrage unitaire) | `forecasts/pooled.parquet` (203 911 prévisions) |43| Pooled leave-one-out (NVDA, GBPUSD, ETH, GC × 3 horizons, 12 processus) | `python3 scripts/05_robustness.py --part loo-forecast` | 23 min 59 s (simultané au pooled) | `forecasts/pooled_loo.parquet` (34 484 prévisions) |44| Évaluation (échantillon commun, combinaisons, pertes, DM, MCS 5 000 bootstraps, MZ, encompassing) | `python3 scripts/04_evaluate.py` | 35 s | `results/reproduced/{losses_*,dm_*,mcs_*,mz_*,encompassing_*}.csv` |45| Robustesse : sous-périodes, LOO (comparaison), GR, outliers | `python3 scripts/05_robustness.py --part subperiods|loo|gr|outliers` | 6 s | `subperiod_losses.csv`, `transferability.csv`, `gr_fluctuation.csv`, `outlier_sensitivity.csv` |46| Interprétation (SHAP + permutation, pooled h=1) | `python3 scripts/03_run_models.py --family interpret` | 11 s | `shap_h1.csv`, `permutation_h1.csv` |47| Valeur économique (timing, utilité, VaR) | `python3 scripts/06_economic_value.py` | 4 s | `timing_*.csv`, `utility_*.csv`, `var_*.csv` |4849**Budget** : le protocole autorisait < 30 min ; l'estimation préalable (econ 4 min, pooled 8 min, LOO 10 min, reste 5 min) tenait dans50le budget, mais la contention CPU entre le pooled et le LOO lancés ensemble (30 threads sur 18 cœurs) a porté ces deux étapes à 24 min,51et les deux corrections C10-C11 découvertes à l'évaluation ont imposé deux ré-exécutions de la famille économétrique. Temps machine total52≈ 45 min. Toutes les sorties sont réelles et reproductibles par les commandes ci-dessus.53| Figures et tables | `python3 scripts/07_make_figures.py && python3 scripts/08_make_tables.py` | < 1 min | `figures/*.png`, `results/tables/*.tex` |5455Prévisions **réutilisées** de l'exécution de l'auteur du 2026-08-10 (code inchangé depuis pour ces familles, vérifié par `git log` sur56`models_ml.py` : dernier commit 0ca469f du 2026-08-10 20:56, fichiers écrits 21:12–22:33) : `ml_*.parquet` (12 modèles tabulaires × 25 actifs,57≈ 2 h de calcul), `deep_*.parquet` (LSTM, Transformer), et `results/reproduced/frequency_sensitivity.csv` (`05 --part freq`, écrit 22:51).5859## 4. Références (57 → 73, toutes vérifiées sur Crossref — `docs/bib-verification.csv`)6061- **DOI de revue ajouté** sur 53 entrées existantes (Crossref renvoyait souvent la version SSRN/NBER : remplacée par le DOI de l'article publié, résolu62 et contrôlé titre/revue/volume/pages via `api.crossref.org/works/<doi>`). Sans DOI (inexistant) : Mincer-Zarnowitz 1969 (chapitre NBER, URL63 ajoutée), Vaswani et al. 2017, Lundberg-Lee 2017, Ke et al. 2017 (NeurIPS).64- **Corrigées** : `RahimikiaPoon2020` (était un `@article` avec « journal = SSRN Working Paper » → `@techreport`, DOI 10.2139/ssrn.3707796) ;65 `MincerZarnowitz1969` (éditeur, lieu, URL).66- **Ajoutées (16)** : Bollerslev-Hood-Huss-Pedersen 2018 RFS (10.1093/rfs/hhy041) ; Zhang-Zhang-Cucuringu-Qian 2024 JFEC (10.1093/jjfinec/nbad005) ;67 Branco-Rubesam-Zevallos 2024 JEF (10.1016/j.jempfin.2024.101524) ; Andersen-Bollerslev-Meddahi 2005 Econometrica (10.1111/j.1468-0262.2005.00572.x) ;68 Hansen-Lunde 2006b J. Econometrics (10.1016/j.jeconom.2005.01.005) ; Diebold 2015 JBES (10.1080/07350015.2014.983236) ; Clements-Preve 2021 JBF69 (10.1016/j.jbankfin.2021.106285) ; Hansen-Huang 2016 JBES (10.1080/07350015.2015.1038543) ; Patton-Sheppard 2009 Handbook (10.1007/978-3-540-71297-8_36) ;70 Buccheri-Corsi 2021 JFEC (10.1093/jjfinec/nbz025) ; West 1996 Econometrica (10.2307/2171956) ; Brownlees-Gallo 2006 CSDA (10.1016/j.csda.2006.09.030) ;71 Patton 2020 JBES (10.1080/07350015.2019.1585256) ; Catania-Grassi-Ravazzolo 2019 IJF (10.1016/j.ijforecast.2018.09.005) ; Alexander-Dakos 2020 QF72 (10.1080/14697688.2019.1641347) ; Aït-Sahalia-Mykland-Zhang 2005 RFS (10.1093/rfs/hhi016).73- **Retirées** : aucune (toutes les références v0.1 existent et sont correctement citées).7475## 5. Non modifié faute de temps de calcul (< 30 min imposés) — voir REVIEW-REPORT « analyses recommandées non exécutées »7677- Sensibilité à la fenêtre d'estimation (500 / 1 000 / 2 000 j) : `05 --part window` (~20 min sur 16 cœurs) — table du papier imprimée sans ce bloc.78- Ré-exécution des 12 apprenants tabulaires et des 2 apprenants profonds (≈ 2 h 20) : prévisions de l'auteur réutilisées (code inchangé).79- Nettoyage des barres crypto (Brownlees-Gallo 2006) et test de sauts par seuil (Corsi-Pirino-Renò 2010) : non implémentés.80