using System; using System.Collections.Generic; using FinlyticCore.Dtos.TechnicalAnalysis; using FinlyticCore.Dtos.Trading; using FinlyticEngine.Database.Entities; namespace FinlyticEngine.Tests.TestSupport; /// /// Small builder helpers for the entities used across the TradeLifecycleService tenant-boundary tests, to /// keep individual test methods focused on the behavior under test rather than entity plumbing. /// public static class TestData { public static ExitPlan SimpleExitPlan(decimal stopLoss = 90m, decimal takeProfit = 110m) => new( StrategyType: ExitStrategyType.FixedSingleTarget, InitialStopLoss: stopLoss, TakeProfitStages: new List { new(1, takeProfit, 100m, 1m, "Test stage") }); public static AiValidationResultDto ApprovedAiValidation() => new( IsApproved: true, Confidence: 0.9m, Source: ValidationSource.Ai, ThesisSummary: "Test thesis", InvalidationReason: "", KeyCatalysts: new List(), IdentifiedRisks: new List()); /// /// Builds an active, non-expired trade proposal ("system-wide opportunity") ready to be accepted. /// public static EngineTradeProposalEntity ActiveProposal( string isin = "US0378331005", decimal entryPrice = 100m, decimal stopLoss = 90m, bool isActive = true, DateTime? expiresAtUtc = null) { return new EngineTradeProposalEntity { Id = Guid.NewGuid(), UnderlyingIsin = isin, Symbol = "AAPL", StrategyKey = "TestStrategy", Direction = SignalDirection.Buy, QualityScore = 80m, CompositeScore = 80m, CurrentPrice = entryPrice, EntryPrice = entryPrice, StopLoss = stopLoss, TakeProfit1 = entryPrice * 1.1m, RiskRewardRatio = 2m, ExitPlan = SimpleExitPlan(stopLoss, entryPrice * 1.1m), SelectedDerivative = null, AiValidation = ApprovedAiValidation(), IsActive = isActive, CreatedAtUtc = DateTime.UtcNow, ExpiresAtUtc = expiresAtUtc ?? DateTime.UtcNow.AddHours(24) }; } /// /// Builds an active trade owned by , optionally linked to a proposal. /// public static EngineTradeEntity ActiveTrade( Guid userId, Guid? proposalId = null, string isin = "US0378331005", decimal averageBuyIn = 100m, decimal stopLoss = 90m, TradeStatus status = TradeStatus.Active) { return new EngineTradeEntity { Id = Guid.NewGuid(), UserId = userId, ProposalId = proposalId ?? Guid.Empty, UnderlyingIsin = isin, Symbol = "AAPL", ExecutionMode = ExecutionMode.ManualTradeRepublic, InstrumentType = InstrumentCategoryType.Stock, Direction = SignalDirection.Buy, Status = status, AverageBuyIn = averageBuyIn, TotalQuantity = 1m, InitialStopLoss = stopLoss, CurrentStopLoss = stopLoss, CurrentPrice = averageBuyIn, TakeProfit1 = averageBuyIn * 1.1m, TakeProfit2 = averageBuyIn * 1.2m, ExitPlan = SimpleExitPlan(stopLoss, averageBuyIn * 1.1m), OpenedAtUtc = DateTime.UtcNow, LastUpdatedAtUtc = DateTime.UtcNow }; } }