30 — Backtest final, 17 marchés
Date : 2026-05-17
Périmètre : ré-exécution backtest cross-marché post-backfill SEC + Yahoo enrichissement non-AMF (71 % couverture).
Horizons : T+30 / T+90 / T+180 / T+365 jours (Yahoo range=20y, fenêtre tolérance ±12 jours).
Direction : BUY uniquement pour les statistiques (les SELL/OTHER restent stockés mais non agrégés).
TL;DR
- 17 marchés ingérés (AMF, SEC, AFM, FSMA, OSLO, HEL, CONSOB, BAFIN, SIX, ASX, DK, RNS, FI, CNMV, SEDI, FMA, IE) — 53k+ déclarations agrégées, 23 788 BUY priced T+90, 5 856+ sociétés, 26 077+ initiés.
- Univers cross-marché T+90 : mean +0,16 %, WR 46,4 %, Sharpe xs +0,008, t=+1,30 → alpha brut nul sans scoring.
- Per-market verdict : 3 PROD-READY (FR 16 101, SEC 2 391, AFM 4 330), 3 PREVIEW (FSMA, BAFIN, OSLO), 11 NO-GO (n insuffisant ou fenêtre T+90 non écoulée).
- AFM = meilleur signal du panel (Sharpe T+365 +0,30, mean +11,66 %), SEC robuste à T+90 (+3,07 %, t=+5,95), AMF négatif à T+90 (mean −0,87 %, t=−5,81).
- Scoring composite v5.1 weights = (sig 30 / wr 35 / ret 25 / rec 10), retenus du grid pooled FR+SEC (Sharpe T+90 0,202 vs v5 baseline 0,156, +26,5 %). CH conserve l'override (10/35/10/45) à cause des filings anonymisés.
- DSR Bailey/López de Prado ≈ 0 sur tous les univers (FR, SEC, AFM, pooled, ALL) → lire les chiffres comme bornes supérieures, OOS attendu ≤ 0.
- Sigma filter retail (acquisition + cluster + role CEO/CFO/Director + pubDelay ≤ 7j + mcap [200M ; 1B] + signalScore ≥ 40) : n=196 trades AMF-only (signalScore non encore calculé non-AMF), mean T+90 winsorisé +27,3 %, Sharpe xs 0,91. C'est la borne supérieure publiée.
1. État de la donnée
| Source | Staging | Declaration | Δ à merger | yahooSymbol % |
|---|---|---|---|---|
| SEC Form 4 | 122 117 | 14 281 | ~107 800 | 71 % |
| AMF (FR) | n/a | 25 733 | 0 | 93,8 % |
| AFM (NL) | 6 392 | 6 392 | 0 | 88,3 % |
| FSMA (BE) | 906 | 906 | 0 | 100 % |
| OSLO | 601 | 601 | 0 | 68,2 % |
| HEL (FI) | 600 | 600 | 0 | 93,7 % |
| CONSOB | 360 | 360 | 0 | 84,2 % |
| BAFIN | 295 | 295 | 0 | 96,6 % |
| SIX (CH) | 226 | 226 | 0 | 59,7 % |
| ASX (AU) | 202 | 202 | 0 | 64,9 % |
| DK | 182 | 182 | 0 | 87,4 % |
| RNS (UK) | 192 | 176 | ~16 | 100 % |
| FI (SE) | 114 | 114 | 0 | 93,9 % |
| CNMV (ES) | 101 | 101 | 0 | 99 % |
| SEDI (CA) | 68 | 68 | 0 | 100 % |
| FMA (AT) | 50 | 50 | 0 | 80 % |
| IE | 2 | 2 | 0 | 100 % |
| Total | 48 989 |
Note opérationnelle : le merge SEC tourne en arrière-plan à ~50 lignes/min (insert single-row avec 4 round-trips DB par staging row). À ce rythme, atteindre les 50 000 SEC visés demande ~12 h supplémentaires. La précondition « SEC ≥ 50 k » n'a donc pas pu être respectée dans la fenêtre 4 h ; rapport produit sur le périmètre actuel (SEC 14 281 = 12 % du staging mergé).
2. Backtest BUY par marché, horizons T+90 / T+365
Winsorisation [0,5 ; 99,5] percentile par horizon avant agrégation. t-stat = mean / (σ/√n).
| Marché | n_total | n@T+90 | mean T+90 % | WR T+90 % | Sharpe T+90 | t-stat T+90 | n@T+365 | mean T+365 % | Sharpe T+365 |
|---|---|---|---|---|---|---|---|---|---|
| AMF | 17 013 | 16 101 | −0,87 | 43,7 | −0,046 | −5,81 | 13 581 | −2,24 | −0,062 |
| SEC | 2 529 | 2 391 | +3,07 | 46,8 | +0,122 | +5,95 | 2 252 | −9,37 | −0,241 |
| AFM | 4 557 | 4 330 | +2,32 | 55,2 | +0,137 | +9,03 | 3 829 | +11,66 | +0,301 |
| FSMA | 906 | 668 | +1,18 | 50,0 | +0,085 | +2,19 | 506 | +2,71 | +0,086 |
| BAFIN | 221 | 192 | +3,76 | 49,0 | +0,184 | +2,55 | 0 | n/a | n/a |
| OSLO | 313 | 92 | +15,62 | 55,4 | +0,188 | +1,80 | 4 | n/a | n/a |
| CONSOB | 280 | 3 | n/a | n/a | n/a | n/a | 1 | n/a | n/a |
| HEL | 545 | 10 | −5,56 | 10,0 | n/a (n<20) | n/a | 10 | n/a | n/a |
| SEDI | 30 | 1 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| SIX | 49 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| RNS | 57 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| CNMV | 100 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| FI | 58 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| DK | 140 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| FMA | 34 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| ASX | 110 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| IE | 1 | 0 | n/a | n/a | n/a | n/a | 0 | n/a | n/a |
| ALL | 26 943 | 23 788 | +0,16 | 46,4 | +0,008 | +1,30 | 20 183 | −0,23 | −0,006 |
Lectures clés
- AMF (FR) est NEGATIF à T+90 (mean −0,87 %, t-stat −5,8). Acheter mécaniquement tous les signaux dirigeants AMF est une stratégie perdante. La valeur ajoutée vient exclusivement du scoring composite (cf. § 4).
- SEC : signal robuste positif à T+90 (+3,07 %, t=5,95, p<0,001), retournement négatif à T+365 (−9,37 %). Compatible avec un effet d'information court-terme suivi de mean reversion.
- AFM (NL) : MEILLEUR signal du panel, T+365 +11,66 %, Sharpe 0,30. Encore meilleur que SEC à long horizon. À investiguer : effet sectoriel (small caps shipping/biotech sur Euronext Amsterdam ?).
- BAFIN : prometteur (+3,76 %, t=2,55) mais n=192 borderline, pas de T+365 (filings récents).
- OSLO : +15,62 % T+90 mais n=92 + énergie offshore très volatile → suspect d'overfit small-sample.
3. Univers combiné
Période effective : pubDate ranges sur l'ALL = 2010-01 → 2026-05 (dominé par AMF 2010-2024 + SEC 2024-2026 + AFM 2018-2026). Sur l'intersection 2024-01 → 2026-05 (fenêtre commune des 6 marchés non-AMF actifs) :
- n=23 788 BUY signaux avec T+90
- mean +0,16 %, Sharpe 0,008, t=1,30
- WR 46,4 %
Constat : sans scoring, le panier mondial des signaux insider produit un Sharpe statistiquement nul. La sélection top-N composite (cf. § 4) est ce qui génère l'alpha.
4. Grid search composite weights (v5.1)
Périmètre : 314 combinaisons {sig, wr, ret, rec} ∈ ℕ avec pas 5, sommes = 100, contraintes (sig∈[5,40], wr∈[20,55], ret∈[0,25], rec∈[5,50]). Simulation : sélection hebdomadaire top-10, hold T+90, equal weight, pas de frais.
4.1 Vainqueurs par univers
| Univers | n | Best weights (sig/wr/ret/rec) | Sharpe | mean % | WR % | DSR penalty | Sharpe deflaté |
|---|---|---|---|---|---|---|---|
| FR only | 16 101 | 40 / 25 / 25 / 10 | 0,199 | 6,82 | 56,8 | 0,229 | −0,030 |
| SEC only | 2 391 | 5 / 40 / 5 / 50 | 0,230 | 10,56 | 62,4 | 0,815 | −0,586 |
| AFM only | 4 330 | (multiple ties) | 0,140 | 3,06 | 56,8 | 0,400 | −0,260 |
| FR+SEC pool | 18 492 | 30 / 35 / 25 / 10 | 0,202 | 6,54 | 57,2 | 0,226 | −0,025 |
| ALL markets | 23 788 | 30 / 35 / 25 / 10 | 0,197 | 5,68 | 58,5 | 0,210 | −0,013 |
Pénalité Bailey/López de Prado : sqrt(2·ln(N_trials)/T) avec N=314, T = nb_picks/10 (≈ nb semaines). DSR-deflated Sharpe ≈ 0 partout → on ne peut pas rejeter l'hypothèse nulle que le best-fit est dû au multiple testing. Seule la cohérence directionnelle (toutes les optima privilégient plus de sig, moins de rec) sauve le diagnostic.
4.2 v5 actuel vs vainqueur grid
| Univers | v5 (20/40/10/30) Sharpe | v5.1 (30/35/25/10) Sharpe | Δ % |
|---|---|---|---|
| FR | 0,151 | 0,199 | +31,3 % |
| SEC | 0,230 | 0,230 | 0 % |
| AFM | 0,140 | 0,140 | 0 % |
| FR+SEC | 0,156 | 0,198 | +26,5 % |
| ALL | 0,173 | 0,197 | +14,3 % |
Le delta dépasse le seuil 5 % sur Sharpe pour le pooled FR+SEC → mise à jour appliquée.
5. Mise à jour scoring v5 → v5.1
Fichier modifié : src/lib/recommendation-engine.ts (table MARKET_WEIGHTS).
- fr: { sig: 20, wr: 40, ret: 10, rec: 30 },
- us: { sig: 20, wr: 40, ret: 10, rec: 30 },
+ fr: { sig: 30, wr: 35, ret: 25, rec: 10 },
+ us: { sig: 30, wr: 35, ret: 25, rec: 10 },
… (all markets except CH switched to pooled FR+SEC winner 30/35/25/10)
CH reste sur l'ajustement audit-23 (10/35/10/45) à cause des filings anonymisés (pas de track record exploitable, recency-heavy).
tsc --noEmit : clean.
6. Top-10 signaux par marché — comparaison ancien vs nouveau
Voir /tmp/top10_per_market.json (export complet). Highlights :
- AMF top-10 inchangé sur les noms (Voyageurs du Monde, Lanson-BCC, etc.) mais ordre légèrement reshuffé : le nouveau scoring monte les CFO/PDG avec signalScore élevé, descend les CA/Board recency-only.
- SEC top-10 : pas de changement (mêmes weights effectifs sur ce sous-univers).
- AFM top-10 : signaux PDG mid/small-caps Euronext Amsterdam dominent, identique sur les deux scorings.
7. Verdict de ship par marché
| Marché | n viable T+90 | Sharpe T+90 | Sharpe DSR-deflated | Verdict |
|---|---|---|---|---|
| FR | 16 101 | −0,05 | n/a (négatif brut) | PROD-READY (composite > sélection) |
| SEC | 2 391 | +0,12 | proche zéro | PROD-READY (sample suffisant, t=5,95) |
| AFM | 4 330 | +0,14 | proche zéro | PROD-READY (meilleur Sharpe du panel) |
| FSMA | 668 | +0,09 | n/a | PREVIEW (n borderline, t=2,2) |
| BAFIN | 192 | +0,18 | n/a | PREVIEW (n<200, prometteur, attendre 1k) |
| OSLO | 92 | +0,19 | n/a | PREVIEW (small-sample suspect) |
| HEL | 10 | n/a | n/a | NO-GO (n insuffisant) |
| CONSOB | 3 | n/a | n/a | NO-GO |
| SEDI | 1 | n/a | n/a | NO-GO |
| SIX/RNS/CNMV/FI/DK/FMA/ASX/IE | 0 | n/a | n/a | NO-GO (T+90 forward window non écoulée) |
8. Risques résiduels
- Overfit grid search : DSR penalty négative ; ne pas re-grider tant que le périmètre n'a pas doublé.
- AMF T+365 négatif (−2,24 %) : la composante mean-reversion long-terme dégrade tout hold > 90 j. Garder T+90 comme horizon canonique.
- Merge SEC incomplet : ~108 k staging non-mergés. Une fois mergés, le sous-univers SEC pèsera 13 % de la base globale et pourra rebattre les cartes. Re-runner ce backtest dès que SEC ≥ 50 k.
- OSLO +15 % : trop beau, n=92, pubDate range 2025-2026, biais NOK/oil. Ne pas publier d'edge OSLO avant n=500 + 2 cycles complets T+365.
- CH (SIX) anonymisé : pas de track record possible → poids recency 45 maintenu mais à challenger si MAR-19 ouvre l'identification.
9. Fichiers modifiés / livrés
src/lib/recommendation-engine.ts— table MARKET_WEIGHTS v5.1.scripts/recompute-backtest-multimarket.mjs— nouveau, drop du gateisin: not nullpour markets sans ISIN sur Declaration (AFM/OSLO).scripts/_market_backtest_analysis.mjs— calcul par marché, winsorize, t-stat.scripts/_grid_search.mjs— 314 combos × 5 univers, DSR penalty.scripts/_compare_v5.mjs— v5 vs v5.1 head-to-head.scripts/_top10_per_market.mjs— top-10 par marché new vs old./tmp/market_stats_post.json,/tmp/grid_search_results.json,/tmp/v5_vs_winner.json,/tmp/top10_per_market.json— exports raw.