using System; namespace PolyTraderSharp.Models { /// Ausgang einer Handelsentscheidung im Entscheidungsjournal. 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) } /// /// 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. /// 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) } /// /// 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/archiv/konzepte/KONZEPT-Modul-Supervisor.md. /// public class DecisionRecord { public long Id { get; set; } // DB-Autoincrement public DateTime Timestamp { get; set; } = DateTime.UtcNow; /// Korrelation: verbindet Signal → Entscheidungen → Orders → ClosedTrade. 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; } /// Kompakte Kontext-Zahlen als JSON (Limitwerte, Budgets, berechnete Größen …). public string ContextJson { get; set; } = string.Empty; /// Menschlicher Begründungstext (wie bisher im Log). public string Message { get; set; } = string.Empty; } }