Update bot config on front and back

This commit is contained in:
2025-06-04 15:42:21 +07:00
parent f41af96406
commit 756cd5fb11
14 changed files with 422 additions and 369 deletions

View File

@@ -178,39 +178,21 @@ public class BacktestController : BaseController
break;
case BotType.ScalpingBot:
backtestResult = await _backtester.RunScalpingBotBacktest(
account,
moneyManagement,
request.Config.Ticker,
scenario,
request.Config.Timeframe,
request.Balance,
backtestConfig,
request.StartDate,
request.EndDate,
user,
request.WatchOnly,
request.Save,
cooldownPeriod: request.Config.CooldownPeriod,
maxLossStreak: request.Config.MaxLossStreak,
maxPositionTimeHours: request.Config.MaxPositionTimeHours,
flipOnlyWhenInProfit: request.Config.FlipOnlyWhenInProfit);
null);
break;
case BotType.FlippingBot:
backtestResult = await _backtester.RunFlippingBotBacktest(
account,
moneyManagement,
request.Config.Ticker,
scenario,
request.Config.Timeframe,
request.Balance,
backtestConfig,
request.StartDate,
request.EndDate,
user,
request.WatchOnly,
request.Save,
cooldownPeriod: request.Config.CooldownPeriod,
maxLossStreak: request.Config.MaxLossStreak,
maxPositionTimeHours: request.Config.MaxPositionTimeHours,
flipOnlyWhenInProfit: request.Config.FlipOnlyWhenInProfit);
null);
break;
}

View File

@@ -105,52 +105,64 @@ public class BotController : BaseController
{
try
{
// Check if user owns the account
if (!await UserOwnsBotAccount(request.Identifier, request.AccountName))
if (request.Config == null)
{
return Forbid("You don't have permission to start this bot");
return BadRequest("Bot configuration is required");
}
// Check if user owns the account specified in the request
if (!await UserOwnsBotAccount(null, request.Config.AccountName))
{
return Forbid("You don't have permission to start a bot with this account");
}
// Trigger error if money management is not provided
if (string.IsNullOrEmpty(request.MoneyManagementName))
if (string.IsNullOrEmpty(request.MoneyManagementName) && request.Config.MoneyManagement == null)
{
return BadRequest("Money management name is required");
return BadRequest("Money management name or money management object is required");
}
var user = await GetUser();
var moneyManagement = await _moneyManagementService.GetMoneyMangement(user, request.MoneyManagementName);
if (moneyManagement == null)
// Get money management if name is provided
MoneyManagement moneyManagement = request.Config.MoneyManagement;
if (!string.IsNullOrEmpty(request.MoneyManagementName))
{
return BadRequest("Money management not found");
moneyManagement = await _moneyManagementService.GetMoneyMangement(user, request.MoneyManagementName);
if (moneyManagement == null)
{
return BadRequest("Money management not found");
}
}
// Validate initialTradingBalance
if (request.InitialTradingBalance <= Constants.GMX.Config.MinimumPositionAmount)
if (request.Config.BotTradingBalance <= Constants.GMX.Config.MinimumPositionAmount)
{
return BadRequest(
$"Initial trading balance must be greater than {Constants.GMX.Config.MinimumPositionAmount}");
}
// Update the config with final money management
var config = new TradingBotConfig
{
AccountName = request.AccountName,
AccountName = request.Config.AccountName,
MoneyManagement = moneyManagement,
Ticker = request.Ticker,
ScenarioName = request.Scenario,
Timeframe = request.Timeframe,
IsForWatchingOnly = request.IsForWatchOnly,
BotTradingBalance = request.InitialTradingBalance,
BotType = request.BotType,
CooldownPeriod = request.CooldownPeriod,
MaxLossStreak = request.MaxLossStreak,
MaxPositionTimeHours = request.MaxPositionTimeHours,
FlipOnlyWhenInProfit = request.FlipOnlyWhenInProfit,
Ticker = request.Config.Ticker,
ScenarioName = request.Config.ScenarioName,
Timeframe = request.Config.Timeframe,
IsForWatchingOnly = request.Config.IsForWatchingOnly,
BotTradingBalance = request.Config.BotTradingBalance,
BotType = request.Config.BotType,
CooldownPeriod = request.Config.CooldownPeriod,
MaxLossStreak = request.Config.MaxLossStreak,
MaxPositionTimeHours = request.Config.MaxPositionTimeHours,
FlipOnlyWhenInProfit = request.Config.FlipOnlyWhenInProfit,
IsForBacktest = false,
FlipPosition = request.BotType == BotType.FlippingBot,
Name = request.Name
FlipPosition = request.Config.BotType == BotType.FlippingBot,
Name = request.Config.Name
};
var result = await _mediator.Send(new StartBotCommand(config, request.Name, user));
var result = await _mediator.Send(new StartBotCommand(config, request.Config.Name, user));
await NotifyBotSubscriberAsync();
return Ok(result);
@@ -684,77 +696,14 @@ public class ClosePositionRequest
public class StartBotRequest
{
/// <summary>
/// The type of bot to start
/// The trading bot configuration
/// </summary>
public BotType BotType { get; set; }
public TradingBotConfig Config { get; set; }
/// <summary>
/// The identifier of the bot
/// Optional money management name (if not included in Config.MoneyManagement)
/// </summary>
public string Identifier { get; set; }
/// <summary>
/// The ticker to trade
/// </summary>
public Ticker Ticker { get; set; }
/// <summary>
/// The scenario to use
/// </summary>
public string Scenario { get; set; }
/// <summary>
/// The timeframe to use
/// </summary>
public Timeframe Timeframe { get; set; }
/// <summary>
/// The account name to use
/// </summary>
public string AccountName { get; set; }
/// <summary>
/// The money management name to use
/// </summary>
public string MoneyManagementName { get; set; }
/// <summary>
/// Whether the bot is for watching only
/// </summary>
public bool IsForWatchOnly { get; set; }
/// <summary>
/// The initial trading balance
/// </summary>
public decimal InitialTradingBalance { get; set; }
/// <summary>
/// The cooldown period in candles between positions
/// </summary>
public int CooldownPeriod { get; set; }
/// <summary>
/// The maximum number of consecutive losses before stopping
/// </summary>
public int MaxLossStreak { get; set; }
/// <summary>
/// The name of the bot
/// </summary>
public string Name { get; set; }
/// <summary>
/// Maximum time in hours that a position can remain open before being automatically closed.
/// Supports fractional values (e.g., 2.5 for 2 hours and 30 minutes).
/// If null, time-based position closure is disabled.
/// </summary>
public decimal? MaxPositionTimeHours { get; set; } = null;
/// <summary>
/// If true, positions will only be flipped when the current position is in profit.
/// If false, positions will be flipped regardless of profit status.
/// </summary>
public bool FlipOnlyWhenInProfit { get; set; } = true;
public string? MoneyManagementName { get; set; }
}
/// <summary>