using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Managing.Infrastructure.Databases.PostgreSql.Entities; [Table("Backtests")] public class BacktestEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Required] [MaxLength(255)] public string Identifier { get; set; } = string.Empty; [Required] public Guid RequestId { get; set; } [Required] [Column(TypeName = "decimal(18,8)")] public decimal FinalPnl { get; set; } [Required] public int WinRate { get; set; } [Required] [Column(TypeName = "decimal(18,8)")] public decimal GrowthPercentage { get; set; } [Required] [Column(TypeName = "decimal(18,8)")] public decimal HodlPercentage { get; set; } [Required] [Column(TypeName = "jsonb")] public string ConfigJson { get; set; } = string.Empty; // Denormalized bot/backtest name (e.g., "MyBundleTest #3") for sorting/filtering [Required] [MaxLength(255)] public string Name { get; set; } = string.Empty; // Denormalized ticker string for fast filtering/sorting [Required] [MaxLength(32)] public string Ticker { get; set; } = string.Empty; // Stored timeframe as enum numeric value for direct sorting/filtering [Required] public int Timeframe { get; set; } // Stored trading type as enum numeric value for direct filtering [Required] public int TradingType { get; set; } // Comma-separated indicator types for filtering, e.g., "EMA_CROSS,MACD_CROSS" [Column(TypeName = "text")] public string IndicatorsCsv { get; set; } = string.Empty; // Number of indicators used in the scenario for sorting/filtering [Required] public int IndicatorsCount { get; set; } [Required] [Column(TypeName = "jsonb")] public string PositionsJson { get; set; } = string.Empty; [Required] [Column(TypeName = "jsonb")] public string SignalsJson { get; set; } = string.Empty; [Required] public DateTime StartDate { get; set; } [Required] public DateTime EndDate { get; set; } // Precomputed for filtering: EndDate - StartDate [Required] public TimeSpan Duration { get; set; } [Required] [Column(TypeName = "jsonb")] public string MoneyManagementJson { get; set; } = string.Empty; [Required] public int UserId { get; set; } // Navigation property public UserEntity? User { get; set; } [Column(TypeName = "jsonb")] public string? StatisticsJson { get; set; } // Extracted metrics for efficient querying/indexing [Required] [Column(TypeName = "decimal(18,8)")] public decimal SharpeRatio { get; set; } [Required] [Column(TypeName = "decimal(18,8)")] public decimal MaxDrawdown { get; set; } // PostgreSQL maps TimeSpan to interval [Required] public TimeSpan MaxDrawdownRecoveryTime { get; set; } [Required] [Column(TypeName = "decimal(18,8)")] public decimal Fees { get; set; } [Required] public double Score { get; set; } [Column(TypeName = "text")] public string ScoreMessage { get; set; } = string.Empty; [Column(TypeName = "text")] public string? Metadata { get; set; } [Required] public DateTime CreatedAt { get; set; } = DateTime.UtcNow; [Required] public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; [Required] [Column(TypeName = "decimal(18,8)")] public decimal InitialBalance { get; set; } [Required] [Column(TypeName = "decimal(18,8)")] public decimal NetPnl { get; set; } [Required] public int PositionCount { get; set; } }