Quand une banque centrale publie une décision sur les taux ou qu'un bureau de statistique publie un nouveau relevé d'inflation, l'annonce brutale arrive souvent avec un bruit: des objets de codage, des pages partielles, des champs manquants ou des révisions qui contredisent le mois précédent.
Chez FXMacroData, nous traitons la qualité des données comme une préoccupation de premier ordre. Chaque indicateur de chaque devise passe par un pipeline de validation déterministe avant d'être écrit dans Firestore et exposé via l'API. Ce post traverse ce pipeline couche par couche du moment où un récupérateur télécharge une réponse brute au moment où une valeur devient consultable à
les points de fin comme /v1/announcements/{currency}/{indicator}Je suis désolé .
Le pipeline en un coup d'œil
Étape 1: ingestion
Étape 1 Ingestion: les sources de récupération structurées
La validation commence avant qu'une seule valeur ne soit extraite. Chaque monnaie a une classe de récupérateur dédiée qui cible une source primaire officielle le site Web de la banque centrale, le bureau national des statistiques ou un portail de données gouvernementales. Nous évitons délibérément les agrégateurs secondaires dans le chemin d'ingestion: leur retard, les termes de licence et les révisions silencieuses occasionnelles introduisent une incertitude que nous ne pouvons pas contrôler.
Les Fetchers sont des classes Python asynchrones qui implémentent un async with Le modèle de gestionnaire de contexte. aiohttp.ClientSession avec une réaliste User-Agent et des temps d'arrêt contrôlés; à la sortie, ils se ferment proprement, peu importe si la récupération a réussi ou pas. lxml ou ... BeautifulSoup En utilisant des sélecteurs d'éléments exacts plutôt que des cas de réserve regex contre la balisage brut, et les API JSON sont accessibles via des touches d'accès tapées qui se lèvent immédiatement si un champ est absent ou renommé en amont.
Contrat de récupération clés de sortie requises
{
"date": "2026-03-31", # Chaîne de dates ISO-8601
"val": 3.5, # flotté jamais en chaîne
"announcement_datetime": "..." # UTC ISO-8601 si elle est disponible
}
Le contrat de sortie est exécuté à la limite du porteur: tout enregistrement manquant date ou ... val est rejeté avant d'atteindre le stade suivant. announcement_datetime est facultatif à l'ingestion mais requis pour les terminaux orientés vers la publication qui exposent le calendrier des événements aux utilisateurs des API.
===== Étape 2: vérification du schéma ====
Étape 2 Vérification du schéma: validation du type et de l'exhaustivité
La sortie du capteur brut est remise à un validateur de schéma qui applique quatre vérifications sur chaque enregistrement:
Format de la date
Parse comme une date ISO-8601. Les chaînes non parsables, les dates futures au-delà d'une fenêtre de grâce de deux jours et les dates antérieures à 1960 sont toutes rejetées.
Type de valeur
val Il faut forcer un Python fini . floatJe suis désolé . NaNJe suis désolé . Inf, et des chaînes non numériques (par exemple "n/a", chaînes vides) sont rejetées plutôt que forcées à zéro.
Détection de doublons
Si deux enregistrements partagent la même chose (currency, indicator, date) La clé, le pipeline conserve la dernière ingérée et enregistre la collision.
Accouplement des indicateurs de devises
Chaque enregistrement est validé par rapport au catalogue d'indicateurs publié. unemployment pour une devise qui n'expose pas cet indicateur, une erreur est générée et le lot est arrêté.
Les défaillances de schéma sont affichées sous forme d' entrées de Cloud Logging structurées avec severity=ERRORJe suis désolé . stage=schema_check, et le nom de l'obtenteur d'origine. Cela rend la différence de course croisée simple dans la console GCP.
ÉTAPE 3: Filtre extérieur
Étape 3 Filtre de la plage et des limites
La validité structurelle est nécessaire mais pas suffisante. 250.0 La phase 3 applique deux vérifications complémentaires pour détecter ces erreurs sémantiques.
Limites de portée
Chaque indicateur comporte une entrée de catalogue qui comprend des informations facultatives min_val Je suis désolé . max_val Les taux directeurs, par exemple, sont délimités entre -5.0 Je suis désolé . 30.0 L'inflation annuelle est limitée entre -30.0 Je suis désolé . 300.0 Les valeurs situées en dehors de ces limites sont mises en quarantaine en attendant un examen manuel.
Détection des valeurs aberrantes du score z en roulant
Pour les indicateurs ayant au moins 24 mois d'historique dans Firestore, le pipeline calcule une moyenne mobile de 36 mois et un écart type et marque tout nouveau record dont le score z dépasse |4.0|Contrairement aux limites strictes, les drapeaux z-score ne rejettent pas automatiquement les enregistrements ils créent une entrée de révision et joignent un outlier_flag: true Le champ de recherche est ajouté au document Firestore afin que les utilisateurs d'API puissent filtrer optionnellement les enregistrements avec balises aberrantes dans leurs propres flux de travail.
Pourquoi 4σ au lieu de 3σ ?
Les indicateurs macro montrent vraiment des queues de graisse. Les chocs d'approvisionnement de COVID-19, la crise énergétique de 2022 et les cycles de randonnée rapides de la banque centrale ont tous produit des lectures statistiquement rares mais réelles. Un seuil de 3σ mettrait en quarantaine les données légitimes pendant les changements de régime, exactement lorsque les lectures précises sont les plus importantes.
Étape 4: Réconciliation entre les sources
Étape 4 Reconciliation entre les sources
Pour un sous-ensemble d'indicateurs d'importance élevée taux de la banque centrale, IPC et chômage , le pipeline maintient une source secondaire à comparer.
Quand les valeurs primaires et secondaires sont les mêmes (currency, indicator, date) Si une valeur de la politique de taux dépasse une tolérance configurable, une alerte est déclenchée et la valeur principale est maintenue en attente d'enquête. 5 basis pointsPour l' IPC , c' est ça . 0.1 percentage pointsLes tolérances sont intentionnellement étroites pour ces indicateurs, car même de petites divergences indiquent souvent une erreur d'analyse, un retard de reporting ou un conflit de révision préliminaire-versus-finale.
Les sources primaires
- Communiqués officiels de la banque centrale
- Les bureaux nationaux de statistique
- Portails de données gouvernementaux
Les sources de référence
- Les résultats officiels parallèles (par exemple BRI)
- Les documents historiques marqués par une révision
- Contrôle interne de la cohérence antérieur à la période
Au-delà des vérifications croisées par enregistrement, le pipeline a également un vérification de la continuité d'un mois à l'autre: si un nouveau enregistrement représente un changement de plus de N Les éditions préliminaires diffèrent souvent des édition finales; le pipeline enregistre les deux valeurs et expose un revised La valeur d'une date est mise à jour après la publication initiale.
Étape 5: intégrité du jour de travail
Étape 5 Intégrité des activités
La phase finale de validation aborde une contrainte subtile mais importante: chaque announcement_datetime doit tomber sur un jour ouvrable valide dans le fuseau horaire du marché Les bureaux de statistique et les banques centrales ne publient pas d'annonces le week-end ou les jours fériés donc si le pipeline produit un horodatage qui tombe un samedi à Tokyo ou un jour férié à Sydney, quelque chose a mal tourné en amont.
Le validateur appelle . is_valid_announcement_date(currency, local_date), qui vérifie la date par définition de fuseau horaire par devise et les calendriers de vacances complets maintenus dans la base de code. Chaque devise desservie par l'API AUD, EUR, GBP, JPY, USD, CAD, CHF, NZD et toutes les autres a son propre fuseaux horaires et table des vacances indépendants. Les devises n'héritent pas de leur session FX; un vendredi à New York peut être un samedi à Sydney, et le validateur gère cela précisément.
Validation au jour ouvrable (simplifiée)
définition est_valide_annonce_date(currency: str, local_date: date) -> bool: tz = CURRENCY_TIMEZONE[currency] # Rejeter les week-ends if local_date.weekday() >= 5: retour False # Rejeter les jours fériés if local_date in _build_holiday_set(currency, local_date.year): retour False retour True
Quand une date calculée échoue à cette vérification, next_valid_announcement_date Il s'agit d'un système de gestion de la date de sortie de l'application qui permet de prévoir la date d'expiration de l"application. Il permet de la faire avancer au jour ouvrable suivant par exemple, en faisant rouler une annonce de Noël au lundi suivant. Cela garantit que le point de sorties du calendrier servi aux consommateurs d'API contient toujours des dates qui peuvent être utilisées directement dans les calendriers de trading sans nettoyage manuel. Ces règles de jour ouvré sont également appliquées par une suite de tests CI qui échoue à la compilation si une devise dans le catalogue manque de données de fuseau horaire ou de vacances.
Précision du calendrier de sortie: Les dates des événements à venir à partir du point final du calendrier de publication tels que la prochaine réunion de la Fed ou la décision du taux de la RBA sont garanties pour tomber sur des jours ouvrables valides dans le fuseau horaire du marché de la monnaie. /api/v1/calendrier/{monnaie} reflète directement ce calendrier validé.
Je suis un homme de parole.
Surveillance et alerte continue
Passer le pipeline de validation une fois ne suffit pas. Le pipeline fonctionne selon un calendrier déclenché par les tâches Cloud et les flux de travail de remplissage et chaque exécution produit une télémétrie structurée qui alimente une couche de surveillance.
Alertes au stade
Les défaillances à n'importe quelle étape du pipeline émettent une entrée Cloud Logging immédiatement pour le triage.
Hachage du contenu
Chaque écriture de Firestore inclut un content_hash pour détecter et faire apparaître des révisions silencieuses en amont.
Vérification de l'épuisement
Les lecteurs détectent lorsque les données stockées sont plus de N jours en retard par rapport à la plage demandée et affichent un signal d'intervalle plutôt que de renvoyer silencieusement des valeurs périmées.
Lorsqu'un récupérateur ne parvient pas à renvoyer les données délai d'expiration du réseau, changement de site en amont ou changement d'une structure de réponse le pipeline ne revient pas aux appels en amonte au moment de la demande. DataUnavailableError Cela empêche les données périmées ou partiellement validées d'atteindre la couche API, même temporairement.
===== Gestion de la révision =======
Comment traiter les révisions et les remaniements
Les révisions des données macro sont un fait de la vie. Les estimations initiales du PIB sont révisées deux ou trois fois. Les salaires sont significativement réévalués. Le pipeline gère les révisions explicitement plutôt que de les écraser silencieusement:
- Conservation de la première impression: Le pipeline stocke la première valeur pour un donné
(currency, indicator, date)avec unrevised: falseLe drapeau. - Détection de révision: Lors des séries d'ingestion suivantes, si la valeur d'une date a changé de plus que le seuil de révision de l'indicateur, le document est mis à jour et
revised: trueest réglée. - Préservation de l'histoire: La valeur originale de la première impression est conservée dans un
prior_valdomaine à des fins d'audit et de comparaison. - Transparence des API: Le
revisedLe champ est exposé dans les réponses API afin que les applications consommatrices puissent distinguer les lectures préliminaires des lectures finales.
Cela est particulièrement important pour des indicateurs tels que les feuilles de paie non agricoles, où l'impression préliminaire et la révision ultérieure peuvent différer de dizaines de milliers d'emplois un signal significatif à part entière pour les traders de devises qui suivent le récit de l'emploi en USD via le point final des effectifs non agricolesJe suis désolé .
Ce que cela signifie pour les consommateurs d'API
Ce que cela signifie pour les consommateurs d'API
Le résultat pratique de ce pipeline pour quiconque interroge l'API:
- Je ne veux pas .
NaNou ...nullvaleurs de la série les enregistrements avec des valeurs invalides sont exclus à l'étape 2 plutôt que de passer comme des trous. - Des dates auxquelles on peut faire confiance. chaque date d'une réponse est une date calendaire valide sur un jour ouvrable du marché de cette devise, adaptée à une utilisation directe dans les calendriers de négociation ou les moteurs de backtesting.
- Marquage des heures d'annonce à la seconde de précision le cas échéant,
announcement_datetimereflète la seconde UTC exacte de la version officielle, et non un espace réservé à minuit. - Drapeaux de révision le
revisedLe champ de lecture permet de distinguer si vous travaillez avec une lecture préliminaire ou finale. - Unités d'indicateur cohérentes les indicateurs de taux sont toujours exprimés en pourcentage, et non en chiffres décimaux (par exemple
5.25Je ne veux pas .0.0525), correspondant à la représentation sur les sites officiels de la banque centrale.
Si vous consultez n'importe quel indicateur taux directeur, IPC principal, chômage , vous recevrez une réponse qui a déjà passé les cinq étapes.
Je termine le CTA .