using System; using System.Collections.Generic; using System.Text.Json.Serialization; using FinlyticCore.Dtos.TechnicalAnalysis; namespace FinlyticCore.Dtos.Trading; public record DerivativeSelectionDto( [property: JsonPropertyName("derivativeIsin")] string DerivativeIsin, // Trade Republic liefert für Derivate keine WKN, nur die ISIN (siehe TradeRepublicDerivativeItemDto). // Daher ist dieses Feld nullable: eine ISIN darf hier NICHT als Ersatz-WKN eingetragen werden (Rules.md §4). [property: JsonPropertyName("derivativeWkn")] string? DerivativeWkn, [property: JsonPropertyName("issuer")] string Issuer, [property: JsonPropertyName("optionType")] string OptionType, // "LONG" oder "SHORT" [property: JsonPropertyName("strike")] decimal Strike, [property: JsonPropertyName("barrier")] decimal Barrier, [property: JsonPropertyName("leverage")] decimal Leverage, [property: JsonPropertyName("safetyBufferPercent")] decimal SafetyBufferPercent, [property: JsonPropertyName("spreadPercentage")] decimal SpreadPercentage, [property: JsonPropertyName("size")] decimal Size ); /// /// Kennzeichnet die Herkunft einer -Entscheidung, damit /// Konsumenten (Frontend, Logs) eine echte KI-Analyse von einer regelbasierten Ersatzentscheidung /// unterscheiden können. Der Enum-Wert ist absichtlich der Default (0), damit ein /// vom N8N-Webhook geliefertes JSON, das dieses Feld (noch) nicht setzt, korrekt als KI-Ergebnis /// interpretiert wird. /// [JsonConverter(typeof(JsonStringEnumConverter))] public enum ValidationSource { Ai, RuleBased } /// /// Ergebnis des AI-Reasoning-Gates. ist nur gesetzt, wenn /// den Wert hat, da eine Konfidenz ohne tatsächliche KI-Bewertung /// erfunden wäre (Rules.md §4). /// public record AiValidationResultDto( [property: JsonPropertyName("isApproved")] bool IsApproved, [property: JsonPropertyName("confidence")] decimal? Confidence, [property: JsonPropertyName("validationSource")] ValidationSource Source, [property: JsonPropertyName("thesisSummary")] string ThesisSummary, [property: JsonPropertyName("invalidationReason")] string InvalidationReason, [property: JsonPropertyName("keyCatalysts")] List KeyCatalysts, [property: JsonPropertyName("identifiedRisks")] List IdentifiedRisks ); public record TradeProposalDto( [property: JsonPropertyName("proposalId")] Guid ProposalId, [property: JsonPropertyName("underlyingIsin")] string UnderlyingIsin, [property: JsonPropertyName("symbol")] string Symbol, [property: JsonPropertyName("strategyKey")] string StrategyKey, [property: JsonPropertyName("direction")] SignalDirection Direction, [property: JsonPropertyName("qualityScore")] decimal QualityScore, [property: JsonPropertyName("compositeScore")] decimal CompositeScore, [property: JsonPropertyName("currentPrice")] decimal CurrentPrice, [property: JsonPropertyName("entryPrice")] decimal EntryPrice, [property: JsonPropertyName("invalidationPrice")] decimal InvalidationPrice, [property: JsonPropertyName("exitPlan")] ExitPlan ExitPlan, [property: JsonPropertyName("selectedDerivative")] DerivativeSelectionDto? SelectedDerivative, [property: JsonPropertyName("aiValidation")] AiValidationResultDto AiValidation, [property: JsonPropertyName("createdAtUtc")] DateTime CreatedAtUtc, [property: JsonPropertyName("expiresAtUtc")] DateTime ExpiresAtUtc ); /// /// Full result of ITradeLifecycleService.EvaluateAssetAsync, carrying both possible outcomes of the /// evaluation pipeline (technicals, sentiment, fundamentals, simulation-reliability, AI reasoning gate): /// an accepted opportunity ( is set) or a rejection, in which case /// is but every score/reasoning field below is still populated with the real, /// already-computed values instead of leaving the caller with silence (Rules.md §4). /// /// When the pipeline could not even produce a score (no technical setups available for the ISIN, or the /// ISIN was blank), the score fields are 0 and carries a /// "[Regelbasiert]"-prefixed explanation — the same prefix uses for /// its fallback — so a caller/UI can recognize this is not a real /// AI verdict, just as it already must for a rule-based . /// /// public record AssetEvaluationResultDto( [property: JsonPropertyName("proposal")] TradeProposalDto? Proposal, [property: JsonPropertyName("compositeScore")] decimal CompositeScore, [property: JsonPropertyName("technicalScore")] decimal TechnicalScore, [property: JsonPropertyName("sentimentScore")] decimal SentimentScore, [property: JsonPropertyName("fundamentalScore")] decimal FundamentalScore, [property: JsonPropertyName("passedEarningsLockout")] bool PassedEarningsLockout, [property: JsonPropertyName("daysToNextEarnings")] int? DaysToNextEarnings, [property: JsonPropertyName("passedDividendGate")] bool PassedDividendGate, [property: JsonPropertyName("daysToNextExDividend")] int? DaysToNextExDividend, [property: JsonPropertyName("aiApproved")] bool AiApproved, [property: JsonPropertyName("aiThesisSummary")] string AiThesisSummary, [property: JsonPropertyName("aiIdentifiedRisks")] List AiIdentifiedRisks ); public record TradeFillDto( [property: JsonPropertyName("fillId")] Guid FillId, [property: JsonPropertyName("executedAtUtc")] DateTime ExecutedAtUtc, [property: JsonPropertyName("price")] decimal Price, [property: JsonPropertyName("quantity")] decimal Quantity, [property: JsonPropertyName("fee")] decimal Fee, [property: JsonPropertyName("note")] string? Note ); public record ActiveTradeDto( [property: JsonPropertyName("tradeId")] Guid TradeId, [property: JsonPropertyName("proposalId")] Guid ProposalId, [property: JsonPropertyName("userId")] Guid UserId, [property: JsonPropertyName("underlyingIsin")] string UnderlyingIsin, [property: JsonPropertyName("symbol")] string Symbol, [property: JsonPropertyName("derivativeIsin")] string? DerivativeIsin, [property: JsonPropertyName("derivativeWkn")] string? DerivativeWkn, [property: JsonPropertyName("executionMode")] ExecutionMode ExecutionMode, [property: JsonPropertyName("instrumentType")] InstrumentCategoryType InstrumentType, [property: JsonPropertyName("direction")] SignalDirection Direction, [property: JsonPropertyName("status")] TradeStatus Status, [property: JsonPropertyName("averageBuyIn")] decimal AverageBuyIn, [property: JsonPropertyName("totalQuantity")] decimal TotalQuantity, [property: JsonPropertyName("initialStopLoss")] decimal InitialStopLoss, [property: JsonPropertyName("currentStopLoss")] decimal CurrentStopLoss, [property: JsonPropertyName("currentPrice")] decimal CurrentPrice, [property: JsonPropertyName("unrealizedPnlEur")] decimal UnrealizedPnlEur, [property: JsonPropertyName("unrealizedPnlPercent")] decimal UnrealizedPnlPercent, [property: JsonPropertyName("realizedPnlEur")] decimal RealizedPnlEur, [property: JsonPropertyName("exitPlan")] ExitPlan ExitPlan, [property: JsonPropertyName("fills")] List Fills, [property: JsonPropertyName("openedAtUtc")] DateTime OpenedAtUtc, [property: JsonPropertyName("closedAtUtc")] DateTime? ClosedAtUtc );