diff --git a/src/Managing.Api/Controllers/BotController.cs b/src/Managing.Api/Controllers/BotController.cs
index 63f3b4c..27aa177 100644
--- a/src/Managing.Api/Controllers/BotController.cs
+++ b/src/Managing.Api/Controllers/BotController.cs
@@ -629,6 +629,20 @@ public class BotController : BaseController
}
}
+ // If the bot name is being changed, check for conflicts
+ var isNameChanging = !string.IsNullOrEmpty(request.Config.Name) &&
+ request.Config.Name != request.Identifier;
+
+ if (isNameChanging)
+ {
+ // Check if new name already exists
+ var existingBotWithNewName = bots.FirstOrDefault(b => b.Identifier == request.Config.Name);
+ if (existingBotWithNewName != null)
+ {
+ return BadRequest($"A bot with the name '{request.Config.Name}' already exists");
+ }
+ }
+
// Validate the money management if provided
if (request.Config.MoneyManagement != null)
{
@@ -662,19 +676,27 @@ public class BotController : BaseController
return BadRequest("CloseEarlyWhenProfitable requires MaxPositionTimeHours to be set");
}
- // Update the bot configuration using the new method
+ // Update the bot configuration using the enhanced method
var success = await _botService.UpdateBotConfiguration(request.Identifier, request.Config);
if (success)
{
- await _hubContext.Clients.All.SendAsync("SendNotification",
- $"Bot {request.Identifier} configuration updated successfully by {user.Name}.", "Info");
+ var finalBotName = isNameChanging ? request.Config.Name : request.Identifier;
- return Ok("Bot configuration updated successfully");
+ await _hubContext.Clients.All.SendAsync("SendNotification",
+ $"Bot {finalBotName} configuration updated successfully by {user.Name}." +
+ (isNameChanging ? $" (renamed from {request.Identifier})" : ""), "Info");
+
+ await NotifyBotSubscriberAsync();
+
+ return Ok(isNameChanging
+ ? $"Bot configuration updated successfully and renamed to '{request.Config.Name}'"
+ : "Bot configuration updated successfully");
}
else
{
- return BadRequest("Failed to update bot configuration");
+ return BadRequest("Failed to update bot configuration. " +
+ (isNameChanging ? "The new name might already be in use." : ""));
}
}
catch (Exception ex)
diff --git a/src/Managing.Application/Bots/TradingBot.cs b/src/Managing.Application/Bots/TradingBot.cs
index a424cfc..42abbd8 100644
--- a/src/Managing.Application/Bots/TradingBot.cs
+++ b/src/Managing.Application/Bots/TradingBot.cs
@@ -1278,12 +1278,23 @@ public class TradingBot : Bot, ITradingBot
///
/// Updates the trading bot configuration with new settings.
- /// This method validates the new configuration and applies it to the running bot.
///
/// The new configuration to apply
/// True if the configuration was successfully updated, false otherwise
- /// Thrown when the new configuration is invalid
public async Task UpdateConfiguration(TradingBotConfig newConfig)
+ {
+ return await UpdateConfiguration(newConfig, allowNameChange: false);
+ }
+
+ ///
+ /// Updates the trading bot configuration with new settings.
+ /// This method validates the new configuration and applies it to the running bot.
+ ///
+ /// The new configuration to apply
+ /// Whether to allow changing the bot name/identifier
+ /// True if the configuration was successfully updated, false otherwise
+ /// Thrown when the new configuration is invalid
+ public async Task UpdateConfiguration(TradingBotConfig newConfig, bool allowNameChange = false)
{
try
{
@@ -1312,7 +1323,7 @@ public class TradingBot : Bot, ITradingBot
// Protect critical properties that shouldn't change for running bots
var protectedBotType = Config.BotType;
var protectedIsForBacktest = Config.IsForBacktest;
- var protectedName = Config.Name;
+ var protectedName = allowNameChange ? newConfig.Name : Config.Name;
// Log the configuration update (before changing anything)
await LogInformation("āļø **Configuration Update**\n" +
@@ -1321,7 +1332,8 @@ public class TradingBot : Bot, ITradingBot
$"ā±ļø Max Time: {(Config.MaxPositionTimeHours?.ToString() + "h" ?? "Disabled")}\n" +
$"š Flip Only in Profit: {(Config.FlipOnlyWhenInProfit ? "ā
" : "ā")}\n" +
$"ā³ Cooldown: {Config.CooldownPeriod} candles\n" +
- $"š Max Loss Streak: {Config.MaxLossStreak}");
+ $"š Max Loss Streak: {Config.MaxLossStreak}" +
+ (allowNameChange && newConfig.Name != Config.Name ? $"\nš·ļø Name: {Config.Name} ā {newConfig.Name}" : ""));
// Update the configuration
Config = newConfig;
@@ -1331,6 +1343,13 @@ public class TradingBot : Bot, ITradingBot
Config.IsForBacktest = protectedIsForBacktest;
Config.Name = protectedName;
+ // Update bot name and identifier if allowed
+ if (allowNameChange && !string.IsNullOrEmpty(newConfig.Name))
+ {
+ Name = newConfig.Name;
+ Identifier = newConfig.Name;
+ }
+
// If account changed, reload it
if (Config.AccountName != Account?.Name)
{
diff --git a/src/Managing.Application/ManageBot/BotService.cs b/src/Managing.Application/ManageBot/BotService.cs
index 81e0b5a..886c25b 100644
--- a/src/Managing.Application/ManageBot/BotService.cs
+++ b/src/Managing.Application/ManageBot/BotService.cs
@@ -247,12 +247,49 @@ namespace Managing.Application.ManageBot
if (_botTasks.TryGetValue(identifier, out var botTaskWrapper) &&
botTaskWrapper.BotInstance is TradingBot tradingBot)
{
- return await tradingBot.UpdateConfiguration(newConfig);
+ // Check if the bot name is changing
+ if (newConfig.Name != identifier && !string.IsNullOrEmpty(newConfig.Name))
+ {
+ // Check if new name already exists
+ if (_botTasks.ContainsKey(newConfig.Name))
+ {
+ return false; // New name already in use
+ }
+
+ // Update the bot configuration first
+ var updateResult = await tradingBot.UpdateConfiguration(newConfig, allowNameChange: true);
+
+ if (updateResult)
+ {
+ // Update the dictionary key
+ if (_botTasks.TryRemove(identifier, out var removedWrapper))
+ {
+ _botTasks.TryAdd(newConfig.Name, removedWrapper);
+
+ // Update the backup with the new identifier
+ if (!newConfig.IsForBacktest)
+ {
+ // Delete old backup
+ await _botRepository.DeleteBotBackup(identifier);
+ // Save new backup will be handled by the bot's SaveBackup method
+ }
+ }
+ }
+
+ return updateResult;
+ }
+ else
+ {
+ // No name change, just update configuration
+ return await tradingBot.UpdateConfiguration(newConfig);
+ }
}
return false;
}
+
+
public ITradingBot CreateTradingBot(TradingBotConfig config)
{
return new TradingBot(