20, Multi-market feasibility: USA / Japon / Allemagne / UK / Suisse
Auteur : revue ingestion multi-marchés Date : 2026-05-16 Périmètre : preuve de faisabilité d'ingestion de signaux insider sur 5 marchés en plus de l'AMF (France). Chaque source a été testée live (endpoint réel, échantillon réel, mapping de schéma).
TL;DR
| Marché | Source | Auth | Coût | Données réelles obtenues | Verdict | Effort |
|---|---|---|---|---|---|---|
| USA | SEC EDGAR Form 4 (XML) | UA header obligatoire | Gratuit | ✅ 1 filing 2026 réel (CIK 1352851) | GO | 1-2 j |
| Allemagne | BaFin Directors' Dealings | aucune | Gratuit | ✅ Allianz, Röhler, 2026-05-11, 124 824 € | GO | 1 j |
| UK | Investegate (RNS scrape) | aucune | Gratuit | ✅ Kier Group, 2026-05-15, 68 917 GBP | GO | 2 j (regex/NLP) |
| Suisse | SER RSS feed | aucune | Gratuit | ✅ Medacta, 2026-05-15, 30 134 CHF | GO (role only, anonymisé) | 1 j |
| Japon | EDINET API v2 | clé gratuite + tel JP | Gratuit | ⚠️ Pas de Form 4 équivalent | WAIT | bloqué |
4 marchés sur 5 viables. Couverture cumulée immédiate : France + USA + Allemagne + UK + Suisse = ~6500 sociétés cotées vs ~700 sur AMF seul. Japon nécessite un workaround (numéro JP) et un parsing XBRL lourd pour officer trades, à reporter.
1. Socle commun de données
Schéma cible unifié pour les 5 marchés (toute table Declaration étendue) :
interface InsiderFiling {
// Issuer
issuer_name: string; // requis partout
issuer_isin: string | null; // AMF/BaFin/SIX direct, SEC/RNS via enrichissement
issuer_lei: string | null; // BaFin via GLEIF, RNS via body
issuer_ticker: string | null; // SEC/RNS/EDINET; BaFin/SIX absent
issuer_country: "FR" | "US" | "DE" | "GB" | "CH" | "JP";
source_id: string; // ID interne du dépôt (accession SEC, bafin_id, RNS id...)
// Insider
insider_name: string | null; // null seulement en CH (anonymisé legal)
insider_role: string; // toujours présent (rôle ou label)
insider_is_10pct_owner: boolean | null;
// Transaction
transaction_date: string | null; // YYYY-MM-DD, null en CH RSS
filing_date: string; // requis
published_at: string;
transaction_type: "Buy" | "Sell" | "Grant" | "OptionExercise" | "Gift" | "Tax" | "Other";
nature_code: string; // code natif (P/S/A/M SEC, Erwerb/Veräusserung CH, etc.)
// Quantities
shares_qty: number | null; // dérivé en BaFin/CH
price_per_share: number | null;
total_amount: number;
currency: "EUR" | "USD" | "GBP" | "CHF" | "JPY";
post_transaction_holdings: number | null;
is_direct_or_indirect: "D" | "I" | null;
}
Couverture par source (✅ direct, 🟡 dérivé/enrichi, ❌ absent) :
| Champ | AMF | SEC | BaFin | RNS UK | SIX CH | EDINET JP |
|---|---|---|---|---|---|---|
| issuer_name | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| issuer_isin | ✅ | 🟡 OpenFIGI | ✅ | 🟡 body | 🟡 SIX lookup | 🟡 |
| issuer_lei | 🟡 GLEIF | 🟡 | 🟡 GLEIF | ✅ body | 🟡 | 🟡 |
| issuer_ticker | ✅ | ✅ company_tickers | ❌ | ✅ URL slug | ❌ | ✅ secCode |
| insider_name | ✅ | ✅ | ✅ | ✅ | ❌ legal | 🟡 XBRL |
| insider_role | ✅ | ✅ officerTitle | ✅ | 🟡 regex | ✅ | 🟡 |
| transaction_date | ✅ | ✅ | ✅ | ✅ | ❌ filing only | 🟡 XBRL body |
| transaction_type | ✅ | ✅ code char | ✅ | 🟡 regex | ✅ Erwerb/Veräuss | 🟡 dérivé delta |
| shares_qty | ✅ | ✅ | 🟡 total/price | ✅ | 🟡 regex | 🟡 XBRL |
| price_per_share | ✅ | ✅ (sauf grants) | ✅ | ✅ | ✅ | 🟡 XBRL |
| total_amount | ✅ | 🟡 qty×price | ✅ | ✅ | ✅ | 🟡 XBRL |
| currency | EUR | USD | EUR | GBP | CHF | JPY |
2. USA, SEC EDGAR Form 4
Endpoints
- Atom recent :
https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent&type=4&output=atom - Full-text :
https://efts.sec.gov/LATEST/search-index?forms=4&dateRange=custom&startdt=...&enddt=... - Submissions :
https://data.sec.gov/submissions/CIK{10}.json - XML :
https://www.sec.gov/Archives/edgar/data/{cik}/{accession}/xslF345X05/ownership.xml - CIK→ticker :
https://www.sec.gov/files/company_tickers_exchange.json
Auth & limites
User-Agent: <app> <email>obligatoire (403 sinon). Aucune clé.- 10 req/s global, sinon block IP 10 min.
- Browser tools KO (UA non éditable) → curl/Python only.
Échantillon live
- Accession
0001104659-26-046993, CIK1352851, filé en 2026. - Berkshire 2024 contrôle :
0000950170-24-114125.
Mapping (XPath dans ownershipDocument)
- issuer_name :
//issuer/issuerName - issuer_cik :
//issuer/issuerCik - issuer_ticker :
//issuer/issuerTradingSymbol(nullable, fallback via company_tickers) - insider_name :
//reportingOwner/reportingOwnerId/rptOwnerName - insider_role :
//reportingOwner/reportingOwnerRelationship/officerTitle - is_10pct :
//reportingOwner/reportingOwnerRelationship/is10PercentOwner - transaction_date :
//nonDerivativeTransaction/transactionDate/value - nature_code :
//nonDerivativeTransaction/transactionCoding/transactionCode(P/S/A/M/X/F/D/G/C/W/J/V) - shares_qty :
//nonDerivativeTransaction/transactionAmounts/transactionShares/value - price :
//nonDerivativeTransaction/transactionAmounts/transactionPricePerShare/value(0 ou absent pour grants) - post_holdings :
//nonDerivativeTransaction/postTransactionAmounts/sharesOwnedFollowingTransaction/value - direct/indirect :
//ownershipNature/directOrIndirectOwnership/value
Gotchas
- Table I (équité) + Table II (dérivés), parser les deux blocs.
transactionPricePerSharenul/0 pour codes A/G/F →total_amountdérivé manuellement.- Plusieurs reportingOwners possibles par filing.
- Currency toujours USD (hardcoder, pas de tag XML).
Volume attendu
~1500 tickers actifs Form 4, ~50× volume AMF.
3. Allemagne, BaFin Directors' Dealings
Endpoints
- Browse (alphabétique A-Z) :
https://portal.mvp.bafin.de/database/DealingsInfo/sucheForm.do?emittentName={A-Z}&locale=en_GB - CSV export : même URL avec
6578706f7274=1&d-4000784-e=1(6578706f7274= hex "export") - XML export : même URL avec
d-4000784-e=3
Auth & limites
- Aucune auth, aucun token. Session cookie auto.
- Pas de rate limit documenté → 1 req/s par courtoisie.
Échantillon live
- Allianz SE (ISIN DE0008404005), Röhler (Klaus-Peter), Management Board, 2026-05-11 → 124 824,63 EUR @ 369,30 (~338 actions).
Mapping CSV → schéma
| CSV BaFin | Champ commun |
|---|---|
| Issuer | issuer_name |
| ISIN | issuer_isin |
| BaFin-ID | source_id |
| Parties subject to notification | insider_name |
| Position / status | insider_role |
| Nature of transaction | transaction_type / nature_code |
| Averrage price (sic) | price_per_share |
| Aggregated volume | total_amount |
| Date of transaction | transaction_date |
| Date of notification | filing_date |
| Date of activation | published_at |
Gotchas
- Format numérique allemand :
124.824,63→ normaliser (.= milliers,,= décimal) avantparseFloat. - CSV en UTF-8 (pas Latin-1 comme dans pudo/bafin legacy).
- Browse alphabétique forcé → itérer 27 buckets (A-Z + "Other"), ~5s/bucket = full refresh ~2 min.
shares_qtyà dériver (total_amount / price_per_share), KO pour grants à prix 0.- LEI absent → enrichissement GLEIF par ISIN :
https://api.gleif.org/api/v1/lei-records?filter[isin]=...
Volume
~2200 issuers DAX/MDAX/SDAX/scale.
4. UK, Investegate (RNS scrape)
Endpoints
- Listing :
https://www.investegate.co.uk/category/directors-dealings - Détail :
https://www.investegate.co.uk/announcement/rns/{slug}--{ticker}/director-pdmr-shareholding/{id} - FCA NSM direct : 403 sur fetch non-browser → inutilisable.
- LSE RNS officiel : payant (licence LSEG).
Auth & limites
- Aucune auth. Pas de RSS officiel pour la catégorie → scraping HTML.
- 2 GETs par filing (listing + détail).
Échantillon live
- Kier Group PLC (KIE, ISIN GB0004915632, LEI 2138002RKCU2OM4Y7O48), Leigh Thomas PDMR.
- 4 personnes connectées, 33 928 actions, 68 917,17 GBP, 2026-05-15.
Mapping
RNS = prose freeform avec tableau MAR Art 19 inline. Extraction :
- regex strict sur
LEI: ([0-9A-Z]{20}) - table MAR Art 19 (volume, unit price, currency, nature, date) en HTML semi-structuré
- ticker dans le slug URL
Gotchas
- Connected persons (épouse/enfants) déposent sous l'identité du PDMR → flag
connected_person. - ~85% des filings suivent le template FCA → 15% nécessitent NLP / LLM extraction.
- Pas de RSS catégorie → polling listing page paginée.
- LEI seulement dans le corps texte (pas dans la liste).
Volume
FTSE 100 + 250 + AIM = ~1900 sociétés, latence horaire.
5. Suisse, SER RSS
Endpoint
https://www.ser-ag.com/itf-data/management-transactions/rss-en.xml(2 min TTL)
Auth & limites
- Aucune. Polling toutes 2 min OK.
Échantillon live
- Medacta Group SA, role "Executive member of the board of directors / member of senior management", 2026-05-15 12:00 +0200.
- 219 titres, CHF 137,60, total 30 134,40 CHF. Type : Sale (Veräusserung).
- Transaction ID T1Q5F00013.
Mapping
<title>→ issuer_name<pubDate>→ filing_date<description>parsing regex multilangue (EN seul recommandé) :(\d[\d,]+) Titel.*CHF\s+([\d,]+\.\d+).*CHF\s+([\d.]+)→ qty, price, total
<guid>contient transaction ID → source_id- Currency = CHF (hardcode)
Gotchas (3 contraintes structurelles)
insider_namejamais public, légalement anonymisé. Role label seulement.transaction_dateabsent du feed (seulement filing). Date réelle dans détail SPA JS → headless browser requis.issuer_isinabsent → lookup SIX par nom requis.
Volume
SMI + SPI = ~250 cotées, mais turnover dirigeants élevé. Coverage suffit pour Nestlé / Roche / Novartis / UBS / etc.
6. Japon, EDINET ⚠️ WAIT
Endpoint
https://api.edinet-fsa.go.jp/api/v2/documents.json?date=YYYY-MM-DD&type=2&Subscription-Key=KEY
Blocage principal
Pas de Form 4 équivalent au Japon. Officer trades enfouis dans le rapport annuel (docTypeCode=120, section "Status of Major Shareholders and Officers' Shareholdings"), pas de flux temps réel par dirigeant. EDINET couvre uniquement :
350: Large Shareholding Report (5%+) → activistes / institutionnels, pas insiders perso360: Change Report
Blocage secondaire
- Clé API gratuite mais inscription requiert un numéro de téléphone japonais (SMS verification).
- Parsing XBRL ZIP multi-Mo, kanji-only, mapping ticker via JCN séparé.
Verdict
Reporter. À revisiter avec :
- a) numéro JP virtuel (Viber/Skype JP), ou
- b) lib
edinet-toolsPython pour parser annual reports une fois par fiscal year, beaucoup moins live que les 4 autres sources.
7. Plan d'implémentation (ordre ROI décroissant)
Phase 1, USA (1-2 j) → priorité absolue
- Étendre
Declaration+Insider+Companyavecsource_country+source_id. - Worker
src/lib/ingest/sec-form4.ts: poll atom feedgetcurrenttoutes 10 min, parse XML, upsert sur(cik, accession_no). - Bridge CIK→ticker→ISIN via
company_tickers_exchange.json+ OpenFIGI. - Volume attendu : ~50× AMF. Backtest immédiat sur historique 5 ans.
Phase 2, Allemagne (1 j)
- Worker
src/lib/ingest/bafin.ts: 27 buckets A-Z, parse CSV, normaliser format numérique allemand. - Enrichissement LEI via GLEIF.
- Volume : ~3× AMF.
Phase 3, Suisse (1 j)
- Worker
src/lib/ingest/six-ser.ts: RSS poll 2 min, regex EN description. - Lookup ISIN SIX par nom une fois (table de mapping statique).
- Accepter
insider_name = nullpour CH (flag UI).
Phase 4, UK (2 j)
- Worker
src/lib/ingest/lse-rns.ts: scrape Investegate listing + détail. - Regex sur 85% des filings ; LLM extraction (Sonnet 4.6 batch) sur 15% non-conformes.
- Throttle 1 req/s, respect robots.
Phase 5, Japon (reporter)
- Acquérir numéro JP (Skype JP ou équivalent) → clé EDINET.
- Implémenter parsing XBRL pour rapports annuels (1× / an / société).
- Évaluer si pertinent vs effort (officer trades non temps réel).
8. Risques transversaux
| Risque | Impact | Mitigation |
|---|---|---|
Comparabilité cross-marché des transaction_type |
Élevé | Mapping unifié documenté (P/S/A/M/X → Buy/Sell/Grant/OptionExercise). Garder nature_code natif pour audit. |
| Devises mixtes USD/EUR/GBP/CHF/JPY dans backtest | Élevé | FX history déjà ingéré (cf chantier round 3). Toujours convertir en EUR avant scoring. |
| Anonymisation Suisse | Moyen | Flag insider_name_is_anonymized + scoring sans priorAlphaForInsider (track-record impossible). |
| Connected persons UK | Moyen | Schema additionnel connected_person_flag. |
| Pas de transaction_date Suisse | Moyen | Utiliser filing_date comme proxy ou headless browser pour détail. |
| Coverage UK via Investegate (3rd party) | Moyen | Backup : monitoring du site, fallback LSEG payant si disparition. |
| Scaling crawl BaFin (27 buckets) | Faible | Bucket-level pagination + checkpoint. |
9. Verdict global
4 marchés viables immédiatement, 1 reporté.
Couverture combinée prévue : France (700) + USA (1500) + Allemagne (2200) + UK (1900) + Suisse (250) = ~6550 sociétés vs 700 actuelles = +836%.
Effort total Phase 1-4 : 5-6 jours-homme. ROI : multiplication par ~9× du volume de signaux, accès aux marchés USA + DAX + FTSE (les plus suivis sell-side ⇒ benchmarks plus solides pour backtest).
À chiffrer ensuite : impact sur la stratégie "Sigma Winning" (le grid-search actuel est calibré sur AMF, re-run grid-search par pays pour vérifier si les 6 filtres tiennent ou non).