7.9 KiB
Plan: Daten-Ingest skalieren (Rate-Limits, Egress-Kanäle, Blockchain)
Stand: 2026-07-12 · Status: Richtung bestätigt (Nutzer: beide Egress-Wege umschaltbar umsetzen, sofern Aufwand vertretbar). Kein Code in diesem Schritt. Problem: Polymarket-Rate-Limits bremsen den Datenimport teils extrem aus.
0. Ist-Zustand (verifiziert)
RateLimiterService= globaler Singleton-Token-Bucket, feste Delays je Endpoint-Gruppe (Gamma ≈28/s, Data ≈18/s, Clob ≈66/s).PolymarketApiClient= Singleton mit 3 benannten HttpClients, ohne Proxy/IP-Konfig → ein einziger Ausgangs-IP, ein globales Budget. Das ist die echte Bremse.
Zwei Hebel: Nachfrage senken (Abschnitt 1, größter Gewinn) und Angebot erhöhen (Abschnitt 2, Egress-Kanäle). Der Nutzer möchte in Abschnitt 2 beide Egress-Arten (eigene IPs UND Proxys) umschaltbar — und das ist billig, weil beide derselbe HttpClient-Seam sind (Abschnitt 2).
1. Nachfrage senken — größter Hebel (zuerst)
1a. Historische Massendaten aus Blockchain/Subgraph statt REST
Polymarket-Trades sind On-Chain-Events auf Polygon. Für Backfill/Deep-Resync (größter
REST-Verbraucher) ist /activity die falsche Quelle.
- The-Graph-/Goldsky-Subgraph für Polymarket evaluieren: ein GraphQL-Call → tausende Fills eines Wallets, statt seitenweiser rate-limitierter REST-Abrufe.
- Neue
IHistoricalTradeSourceneben dem REST-Provider; DeepResync (FIXPLAN A6) zieht Bulk hierüber. Effekt: nimmt die teuerste Last komplett von der REST-API.
1b. Markt-Stammdaten aggressiv cachen
- Metadaten (Frage, Kategorie, Outcomes,
ConditionId↔TokenId) einmal ziehen, lange cachen; nur Volume/Liquidity/Auflösung periodisch aktualisieren. Geschlossene Märkte nie voll re-syncen.
1c. Ingest-Tiering (FIXPLAN D3)
- Ultra-HF-Trader im
SnapshotOnly-Modus erzeugen null Trade-Calls (PnL aus/positions+ Leaderboard, wöchentliche Biopsie). Entfernt genau die Wallets, die das Budget auffressen.
1d. Redundanz vermeiden
- Worker-übergreifender Kurzzeit-Cache „gerade geholt", damit nicht mehrere Worker denselben Markt/Trader kurz hintereinander abrufen.
2. Angebot erhöhen: umschaltbare Egress-Kanäle (eigene IPs UND Proxys — eine Mechanik)
Die Schlüssel-Einsicht: Ob eine Anfrage über eine eigene Quell-IP oder über einen
Proxy rausgeht, ist im HttpClient nur eine andere Konfiguration desselben SocketsHttpHandler.
Deshalb wird nicht zweimal gebaut, sondern ein Konzept: der Egress-Kanal. Umschalten =
Konfiguration, nicht Code. Damit bekommt der Nutzer „beides, umschaltbar" zu geringen Kosten.
2a. Abstraktion EgressChannel
Ein Kanal ist genau eine Ausgangsroute, per Config als einer von zwei Typen definiert:
"Egress": {
"Channels": [
{ "id": "ip-a", "type": "SourceIp", "value": "203.0.113.10" }, // eigene IP
{ "id": "ip-b", "type": "SourceIp", "value": "203.0.113.11" },
{ "id": "prox-1", "type": "Proxy", "value": "http://user:pass@proxy.example:8080" }
]
}
- Pro Kanal ein
SocketsHttpHandler:SourceIp→ConnectCallback, Socket vor Connect an die lokale IP binden (socket.Bind(new IPEndPoint(ip, 0))).Proxy→handler.Proxy = new WebProxy(url); handler.UseProxy = true;.
IEgressPoolverteilt Requests round-robin/least-loaded über die aktiven Kanäle. Leere/❑ Kanalliste = heutiges Verhalten (ein Default-Ausgang).- Umschalten „nur eigene IPs" ↔ „nur Proxys" ↔ „Mix" = Config ändern, kein Deploy-Umbau.
2b. Rate-Limiter pro Kanal (Generalisierung des globalen Limiters)
- Limiter-Schlüssel wird
{platform}-{endpointGroup}-{channelId}. Jeder Kanal hält sein eigenes Budget → N Kanäle ≈ N× Durchsatz, jeder Kanal bleibt unter dem Per-Route-Limit. - 429 sperrt nur den betroffenen Kanal kurz, nicht alle.
2c. Betrieb
- Bei eigenen IPs prüfen: sind es echte getrennte Egress-IPs (multi-homed), nicht NAT hinter einer.
- Health/Statistik je Kanal (Erfolg, 429-Rate, Latenz), damit tote Proxys automatisch pausiert werden.
Aufwand: moderat und einmalig — durch die gemeinsame Abstraktion kostet „beides umschaltbar" kaum mehr als „nur IPs".
3. Proxys & Header-Rotation — Einordnung (korrigiert)
Klarstellung (Korrektur einer früheren Fassung): Predictalytics betreibt kein Trading und keine Wallet — es ist reine Analysesoftware, die ausschließlich öffentliche Marktdaten liest. Das frühere „Ban gefährdet die Trading-Wallet"-Argument gehört zu PolyTrader (getrenntes Projekt) und trifft hier nicht zu. Damit ist die Proxy-Wahl eine reine Engineering-Entscheidung des Nutzers — freie Proxys eingeschlossen.
Was real bleibt (ehrliche Hinweise, keine Blocker — Entscheidung liegt beim Nutzer):
- ToS-Grauzone: Rate-Limit-Umgehung per Routen-/Header-Rotation widerspricht vermutlich Polymarkets Nutzungsbedingungen. Realistische Konsequenz hier: einzelne IPs/Proxys werden geblockt und müssen ersetzt werden — mehr nicht (kein Kapital, keine Wallet betroffen).
- Datenintegrität (der eigentlich relevante Punkt): Ein kaputter/bösartiger (v. a. gratis) Proxy kann Antworten verfälschen → korrupte Analyse („garbage in, garbage out"). Da die gesamte Auswertung darauf aufbaut, lohnt sich eine Plausibilitätsprüfung der Antworten (Feldtypen, Wertebereiche, z. B. Preise ∈ [0,1]) und — wo Genauigkeit zählt — das Bevorzugen kontrollierter Proxys/eigener IPs. Rein informativ, kein Zwang.
- DB-Verbindung NIE über Proxy (ausdrücklicher Nutzer-Wille): Die MySQL-Verbindung läuft immer direkt. Der Egress-Pool gilt ausschließlich für ausgehende Polymarket-HTTP-Calls, niemals für die DB.
3a. Header-Rotation (separat aktivierbar, standardmäßig AUS)
Auf Wunsch integriert, bewusst opt-in:
- Config
Egress.HeaderRotation.Enabled— Defaultfalse. Beifalsewird ein einziger, konsistenter Standard-Header-Satz gesendet (heutiges Verhalten). - Rotiert kohärente Header-SETS, nicht nur den User-Agent isoliert: je Eintrag ein
zusammenpassendes Bündel (
User-Agent+Accept+Accept-Language+Sec-CH-UA…), damit die Kombination realistisch bleibt — ein moderner UA mit widersprüchlichen Accept-Headern fällt eher auf als gar keine Rotation. Set-Pool aus Config ladbar. - Auswahl pro Kanal oder pro Request (konfigurierbar).
- Greift nur für Polymarket-Read-Calls; unabhängig vom Kanaltyp (IP oder Proxy) nutzbar.
4. Reihenfolge
- 1b + 1d (Caching/Dedup) — sofort, klein, spürbar.
- 2a–2c (Egress-Kanäle + Per-Kanal-Limiter) — moderat, liefert „eigene IPs UND Proxys umschaltbar".
- 1c (Tiering) — hängt an FIXPLAN D3.
- 1a (Blockchain/Subgraph-Bulk) — größter struktureller Hebel; eigener Rechercheschritt
(welcher Subgraph deckt Fills sauber ab?), dann als
IHistoricalTradeSource.
5. Tests / Abnahme
- Per-Kanal-Limiter: unabhängige Budgets (kein globales Blocken); 429 sperrt nur einen Kanal.
- Egress-Binding: Smoke gegen einen Dienst, der die Quell-IP zurückgibt → Round-Robin nutzt wirklich verschiedene IPs; Proxy-Kanal geht über den Proxy.
- Kanal-Health: toter Proxy wird automatisch pausiert, Pool weicht aus.
- Blockchain-Quelle: Stichproben-Abgleich Bulk-Historie ↔ REST-
/activityeines Wallets, bevor sie produktiv wird. - Header-Rotation: bei
Enabled=falsewird genau ein konsistenter Standard-Satz gesendet (kein Rotieren); beiEnabled=truestammt jeder gesendete Header-Satz unverändert aus dem Pool (kohärent, keine zusammengewürfelten Felder). - DB-Guard: die MySQL-Verbindung nutzt nie den Egress-Pool/Proxy (Regressionsschutz).
- Response-Plausibilität: grob unplausible Provider-Antworten (z. B. Preis außerhalb [0,1]) werden erkannt und verworfen statt in die DB zu wandern.