Trading bot grain (#33)
* Trading bot Grain * Fix a bit more of the trading bot * Advance on the tradingbot grain * Fix build * Fix db script * Fix user login * Fix a bit backtest * Fix cooldown and backtest * start fixing bot start * Fix startup * Setup local db * Fix build and update candles and scenario * Add bot registry * Add reminder * Updateing the grains * fix bootstraping * Save stats on tick * Save bot data every tick * Fix serialization * fix save bot stats * Fix get candles * use dict instead of list for position * Switch hashset to dict * Fix a bit * Fix bot launch and bot view * add migrations * Remove the tolist * Add agent grain * Save agent summary * clean * Add save bot * Update get bots * Add get bots * Fix stop/restart * fix Update config * Update scanner table on new backtest saved * Fix backtestRowDetails.tsx * Fix agentIndex * Update agentIndex * Fix more things * Update user cache * Fix * Fix account load/start/restart/run
This commit is contained in:
@@ -29,9 +29,10 @@ public class ManagingDbContext : DbContext
|
||||
public DbSet<SpotlightOverviewEntity> SpotlightOverviews { get; set; }
|
||||
public DbSet<TraderEntity> Traders { get; set; }
|
||||
public DbSet<FundingRateEntity> FundingRates { get; set; }
|
||||
public DbSet<AgentSummaryEntity> AgentSummaries { get; set; }
|
||||
|
||||
// Bot entities
|
||||
public DbSet<BotBackupEntity> BotBackups { get; set; }
|
||||
public DbSet<BotEntity> Bots { get; set; }
|
||||
|
||||
// Settings entities
|
||||
public DbSet<MoneyManagementEntity> MoneyManagements { get; set; }
|
||||
@@ -46,6 +47,10 @@ public class ManagingDbContext : DbContext
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// Configure schema for Orleans tables (if needed for future organization)
|
||||
// Orleans tables will remain in the default schema for now
|
||||
// This can be changed later if needed by configuring specific schemas
|
||||
|
||||
// Configure Account entity
|
||||
modelBuilder.Entity<AccountEntity>(entity =>
|
||||
{
|
||||
@@ -280,8 +285,7 @@ public class ManagingDbContext : DbContext
|
||||
// Configure Position entity
|
||||
modelBuilder.Entity<PositionEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Identifier).IsRequired().HasMaxLength(255);
|
||||
entity.HasKey(e => e.Identifier);
|
||||
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>();
|
||||
@@ -348,7 +352,6 @@ public class ManagingDbContext : DbContext
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Configure TopVolumeTicker entity
|
||||
modelBuilder.Entity<TopVolumeTickerEntity>(entity =>
|
||||
{
|
||||
@@ -425,22 +428,26 @@ public class ManagingDbContext : DbContext
|
||||
});
|
||||
|
||||
// Configure BotBackup entity
|
||||
modelBuilder.Entity<BotBackupEntity>(entity =>
|
||||
modelBuilder.Entity<BotEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.HasKey(e => e.Identifier);
|
||||
entity.Property(e => e.Identifier).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.UserName).HasMaxLength(255);
|
||||
entity.Property(e => e.Data).IsRequired().HasColumnType("text");
|
||||
entity.Property(e => e.Name).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.Status).IsRequired().HasConversion<string>();
|
||||
entity.Property(e => e.CreateDate).IsRequired();
|
||||
entity.Property(e => e.StartupTime).IsRequired();
|
||||
entity.Property(e => e.TradeWins).IsRequired();
|
||||
entity.Property(e => e.TradeLosses).IsRequired();
|
||||
entity.Property(e => e.Pnl).HasPrecision(18, 8);
|
||||
entity.Property(e => e.Roi).HasPrecision(18, 8);
|
||||
entity.Property(e => e.Volume).HasPrecision(18, 8);
|
||||
entity.Property(e => e.Fees).HasPrecision(18, 8);
|
||||
|
||||
// Create indexes
|
||||
entity.HasIndex(e => e.Identifier).IsUnique();
|
||||
entity.HasIndex(e => e.UserName);
|
||||
entity.HasIndex(e => e.LastStatus);
|
||||
entity.HasIndex(e => e.Status);
|
||||
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()
|
||||
@@ -517,5 +524,105 @@ public class ManagingDbContext : DbContext
|
||||
entity.HasIndex(e => e.CacheKey).IsUnique();
|
||||
entity.HasIndex(e => e.CreatedAt);
|
||||
});
|
||||
|
||||
// Configure AgentSummary entity
|
||||
modelBuilder.Entity<AgentSummaryEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.UserId).IsRequired();
|
||||
entity.Property(e => e.AgentName).IsRequired().HasMaxLength(255);
|
||||
entity.Property(e => e.TotalPnL).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.TotalROI).HasColumnType("decimal(18,8)");
|
||||
entity.Property(e => e.Wins).IsRequired();
|
||||
entity.Property(e => e.Losses).IsRequired();
|
||||
entity.Property(e => e.Runtime);
|
||||
entity.Property(e => e.CreatedAt).IsRequired();
|
||||
entity.Property(e => e.UpdatedAt).IsRequired();
|
||||
entity.Property(e => e.ActiveStrategiesCount).IsRequired();
|
||||
entity.Property(e => e.TotalVolume).HasPrecision(18, 8);
|
||||
|
||||
// Create indexes for common queries
|
||||
entity.HasIndex(e => e.UserId).IsUnique();
|
||||
entity.HasIndex(e => e.AgentName);
|
||||
entity.HasIndex(e => e.TotalPnL);
|
||||
entity.HasIndex(e => e.UpdatedAt);
|
||||
|
||||
// Configure relationship with User
|
||||
entity.HasOne(e => e.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures Orleans tables are properly initialized in the database.
|
||||
/// This method can be called during application startup to verify Orleans infrastructure.
|
||||
/// </summary>
|
||||
public async Task EnsureOrleansTablesExistAsync()
|
||||
{
|
||||
// Orleans tables are automatically created by the Orleans framework
|
||||
// when using AdoNetClustering and AdoNetReminderService.
|
||||
// This method serves as a verification point and can be extended
|
||||
// for custom Orleans table management if needed.
|
||||
|
||||
// For now, we just ensure the database is accessible
|
||||
await Database.CanConnectAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Orleans table statistics for monitoring purposes.
|
||||
/// This helps track Orleans table sizes and performance.
|
||||
/// </summary>
|
||||
public async Task<Dictionary<string, long>> GetOrleansTableStatsAsync()
|
||||
{
|
||||
var stats = new Dictionary<string, long>();
|
||||
|
||||
// Orleans table names
|
||||
var orleansTables = new[]
|
||||
{
|
||||
"orleansmembershiptable",
|
||||
"orleansmembershipversiontable",
|
||||
"orleansquery",
|
||||
"orleansreminderstable",
|
||||
"orleansstorage"
|
||||
};
|
||||
|
||||
foreach (var tableName in orleansTables)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await Database.SqlQueryRaw<long>($"SELECT COUNT(*) FROM {tableName}").FirstOrDefaultAsync();
|
||||
stats[tableName] = count;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Table might not exist yet (normal during startup)
|
||||
stats[tableName] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Database organization strategy:
|
||||
/// - Application tables: Default schema (public)
|
||||
/// - Orleans tables: Default schema (public) - managed by Orleans framework
|
||||
/// - Future consideration: Move Orleans tables to 'orleans' schema if needed
|
||||
///
|
||||
/// Benefits of current approach:
|
||||
/// - Single database simplifies deployment and backup
|
||||
/// - Orleans tables are automatically managed by the framework
|
||||
/// - No additional configuration complexity
|
||||
/// - Easier monitoring and maintenance
|
||||
/// </summary>
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
|
||||
// Add any additional configuration here if needed
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user