Postgres (#30)
* Add postgres * Migrate users * Migrate geneticRequest * Try to fix Concurrent call * Fix asyncawait * Fix async and concurrent * Migrate backtests * Add cache for user by address * Fix backtest migration * Fix not open connection * Fix backtest command error * Fix concurrent * Fix all concurrency * Migrate TradingRepo * Fix scenarios * Migrate statistic repo * Save botbackup * Add settings et moneymanagement * Add bot postgres * fix a bit more backups * Fix bot model * Fix loading backup * Remove cache market for read positions * Add workers to postgre * Fix workers api * Reduce get Accounts for workers * Migrate synth to postgre * Fix backtest saved * Remove mongodb * botservice decorrelation * Fix tradingbot scope call * fix tradingbot * fix concurrent * Fix scope for genetics * Fix account over requesting * Fix bundle backtest worker * fix a lot of things * fix tab backtest * Remove optimized moneymanagement * Add light signal to not use User and too much property * Make money management lighter * insert indicators to awaitable * Migrate add strategies to await * Refactor scenario and indicator retrieval to use asynchronous methods throughout the application * add more async await * Add services * Fix and clean * Fix bot a bit * Fix bot and add message for cooldown * Remove fees * Add script to deploy db * Update dfeeploy script * fix script * Add idempotent script and backup * finish script migration * Fix did user and agent name on start bot
This commit is contained in:
@@ -0,0 +1,521 @@
|
||||
using Managing.Infrastructure.Databases.PostgreSql.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Managing.Infrastructure.Databases.PostgreSql;
|
||||
|
||||
public class ManagingDbContext : DbContext
|
||||
{
|
||||
public ManagingDbContext(DbContextOptions<ManagingDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<AccountEntity> Accounts { get; set; }
|
||||
public DbSet<UserEntity> Users { get; set; }
|
||||
public DbSet<GeneticRequestEntity> GeneticRequests { get; set; }
|
||||
public DbSet<BacktestEntity> Backtests { get; set; }
|
||||
public DbSet<BundleBacktestRequestEntity> BundleBacktestRequests { get; set; }
|
||||
|
||||
// Trading entities
|
||||
public DbSet<ScenarioEntity> Scenarios { get; set; }
|
||||
public DbSet<IndicatorEntity> Indicators { get; set; }
|
||||
public DbSet<ScenarioIndicatorEntity> ScenarioIndicators { get; set; }
|
||||
public DbSet<SignalEntity> Signals { get; set; }
|
||||
public DbSet<PositionEntity> Positions { get; set; }
|
||||
public DbSet<TradeEntity> Trades { get; set; }
|
||||
|
||||
|
||||
// Statistics entities
|
||||
public DbSet<TopVolumeTickerEntity> TopVolumeTickers { get; set; }
|
||||
public DbSet<SpotlightOverviewEntity> SpotlightOverviews { get; set; }
|
||||
public DbSet<TraderEntity> Traders { get; set; }
|
||||
public DbSet<FundingRateEntity> FundingRates { get; set; }
|
||||
|
||||
// Bot entities
|
||||
public DbSet<BotBackupEntity> BotBackups { get; set; }
|
||||
|
||||
// Settings entities
|
||||
public DbSet<MoneyManagementEntity> MoneyManagements { get; set; }
|
||||
|
||||
// Worker entities
|
||||
public DbSet<WorkerEntity> Workers { get; set; }
|
||||
|
||||
public DbSet<SynthMinersLeaderboardEntity> SynthMinersLeaderboards { get; set; }
|
||||
public DbSet<SynthPredictionEntity> SynthPredictions { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// Configure Account entity
|
||||
modelBuilder.Entity<AccountEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Name).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Key).HasMaxLength(500);
|
||||
entity.Property(e => e.Secret).HasMaxLength(500);
|
||||
entity.Property(e => e.Exchange)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
entity.Property(e => e.Type)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
|
||||
// Create unique index on account name
|
||||
entity.HasIndex(e => e.Name).IsUnique();
|
||||
entity.HasIndex(e => e.Key);
|
||||
|
||||
// Configure relationship with User
|
||||
entity.HasOne(e => e.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
// Configure User entity
|
||||
modelBuilder.Entity<UserEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Name).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.AgentName).HasMaxLength(255);
|
||||
entity.Property(e => e.AvatarUrl).HasMaxLength(500);
|
||||
entity.Property(e => e.TelegramChannel).HasMaxLength(255);
|
||||
});
|
||||
|
||||
// Configure GeneticRequest entity
|
||||
modelBuilder.Entity<GeneticRequestEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.RequestId).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Status).IsRequired().HasMaxLength(50);
|
||||
entity.Property(e => e.Ticker)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
entity.Property(e => e.Timeframe)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
entity.Property(e => e.SelectionMethod)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
entity.Property(e => e.CrossoverMethod)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
entity.Property(e => e.MutationMethod)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
entity.Property(e => e.Balance).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.BestIndividual).HasMaxLength(4000);
|
||||
entity.Property(e => e.ErrorMessage).HasMaxLength(2000);
|
||||
entity.Property(e => e.ProgressInfo).HasMaxLength(4000);
|
||||
entity.Property(e => e.BestChromosome).HasMaxLength(4000);
|
||||
entity.Property(e => e.EligibleIndicatorsJson).HasMaxLength(2000);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.RequestId).IsUnique();
|
||||
entity.HasIndex(e => e.Status);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
|
||||
// Configure relationship with User
|
||||
entity.HasOne(e => e.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
// Configure Backtest entity
|
||||
modelBuilder.Entity<BacktestEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Identifier).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.RequestId).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.UserName).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.FinalPnl).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.GrowthPercentage).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.HodlPercentage).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.Fees).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.ConfigJson).HasColumnType("jsonb");
|
||||
entity.Property(e => e.PositionsJson).HasColumnType("jsonb");
|
||||
entity.Property(e => e.SignalsJson).HasColumnType("jsonb");
|
||||
entity.Property(e => e.MoneyManagementJson).HasColumnType("jsonb");
|
||||
entity.Property(e => e.StatisticsJson).HasColumnType("jsonb");
|
||||
entity.Property(e => e.ScoreMessage).HasMaxLength(1000);
|
||||
entity.Property(e => e.Metadata).HasColumnType("text");
|
||||
|
||||
// Create indexes for common queries
|
||||
entity.HasIndex(e => e.Identifier).IsUnique();
|
||||
entity.HasIndex(e => e.RequestId);
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.Score);
|
||||
entity.HasIndex(e => e.FinalPnl);
|
||||
entity.HasIndex(e => e.WinRate);
|
||||
entity.HasIndex(e => e.StartDate);
|
||||
entity.HasIndex(e => e.EndDate);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
|
||||
// Composite indexes for efficient pagination and filtering
|
||||
entity.HasIndex(e => new { e.UserName, e.Score });
|
||||
entity.HasIndex(e => new { e.RequestId, e.Score });
|
||||
});
|
||||
|
||||
// Configure BundleBacktestRequest entity
|
||||
modelBuilder.Entity<BundleBacktestRequestEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.RequestId).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.UserName).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Name).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Status)
|
||||
.IsRequired()
|
||||
.HasConversion<string>(); // Store enum as string
|
||||
entity.Property(e => e.BacktestRequestsJson).HasColumnType("text");
|
||||
entity.Property(e => e.ErrorMessage).HasColumnType("text");
|
||||
entity.Property(e => e.ProgressInfo).HasColumnType("text");
|
||||
entity.Property(e => e.CurrentBacktest).HasMaxLength(500);
|
||||
entity.Property(e => e.ResultsJson).HasColumnType("jsonb");
|
||||
|
||||
// Configure relationship with User
|
||||
entity.HasOne(e => e.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
// Create indexes for common queries
|
||||
entity.HasIndex(e => e.RequestId).IsUnique();
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.Status);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
entity.HasIndex(e => e.CompletedAt);
|
||||
entity.HasIndex(e => e.UserId);
|
||||
|
||||
// Composite index for user queries ordered by creation date
|
||||
entity.HasIndex(e => new { e.UserName, e.CreatedAt });
|
||||
});
|
||||
|
||||
// Configure Scenario entity
|
||||
modelBuilder.Entity<ScenarioEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Name).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.UserName).HasMaxLength(255);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Name);
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
|
||||
// Composite index for user scenarios
|
||||
entity.HasIndex(e => new { e.UserName, e.Name });
|
||||
});
|
||||
|
||||
// Configure Indicator entity
|
||||
modelBuilder.Entity<IndicatorEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Name).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Type).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Timeframe).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.SignalType).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.UserName).HasMaxLength(255);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Name);
|
||||
entity.HasIndex(e => e.Type);
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
|
||||
// Composite index for user indicators
|
||||
entity.HasIndex(e => new { e.UserName, e.Name });
|
||||
});
|
||||
|
||||
// Configure ScenarioIndicator junction table
|
||||
modelBuilder.Entity<ScenarioIndicatorEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
|
||||
// Configure relationships
|
||||
entity.HasOne(e => e.Scenario)
|
||||
.WithMany(s => s.ScenarioIndicators)
|
||||
.HasForeignKey(e => e.ScenarioId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.HasOne(e => e.Indicator)
|
||||
.WithMany(i => i.ScenarioIndicators)
|
||||
.HasForeignKey(e => e.IndicatorId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.ScenarioId);
|
||||
entity.HasIndex(e => e.IndicatorId);
|
||||
entity.HasIndex(e => new { e.ScenarioId, e.IndicatorId }).IsUnique();
|
||||
});
|
||||
|
||||
// Configure Signal entity
|
||||
modelBuilder.Entity<SignalEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Identifier).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Direction).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Confidence).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Ticker).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Status).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Timeframe).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Type).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.SignalType).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.IndicatorName).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.UserName).HasMaxLength(255);
|
||||
entity.Property(e => e.CandleJson).HasColumnType("text");
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Identifier);
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.Date);
|
||||
entity.HasIndex(e => e.Ticker);
|
||||
entity.HasIndex(e => e.Status);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
|
||||
// Composite indexes for common queries
|
||||
entity.HasIndex(e => new { e.UserName, e.Date });
|
||||
entity.HasIndex(e => new { e.Identifier, e.Date, e.UserName }).IsUnique();
|
||||
});
|
||||
|
||||
// Configure Position entity
|
||||
modelBuilder.Entity<PositionEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Identifier).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.ProfitAndLoss).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.OriginDirection).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Status).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Ticker).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Initiator).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.SignalIdentifier).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.AccountName).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.UserName).HasMaxLength(255);
|
||||
entity.Property(e => e.MoneyManagementJson).HasColumnType("text");
|
||||
|
||||
// Configure relationships with trades
|
||||
entity.HasOne(e => e.OpenTrade)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.OpenTradeId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
entity.HasOne(e => e.StopLossTrade)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.StopLossTradeId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
entity.HasOne(e => e.TakeProfit1Trade)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.TakeProfit1TradeId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
entity.HasOne(e => e.TakeProfit2Trade)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.TakeProfit2TradeId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Identifier).IsUnique();
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.Status);
|
||||
entity.HasIndex(e => e.Initiator);
|
||||
entity.HasIndex(e => e.Date);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
|
||||
// Composite indexes
|
||||
entity.HasIndex(e => new { e.UserName, e.Identifier });
|
||||
});
|
||||
|
||||
// Configure Trade entity
|
||||
modelBuilder.Entity<TradeEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Direction).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Status).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.TradeType).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Ticker).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.Fee).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.Quantity).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.Price).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.Leverage).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.ExchangeOrderId).HasMaxLength(255);
|
||||
entity.Property(e => e.Message).HasColumnType("text");
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Date);
|
||||
entity.HasIndex(e => e.Status);
|
||||
entity.HasIndex(e => e.ExchangeOrderId);
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Configure TopVolumeTicker entity
|
||||
modelBuilder.Entity<TopVolumeTickerEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Volume).HasPrecision(18, 8);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Ticker);
|
||||
entity.HasIndex(e => e.Date);
|
||||
entity.HasIndex(e => e.Exchange);
|
||||
entity.HasIndex(e => e.Rank);
|
||||
|
||||
// Composite indexes for efficient queries
|
||||
entity.HasIndex(e => new { e.Exchange, e.Date });
|
||||
entity.HasIndex(e => new { e.Date, e.Rank });
|
||||
});
|
||||
|
||||
// Configure SpotlightOverview entity
|
||||
modelBuilder.Entity<SpotlightOverviewEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Identifier).IsRequired();
|
||||
entity.Property(e => e.SpotlightsJson).HasColumnType("jsonb");
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Identifier).IsUnique();
|
||||
entity.HasIndex(e => e.DateTime);
|
||||
entity.HasIndex(e => e.ScenarioCount);
|
||||
|
||||
// Composite index for efficient queries
|
||||
entity.HasIndex(e => new { e.DateTime, e.ScenarioCount });
|
||||
});
|
||||
|
||||
// Configure Trader entity
|
||||
modelBuilder.Entity<TraderEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Address).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Pnl).HasPrecision(18, 8);
|
||||
entity.Property(e => e.AverageWin).HasPrecision(18, 8);
|
||||
entity.Property(e => e.AverageLoss).HasPrecision(18, 8);
|
||||
entity.Property(e => e.Roi).HasPrecision(18, 8);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Address);
|
||||
entity.HasIndex(e => e.IsBestTrader);
|
||||
entity.HasIndex(e => e.Winrate);
|
||||
entity.HasIndex(e => e.Pnl);
|
||||
entity.HasIndex(e => e.Roi);
|
||||
|
||||
// Composite indexes for efficient queries
|
||||
entity.HasIndex(e => new { e.IsBestTrader, e.Winrate });
|
||||
entity.HasIndex(e => new { e.IsBestTrader, e.Roi });
|
||||
entity.HasIndex(e => new { e.Address, e.IsBestTrader }).IsUnique();
|
||||
});
|
||||
|
||||
// Configure FundingRate entity
|
||||
modelBuilder.Entity<FundingRateEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Rate).HasPrecision(18, 8);
|
||||
entity.Property(e => e.OpenInterest).HasPrecision(18, 8);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Ticker);
|
||||
entity.HasIndex(e => e.Exchange);
|
||||
entity.HasIndex(e => e.Date);
|
||||
entity.HasIndex(e => e.Direction);
|
||||
|
||||
// Composite indexes for efficient queries
|
||||
entity.HasIndex(e => new { e.Ticker, e.Exchange });
|
||||
entity.HasIndex(e => new { e.Exchange, e.Date });
|
||||
entity.HasIndex(e => new { e.Ticker, e.Exchange, e.Date }).IsUnique();
|
||||
});
|
||||
|
||||
// Configure BotBackup entity
|
||||
modelBuilder.Entity<BotBackupEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Identifier).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.UserName).HasMaxLength(255);
|
||||
entity.Property(e => e.Data).IsRequired().HasColumnType("text");
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Identifier).IsUnique();
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.LastStatus);
|
||||
entity.HasIndex(e => e.CreateDate);
|
||||
|
||||
// Composite index for user bots
|
||||
entity.HasIndex(e => new { e.UserName, e.CreateDate });
|
||||
|
||||
// Configure relationship with User
|
||||
entity.HasOne(e => e.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
// Configure MoneyManagement entity
|
||||
modelBuilder.Entity<MoneyManagementEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Name).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Timeframe).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.StopLoss).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.TakeProfit).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.Leverage).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.UserName).HasMaxLength(255);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Name);
|
||||
entity.HasIndex(e => e.UserName);
|
||||
|
||||
// Composite index for user money managements
|
||||
entity.HasIndex(e => new { e.UserName, e.Name });
|
||||
|
||||
// Configure relationship with User
|
||||
entity.HasOne(e => e.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
// Configure Worker entity
|
||||
modelBuilder.Entity<WorkerEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.WorkerType).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.StartTime).IsRequired();
|
||||
entity.Property(e => e.LastRunTime);
|
||||
entity.Property(e => e.ExecutionCount).IsRequired();
|
||||
entity.Property(e => e.DelayTicks).IsRequired();
|
||||
entity.Property(e => e.IsActive).IsRequired();
|
||||
entity.HasIndex(e => e.WorkerType).IsUnique();
|
||||
});
|
||||
|
||||
// Configure SynthMinersLeaderboard entity
|
||||
modelBuilder.Entity<SynthMinersLeaderboardEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Asset).IsRequired().HasMaxLength(32);
|
||||
entity.Property(e => e.TimeIncrement).IsRequired();
|
||||
entity.Property(e => e.SignalDate);
|
||||
entity.Property(e => e.IsBacktest).IsRequired();
|
||||
entity.Property(e => e.MinersData).HasColumnType("jsonb");
|
||||
entity.Property(e => e.CacheKey).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.CreatedAt).IsRequired();
|
||||
entity.HasIndex(e => e.CacheKey).IsUnique();
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
});
|
||||
|
||||
// Configure SynthPrediction entity
|
||||
modelBuilder.Entity<SynthPredictionEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Asset).IsRequired().HasMaxLength(32);
|
||||
entity.Property(e => e.MinerUid).IsRequired();
|
||||
entity.Property(e => e.TimeIncrement).IsRequired();
|
||||
entity.Property(e => e.TimeLength).IsRequired();
|
||||
entity.Property(e => e.SignalDate);
|
||||
entity.Property(e => e.IsBacktest).IsRequired();
|
||||
entity.Property(e => e.PredictionData).HasColumnType("jsonb");
|
||||
entity.Property(e => e.CacheKey).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.CreatedAt).IsRequired();
|
||||
entity.HasIndex(e => e.CacheKey).IsUnique();
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user