Test strategy combo
This commit is contained in:
@@ -56,47 +56,32 @@ namespace Managing.Application.Backtesting
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a unified trading bot backtest with the specified configuration and date range.
|
||||
/// Automatically handles ScalpingBot and FlippingBot behavior based on config.BotType.
|
||||
/// Runs a trading bot backtest with the specified configuration and date range.
|
||||
/// Automatically handles different bot types based on config.BotType.
|
||||
/// </summary>
|
||||
/// <param name="config">The trading bot configuration</param>
|
||||
/// <param name="config">The trading bot configuration (must include Scenario object or ScenarioName)</param>
|
||||
/// <param name="startDate">The start date for the backtest</param>
|
||||
/// <param name="endDate">The end date for the backtest</param>
|
||||
/// <param name="user">The user running the backtest</param>
|
||||
/// <param name="user">The user running the backtest (optional)</param>
|
||||
/// <param name="save">Whether to save the backtest results</param>
|
||||
/// <param name="initialCandles">Optional pre-loaded candles</param>
|
||||
/// <returns>The backtest results</returns>
|
||||
public async Task<Backtest> RunTradingBotBacktest(
|
||||
TradingBotConfig config,
|
||||
DateTime startDate,
|
||||
DateTime endDate,
|
||||
User user = null,
|
||||
bool save = false,
|
||||
List<Candle>? initialCandles = null)
|
||||
bool save = false)
|
||||
{
|
||||
var account = await GetAccountFromConfig(config);
|
||||
var candles = GetCandles(account, config.Ticker, config.Timeframe, startDate, endDate);
|
||||
|
||||
// Set FlipPosition based on BotType
|
||||
config.FlipPosition = config.BotType == BotType.FlippingBot;
|
||||
var result = await RunBacktestWithCandles(config, candles, user);
|
||||
|
||||
var tradingBot = _botFactory.CreateBacktestTradingBot(config);
|
||||
tradingBot.LoadScenario(config.ScenarioName);
|
||||
tradingBot.User = user;
|
||||
await tradingBot.LoadAccount();
|
||||
|
||||
var candles = initialCandles ?? GetCandles(account, config.Ticker, config.Timeframe, startDate, endDate);
|
||||
var result = GetBacktestingResult(config, tradingBot, candles);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
result.User = user;
|
||||
}
|
||||
|
||||
// Set start and end dates
|
||||
result.StartDate = startDate;
|
||||
result.EndDate = endDate;
|
||||
|
||||
if (save)
|
||||
if (save && user != null)
|
||||
{
|
||||
_backtestRepository.InsertBacktestForUser(user, result);
|
||||
}
|
||||
@@ -105,25 +90,48 @@ namespace Managing.Application.Backtesting
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a unified trading bot backtest with pre-loaded candles.
|
||||
/// Automatically handles ScalpingBot and FlippingBot behavior based on config.BotType.
|
||||
/// Runs a trading bot backtest with pre-loaded candles.
|
||||
/// Automatically handles different bot types based on config.BotType.
|
||||
/// </summary>
|
||||
/// <param name="config">The trading bot configuration</param>
|
||||
/// <param name="config">The trading bot configuration (must include Scenario object or ScenarioName)</param>
|
||||
/// <param name="candles">The candles to use for backtesting</param>
|
||||
/// <param name="user">The user running the backtest</param>
|
||||
/// <param name="user">The user running the backtest (optional)</param>
|
||||
/// <returns>The backtest results</returns>
|
||||
public async Task<Backtest> RunTradingBotBacktest(
|
||||
TradingBotConfig config,
|
||||
List<Candle> candles,
|
||||
User user = null)
|
||||
{
|
||||
var account = await GetAccountFromConfig(config);
|
||||
|
||||
return await RunBacktestWithCandles(config, candles, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Core backtesting logic - handles the actual backtest execution with pre-loaded candles
|
||||
/// </summary>
|
||||
private async Task<Backtest> RunBacktestWithCandles(
|
||||
TradingBotConfig config,
|
||||
List<Candle> candles,
|
||||
User user = null)
|
||||
{
|
||||
// Set FlipPosition based on BotType
|
||||
config.FlipPosition = config.BotType == BotType.FlippingBot;
|
||||
|
||||
var tradingBot = _botFactory.CreateBacktestTradingBot(config);
|
||||
tradingBot.LoadScenario(config.ScenarioName);
|
||||
|
||||
// Load scenario - prefer Scenario object over ScenarioName
|
||||
if (config.Scenario != null)
|
||||
{
|
||||
tradingBot.LoadScenario(config.Scenario);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(config.ScenarioName))
|
||||
{
|
||||
tradingBot.LoadScenario(config.ScenarioName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Either Scenario object or ScenarioName must be provided in TradingBotConfig");
|
||||
}
|
||||
|
||||
tradingBot.User = user;
|
||||
await tradingBot.LoadAccount();
|
||||
|
||||
@@ -137,73 +145,25 @@ namespace Managing.Application.Backtesting
|
||||
return result;
|
||||
}
|
||||
|
||||
// Legacy methods - maintained for backward compatibility
|
||||
public async Task<Backtest> RunScalpingBotBacktest(
|
||||
TradingBotConfig config,
|
||||
DateTime startDate,
|
||||
DateTime endDate,
|
||||
User user = null,
|
||||
bool save = false,
|
||||
List<Candle>? initialCandles = null)
|
||||
{
|
||||
config.BotType = BotType.ScalpingBot; // Ensure correct type
|
||||
return await RunTradingBotBacktest(config, startDate, endDate, user, save, initialCandles);
|
||||
}
|
||||
|
||||
public async Task<Backtest> RunFlippingBotBacktest(
|
||||
TradingBotConfig config,
|
||||
DateTime startDate,
|
||||
DateTime endDate,
|
||||
User user = null,
|
||||
bool save = false,
|
||||
List<Candle>? initialCandles = null)
|
||||
{
|
||||
config.BotType = BotType.FlippingBot; // Ensure correct type
|
||||
return await RunTradingBotBacktest(config, startDate, endDate, user, save, initialCandles);
|
||||
}
|
||||
|
||||
public async Task<Backtest> RunScalpingBotBacktest(
|
||||
TradingBotConfig config,
|
||||
List<Candle> candles,
|
||||
User user = null)
|
||||
{
|
||||
config.BotType = BotType.ScalpingBot; // Ensure correct type
|
||||
return await RunTradingBotBacktest(config, candles, user);
|
||||
}
|
||||
|
||||
public async Task<Backtest> RunFlippingBotBacktest(
|
||||
TradingBotConfig config,
|
||||
List<Candle> candles,
|
||||
User user = null)
|
||||
{
|
||||
config.BotType = BotType.FlippingBot; // Ensure correct type
|
||||
return await RunTradingBotBacktest(config, candles, user);
|
||||
}
|
||||
|
||||
private async Task<Account> GetAccountFromConfig(TradingBotConfig config)
|
||||
{
|
||||
// Use the account service to get the actual account
|
||||
var account = await _accountService.GetAccount(config.AccountName, false, false);
|
||||
if (account != null)
|
||||
{
|
||||
return account;
|
||||
}
|
||||
|
||||
// Fallback: create a basic account structure if not found
|
||||
return new Account
|
||||
{
|
||||
Name = config.AccountName,
|
||||
Exchange = TradingExchanges.GmxV2 // Default exchange, should be configurable
|
||||
Exchange = TradingExchanges.GmxV2
|
||||
};
|
||||
}
|
||||
|
||||
private List<Candle> GetCandles(Account account, Ticker ticker, Timeframe timeframe,
|
||||
DateTime startDate, DateTime endDate)
|
||||
{
|
||||
List<Candle> candles;
|
||||
|
||||
// Use specific date range
|
||||
candles = _exchangeService.GetCandlesInflux(account.Exchange, ticker,
|
||||
var candles = _exchangeService.GetCandlesInflux(account.Exchange, ticker,
|
||||
startDate, timeframe, endDate).Result;
|
||||
|
||||
if (candles == null || candles.Count == 0)
|
||||
@@ -326,13 +286,10 @@ namespace Managing.Application.Backtesting
|
||||
return strategiesValues;
|
||||
}
|
||||
|
||||
|
||||
public bool DeleteBacktest(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Since we no longer have a general DeleteBacktestById method in the repository,
|
||||
// this should be implemented using DeleteBacktestByIdForUser with null
|
||||
_backtestRepository.DeleteBacktestByIdForUser(null, id);
|
||||
return true;
|
||||
}
|
||||
@@ -347,8 +304,6 @@ namespace Managing.Application.Backtesting
|
||||
{
|
||||
try
|
||||
{
|
||||
// Since we no longer have a general DeleteAllBacktests method in the repository,
|
||||
// this should be implemented using DeleteAllBacktestsForUser with null
|
||||
_backtestRepository.DeleteAllBacktestsForUser(null);
|
||||
return true;
|
||||
}
|
||||
@@ -363,10 +318,8 @@ namespace Managing.Application.Backtesting
|
||||
{
|
||||
var backtests = _backtestRepository.GetBacktestsByUser(user).ToList();
|
||||
|
||||
// For each backtest, ensure candles are loaded
|
||||
foreach (var backtest in backtests)
|
||||
{
|
||||
// If the backtest has no candles or only a few sample candles, retrieve them
|
||||
if (backtest.Candles == null || backtest.Candles.Count == 0 || backtest.Candles.Count < 10)
|
||||
{
|
||||
try
|
||||
@@ -386,7 +339,6 @@ namespace Managing.Application.Backtesting
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to retrieve candles for backtest {Id}", backtest.Id);
|
||||
// Continue with the next backtest if there's an error
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,22 +348,18 @@ namespace Managing.Application.Backtesting
|
||||
|
||||
public Backtest GetBacktestByIdForUser(User user, string id)
|
||||
{
|
||||
// Get the backtest from the repository
|
||||
var backtest = _backtestRepository.GetBacktestByIdForUser(user, id);
|
||||
|
||||
if (backtest == null)
|
||||
return null;
|
||||
|
||||
// If the backtest has no candles or only a few sample candles, retrieve them
|
||||
if (backtest.Candles == null || backtest.Candles.Count == 0 || backtest.Candles.Count < 10)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the account
|
||||
var account = new Account
|
||||
{ Name = backtest.Config.AccountName, Exchange = TradingExchanges.Evm };
|
||||
|
||||
// Use the stored start and end dates to retrieve candles
|
||||
var candles = _exchangeService.GetCandlesInflux(
|
||||
account.Exchange,
|
||||
backtest.Config.Ticker,
|
||||
@@ -427,7 +375,6 @@ namespace Managing.Application.Backtesting
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to retrieve candles for backtest {Id}", id);
|
||||
// Return the backtest without candles if there's an error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user