Alle Beiträge

Alternative Daten: Wenn ein Block wie ein Datenpunkt aussieht

Pipelines für alternative Daten scheitern häufiger an stillen Erfassungsfehlern als an schlechten Modellen. So wird eine geblockte Seite zum falschen Signal und so verhinderst du es.

Die Produktseite eines Einzelhändlers antwortete mit Status 200 und keinem Inhalt. Die Pipeline protokollierte keine Blockierung. Sie protokollierte ein leeres Regal.

Das ist der Fehler, den niemand bei alternativen Daten einplant. Kein fehlendes Dataset, kein langsamer Anbieter. Ein Collection Layer, der dir weiterhin Zeilen liefert, während er leise etwas anderes misst als das Unternehmen, das du analysierst.

Die Herausforderung

Im Januar 2026 befragte Exabel 100 fundamentale Portfolio-Manager und Analysten in den USA, Großbritannien, Singapur und Hongkong, die zusammen rund 610 Milliarden US-Dollar verwalten. 71 % nannten die Kombination von Daten aus verschiedenen Quellen als den frustrierendsten Teil der Arbeit mit alternativen Daten, und 94 % gaben an, dass sie bereits KI oder maschinelles Lernen in ihrem Research-Prozess einsetzen.

Lies diese beiden Zahlen nebeneinander, und das Ausmaß des Problems wird deutlich. Die Modeling-Seite ist gut besetzt. Die Infrastruktur darunter nicht.

Ein im Web gesammeltes Panel (Preise, Lagerstatus, Karriereseiten, Bewertungsanzahl, Marktplatz-Sortiment) ist in erster Linie eine Zeitreihe. Jede Zeitreihe birgt eine Annahme, die niemand in die Spezifikation schreibt: Die heutige Beobachtung wurde genauso erfasst wie die gestrige. Brich diese Annahme laut, und du erhältst einen Alert. Brich sie leise, und du erhältst ein Signal.

Drei dieser leisen Brüche tauchen in fast jedem im Web gesammelten Panel auf.

Der 200er, der kein Inhalt ist. Bot-Abwehrmechanismen haben schon lange aufgehört, mit einem sauberen 403 zu antworten. Eine Challenge-Seite, eine Consent-Wall oder ein Template für leere Ergebnisse kommt mit einem Erfolgsstatus an und einem Body, den dein Parser als null Ergebnisse liest. Weniger Listings sehen identisch aus wie weniger Nachfrage.

Der Beobachtungspunkt hat sich verschoben. Preis, Währung, Sortiment, Werbebanner, manchmal sogar, ob die Seite überhaupt gerendert wird: Einzelhändler entscheiden das alles danach, woher die Request zu kommen scheint. Wenn die Collection am Montag in Deutschland ausging und am Donnerstag in Polen, hast du einen Sprung in deiner Serie, der von dir stammt, nicht vom Einzelhändler.

Die Rotation, die die erste Antwort nahm. Rotiere durch Exits, ohne dem Collector zu sagen, was Erfolg bedeutet, und er stoppt beim ersten Exit, der antwortet. Eine Ablehnung ist eine Response. Die Zeile landet also in der Datenbank, der Job wird grün, und niemand schaut mehr hin.

Keines davon wirft eine Exception. Die Ingestion zählt Zeilen, das Dashboard bleibt grün, und der Analyst bekommt ein Chart. Dann verbringt das Modell ein Quartal damit, das Verhalten deiner Collection-Infrastruktur zu lernen, anstatt das Verhalten des Unternehmens.

Der Ansatz

Behandle Datenintegrität als Eigenschaft der Request, nicht des Parsers weiter hinten. Drei Dinge müssen zutreffen.

1. Sag, wie eine echte Seite aussieht. Der Collector kann das nicht von selbst herausfinden. Übergib einen String, den nur echter Content enthält, und ein paar, die nur bei Ablehnungen vorkommen. So zählt eine Challenge-Seite nicht mehr als Observation. Wir haben darüber geschrieben, als validate-Regeln eingeführt wurden: Der Request selbst bestimmt, was Erfolg bedeutet.

import requests

r = requests.post(
    "https://api.foura.ai/api/proxy",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "maxTries": 8,
        "exitCountries": ["DE"],
        "request": {
            "method": "GET",
            "url": "https://retailer.example/p/12345",
            "validate": {
                "status": {"accept": [200]},
                "data": {
                    "accept": ["data-testid=\"price\""],
                    "fail": ["Access Denied", "Just a moment"]
                }
            }
        }
    }
).json()

observation = r["data"]        # content your rules accepted, or nothing
exit_id = r["proxy"]           # opaque ID of the exit that delivered it
served_from = r["exitCountry"] # verify it against what you asked for

Rotation hat jetzt eine Definition of Done. Sie probiert weiter Exits, bis einer etwas zurückgibt, das deine Regeln besteht, anstatt das erste seitenähnliche Objekt zurückzugeben, das ihr begegnet.

2. Halte den Ausgangspunkt still. exitCountries ist eine strikte Allowlist zieloffener Ländercodes, und Exits mit unbekannter Geografie werden ausgelassen statt ersetzt. Zwei ehrliche Vorbehalte, die du kennen solltest, bevor du darauf aufbaust. Ländermetadaten werden zyklisch aktualisiert (normalerweise innerhalb von etwa zehn Minuten), es ist also kein Live-Lookup zur Request-Zeit, weshalb die Response genau deshalb exitCountry zur Prüfung für dich enthält. Und wenn der Pool keinen Treffer für den angefragten Scope hat, kommt der Call mit HTTP 200 und einem Fehler-Umschlag zurück statt mit einer Exception. Lies den Body, nicht den Status. Behalte den Scope bei und versuche es später erneut, anstatt ihn zu erweitern, denn ein erweiterter Scope bricht die Serie.

3. Behalte die Identität des Exits. Das proxy-Feld ist eine undurchsichtige ID, keine Adresse. Gib sie bei einem folgenden Single- oder Browser-Call zurück und die Detailseite kommt vom selben Ausgangspunkt wie die Suchseite, die sie gefunden hat (wie man einen Exit wiederverwendet). Speichere diese ID und den X-FourA-Request-Id-Header neben jeder Zeile. Wenn ein Analyst sechs Wochen später einen Ausschlag hinterfragt, wird die Frage "war das echt?" zu einem Lookup statt einer Diskussion.

Für eine Quelle, die du onboardest und noch nicht verstehst, ist Auto der schnellste Weg, einen funktionierenden Pfad zu finden: Es geht die Leiter von billig zu teuer durch, sagt dir, welche Stufe gewonnen hat, und gibt die funktionierende Session zurück. Nutze es, um die Route zu finden, und lege dann das Produktionsvolumen auf die direkten Engines. Spiele diese Session durch Single ab, wenn nichts gerendert werden muss, und durch Browser, wenn es zwingend nötig ist. Pfadfindung und Steady-State-Sammlung sind verschiedene Aufgaben.

Ergebnisse

Was sich ändert, wenn diese drei Eigenschaften gelten, bei einem Panel von einigen tausend Produktseiten pro Tag über ein Dutzend Händler hinweg (illustratives Szenario basierend auf Branchen-Benchmarks):

  • Eine Lücke ist eine Lücke, keine Vermutung. Ablehnungen kommen nie als Nullen ins Panel, also bedeutet eine leere Ergebnismenge, dass der Händler nichts gezeigt hat, und dein Abwesenheitssignal ist verlässlich handelbar.
  • Vergleichbare Zeilen. Jede Beobachtung in einer Serie stammt aus dem Land, in dem die Serie definiert ist, also ist eine Preisbewegung eine Preisbewegung.
  • Reproduzierbare Historie. Exit-ID plus Request-ID pro Zeile bedeutet, dass jeder umstrittene Datenpunkt auf den genauen Call zurückgeführt werden kann, der ihn erzeugt hat.
  • Günstiger pro nutzbarer Zeile. Requests, die eine verworfene Beobachtung erzeugt hätten, werden zur Sammlungszeit erneut versucht, anstatt dass sie bezahlt, geparst, gespeichert und später aus einem Backtest bereinigt werden.

Aber das Letzte ist das, was Research-Teams unterschätzen. Eine schlechte Zeile ist nicht kostenlos, nur weil sie billig abzurufen war. Sie kostet einen Research-Zyklus, und manchmal kostet sie das Vertrauen der Person, die das Signal freigeben muss.

Wichtigste Erkenntnis

Käufer von alternativen Daten bewerten Anbieter nach Abdeckung, Latenz und Historientiefe. Fast niemand stellt die Frage, die entscheidet, ob ein Panel handelbar ist: Wie verhält sich dieser Datensatz an dem Tag, an dem die Quelle die Antwort verweigert?

Ein Anbieter, der die Zeile löscht, ist ehrlich. Ein Anbieter, der eine Fehlerseite als Beobachtung zurückgibt, hat dir eine Messung seiner eigenen Infrastruktur verkauft, und du bezahlst dafür in einem Backtest, der genau so lange funktioniert, bis er scheitert. Diese Frage gehört in jede Checkliste zur Datenprüfung, und sie gehört zuerst in deine eigene Pipeline, denn wenn du die Daten selbst sammelst, bist du der Anbieter.