diff --git a/src/Managing.Api/Controllers/BacktestController.cs b/src/Managing.Api/Controllers/BacktestController.cs
index 3e621aff..e11d45d1 100644
--- a/src/Managing.Api/Controllers/BacktestController.cs
+++ b/src/Managing.Api/Controllers/BacktestController.cs
@@ -104,52 +104,6 @@ public class BacktestController : BaseController
return Ok(backtest);
}
- ///
- /// Retrieves only the statistical information for a specific backtest by ID.
- /// This endpoint returns only the performance metrics without positions, signals, or candles.
- /// Useful for displaying backtest stats when starting a bot from a backtest.
- ///
- /// The ID of the backtest to retrieve stats for.
- /// The backtest statistics without detailed position/signal data.
- [HttpGet("{id}/stats")]
- public async Task> GetBacktestStats(int id)
- {
- var user = await GetUser();
- var backtest = await _backtester.GetBacktestByIdForUserAsync(user, id.ToString());
-
- if (backtest == null)
- {
- return NotFound($"Backtest with ID {id} not found or doesn't belong to the current user.");
- }
-
- // Return only the statistical information
- var stats = new
- {
- id = backtest.Id,
- name = backtest.Config.Name,
- ticker = backtest.Config.Ticker,
- timeframe = backtest.Config.Timeframe,
- tradingType = backtest.Config.TradingType,
- startDate = backtest.StartDate,
- endDate = backtest.EndDate,
- initialBalance = backtest.InitialBalance,
- finalPnl = backtest.FinalPnl,
- netPnl = backtest.NetPnl,
- growthPercentage = backtest.GrowthPercentage,
- hodlPercentage = backtest.HodlPercentage,
- winRate = backtest.WinRate,
- sharpeRatio = backtest.Statistics?.SharpeRatio ?? 0,
- maxDrawdown = backtest.Statistics?.MaxDrawdown ?? 0,
- maxDrawdownRecoveryTime = backtest.Statistics?.MaxDrawdownRecoveryTime ?? TimeSpan.Zero,
- fees = backtest.Fees,
- score = backtest.Score,
- scoreMessage = backtest.ScoreMessage,
- positionCount = backtest.PositionCount
- };
-
- return Ok(stats);
- }
-
///
/// Deletes a specific backtest by ID for the authenticated user.
///
diff --git a/src/Managing.Api/Controllers/DataController.cs b/src/Managing.Api/Controllers/DataController.cs
index 2f6edce9..e78a4fc8 100644
--- a/src/Managing.Api/Controllers/DataController.cs
+++ b/src/Managing.Api/Controllers/DataController.cs
@@ -42,6 +42,7 @@ public class DataController : ControllerBase
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IBotService _botService;
private readonly IConfiguration _configuration;
+ private readonly IBacktester _backtester;
///
/// Initializes a new instance of the class.
@@ -57,6 +58,7 @@ public class DataController : ControllerBase
/// Service scope factory for creating scoped services.
/// Service for bot operations.
/// Configuration for accessing environment variables.
+ /// Service for backtest operations.
public DataController(
IExchangeService exchangeService,
IAccountService accountService,
@@ -68,7 +70,8 @@ public class DataController : ControllerBase
IGrainFactory grainFactory,
IServiceScopeFactory serviceScopeFactory,
IBotService botService,
- IConfiguration configuration)
+ IConfiguration configuration,
+ IBacktester backtester)
{
_exchangeService = exchangeService;
_accountService = accountService;
@@ -81,6 +84,7 @@ public class DataController : ControllerBase
_serviceScopeFactory = serviceScopeFactory;
_botService = botService;
_configuration = configuration;
+ _backtester = backtester;
}
///
@@ -1048,4 +1052,50 @@ public class DataController : ControllerBase
return list;
}
+
+ ///
+ /// Retrieves only the statistical information for a specific backtest by ID.
+ /// This endpoint returns only the performance metrics without positions, signals, or candles.
+ /// Useful for displaying backtest stats when starting a bot from a backtest.
+ /// No authentication required.
+ ///
+ /// The ID of the backtest to retrieve stats for.
+ /// The backtest statistics without detailed position/signal data.
+ [HttpGet("GetBacktestStats/{id}")]
+ public async Task> GetBacktestStats(int id)
+ {
+ var backtest = await _backtester.GetBacktestByIdAsync(id.ToString());
+
+ if (backtest == null)
+ {
+ return NotFound($"Backtest with ID {id} not found.");
+ }
+
+ // Return only the statistical information
+ var stats = new
+ {
+ id = backtest.Id,
+ name = backtest.Config.Name,
+ ticker = backtest.Config.Ticker,
+ timeframe = backtest.Config.Timeframe,
+ tradingType = backtest.Config.TradingType,
+ startDate = backtest.StartDate,
+ endDate = backtest.EndDate,
+ initialBalance = backtest.InitialBalance,
+ finalPnl = backtest.FinalPnl,
+ netPnl = backtest.NetPnl,
+ growthPercentage = backtest.GrowthPercentage,
+ hodlPercentage = backtest.HodlPercentage,
+ winRate = backtest.WinRate,
+ sharpeRatio = backtest.Statistics?.SharpeRatio ?? 0,
+ maxDrawdown = backtest.Statistics?.MaxDrawdown ?? 0,
+ maxDrawdownRecoveryTime = backtest.Statistics?.MaxDrawdownRecoveryTime ?? TimeSpan.Zero,
+ fees = backtest.Fees,
+ score = backtest.Score,
+ scoreMessage = backtest.ScoreMessage,
+ positionCount = backtest.PositionCount
+ };
+
+ return Ok(stats);
+ }
}
\ No newline at end of file
diff --git a/src/Managing.Application.Abstractions/Repositories/IBacktestRepository.cs b/src/Managing.Application.Abstractions/Repositories/IBacktestRepository.cs
index abc6386b..bd479b56 100644
--- a/src/Managing.Application.Abstractions/Repositories/IBacktestRepository.cs
+++ b/src/Managing.Application.Abstractions/Repositories/IBacktestRepository.cs
@@ -38,6 +38,7 @@ public interface IBacktestRepository
BacktestsFilter? filter = null);
Task GetBacktestByIdForUserAsync(User user, string id);
+ Task GetBacktestByIdAsync(string id);
Task DeleteBacktestByIdForUserAsync(User user, string id);
Task DeleteBacktestsByIdsForUserAsync(User user, IEnumerable ids);
void DeleteAllBacktestsForUser(User user);
diff --git a/src/Managing.Application.Abstractions/Services/IBacktester.cs b/src/Managing.Application.Abstractions/Services/IBacktester.cs
index 2809db2a..c3058226 100644
--- a/src/Managing.Application.Abstractions/Services/IBacktester.cs
+++ b/src/Managing.Application.Abstractions/Services/IBacktester.cs
@@ -64,6 +64,7 @@ namespace Managing.Application.Abstractions.Services
(IEnumerable Backtests, int TotalCount) GetBacktestsByRequestIdPaginated(Guid requestId, int page, int pageSize, string sortBy = "score", string sortOrder = "desc");
Task<(IEnumerable Backtests, int TotalCount)> GetBacktestsByRequestIdPaginatedAsync(Guid requestId, int page, int pageSize, string sortBy = "score", string sortOrder = "desc");
Task GetBacktestByIdForUserAsync(User user, string id);
+ Task GetBacktestByIdAsync(string id);
Task DeleteBacktestByUserAsync(User user, string id);
Task DeleteBacktestsByIdsForUserAsync(User user, IEnumerable ids);
bool DeleteBacktestsByUser(User user);
diff --git a/src/Managing.Application/Backtests/Backtester.cs b/src/Managing.Application/Backtests/Backtester.cs
index 98f0140f..8455fbd3 100644
--- a/src/Managing.Application/Backtests/Backtester.cs
+++ b/src/Managing.Application/Backtests/Backtester.cs
@@ -218,6 +218,16 @@ namespace Managing.Application.Backtests
return backtest;
}
+ public async Task GetBacktestByIdAsync(string id)
+ {
+ var backtest = await _backtestRepository.GetBacktestByIdAsync(id);
+
+ if (backtest == null)
+ return null;
+
+ return backtest;
+ }
+
public async Task DeleteBacktestByUserAsync(User user, string id)
{
try
diff --git a/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlBacktestRepository.cs b/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlBacktestRepository.cs
index c3580e05..8dcb94f1 100644
--- a/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlBacktestRepository.cs
+++ b/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlBacktestRepository.cs
@@ -298,6 +298,17 @@ public class PostgreSqlBacktestRepository : IBacktestRepository
return entity != null ? PostgreSqlMappers.Map(entity) : null;
}
+ public async Task GetBacktestByIdAsync(string id)
+ {
+ var entity = await _context.Backtests
+ .AsNoTracking()
+ .Include(b => b.User)
+ .FirstOrDefaultAsync(b => b.Identifier == id)
+ .ConfigureAwait(false);
+
+ return entity != null ? PostgreSqlMappers.Map(entity) : null;
+ }
+
public void DeleteBacktestByIdForUser(User user, string id)
{
var entity = _context.Backtests