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
};
}
}