# Umsetzungsplan: AI-Bewertung der Auflösequalität (C-S4) > Stand: 2026-07-11 > Ziel: Ein LLM (via OpenRouter) bewertet je Markt das RESOLUTION-Risiko (subjektive > Auflösequellen, Regeltext-Fallen, UMA-Dispute-Muster). Die Bewertung wird beim > Markt-Import in der DB gespeichert und dient als Entry-Gate — zuerst im > ResolutionFarming, perspektivisch auch im Copytrading. > Einordnung: Core-Baustein (beide Module profitieren), kein eigenes Strategiemodul. --- ## 1. Abgrenzung (wichtig für die Umsetzung) Das LLM prognostiziert NICHT den Markt-Ausgang. Es beantwortet ausschließlich: **„Wie sauber/objektiv wird dieser Markt aufgelöst werden?"** — Input ist der Regeltext, nicht das Weltgeschehen. Das hält die Aufgabe eng, billig und testbar. ## 2. Architektur ### 2.1 Core-Service `IMarketRiskRater` (PolyTrader.Core) ```csharp public interface IMarketRiskRater { /// Liefert die (ggf. gecachte) Bewertung; null wenn (noch) keine vorliegt. Task GetOrRateAsync(MarketData market, CancellationToken ct); } public class MarketRiskRating // Tabelle core_market_risk_ratings { public string ConditionId { get; set; } // PK — Regeltexte ändern sich nicht → dauerhaft cachebar public int Score { get; set; } // 0–100 (100 = völlig objektiv auflösbar) public string Flags { get; set; } // CSV: SUBJECTIVE_SOURCE, DEADLINE_AMBIGUITY, // MENTIONS_TYPE, DISPUTE_PATTERN, MISSING_RULES public string Reason { get; set; } // Einzeiler-Begründung des Modells public string Model { get; set; } // verwendetes Modell (Nachvollziehbarkeit) public DateTime RatedAt { get; set; } } ``` ### 2.2 `OpenRouterClient` (Core, dünn) - HTTP-Client gegen https://openrouter.ai/api/v1/chat/completions, API-Key aus appsettings (`OpenRouter:ApiKey`, gitignoriert wie andere Secrets). - **Modellwahl:** günstiges Modell reicht (Haiku-Klasse, z. B. `anthropic/claude-haiku-4.5` via OpenRouter; Modell-ID als Setting, nicht hartkodieren). Kosten je Markt: Bruchteile eines Cents; mit Cache je ConditionId einmalig pro Markt. - **Structured Output:** Antwort als JSON erzwingen (Schema im Prompt + JSON-Mode); bei Parse-Fehler 1 Retry, danach „kein Rating" (fail-closed, siehe 3.3). - Timeout kurz (~15 s), Fehler loggen, NIE den aufrufenden Scanner blockieren. ### 2.3 Prompt (Kern, bei Umsetzung feinjustieren) Input je Markt: `Question`, `Description`/Resolution-Kriterien (Gamma-API liefert den Regeltext am Markt-Objekt — Feld bei Umsetzung verifizieren), Kategorie, EndDate. Bewertungsauftrag an das Modell (sinngemäß): 1. Gibt es eine EINDEUTIGE, öffentlich prüfbare Auflösequelle (offizielles Endergebnis, behördliche Zahl, On-Chain-Fakt)? 2. Sind Randfälle geregelt (Verschiebung, Abbruch, Unentschieden, Definitionsfragen wie „offiziell angekündigt")? 3. Ähnelt der Markt bekannten Streit-Mustern (Mentions-/„sagt X"-Märkte, vage Deadlines, Definitions-Ambiguität, mehrdeutige Quellen)? Output: `{ "score": 0-100, "flags": [...], "reason": "…" }`. ## 3. Integration ### 3.1 Wann wird bewertet? Beim Markt-Import bzw. beim ersten Kontakt: Der **RF-Scanner** ruft `GetOrRateAsync` für jeden Kandidaten auf, der alle billigen Filter passiert hat (NACH Preisband/Kategorie/Fenster, VOR dem Accept — kein LLM-Call für offensichtliche Rejects). Cache macht Wiederholungs-Scans kostenlos. ### 3.2 Entry-Gate im ResolutionFarming Neue `RfSettings`: - `MinResolutionScore` (Default 70): Kandidaten mit Score darunter → Reject mit Grund `"AI-Resolution-Score {score} < {min}: {reason}"` (landet wie alle Rejects in rf_candidates → die Kalibrierung kann später prüfen, ob das Gate Geld spart!). - `RequireRating` (Default true): fail-closed-Schalter (siehe 3.3). ### 3.3 Fail-Closed-Regeln (Sicherheitskern) 1. Kein Rating verfügbar (API down, Parse-Fehler, kein Regeltext) → Kandidat gilt als riskant und wird abgelehnt — AUSSER die Kategorie steht auf einer Objektiv-Whitelist (Default: Sports-Endergebnisse), dann Durchlass mit Log. 2. Das Rating **ersetzt die harte Blacklist nicht**: bekannte Giftmuster (Mentions-Märkte etc.) bleiben in `BlacklistCsv` hart geblockt. Das LLM ist die zweite Verteidigungslinie für den Long Tail, nicht die erste. 3. **Post-Mortem-Pflicht:** Jeder real erlebte Dispute → Muster in Blacklist/Prompt aufnehmen. Dafür Flag-Feld in rf_closed_trades (`ResolutionDisputed`) vorsehen. ### 3.4 Copytrading (zweiter Schritt, optional) Gleicher Service: Vor einem BUY den Score prüfen; unter Schwelle → Trade verwerfen mit TradeReasoning-Log. Als Per-Account-Setting (`MinResolutionScore`, 0 = aus), Default zunächst AUS, um das Copy-Verhalten nicht zu verändern, bis der Rater validiert ist. ## 4. Validierung VOR dem Scharfschalten (Pflicht-Phase) 1. **Retrospektiv-Test:** ~15–20 öffentlich bekannte, umstrittene UMA-Resolutions (Recherche-Aufgabe: bekannte Dispute-Fälle) + ~30 unstrittig aufgelöste Vergleichsmärkte durch den Rater schicken. Messen: erwischt er die Streitfälle (niedriger Score), ohne die sauberen zu blockieren? 2. **Akzeptanz:** ≥ 80 % der Streitfälle unter der Schwelle, ≤ 10 % der sauberen fälschlich blockiert. Sonst Prompt/Schwelle iterieren. 3. Ergebnisse als Testdaten einfrieren (Golden-File-Test, läuft ohne API gegen gespeicherte Antworten — kein LLM-Call in der CI). ## 5. Phasen | Phase | Inhalt | Akzeptanz | |---|---|---| | AR-1 | OpenRouterClient + IMarketRiskRater + Tabelle/Migration + Unit-Tests (Parsing, Fail-Closed) | Build grün; Rater liefert für einen Beispiel-Regeltext strukturiertes Rating | | AR-2 | Retrospektiv-Validierung (4.) | Akzeptanzquoten erreicht, dokumentiert | | AR-3 | RF-Integration (3.1/3.2/3.3) + UI-Spalte (Score in Kandidaten-Tab) | Rejects mit AI-Grund sichtbar; Kalibrierung kann Gate-Wirkung auswerten | | AR-4 | Copytrading-Integration (3.4), Default aus | Setting vorhanden, dokumentiert | ## 6. Leitplanken - API-Key nie committen; Kosten-Deckel (max. Ratings/Tag als Setting, Default 500). - Der Rater beeinflusst NIE Exits, nur Entries (keine Panik-Verkäufe durch LLM). - Score/Reason immer mitloggen — Entscheidungen müssen im Log nachvollziehbar sein.