Add BacktestCount
This commit is contained in:
@@ -610,6 +610,7 @@ public class DataController : ControllerBase
|
|||||||
TotalVolume = agentSummary.TotalVolume,
|
TotalVolume = agentSummary.TotalVolume,
|
||||||
TotalBalance = agentSummary.TotalBalance,
|
TotalBalance = agentSummary.TotalBalance,
|
||||||
TotalFees = agentSummary.TotalFees,
|
TotalFees = agentSummary.TotalFees,
|
||||||
|
BacktestCount = agentSummary.BacktestCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
agentSummaryViewModels.Add(agentSummaryViewModel);
|
agentSummaryViewModels.Add(agentSummaryViewModel);
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ namespace Managing.Api.Models.Responses
|
|||||||
/// Total fees paid by this agent across all positions
|
/// Total fees paid by this agent across all positions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal TotalFees { get; set; }
|
public decimal TotalFees { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of backtests run by this agent
|
||||||
|
/// </summary>
|
||||||
|
public int BacktestCount { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -41,4 +41,10 @@ public interface IAgentSummaryRepository
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Total number of agents</returns>
|
/// <returns>Total number of agents</returns>
|
||||||
Task<int> GetTotalAgentCount();
|
Task<int> GetTotalAgentCount();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increments the backtest count for a specific user's agent summary
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId">The user ID</param>
|
||||||
|
Task IncrementBacktestCountAsync(int userId);
|
||||||
}
|
}
|
||||||
@@ -27,4 +27,10 @@ public interface IAgentService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Total number of agents</returns>
|
/// <returns>Total number of agents</returns>
|
||||||
Task<int> GetTotalAgentCount();
|
Task<int> GetTotalAgentCount();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increments the backtest count for a specific user's agent summary
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId">The user ID</param>
|
||||||
|
Task IncrementBacktestCountAsync(int userId);
|
||||||
}
|
}
|
||||||
@@ -40,8 +40,9 @@ namespace Managing.Application.Tests
|
|||||||
var tradingBotLogger = TradingBaseTests.CreateTradingBotLogger();
|
var tradingBotLogger = TradingBaseTests.CreateTradingBotLogger();
|
||||||
var backtestLogger = TradingBaseTests.CreateBacktesterLogger();
|
var backtestLogger = TradingBaseTests.CreateBacktesterLogger();
|
||||||
var botService = new Mock<IBotService>().Object;
|
var botService = new Mock<IBotService>().Object;
|
||||||
|
var agentService = new Mock<IAgentService>().Object;
|
||||||
_backtester = new Backtester(_exchangeService, backtestRepository, backtestLogger,
|
_backtester = new Backtester(_exchangeService, backtestRepository, backtestLogger,
|
||||||
scenarioService, _accountService.Object, messengerService, kaigenService, hubContext, null);
|
scenarioService, _accountService.Object, messengerService, kaigenService, hubContext, null, agentService);
|
||||||
_elapsedTimes = new List<double>();
|
_elapsedTimes = new List<double>();
|
||||||
|
|
||||||
// Initialize cross-platform file paths
|
// Initialize cross-platform file paths
|
||||||
|
|||||||
@@ -150,4 +150,19 @@ public class AgentService : IAgentService
|
|||||||
{
|
{
|
||||||
return await _agentSummaryRepository.GetTotalAgentCount();
|
return await _agentSummaryRepository.GetTotalAgentCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task IncrementBacktestCountAsync(int userId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _agentSummaryRepository.IncrementBacktestCountAsync(userId);
|
||||||
|
|
||||||
|
_logger.LogInformation("Backtest count incremented for user {UserId}", userId);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error incrementing backtest count for user {UserId}", userId);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@ namespace Managing.Application.Backtests
|
|||||||
private readonly IKaigenService _kaigenService;
|
private readonly IKaigenService _kaigenService;
|
||||||
private readonly IHubContext<BacktestHub> _hubContext;
|
private readonly IHubContext<BacktestHub> _hubContext;
|
||||||
private readonly IGrainFactory _grainFactory;
|
private readonly IGrainFactory _grainFactory;
|
||||||
|
private readonly IAgentService _agentService;
|
||||||
|
|
||||||
public Backtester(
|
public Backtester(
|
||||||
IExchangeService exchangeService,
|
IExchangeService exchangeService,
|
||||||
@@ -37,7 +38,8 @@ namespace Managing.Application.Backtests
|
|||||||
IMessengerService messengerService,
|
IMessengerService messengerService,
|
||||||
IKaigenService kaigenService,
|
IKaigenService kaigenService,
|
||||||
IHubContext<BacktestHub> hubContext,
|
IHubContext<BacktestHub> hubContext,
|
||||||
IGrainFactory grainFactory)
|
IGrainFactory grainFactory,
|
||||||
|
IAgentService agentService)
|
||||||
{
|
{
|
||||||
_exchangeService = exchangeService;
|
_exchangeService = exchangeService;
|
||||||
_backtestRepository = backtestRepository;
|
_backtestRepository = backtestRepository;
|
||||||
@@ -48,6 +50,7 @@ namespace Managing.Application.Backtests
|
|||||||
_kaigenService = kaigenService;
|
_kaigenService = kaigenService;
|
||||||
_hubContext = hubContext;
|
_hubContext = hubContext;
|
||||||
_grainFactory = grainFactory;
|
_grainFactory = grainFactory;
|
||||||
|
_agentService = agentService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -187,14 +190,25 @@ namespace Managing.Application.Backtests
|
|||||||
// Create Orleans grain for backtesting
|
// Create Orleans grain for backtesting
|
||||||
var backtestGrain = _grainFactory.GetGrain<IBacktestTradingBotGrain>(Guid.NewGuid());
|
var backtestGrain = _grainFactory.GetGrain<IBacktestTradingBotGrain>(Guid.NewGuid());
|
||||||
|
|
||||||
// Run the backtest using the Orleans grain and return LightBacktest directly
|
// Run the backtest using the Orleans grain
|
||||||
return await backtestGrain.RunBacktestAsync(cleanConfig, candles, user, save, withCandles, requestId,
|
var result = await backtestGrain.RunBacktestAsync(cleanConfig, candles, user, save, withCandles, requestId,
|
||||||
metadata);
|
metadata);
|
||||||
|
|
||||||
|
// Increment backtest count for the user if user is provided
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _agentService.IncrementBacktestCountAsync(user.Id);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Failed to increment backtest count for user {UserId}", user.Id);
|
||||||
|
// Don't throw here as the backtest was successful, just log the error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Account> GetAccountFromConfig(TradingBotConfig config)
|
return result;
|
||||||
{
|
|
||||||
return await _accountService.GetAccountByAccountName(config.AccountName, false, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<HashSet<Candle>> GetCandles(Ticker ticker, Timeframe timeframe,
|
private async Task<HashSet<Candle>> GetCandles(Ticker ticker, Timeframe timeframe,
|
||||||
|
|||||||
@@ -53,4 +53,7 @@ public class AgentSummary
|
|||||||
|
|
||||||
[Id(15)]
|
[Id(15)]
|
||||||
public decimal NetPnL { get; set; }
|
public decimal NetPnL { get; set; }
|
||||||
|
|
||||||
|
[Id(16)]
|
||||||
|
public int BacktestCount { get; set; }
|
||||||
}
|
}
|
||||||
1452
src/Managing.Infrastructure.Database/Migrations/20251001055823_AddBacktestCountToAgentSummary.Designer.cs
generated
Normal file
1452
src/Managing.Infrastructure.Database/Migrations/20251001055823_AddBacktestCountToAgentSummary.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Managing.Infrastructure.Databases.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddBacktestCountToAgentSummary : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "BacktestCount",
|
||||||
|
table: "AgentSummaries",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "BacktestCount",
|
||||||
|
table: "AgentSummaries");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -86,6 +86,9 @@ namespace Managing.Infrastructure.Databases.Migrations
|
|||||||
.HasMaxLength(255)
|
.HasMaxLength(255)
|
||||||
.HasColumnType("character varying(255)");
|
.HasColumnType("character varying(255)");
|
||||||
|
|
||||||
|
b.Property<int>("BacktestCount")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
b.Property<DateTime>("CreatedAt")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
|||||||
@@ -251,7 +251,8 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
|||||||
ActiveStrategiesCount = domain.ActiveStrategiesCount,
|
ActiveStrategiesCount = domain.ActiveStrategiesCount,
|
||||||
TotalVolume = domain.TotalVolume,
|
TotalVolume = domain.TotalVolume,
|
||||||
TotalBalance = domain.TotalBalance,
|
TotalBalance = domain.TotalBalance,
|
||||||
TotalFees = domain.TotalFees
|
TotalFees = domain.TotalFees,
|
||||||
|
BacktestCount = domain.BacktestCount
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,6 +270,7 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
|||||||
entity.TotalVolume = domain.TotalVolume;
|
entity.TotalVolume = domain.TotalVolume;
|
||||||
entity.TotalBalance = domain.TotalBalance;
|
entity.TotalBalance = domain.TotalBalance;
|
||||||
entity.TotalFees = domain.TotalFees;
|
entity.TotalFees = domain.TotalFees;
|
||||||
|
entity.BacktestCount = domain.BacktestCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AgentSummary MapToDomain(AgentSummaryEntity entity)
|
private static AgentSummary MapToDomain(AgentSummaryEntity entity)
|
||||||
@@ -290,6 +292,7 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
|||||||
TotalVolume = entity.TotalVolume,
|
TotalVolume = entity.TotalVolume,
|
||||||
TotalBalance = entity.TotalBalance,
|
TotalBalance = entity.TotalBalance,
|
||||||
TotalFees = entity.TotalFees,
|
TotalFees = entity.TotalFees,
|
||||||
|
BacktestCount = entity.BacktestCount,
|
||||||
User = PostgreSqlMappers.Map(entity.User)
|
User = PostgreSqlMappers.Map(entity.User)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -329,4 +332,26 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
|||||||
{
|
{
|
||||||
return await _context.AgentSummaries.CountAsync();
|
return await _context.AgentSummaries.CountAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task IncrementBacktestCountAsync(int userId)
|
||||||
|
{
|
||||||
|
var entity = await _context.AgentSummaries
|
||||||
|
.FirstOrDefaultAsync(a => a.UserId == userId);
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
entity.BacktestCount++;
|
||||||
|
entity.UpdatedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation("Backtest count incremented for user {UserId} to {BacktestCount}",
|
||||||
|
userId, entity.BacktestCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("No AgentSummary found for user {UserId} when trying to increment backtest count",
|
||||||
|
userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@ public class AgentSummaryEntity
|
|||||||
public decimal TotalBalance { get; set; }
|
public decimal TotalBalance { get; set; }
|
||||||
public decimal TotalFees { get; set; }
|
public decimal TotalFees { get; set; }
|
||||||
public decimal NetPnL { get; set; }
|
public decimal NetPnL { get; set; }
|
||||||
|
public int BacktestCount { get; set; }
|
||||||
|
|
||||||
// Navigation property
|
// Navigation property
|
||||||
public UserEntity User { get; set; }
|
public UserEntity User { get; set; }
|
||||||
|
|||||||
@@ -548,6 +548,7 @@ public class ManagingDbContext : DbContext
|
|||||||
entity.Property(e => e.ActiveStrategiesCount).IsRequired();
|
entity.Property(e => e.ActiveStrategiesCount).IsRequired();
|
||||||
entity.Property(e => e.TotalVolume).HasPrecision(18, 8);
|
entity.Property(e => e.TotalVolume).HasPrecision(18, 8);
|
||||||
entity.Property(e => e.TotalBalance).HasPrecision(18, 8);
|
entity.Property(e => e.TotalBalance).HasPrecision(18, 8);
|
||||||
|
entity.Property(e => e.BacktestCount).IsRequired();
|
||||||
|
|
||||||
// Create indexes for common queries
|
// Create indexes for common queries
|
||||||
entity.HasIndex(e => e.UserId).IsUnique();
|
entity.HasIndex(e => e.UserId).IsUnique();
|
||||||
|
|||||||
Reference in New Issue
Block a user