Add new parameters

This commit is contained in:
2025-06-03 01:01:17 +07:00
parent 71bcaea76d
commit 8c2e9b59de
23 changed files with 1346 additions and 510 deletions

View File

@@ -4,6 +4,7 @@ using Managing.Application.Hubs;
using Managing.Application.ManageBot.Commands;
using Managing.Common;
using Managing.Domain.Bots;
using Managing.Domain.MoneyManagements;
using Managing.Domain.Trades;
using MediatR;
using Microsoft.AspNetCore.Authorization;
@@ -142,6 +143,8 @@ public class BotController : BaseController
BotType = request.BotType,
CooldownPeriod = request.CooldownPeriod,
MaxLossStreak = request.MaxLossStreak,
MaxPositionTimeHours = request.MaxPositionTimeHours,
FlipOnlyWhenInProfit = request.FlipOnlyWhenInProfit,
IsForBacktest = false,
FlipPosition = request.BotType == BotType.FlippingBot,
Name = request.Name
@@ -419,7 +422,9 @@ public class BotController : BaseController
AccountName = item.Config.AccountName,
MoneyManagement = item.Config.MoneyManagement,
Identifier = item.Identifier,
AgentName = item.User.AgentName
AgentName = item.User.AgentName,
MaxPositionTimeHours = item.Config.MaxPositionTimeHours,
FlipOnlyWhenInProfit = item.Config.FlipOnlyWhenInProfit
});
}
@@ -543,6 +548,102 @@ public class BotController : BaseController
return StatusCode(500, $"Error closing position: {ex.Message}");
}
}
/// <summary>
/// Updates the configuration of a running bot
/// </summary>
/// <param name="request">The request containing the new bot configuration</param>
/// <returns>A response indicating the result of the operation</returns>
[HttpPut]
[Route("UpdateConfig")]
public async Task<ActionResult<string>> UpdateBotConfig([FromBody] UpdateBotConfigRequest request)
{
try
{
// Check if user owns the account
if (!await UserOwnsBotAccount(request.Identifier))
{
return Forbid("You don't have permission to update this bot's configuration");
}
var activeBots = _botService.GetActiveBots();
var bot = activeBots.FirstOrDefault(b => b.Identifier == request.Identifier);
if (bot == null)
{
return NotFound($"Bot with identifier {request.Identifier} not found or is not running");
}
// Get the user for validation
var user = await GetUser();
// Validate money management if provided
MoneyManagement moneyManagement = null;
if (!string.IsNullOrEmpty(request.MoneyManagementName))
{
moneyManagement = await _moneyManagementService.GetMoneyMangement(user, request.MoneyManagementName);
if (moneyManagement == null)
{
return BadRequest("Money management not found");
}
}
else
{
// Keep existing money management if not provided
moneyManagement = bot.Config.MoneyManagement;
}
// Validate account if provided
if (!string.IsNullOrEmpty(request.AccountName))
{
var account = await _accountService.GetAccount(request.AccountName, true, false);
if (account == null || account.User?.Name != user.Name)
{
return BadRequest("Account not found or you don't have permission to use this account");
}
}
// Create updated configuration
var updatedConfig = new TradingBotConfig
{
AccountName = !string.IsNullOrEmpty(request.AccountName) ? request.AccountName : bot.Config.AccountName,
MoneyManagement = moneyManagement,
Ticker = request.Ticker ?? bot.Config.Ticker,
ScenarioName = !string.IsNullOrEmpty(request.ScenarioName) ? request.ScenarioName : bot.Config.ScenarioName,
Timeframe = request.Timeframe ?? bot.Config.Timeframe,
IsForWatchingOnly = request.IsForWatchingOnly ?? bot.Config.IsForWatchingOnly,
BotTradingBalance = request.BotTradingBalance ?? bot.Config.BotTradingBalance,
BotType = bot.Config.BotType, // Bot type cannot be changed
CooldownPeriod = request.CooldownPeriod ?? bot.Config.CooldownPeriod,
MaxLossStreak = request.MaxLossStreak ?? bot.Config.MaxLossStreak,
MaxPositionTimeHours = request.MaxPositionTimeHours ?? bot.Config.MaxPositionTimeHours,
FlipOnlyWhenInProfit = request.FlipOnlyWhenInProfit ?? bot.Config.FlipOnlyWhenInProfit,
IsForBacktest = bot.Config.IsForBacktest, // Cannot be changed for running bots
FlipPosition = request.FlipPosition ?? bot.Config.FlipPosition,
Name = !string.IsNullOrEmpty(request.Name) ? request.Name : bot.Config.Name
};
// Validate the updated configuration
if (updatedConfig.BotTradingBalance <= Constants.GMX.Config.MinimumPositionAmount)
{
return BadRequest($"Bot trading balance must be greater than {Constants.GMX.Config.MinimumPositionAmount}");
}
// Update the bot's configuration
var updateCommand = new UpdateBotConfigCommand(request.Identifier, updatedConfig);
var result = await _mediator.Send(updateCommand);
_logger.LogInformation($"Bot configuration update result for {request.Identifier} by user {user.Name}: {result}");
await NotifyBotSubscriberAsync();
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error updating bot configuration");
return StatusCode(500, $"Error updating bot configuration: {ex.Message}");
}
}
}
/// <summary>
@@ -627,7 +728,107 @@ public class StartBotRequest
/// </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;
}
/// <summary>
/// Request model for updating bot configuration
/// </summary>
public class UpdateBotConfigRequest
{
/// <summary>
/// The identifier of the bot to update
/// </summary>
public string Identifier { get; set; }
/// <summary>
/// The account name to use (optional - will keep existing if not provided)
/// </summary>
public string? AccountName { get; set; }
/// <summary>
/// The money management name to use (optional - will keep existing if not provided)
/// </summary>
public string? MoneyManagementName { get; set; }
/// <summary>
/// The ticker to trade (optional - will keep existing if not provided)
/// </summary>
public Ticker? Ticker { get; set; }
/// <summary>
/// The scenario to use (optional - will keep existing if not provided)
/// </summary>
public string? ScenarioName { get; set; }
/// <summary>
/// The timeframe to use (optional - will keep existing if not provided)
/// </summary>
public Timeframe? Timeframe { get; set; }
/// <summary>
/// Whether the bot is for watching only (optional - will keep existing if not provided)
/// </summary>
public bool? IsForWatchingOnly { get; set; }
/// <summary>
/// The bot trading balance (optional - will keep existing if not provided)
/// </summary>
public decimal? BotTradingBalance { get; set; }
/// <summary>
/// The cooldown period in candles between positions (optional - will keep existing if not provided)
/// </summary>
public int? CooldownPeriod { get; set; }
/// <summary>
/// The maximum number of consecutive losses before stopping (optional - will keep existing if not provided)
/// </summary>
public int? MaxLossStreak { get; set; }
/// <summary>
/// Maximum time in hours that a position can remain open before being automatically closed (optional - will keep existing if not provided)
/// </summary>
public decimal? MaxPositionTimeHours { get; set; }
/// <summary>
/// If true, positions will only be flipped when the current position is in profit (optional - will keep existing if not provided)
/// </summary>
public bool? FlipOnlyWhenInProfit { get; set; }
/// <summary>
/// Whether position flipping is enabled (optional - will keep existing if not provided)
/// </summary>
public bool? FlipPosition { get; set; }
/// <summary>
/// The name of the bot (optional - will keep existing if not provided)
/// </summary>
public string? Name { get; set; }
}