From 0544749a6975258204df24709aa6d0afff5db421 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Fri, 12 Jul 2024 19:58:19 +0700 Subject: [PATCH] Commit before refact factory into service --- src/Managing.Application.Tests/BotsTests.cs | 1 - .../Abstractions/IBotService.cs | 31 ++++- .../Bots/Base/BotFactory.cs | 3 - src/Managing.Application/Bots/FlippingBot.cs | 33 ++--- src/Managing.Application/Bots/ScalpingBot.cs | 3 +- src/Managing.Application/Bots/SimpleBot.cs | 8 +- src/Managing.Application/Bots/TradingBot.cs | 120 ++++++++++++------ .../ManageBot/BotService.cs | 83 +++++++++++- .../ManageBot/GetActiveBotsCommandHandler.cs | 23 +--- .../ManageBot/LoadBackupBotCommandHandler.cs | 76 ++--------- .../ManageBot/StartBotCommandHandler.cs | 31 +++-- 11 files changed, 243 insertions(+), 169 deletions(-) diff --git a/src/Managing.Application.Tests/BotsTests.cs b/src/Managing.Application.Tests/BotsTests.cs index 31d1cef..e95c049 100644 --- a/src/Managing.Application.Tests/BotsTests.cs +++ b/src/Managing.Application.Tests/BotsTests.cs @@ -32,7 +32,6 @@ namespace Managing.Application.Tests _botFactory = new BotFactory( _exchangeService, tradingBotLogger, - _moneyManagementService.Object, discordService, _accountService.Object, _tradingService.Object, diff --git a/src/Managing.Application/Abstractions/IBotService.cs b/src/Managing.Application/Abstractions/IBotService.cs index bbe668d..b0aef5c 100644 --- a/src/Managing.Application/Abstractions/IBotService.cs +++ b/src/Managing.Application/Abstractions/IBotService.cs @@ -1,8 +1,31 @@ -using Managing.Application.Bots; using Managing.Common; +using Managing.Domain.Bots; +using Managing.Domain.MoneyManagements; +using Managing.Domain.Workflows; + +namespace Managing.Application.Abstractions; public interface IBotService - { - void SaveBotBackup(BotBackup botBackup); - void SaveBotBackup(string name, Enums.BotType botType, string data); +{ + void SaveBotBackup(BotBackup botBackup); + void SaveBotBackup(string name, Enums.BotType botType, string data); + void AddSimpleBotToCache(IBot bot); + void AddTradingBotToCache(ITradingBot bot); + List GetActiveBots(); + IEnumerable GetSavedBots(); + void StartBot(BotBackup backupBot); + + ITradingBot CreateScalpingBot(string accountName, MoneyManagement moneyManagement, string name, Enums.Ticker ticker, + string scenario, Enums.Timeframe interval, bool isForWatchingOnly); + + ITradingBot CreateBacktestScalpingBot(string accountName, MoneyManagement moneyManagement, Enums.Ticker ticker, + string scenario, Enums.Timeframe interval, bool isForWatchingOnly); + + ITradingBot CreateFlippingBot(string accountName, MoneyManagement moneyManagement, string name, Enums.Ticker ticker, + string scenario, Enums.Timeframe interval, bool isForWatchingOnly); + + ITradingBot CreateBacktestFlippingBot(string accountName, MoneyManagement moneyManagement, Enums.Ticker ticker, + string scenario, Enums.Timeframe interval, bool isForWatchingOnly); + + IBot CreateSimpleBot(string botName, Workflow workflow); } \ No newline at end of file diff --git a/src/Managing.Application/Bots/Base/BotFactory.cs b/src/Managing.Application/Bots/Base/BotFactory.cs index b8d188d..ea49f14 100644 --- a/src/Managing.Application/Bots/Base/BotFactory.cs +++ b/src/Managing.Application/Bots/Base/BotFactory.cs @@ -10,7 +10,6 @@ namespace Managing.Application.Bots.Base { public class BotFactory : IBotFactory { - private readonly IMoneyManagementService _moneyManagementService; private readonly IExchangeService _exchangeService; private readonly IMessengerService _messengerService; private readonly IAccountService _accountService; @@ -21,7 +20,6 @@ namespace Managing.Application.Bots.Base public BotFactory( IExchangeService exchangeService, ILogger tradingBotLogger, - IMoneyManagementService moneyManagementService, IMessengerService messengerService, IAccountService accountService, ITradingService tradingService, @@ -29,7 +27,6 @@ namespace Managing.Application.Bots.Base { _tradingBotLogger = tradingBotLogger; _exchangeService = exchangeService; - _moneyManagementService = moneyManagementService; _messengerService = messengerService; _accountService = accountService; _tradingService = tradingService; diff --git a/src/Managing.Application/Bots/FlippingBot.cs b/src/Managing.Application/Bots/FlippingBot.cs index 86ea4d8..9bf2270 100644 --- a/src/Managing.Application/Bots/FlippingBot.cs +++ b/src/Managing.Application/Bots/FlippingBot.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using Managing.Application.Abstractions; +using Microsoft.Extensions.Logging; using static Managing.Common.Enums; using Managing.Application.Abstractions.Services; using Managing.Domain.MoneyManagements; @@ -22,20 +23,20 @@ namespace Managing.Application.Bots bool isForBacktest = false, bool isForWatchingOnly = false) : base(accountName, - moneyManagement, - name, - ticker, - scenario, - exchangeService, - logger, - tradingService, - timeframe, - accountService, - messengerService, - botService, - isForBacktest, - isForWatchingOnly, - flipPosition: true) + moneyManagement, + name, + ticker, + scenario, + exchangeService, + logger, + tradingService, + timeframe, + accountService, + messengerService, + botService, + isForBacktest, + isForWatchingOnly, + flipPosition: true) { BotType = BotType.FlippingBot; } @@ -47,4 +48,4 @@ namespace Managing.Application.Bots Logger.LogInformation($"Starting {Name} bot - Status : {Status}"); } } -} +} \ No newline at end of file diff --git a/src/Managing.Application/Bots/ScalpingBot.cs b/src/Managing.Application/Bots/ScalpingBot.cs index d45bb3d..f69c336 100644 --- a/src/Managing.Application/Bots/ScalpingBot.cs +++ b/src/Managing.Application/Bots/ScalpingBot.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using Managing.Application.Abstractions; +using Microsoft.Extensions.Logging; using static Managing.Common.Enums; using Managing.Application.Abstractions.Services; using Managing.Domain.MoneyManagements; diff --git a/src/Managing.Application/Bots/SimpleBot.cs b/src/Managing.Application/Bots/SimpleBot.cs index ce29c28..c22f3d4 100644 --- a/src/Managing.Application/Bots/SimpleBot.cs +++ b/src/Managing.Application/Bots/SimpleBot.cs @@ -1,4 +1,5 @@ -using Managing.Domain.Bots; +using Managing.Application.Abstractions; +using Managing.Domain.Bots; using Managing.Domain.Workflows; using Microsoft.Extensions.Logging; using Newtonsoft.Json; @@ -12,7 +13,8 @@ namespace Managing.Application.Bots private readonly IBotService _botService; private Workflow _workflow; - public SimpleBot(string name, ILogger logger, Workflow workflow, IBotService botService) : base(name) + public SimpleBot(string name, ILogger logger, Workflow workflow, IBotService botService) : + base(name) { Logger = logger; _botService = botService; @@ -51,4 +53,4 @@ namespace Managing.Application.Bots _workflow = JsonConvert.DeserializeObject(backup.Data); } } -} +} \ No newline at end of file diff --git a/src/Managing.Application/Bots/TradingBot.cs b/src/Managing.Application/Bots/TradingBot.cs index 490cca7..0a380e9 100644 --- a/src/Managing.Application/Bots/TradingBot.cs +++ b/src/Managing.Application/Bots/TradingBot.cs @@ -103,13 +103,15 @@ public class TradingBot : Bot, ITradingBot await CancelAllOrders(); try - { - await MessengerService.SendMessage($"Hi everyone, I'm going to run {Name}. \nI will send a message here everytime a signal is triggered by the {string.Join(",", Strategies.Select(s => s.Name))} strategies."); + { + await MessengerService.SendMessage( + $"Hi everyone, I'm going to run {Name}. \nI will send a message here everytime a signal is triggered by the {string.Join(",", Strategies.Select(s => s.Name))} strategies."); } catch (Exception ex) { Logger.LogError(ex, ex.Message); } + await InitWorker(Run); } @@ -155,7 +157,8 @@ public class TradingBot : Bot, ITradingBot public async Task Run() { Logger.LogInformation($"____________________{Name}____________________"); - Logger.LogInformation($"Time : {DateTime.Now} - Server time {DateTime.Now.ToUniversalTime()} - Bot : {Name} - Type {BotType} - Ticker : {Ticker}"); + Logger.LogInformation( + $"Time : {DateTime.Now} - Server time {DateTime.Now.ToUniversalTime()} - Bot : {Name} - Type {BotType} - Ticker : {Ticker}"); var previousCandleCount = Candles.Count; @@ -183,6 +186,9 @@ public class TradingBot : Bot, ITradingBot private async Task PreloadCandles() { + if (Candles.Any()) + return; + var candles = await ExchangeService.GetCandlesInflux(Account.Exchange, Ticker, PreloadSince, Timeframe); foreach (var candle in candles.Where(c => c.Date < DateTime.Now.ToUniversalTime())) @@ -218,7 +224,7 @@ public class TradingBot : Bot, ITradingBot signal.Status = SignalStatus.Expired; var signalText = $"{Scenario} trigger a signal. Signal told you " + - $"to {signal.Direction} {Ticker} on {Timeframe}. The confidence in this signal is {signal.Confidence}. Identifier : {signal.Identifier}"; + $"to {signal.Direction} {Ticker} on {Timeframe}. The confidence in this signal is {signal.Confidence}. Identifier : {signal.Identifier}"; Logger.LogInformation(signalText); @@ -280,7 +286,9 @@ public class TradingBot : Bot, ITradingBot { Logger.LogInformation($"Updating position {positionForSignal.SignalIdentifier}"); - var position = IsForBacktest ? positionForSignal : TradingService.GetPositionByIdentifier(positionForSignal.Identifier); + var position = IsForBacktest + ? positionForSignal + : TradingService.GetPositionByIdentifier(positionForSignal.Identifier); if (position.Status == (PositionStatus.Finished | PositionStatus.Flipped)) { @@ -292,32 +300,41 @@ public class TradingBot : Bot, ITradingBot // For backtesting or force close if not executed on exchange : // check if position is still open // Check status, if still open update the status of the position - var lastCandle = IsForBacktest ? Candles.Last() : ExchangeService.GetCandle(Account, Ticker, DateTime.UtcNow); + var lastCandle = IsForBacktest + ? Candles.Last() + : ExchangeService.GetCandle(Account, Ticker, DateTime.UtcNow); if (positionForSignal.OriginDirection == TradeDirection.Long) { if (positionForSignal.StopLoss.Price >= lastCandle.Low) { - await LogInformation($"Closing position - SL {positionForSignal.StopLoss.Price} >= Price {lastCandle.Low}"); - await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss, positionForSignal.StopLoss.Price, true); + await LogInformation( + $"Closing position - SL {positionForSignal.StopLoss.Price} >= Price {lastCandle.Low}"); + await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss, + positionForSignal.StopLoss.Price, true); positionForSignal.StopLoss.SetStatus(TradeStatus.Filled); } else if (positionForSignal.TakeProfit1.Price <= lastCandle.High - && positionForSignal.TakeProfit1.Status != TradeStatus.Filled) + && positionForSignal.TakeProfit1.Status != TradeStatus.Filled) { - await LogInformation($"Closing position - TP1 {positionForSignal.TakeProfit1.Price} <= Price {lastCandle.High}"); - await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1, positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null); + await LogInformation( + $"Closing position - TP1 {positionForSignal.TakeProfit1.Price} <= Price {lastCandle.High}"); + await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1, + positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null); positionForSignal.TakeProfit1.SetStatus(TradeStatus.Filled); } else if (positionForSignal.TakeProfit2?.Price <= lastCandle.High) { - await LogInformation($"Closing position - TP2 {positionForSignal.TakeProfit2.Price} <= Price {lastCandle.High}"); - await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2, positionForSignal.TakeProfit2.Price, true); + await LogInformation( + $"Closing position - TP2 {positionForSignal.TakeProfit2.Price} <= Price {lastCandle.High}"); + await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2, + positionForSignal.TakeProfit2.Price, true); positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled); } else { - Logger.LogInformation($"Position {signal.Identifier} don't need to be update. Position still opened"); + Logger.LogInformation( + $"Position {signal.Identifier} don't need to be update. Position still opened"); } } @@ -325,26 +342,33 @@ public class TradingBot : Bot, ITradingBot { if (positionForSignal.StopLoss.Price <= lastCandle.High) { - await LogInformation($"Closing position - SL {positionForSignal.StopLoss.Price} <= Price {lastCandle.High}"); - await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss, positionForSignal.StopLoss.Price, true); + await LogInformation( + $"Closing position - SL {positionForSignal.StopLoss.Price} <= Price {lastCandle.High}"); + await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss, + positionForSignal.StopLoss.Price, true); positionForSignal.StopLoss.SetStatus(TradeStatus.Filled); } else if (positionForSignal.TakeProfit1.Price >= lastCandle.Low - && positionForSignal.TakeProfit1.Status != TradeStatus.Filled) + && positionForSignal.TakeProfit1.Status != TradeStatus.Filled) { - await LogInformation($"Closing position - TP1 {positionForSignal.TakeProfit1.Price} >= Price {lastCandle.Low}"); - await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1, positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null); + await LogInformation( + $"Closing position - TP1 {positionForSignal.TakeProfit1.Price} >= Price {lastCandle.Low}"); + await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1, + positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null); positionForSignal.TakeProfit1.SetStatus(TradeStatus.Filled); } else if (positionForSignal.TakeProfit2?.Price >= lastCandle.Low) { - await LogInformation($"Closing position - TP2 {positionForSignal.TakeProfit2.Price} >= Price {lastCandle.Low}"); - await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2, positionForSignal.TakeProfit2.Price, true); + await LogInformation( + $"Closing position - TP2 {positionForSignal.TakeProfit2.Price} >= Price {lastCandle.Low}"); + await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2, + positionForSignal.TakeProfit2.Price, true); positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled); } else { - Logger.LogInformation($"Position {signal.Identifier} don't need to be update. Position still opened"); + Logger.LogInformation( + $"Position {signal.Identifier} don't need to be update. Position still opened"); } } } @@ -368,16 +392,17 @@ public class TradingBot : Bot, ITradingBot } - private async Task OpenPosition(Signal signal) { // Check if a position is already open Logger.LogInformation($"Opening position for {signal.Identifier}"); var openedPosition = Positions.FirstOrDefault(p => p.Status == PositionStatus.Filled - && p.SignalIdentifier != signal.Identifier); + && p.SignalIdentifier != signal.Identifier); - var lastPrice = IsForBacktest ? Candles.Last().Close : ExchangeService.GetPrice(Account, Ticker, DateTime.UtcNow); + var lastPrice = IsForBacktest + ? Candles.Last().Close + : ExchangeService.GetPrice(Account, Ticker, DateTime.UtcNow); // If position open if (openedPosition != null) @@ -388,7 +413,8 @@ public class TradingBot : Bot, ITradingBot if (openedPosition.OriginDirection == signal.Direction) { // An operation is already open for the same direction - await LogInformation($"Signal {signal.Identifier} try to open a position but {previousSignal.Identifier} is already open for the same direction"); + await LogInformation( + $"Signal {signal.Identifier} try to open a position but {previousSignal.Identifier} is already open for the same direction"); SetSignalStatus(signal.Identifier, SignalStatus.Expired); } else @@ -401,11 +427,13 @@ public class TradingBot : Bot, ITradingBot await CloseTrade(previousSignal, openedPosition, openedPosition.Open, lastPrice, true); await SetPositionStatus(previousSignal.Identifier, PositionStatus.Flipped); await OpenPosition(signal); - await LogInformation($"Position {previousSignal.Identifier} flipped by {signal.Identifier} at {lastPrice}$"); + await LogInformation( + $"Position {previousSignal.Identifier} flipped by {signal.Identifier} at {lastPrice}$"); } else { - await LogWarning($"A position is already open for signal {previousSignal.Identifier}. Position flipping is currently not enable, the position will not be flipped."); + await LogWarning( + $"A position is already open for signal {previousSignal.Identifier}. Position flipping is currently not enable, the position will not be flipped."); SetSignalStatus(signal.Identifier, SignalStatus.Expired); } } @@ -414,12 +442,14 @@ public class TradingBot : Bot, ITradingBot { if (!CanOpenPosition(signal)) { - await LogInformation("Tried to open position but last position was a loss. Wait for an opposition direction side or wait x candles to open a new position"); + await LogInformation( + "Tried to open position but last position was a loss. Wait for an opposition direction side or wait x candles to open a new position"); SetSignalStatus(signal.Identifier, SignalStatus.Expired); return; } - await LogInformation($"Open position - Date: {signal.Date:T} - SignalIdentifier : {signal.Identifier} - Strategie : {signal.StrategyType}"); + await LogInformation( + $"Open position - Date: {signal.Date:T} - SignalIdentifier : {signal.Identifier} - Strategie : {signal.StrategyType}"); try { @@ -474,9 +504,9 @@ public class TradingBot : Bot, ITradingBot return true; var lastPosition = Positions.LastOrDefault(p => p.IsFinished() - && p.SignalIdentifier != signal.Identifier - && p.ProfitAndLoss.Realized < 0 - && p.OriginDirection == signal.Direction); + && p.SignalIdentifier != signal.Identifier + && p.ProfitAndLoss.Realized < 0 + && p.OriginDirection == signal.Direction); if (lastPosition == null) return true; @@ -487,15 +517,18 @@ public class TradingBot : Bot, ITradingBot return positionSignal.Date < tenCandleAgo.Date; } - private async Task CloseTrade(Signal signal, Position position, Trade tradeToClose, decimal lastPrice, bool tradeClosingPosition = false) + private async Task CloseTrade(Signal signal, Position position, Trade tradeToClose, decimal lastPrice, + bool tradeClosingPosition = false) { - if (position.TakeProfit2 != null && position.TakeProfit1.Status == TradeStatus.Filled && tradeToClose.TradeType == TradeType.StopMarket) + if (position.TakeProfit2 != null && position.TakeProfit1.Status == TradeStatus.Filled && + tradeToClose.TradeType == TradeType.StopMarket) { // If trade is the 2nd Take profit tradeToClose.Quantity = position.TakeProfit2.Quantity; } - await LogInformation($"Trying to close trade {Ticker} at {lastPrice} - Type : {tradeToClose.TradeType} - Quantity : {tradeToClose.Quantity} " + + await LogInformation( + $"Trying to close trade {Ticker} at {lastPrice} - Type : {tradeToClose.TradeType} - Quantity : {tradeToClose.Quantity} " + $"- Closing Position : {tradeClosingPosition}"); // Get status of position before closing it. The position might be already close by the exchange @@ -509,8 +542,9 @@ public class TradingBot : Bot, ITradingBot var command = new ClosePositionCommand(position, lastPrice); try { - var closedPosition = await (new ClosePositionCommandHandler(ExchangeService, AccountService, TradingService)) - .Handle(command); + var closedPosition = + await (new ClosePositionCommandHandler(ExchangeService, AccountService, TradingService)) + .Handle(command); if (closedPosition.Status == (PositionStatus.Finished | PositionStatus.Flipped)) { @@ -536,7 +570,6 @@ public class TradingBot : Bot, ITradingBot await SetPositionStatus(signal.Identifier, PositionStatus.Finished); } } - } } @@ -549,7 +582,8 @@ public class TradingBot : Bot, ITradingBot position.SignalIdentifier = previousPosition.SignalIdentifier; Positions[positionIndex] = position; SetSignalStatus(position.SignalIdentifier, SignalStatus.Expired); - Logger.LogInformation($"Position {position.SignalIdentifier} type correctly close. Pnl on position : {position.ProfitAndLoss.Realized}"); + Logger.LogInformation( + $"Position {position.SignalIdentifier} type correctly close. Pnl on position : {position.ProfitAndLoss.Realized}"); } else { @@ -689,6 +723,12 @@ public class TradingBot : Bot, ITradingBot Signals = data.Signals; Positions = data.Positions; WalletBalances = data.WalletBalances; + MoneyManagement = data.MoneyManagement; + Timeframe = data.Timeframe; + Ticker = data.Ticker; + Scenario = data.Scenario; + AccountName = data.AccountName; + IsForWatchingOnly = data.IsForWatchingOnly; } } diff --git a/src/Managing.Application/ManageBot/BotService.cs b/src/Managing.Application/ManageBot/BotService.cs index 2ab39a0..8f72196 100644 --- a/src/Managing.Application/ManageBot/BotService.cs +++ b/src/Managing.Application/ManageBot/BotService.cs @@ -1,23 +1,31 @@ using Managing.Application.Abstractions; using Managing.Application.Bots; using Managing.Common; +using Managing.Core; +using Managing.Domain.Bots; +using Newtonsoft.Json; namespace Managing.Application.ManageBot { public class BotService : IBotService { private readonly IBotRepository _botRepository; + private readonly ITaskCache _taskCache; + private readonly IBotFactory _botFactory; + - public BotService(IBotRepository botRepository) + public BotService(IBotRepository botRepository, ITaskCache taskCache, IBotFactory botFactory) { _botRepository = botRepository; + _taskCache = taskCache; + _botFactory = botFactory; } public async void SaveBotBackup(BotBackup botBackup) { - await _botRepository.InsertBotAsync(botBackup); + await _botRepository.InsertBotAsync(botBackup); } - + public BotBackup GetBotBackup(string name) { return _botRepository.GetBots().FirstOrDefault(b => b.Name == name); @@ -26,14 +34,14 @@ namespace Managing.Application.ManageBot public void SaveBotBackup(string name, Enums.BotType botType, string data) { var backup = GetBotBackup(name); - + if (backup != null) { backup.Data = data; _botRepository.UpdateBackupBot(backup); return; } - + var botBackup = new BotBackup { Name = name, @@ -43,5 +51,70 @@ namespace Managing.Application.ManageBot _botRepository.InsertBotAsync(botBackup); } + + public void AddSimpleBotToCache(IBot bot) + { + _taskCache.AddOrGetExisting(bot.GetName(), () => Task.FromResult(bot)); + } + + public void AddTradingBotToCache(ITradingBot bot) + { + _taskCache.AddOrGetExisting(bot.GetName(), () => Task.FromResult(bot)); + } + + public List GetActiveBots() + { + var cachedTask = _taskCache.GetCache>(); + return cachedTask.Select(item => item.Value.Result).ToList(); + } + + public IEnumerable GetSavedBots() + { + return _botRepository.GetBots(); + } + + public void StartBot(BotBackup backupBot) + { + switch (backupBot.BotType) + { + case Enums.BotType.SimpleBot: + Func> simpleBot = () => + Task.FromResult(_botFactory.CreateSimpleBot(backupBot.Name, null)); + var bot1 = _taskCache.AddOrGetExisting(backupBot.Name, simpleBot).Result; + bot1.LoadBackup(backupBot); + bot1.Start(); + break; + case Enums.BotType.ScalpingBot: + var data = JsonConvert.DeserializeObject(backupBot.Data); + Func> scalpingBot = () => Task.FromResult(_botFactory.CreateScalpingBot( + data.AccountName, + data.MoneyManagement, + data.Name, + data.Ticker, + data.Scenario, + data.Timeframe, + data.IsForWatchingOnly)); + var bot2 = _taskCache.AddOrGetExisting(backupBot.Name, scalpingBot).Result; + bot2.LoadBackup(backupBot); + bot2.Start(); + break; + case Enums.BotType.FlippingBot: + var dataFlippingBot = JsonConvert.DeserializeObject(backupBot.Data); + Func> flippingBot = () => Task.FromResult(_botFactory.CreateFlippingBot( + dataFlippingBot.AccountName, + dataFlippingBot.MoneyManagement, + dataFlippingBot.Name, + dataFlippingBot.Ticker, + dataFlippingBot.Scenario, + dataFlippingBot.Timeframe, + dataFlippingBot.IsForWatchingOnly)); + var bot3 = _taskCache.AddOrGetExisting(backupBot.Name, flippingBot).Result; + bot3.LoadBackup(backupBot); + bot3.Start(); + break; + } + + ; + } } } \ No newline at end of file diff --git a/src/Managing.Application/ManageBot/GetActiveBotsCommandHandler.cs b/src/Managing.Application/ManageBot/GetActiveBotsCommandHandler.cs index 4ee8e46..930049e 100644 --- a/src/Managing.Application/ManageBot/GetActiveBotsCommandHandler.cs +++ b/src/Managing.Application/ManageBot/GetActiveBotsCommandHandler.cs @@ -1,30 +1,15 @@ using Managing.Application.Abstractions; using Managing.Application.ManageBot.Commands; -using Managing.Core; using MediatR; namespace Managing.Application.ManageBot { - public class GetActiveBotsCommandHandler : IRequestHandler> + public class GetActiveBotsCommandHandler(IBotService botService) + : IRequestHandler> { - private readonly ITaskCache taskCache; - - public GetActiveBotsCommandHandler(ITaskCache taskCache) - { - this.taskCache = taskCache; - } - public Task> Handle(GetActiveBotsCommand request, CancellationToken cancellationToken) { - var cachedTask = taskCache.GetCache>(); - var result = new List(); - - foreach (var item in cachedTask) - { - result.Add(item.Value.Result); - } - - return Task.FromResult(result); + return Task.FromResult(botService.GetActiveBots()); } } -} +} \ No newline at end of file diff --git a/src/Managing.Application/ManageBot/LoadBackupBotCommandHandler.cs b/src/Managing.Application/ManageBot/LoadBackupBotCommandHandler.cs index ae0e302..b738834 100644 --- a/src/Managing.Application/ManageBot/LoadBackupBotCommandHandler.cs +++ b/src/Managing.Application/ManageBot/LoadBackupBotCommandHandler.cs @@ -11,30 +11,21 @@ namespace Managing.Application.ManageBot; public class LoadBackupBotCommandHandler : IRequestHandler { - private readonly IBotFactory _botFactory; - private readonly ITaskCache _taskCache; - private readonly IMoneyManagementService _moneyManagementService; - private readonly IBotRepository _botRepository; + private readonly IBotService _botService; private readonly ILogger _logger; public LoadBackupBotCommandHandler( - IBotFactory botFactory, - ITaskCache taskCache, - IMoneyManagementService moneyManagementService, - IBotRepository botRepository, - ILogger logger) + ILogger logger, IBotService botService) { - _botFactory = botFactory; - _taskCache = taskCache; - _moneyManagementService = moneyManagementService; - _botRepository = botRepository; _logger = logger; + _botService = botService; } public Task Handle(LoadBackupBotCommand request, CancellationToken cancellationToken) { BotStatus botStatus = BotStatus.Down; - var backupBots = _botRepository.GetBots(); + var backupBots = _botService.GetSavedBots(); + var activeBots = _botService.GetActiveBots(); var result = new Dictionary(); _logger.LogInformation($"Loading {backupBots.Count()} backup bots"); @@ -47,12 +38,11 @@ public class LoadBackupBotCommandHandler : IRequestHandler(backupBot.Name); + var simpleBot = activeBots.FirstOrDefault(b => b.GetName() == backupBot.Name); if (simpleBot == null) { _logger.LogInformation($"Starting backup bot {backupBot.Name}"); - StartBot(backupBot); - simpleBot.LoadBackup(backupBot); + _botService.StartBot(backupBot); result.Add(simpleBot.GetName(), BotStatus.Backup); } else @@ -63,19 +53,18 @@ public class LoadBackupBotCommandHandler : IRequestHandler(backupBot.Name); + var scalpingBot = activeBots.FirstOrDefault(b => b.GetName() == backupBot.Name); if (scalpingBot == null) { _logger.LogInformation($"Starting backup bot {backupBot.Name}"); - StartBot(backupBot); - scalpingBot = _taskCache.Get(backupBot.Name); - scalpingBot.LoadBackup(backupBot); - result.Add(scalpingBot.GetName(), BotStatus.Backup); + _botService.StartBot(backupBot); } else { - result.Add(scalpingBot.GetName(), MiscExtensions.ParseEnum(scalpingBot.GetStatus())); + result.Add(scalpingBot.GetName(), + MiscExtensions.ParseEnum(scalpingBot.GetStatus())); } + break; default: result.Add(backupBot.Name, BotStatus.Down); @@ -91,47 +80,6 @@ public class LoadBackupBotCommandHandler : IRequestHandler> simpleBot = () => Task.FromResult(_botFactory.CreateSimpleBot(backupBot.Name, null)); - var bot1 = _taskCache.AddOrGetExisting(backupBot.Name, simpleBot).Result; - bot1.LoadBackup(backupBot); - bot1.Start(); - break; - case BotType.ScalpingBot: - var data = JsonConvert.DeserializeObject(backupBot.Data); - Func> scalpingBot = () => Task.FromResult(_botFactory.CreateScalpingBot( - data.AccountName, - data.MoneyManagement, - data.Name, - data.Ticker, - data.Scenario, - data.Timeframe, - data.IsForWatchingOnly)); - var bot2 = _taskCache.AddOrGetExisting(backupBot.Name, scalpingBot).Result; - bot2.LoadBackup(backupBot); - bot2.Start(); - break; - case BotType.FlippingBot: - var dataFlippingBot = JsonConvert.DeserializeObject(backupBot.Data); - Func> flippingBot = () => Task.FromResult(_botFactory.CreateFlippingBot( - dataFlippingBot.AccountName, - dataFlippingBot.MoneyManagement, - dataFlippingBot.Name, - dataFlippingBot.Ticker, - dataFlippingBot.Scenario, - dataFlippingBot.Timeframe, - dataFlippingBot.IsForWatchingOnly)); - var bot3 = _taskCache.AddOrGetExisting(backupBot.Name, flippingBot).Result; - bot3.LoadBackup(backupBot); - bot3.Start(); - break; - }; - } } public class LoadBackupBotCommand : IRequest diff --git a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs index 4b74421..38fc4b5 100644 --- a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs +++ b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs @@ -9,13 +9,14 @@ namespace Managing.Application.ManageBot public class StartBotCommandHandler : IRequestHandler { private readonly IBotFactory _botFactory; - private readonly ITaskCache _taskCache; + private readonly IBotService _botService; private readonly IMoneyManagementService _moneyManagementService; - public StartBotCommandHandler(IBotFactory botFactory, ITaskCache taskCache, IMoneyManagementService moneyManagementService) + public StartBotCommandHandler(IBotFactory botFactory, IBotService botService, + IMoneyManagementService moneyManagementService) { _botFactory = botFactory; - _taskCache = taskCache; + _botService = botService; _moneyManagementService = moneyManagementService; } @@ -28,21 +29,25 @@ namespace Managing.Application.ManageBot case BotType.SimpleBot: var bot = _botFactory.CreateSimpleBot(request.Name, null); bot.Start(); - Func> simpleBot = () => Task.FromResult(bot); - return Task.FromResult(_taskCache.AddOrGetExisting(request.Name, simpleBot).Result.GetStatus()); + _botService.AddSimpleBotToCache(bot); + return Task.FromResult(bot.GetStatus()); case BotType.ScalpingBot: - var sBot = _botFactory.CreateScalpingBot(request.AccountName, moneyManagement, request.Name, request.Ticker, request.Scenario, request.Timeframe, request.IsForWatchingOnly); + var sBot = _botFactory.CreateScalpingBot(request.AccountName, moneyManagement, request.Name, + request.Ticker, request.Scenario, request.Timeframe, request.IsForWatchingOnly); sBot.Start(); - Func> scalpingBot = () => Task.FromResult(sBot); - return Task.FromResult(_taskCache.AddOrGetExisting(request.Name, scalpingBot).Result.GetStatus()); + _botService.AddTradingBotToCache(sBot); + return Task.FromResult(sBot.GetStatus()); case BotType.FlippingBot: - var fBot = _botFactory.CreateFlippingBot(request.AccountName, moneyManagement, request.Name, request.Ticker, request.Scenario, request.Timeframe, request.IsForWatchingOnly); + var fBot = _botFactory.CreateFlippingBot(request.AccountName, moneyManagement, request.Name, + request.Ticker, request.Scenario, request.Timeframe, request.IsForWatchingOnly); fBot.Start(); - Func> flippingBot = () => Task.FromResult(fBot); - return Task.FromResult(_taskCache.AddOrGetExisting(request.Name, flippingBot).Result.GetStatus()); - }; + _botService.AddTradingBotToCache(fBot); + return Task.FromResult(fBot.GetStatus()); + } + + ; return Task.FromResult(botStatus.ToString()); } } -} +} \ No newline at end of file