diff --git a/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs b/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs index a6753a57..f96cd6fe 100644 --- a/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs +++ b/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs @@ -28,7 +28,7 @@ public interface ILiveTradingBotGrain : IGrainWithGuidKey Task CreateAsync(TradingBotConfig config, User user); Task StartAsync(); - Task StopAsync(); + Task StopAsync(string reason); Task UpdateConfiguration(TradingBotConfig newConfig); Task GetAccount(); diff --git a/src/Managing.Application/Abstractions/ITradingBot.cs b/src/Managing.Application/Abstractions/ITradingBot.cs index 4ab06689..77ede2fe 100644 --- a/src/Managing.Application/Abstractions/ITradingBot.cs +++ b/src/Managing.Application/Abstractions/ITradingBot.cs @@ -20,6 +20,7 @@ namespace Managing.Application.Abstractions Candle LastCandle { get; set; } Task Run(); + Task StopBot(string reason = null); int GetWinRate(); decimal GetProfitAndLoss(); decimal GetTotalFees(); diff --git a/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs b/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs index bc8741d4..735b28e2 100644 --- a/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs +++ b/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs @@ -265,12 +265,12 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable }); } - public async Task StopAsync() + public async Task StopAsync(string reason) { - await StopAsyncInternal(false); + await StopAsyncInternal(false, reason); } - private async Task StopAsyncInternal(bool isRestarting) + private async Task StopAsyncInternal(bool isRestarting, string? reason = null) { // Only check for open positions if this is not part of a restart operation if (!isRestarting) @@ -318,6 +318,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable SyncStateFromBase(); await _state.WriteStateAsync(); await SaveBotAsync(BotStatus.Stopped); + await _tradingBot?.StopBot(reason)!; _tradingBot = null; await UpdateBotRegistryStatus(BotStatus.Stopped); @@ -409,7 +410,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable // Check if the bot should stop due to this failure if (balanceCheckResult.ShouldStopBot) { - await StopAsync(); + await StopAsync(balanceCheckResult.Message); return; } } @@ -647,7 +648,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable try { // Stop the bot first if it's running - await StopAsync(); + await StopAsync("Deleting bot"); // Unregister from the bot registry var botRegistry = GrainFactory.GetGrain(0); diff --git a/src/Managing.Application/Bots/TradingBotBase.cs b/src/Managing.Application/Bots/TradingBotBase.cs index 1f7569ea..7d607470 100644 --- a/src/Managing.Application/Bots/TradingBotBase.cs +++ b/src/Managing.Application/Bots/TradingBotBase.cs @@ -1889,9 +1889,10 @@ public class TradingBotBase : ITradingBot /// /// Handles bot stopping and notifies platform summary /// - public async Task StopBot() + public async Task StopBot(string reason = null) { - await LogInformation($"🛑 Bot Stopped\nBot: `{Config.Name}`\nTicker: `{Config.Ticker}`"); + await LogInformation( + $"🛑 Bot Stopped\nBot: `{Config.Name}`\nTicker: `{Config.Ticker}`\nReason: `{reason ?? "No reason provided"}`"); } public async Task LogInformation(string message) diff --git a/src/Managing.Application/ManageBot/BotService.cs b/src/Managing.Application/ManageBot/BotService.cs index a35eee52..5b7f7805 100644 --- a/src/Managing.Application/ManageBot/BotService.cs +++ b/src/Managing.Application/ManageBot/BotService.cs @@ -54,7 +54,7 @@ namespace Managing.Application.ManageBot try { var grain = _grainFactory.GetGrain(identifier); - await grain.StopAsync(); + await grain.StopAsync("User requested stop"); return BotStatus.Stopped; } catch (Exception e) @@ -72,7 +72,7 @@ namespace Managing.Application.ManageBot { var config = await grain.GetConfiguration(); var account = await grain.GetAccount(); - await grain.StopAsync(); + await grain.StopAsync("Deleting bot"); await _botRepository.DeleteBot(identifier); await grain.DeleteAsync();