Supervisor S-0a/b: Entscheidungsjournal, Order-Events, SignalId, JSONL-Logs
Datenfundament fuer die KI-Analyse (docs/konzepte/KONZEPT-Modul-Supervisor.md, Phase S-0). Sofortnutzen auch ohne KI: abfragbare Rejects, rekonstruierbare Order-Ketten. - core_decision_journal (DecisionRecord): JEDE Handelsentscheidung strukturiert - Decision (Executed/Rejected/Skipped/Failed) + ReasonCode-Enum (als String, erweiterbar) + Kontext-JSON (kulturinvariant) + MarketSlug/EndDate (counterfactual-ready). - core_order_events (OrderEventRecord): Order-Lifecycle als Daten (Placed/PlaceFailed/ LadderStart/LadderStep/FloorReplaced/DustAbort ...) inkl. CLOB-Response. - SignalId (GUID) auf CopySignal, durchgereicht bis ClosedTrade + Core-TradeRecord (Dual-Write) und in die Leiter (ExitLadderState.SignalId) -> Dossier-Korrelation. - CopyTradingEngine: ~20 Entscheidungs-Sites journalisieren zusaetzlich zum Freitext-Log (Mode/SellOnly/H3/MaxBuyPrice/PerMaster/TimeLimit/Budget/Balance/Minimum/SpamBlock/ Leiter/Ownership/NotFound/Teilverkauf/Inkonsistenz/Grace/Demo-Fill/-Close/Live-BUY). - SellLadderService: Order-Events fuer Start/Step/Floor-Replace/Dust; IOrderEventLog injiziert. - TerminalLogger: JSONL-Sink (eine Datei/Tag, LogJson pur) + CorrelationId-Support. Dual-Sink. - Journal-Writes fehlertolerant (brechen den Geld-Pfad nie). - Migrationen offline generiert UND angewendet (rein additiv): Core (Widen F1 + Journal), CopyTrading (SignalId), RF (Initial) - DB war bis AddMarketTakerFeeBps migriert, verifiziert. - Launcher-Designer: Account-Spalten-Instanziierung wiederhergestellt (war bei Designer- Reserialisierung verloren gegangen -> NullReference im Smoke). Tests: +5 (LogJson, Journal-Roundtrips, SignalId) + Journal-Assertions in Engine-Tests. Build 0 Fehler, 336 Tests gruen, --smoke-ui komplett gruen (alle Views inkl. RF gegen echte Tabellen). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
eac47369f0
commit
bf3e012f8b
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
/// <summary>Ausgang einer Handelsentscheidung im Entscheidungsjournal.</summary>
|
||||
public enum TradeDecision
|
||||
{
|
||||
Executed, // Aktion ausgeführt (Order platziert / Demo-Fill / Leiter gestartet)
|
||||
Rejected, // aktiv abgelehnt (Risk-/Plausibilitätsregel)
|
||||
Skipped, // bewusst übersprungen (z. B. ExitPending, Spam-Blockade, Modus)
|
||||
Failed // versucht, aber fehlgeschlagen (z. B. Order-Fehler)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strukturierter Grund einer Entscheidung (statt Freitext). Wird als STRING persistiert –
|
||||
/// neue Werte können gefahrlos ergänzt werden. Die Codes decken die heutigen
|
||||
/// TradeReasoning-/Reject-Stellen von Engine, Leiter und Monitor ab.
|
||||
/// </summary>
|
||||
public enum DecisionReason
|
||||
{
|
||||
None = 0,
|
||||
|
||||
// ----- Modus / Zustand -----
|
||||
ModeInactive, // Live-/Demo-Trading deaktiviert
|
||||
SellOnlyModeBuyBlocked, // SellOnly-Modus blockiert BUY
|
||||
TraderInactive, // Master nicht gefunden / inaktiv
|
||||
AccountInactive, // Account nicht gefunden / inaktiv
|
||||
|
||||
// ----- BUY-Pfad -----
|
||||
MaxBuyPriceExceeded, // Signalpreis über MaxBuyPrice
|
||||
ExitPendingBuySkip, // H3: SELL-Leiter aktiv – kein Zukauf
|
||||
TimeWindowLimitReached, // Zeitfenster-Budget (6h/24h/72h/None) erschöpft
|
||||
MarketBudgetExhausted, // PerMarket-Budget erschöpft
|
||||
PerMasterLimitReached, // PerMaster-Budget erschöpft
|
||||
InsufficientBalance, // verfügbares Guthaben reicht nicht
|
||||
BelowPolymarketMinimum, // Order unter Minimum (Shares/USDC)
|
||||
MarketExpiredOrTooClose, // EndDate-Filter
|
||||
DuplicateOrPendingOrder, // bereits offene/pending Order
|
||||
|
||||
// ----- SELL-Pfad -----
|
||||
SellSpamBlock, // SELL <20s nach letztem SELL
|
||||
LadderAlreadyActive, // Eskalationsleiter läuft bereits
|
||||
PositionNotFound, // keine passende Position im Portfolio
|
||||
OwnershipMismatch, // Position gehört anderem Trader (Safety)
|
||||
PartialSellBelowThreshold, // Teilverkauf unter Signifikanz-Schwelle
|
||||
MasterPositionInconsistent, // Master hält laut Tracking 0 Shares
|
||||
SyncGracePeriod, // kein Tracking + Haltezeit < Schonfrist
|
||||
|
||||
// ----- Ausführung -----
|
||||
OrderPlaced, // Order erfolgreich platziert
|
||||
OrderFailed, // CLOB-Fehler beim Platzieren
|
||||
DemoFilled, // Demo-Fill gebucht
|
||||
DemoClosed, // Demo-Position geschlossen
|
||||
LadderStarted, // SELL-Leiter gestartet
|
||||
LadderStartFailed, // Leiter-Startorder fehlgeschlagen
|
||||
LadderDustAbort, // H4: Dust-Rest unter Minimum – Leiter beendet
|
||||
ProfitTargetTriggered, // Take-Profit hat Exit ausgelöst
|
||||
SystemResolutionClose // System-Close bei Marktauflösung (TraderId==0)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eine Zeile im Entscheidungsjournal (core_decision_journal): JEDE Handelsentscheidung –
|
||||
/// ausgeführt, abgelehnt oder übersprungen – strukturiert und abfragbar. Grundlage für
|
||||
/// Supervisor-Analysen („warum (nicht) gehandelt?") und Counterfactual-Auswertungen
|
||||
/// (MarketSlug/EndDate sind dafür bewusst enthalten). Siehe docs/konzepte/KONZEPT-Modul-Supervisor.md.
|
||||
/// </summary>
|
||||
public class DecisionRecord
|
||||
{
|
||||
public long Id { get; set; } // DB-Autoincrement
|
||||
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>Korrelation: verbindet Signal → Entscheidungen → Orders → ClosedTrade.</summary>
|
||||
public string SignalId { get; set; } = string.Empty;
|
||||
|
||||
public string ModuleName { get; set; } = string.Empty;
|
||||
public int AccountId { get; set; }
|
||||
public bool IsDemo { get; set; }
|
||||
public int SourceTraderId { get; set; }
|
||||
|
||||
public string TokenId { get; set; } = string.Empty;
|
||||
public string MarketSlug { get; set; } = string.Empty; // counterfactual-ready
|
||||
public string MarketQuestion { get; set; } = string.Empty;
|
||||
public string Side { get; set; } = string.Empty; // BUY/SELL
|
||||
public decimal SignalPrice { get; set; }
|
||||
public DateTime? MarketEndDate { get; set; } // counterfactual-ready
|
||||
|
||||
public TradeDecision Decision { get; set; }
|
||||
public DecisionReason Reason { get; set; }
|
||||
|
||||
/// <summary>Kompakte Kontext-Zahlen als JSON (Limitwerte, Budgets, berechnete Größen …).</summary>
|
||||
public string ContextJson { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Menschlicher Begründungstext (wie bisher im Log).</summary>
|
||||
public string Message { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user