Commit before refact factory into service
This commit is contained in:
@@ -32,7 +32,6 @@ namespace Managing.Application.Tests
|
|||||||
_botFactory = new BotFactory(
|
_botFactory = new BotFactory(
|
||||||
_exchangeService,
|
_exchangeService,
|
||||||
tradingBotLogger,
|
tradingBotLogger,
|
||||||
_moneyManagementService.Object,
|
|
||||||
discordService,
|
discordService,
|
||||||
_accountService.Object,
|
_accountService.Object,
|
||||||
_tradingService.Object,
|
_tradingService.Object,
|
||||||
|
|||||||
@@ -1,8 +1,31 @@
|
|||||||
using Managing.Application.Bots;
|
|
||||||
using Managing.Common;
|
using Managing.Common;
|
||||||
|
using Managing.Domain.Bots;
|
||||||
|
using Managing.Domain.MoneyManagements;
|
||||||
|
using Managing.Domain.Workflows;
|
||||||
|
|
||||||
|
namespace Managing.Application.Abstractions;
|
||||||
|
|
||||||
public interface IBotService
|
public interface IBotService
|
||||||
{
|
{
|
||||||
void SaveBotBackup(BotBackup botBackup);
|
void SaveBotBackup(BotBackup botBackup);
|
||||||
void SaveBotBackup(string name, Enums.BotType botType, string data);
|
void SaveBotBackup(string name, Enums.BotType botType, string data);
|
||||||
|
void AddSimpleBotToCache(IBot bot);
|
||||||
|
void AddTradingBotToCache(ITradingBot bot);
|
||||||
|
List<ITradingBot> GetActiveBots();
|
||||||
|
IEnumerable<BotBackup> 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);
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,6 @@ namespace Managing.Application.Bots.Base
|
|||||||
{
|
{
|
||||||
public class BotFactory : IBotFactory
|
public class BotFactory : IBotFactory
|
||||||
{
|
{
|
||||||
private readonly IMoneyManagementService _moneyManagementService;
|
|
||||||
private readonly IExchangeService _exchangeService;
|
private readonly IExchangeService _exchangeService;
|
||||||
private readonly IMessengerService _messengerService;
|
private readonly IMessengerService _messengerService;
|
||||||
private readonly IAccountService _accountService;
|
private readonly IAccountService _accountService;
|
||||||
@@ -21,7 +20,6 @@ namespace Managing.Application.Bots.Base
|
|||||||
public BotFactory(
|
public BotFactory(
|
||||||
IExchangeService exchangeService,
|
IExchangeService exchangeService,
|
||||||
ILogger<TradingBot> tradingBotLogger,
|
ILogger<TradingBot> tradingBotLogger,
|
||||||
IMoneyManagementService moneyManagementService,
|
|
||||||
IMessengerService messengerService,
|
IMessengerService messengerService,
|
||||||
IAccountService accountService,
|
IAccountService accountService,
|
||||||
ITradingService tradingService,
|
ITradingService tradingService,
|
||||||
@@ -29,7 +27,6 @@ namespace Managing.Application.Bots.Base
|
|||||||
{
|
{
|
||||||
_tradingBotLogger = tradingBotLogger;
|
_tradingBotLogger = tradingBotLogger;
|
||||||
_exchangeService = exchangeService;
|
_exchangeService = exchangeService;
|
||||||
_moneyManagementService = moneyManagementService;
|
|
||||||
_messengerService = messengerService;
|
_messengerService = messengerService;
|
||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
_tradingService = tradingService;
|
_tradingService = tradingService;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Managing.Application.Abstractions;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using static Managing.Common.Enums;
|
using static Managing.Common.Enums;
|
||||||
using Managing.Application.Abstractions.Services;
|
using Managing.Application.Abstractions.Services;
|
||||||
using Managing.Domain.MoneyManagements;
|
using Managing.Domain.MoneyManagements;
|
||||||
@@ -22,20 +23,20 @@ namespace Managing.Application.Bots
|
|||||||
bool isForBacktest = false,
|
bool isForBacktest = false,
|
||||||
bool isForWatchingOnly = false)
|
bool isForWatchingOnly = false)
|
||||||
: base(accountName,
|
: base(accountName,
|
||||||
moneyManagement,
|
moneyManagement,
|
||||||
name,
|
name,
|
||||||
ticker,
|
ticker,
|
||||||
scenario,
|
scenario,
|
||||||
exchangeService,
|
exchangeService,
|
||||||
logger,
|
logger,
|
||||||
tradingService,
|
tradingService,
|
||||||
timeframe,
|
timeframe,
|
||||||
accountService,
|
accountService,
|
||||||
messengerService,
|
messengerService,
|
||||||
botService,
|
botService,
|
||||||
isForBacktest,
|
isForBacktest,
|
||||||
isForWatchingOnly,
|
isForWatchingOnly,
|
||||||
flipPosition: true)
|
flipPosition: true)
|
||||||
{
|
{
|
||||||
BotType = BotType.FlippingBot;
|
BotType = BotType.FlippingBot;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Managing.Application.Abstractions;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using static Managing.Common.Enums;
|
using static Managing.Common.Enums;
|
||||||
using Managing.Application.Abstractions.Services;
|
using Managing.Application.Abstractions.Services;
|
||||||
using Managing.Domain.MoneyManagements;
|
using Managing.Domain.MoneyManagements;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Managing.Domain.Bots;
|
using Managing.Application.Abstractions;
|
||||||
|
using Managing.Domain.Bots;
|
||||||
using Managing.Domain.Workflows;
|
using Managing.Domain.Workflows;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -12,7 +13,8 @@ namespace Managing.Application.Bots
|
|||||||
private readonly IBotService _botService;
|
private readonly IBotService _botService;
|
||||||
private Workflow _workflow;
|
private Workflow _workflow;
|
||||||
|
|
||||||
public SimpleBot(string name, ILogger<TradingBot> logger, Workflow workflow, IBotService botService) : base(name)
|
public SimpleBot(string name, ILogger<TradingBot> logger, Workflow workflow, IBotService botService) :
|
||||||
|
base(name)
|
||||||
{
|
{
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
_botService = botService;
|
_botService = botService;
|
||||||
|
|||||||
@@ -104,12 +104,14 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
|
|
||||||
try
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, ex.Message);
|
Logger.LogError(ex, ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
await InitWorker(Run);
|
await InitWorker(Run);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +157,8 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
public async Task Run()
|
public async Task Run()
|
||||||
{
|
{
|
||||||
Logger.LogInformation($"____________________{Name}____________________");
|
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;
|
var previousCandleCount = Candles.Count;
|
||||||
|
|
||||||
@@ -183,6 +186,9 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
|
|
||||||
private async Task PreloadCandles()
|
private async Task PreloadCandles()
|
||||||
{
|
{
|
||||||
|
if (Candles.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
var candles = await ExchangeService.GetCandlesInflux(Account.Exchange, Ticker, PreloadSince, Timeframe);
|
var candles = await ExchangeService.GetCandlesInflux(Account.Exchange, Ticker, PreloadSince, Timeframe);
|
||||||
|
|
||||||
foreach (var candle in candles.Where(c => c.Date < DateTime.Now.ToUniversalTime()))
|
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;
|
signal.Status = SignalStatus.Expired;
|
||||||
|
|
||||||
var signalText = $"{Scenario} trigger a signal. Signal told you " +
|
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);
|
Logger.LogInformation(signalText);
|
||||||
|
|
||||||
@@ -280,7 +286,9 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
{
|
{
|
||||||
Logger.LogInformation($"Updating position {positionForSignal.SignalIdentifier}");
|
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))
|
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 :
|
// For backtesting or force close if not executed on exchange :
|
||||||
// check if position is still open
|
// check if position is still open
|
||||||
// Check status, if still open update the status of the position
|
// 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.OriginDirection == TradeDirection.Long)
|
||||||
{
|
{
|
||||||
if (positionForSignal.StopLoss.Price >= lastCandle.Low)
|
if (positionForSignal.StopLoss.Price >= lastCandle.Low)
|
||||||
{
|
{
|
||||||
await LogInformation($"Closing position - SL {positionForSignal.StopLoss.Price} >= Price {lastCandle.Low}");
|
await LogInformation(
|
||||||
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss, positionForSignal.StopLoss.Price, true);
|
$"Closing position - SL {positionForSignal.StopLoss.Price} >= Price {lastCandle.Low}");
|
||||||
|
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss,
|
||||||
|
positionForSignal.StopLoss.Price, true);
|
||||||
positionForSignal.StopLoss.SetStatus(TradeStatus.Filled);
|
positionForSignal.StopLoss.SetStatus(TradeStatus.Filled);
|
||||||
}
|
}
|
||||||
else if (positionForSignal.TakeProfit1.Price <= lastCandle.High
|
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 LogInformation(
|
||||||
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1, positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null);
|
$"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);
|
positionForSignal.TakeProfit1.SetStatus(TradeStatus.Filled);
|
||||||
}
|
}
|
||||||
else if (positionForSignal.TakeProfit2?.Price <= lastCandle.High)
|
else if (positionForSignal.TakeProfit2?.Price <= lastCandle.High)
|
||||||
{
|
{
|
||||||
await LogInformation($"Closing position - TP2 {positionForSignal.TakeProfit2.Price} <= Price {lastCandle.High}");
|
await LogInformation(
|
||||||
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2, positionForSignal.TakeProfit2.Price, true);
|
$"Closing position - TP2 {positionForSignal.TakeProfit2.Price} <= Price {lastCandle.High}");
|
||||||
|
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2,
|
||||||
|
positionForSignal.TakeProfit2.Price, true);
|
||||||
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled);
|
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled);
|
||||||
}
|
}
|
||||||
else
|
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)
|
if (positionForSignal.StopLoss.Price <= lastCandle.High)
|
||||||
{
|
{
|
||||||
await LogInformation($"Closing position - SL {positionForSignal.StopLoss.Price} <= Price {lastCandle.High}");
|
await LogInformation(
|
||||||
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss, positionForSignal.StopLoss.Price, true);
|
$"Closing position - SL {positionForSignal.StopLoss.Price} <= Price {lastCandle.High}");
|
||||||
|
await CloseTrade(signal, positionForSignal, positionForSignal.StopLoss,
|
||||||
|
positionForSignal.StopLoss.Price, true);
|
||||||
positionForSignal.StopLoss.SetStatus(TradeStatus.Filled);
|
positionForSignal.StopLoss.SetStatus(TradeStatus.Filled);
|
||||||
}
|
}
|
||||||
else if (positionForSignal.TakeProfit1.Price >= lastCandle.Low
|
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 LogInformation(
|
||||||
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit1, positionForSignal.TakeProfit1.Price, positionForSignal.TakeProfit2 == null);
|
$"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);
|
positionForSignal.TakeProfit1.SetStatus(TradeStatus.Filled);
|
||||||
}
|
}
|
||||||
else if (positionForSignal.TakeProfit2?.Price >= lastCandle.Low)
|
else if (positionForSignal.TakeProfit2?.Price >= lastCandle.Low)
|
||||||
{
|
{
|
||||||
await LogInformation($"Closing position - TP2 {positionForSignal.TakeProfit2.Price} >= Price {lastCandle.Low}");
|
await LogInformation(
|
||||||
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2, positionForSignal.TakeProfit2.Price, true);
|
$"Closing position - TP2 {positionForSignal.TakeProfit2.Price} >= Price {lastCandle.Low}");
|
||||||
|
await CloseTrade(signal, positionForSignal, positionForSignal.TakeProfit2,
|
||||||
|
positionForSignal.TakeProfit2.Price, true);
|
||||||
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled);
|
positionForSignal.TakeProfit2.SetStatus(TradeStatus.Filled);
|
||||||
}
|
}
|
||||||
else
|
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)
|
private async Task OpenPosition(Signal signal)
|
||||||
{
|
{
|
||||||
// Check if a position is already open
|
// Check if a position is already open
|
||||||
Logger.LogInformation($"Opening position for {signal.Identifier}");
|
Logger.LogInformation($"Opening position for {signal.Identifier}");
|
||||||
|
|
||||||
var openedPosition = Positions.FirstOrDefault(p => p.Status == PositionStatus.Filled
|
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 position open
|
||||||
if (openedPosition != null)
|
if (openedPosition != null)
|
||||||
@@ -388,7 +413,8 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
if (openedPosition.OriginDirection == signal.Direction)
|
if (openedPosition.OriginDirection == signal.Direction)
|
||||||
{
|
{
|
||||||
// An operation is already open for the same 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);
|
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -401,11 +427,13 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
await CloseTrade(previousSignal, openedPosition, openedPosition.Open, lastPrice, true);
|
await CloseTrade(previousSignal, openedPosition, openedPosition.Open, lastPrice, true);
|
||||||
await SetPositionStatus(previousSignal.Identifier, PositionStatus.Flipped);
|
await SetPositionStatus(previousSignal.Identifier, PositionStatus.Flipped);
|
||||||
await OpenPosition(signal);
|
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
|
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);
|
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -414,12 +442,14 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
{
|
{
|
||||||
if (!CanOpenPosition(signal))
|
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);
|
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
|
||||||
return;
|
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
|
try
|
||||||
{
|
{
|
||||||
@@ -474,9 +504,9 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
var lastPosition = Positions.LastOrDefault(p => p.IsFinished()
|
var lastPosition = Positions.LastOrDefault(p => p.IsFinished()
|
||||||
&& p.SignalIdentifier != signal.Identifier
|
&& p.SignalIdentifier != signal.Identifier
|
||||||
&& p.ProfitAndLoss.Realized < 0
|
&& p.ProfitAndLoss.Realized < 0
|
||||||
&& p.OriginDirection == signal.Direction);
|
&& p.OriginDirection == signal.Direction);
|
||||||
|
|
||||||
if (lastPosition == null)
|
if (lastPosition == null)
|
||||||
return true;
|
return true;
|
||||||
@@ -487,15 +517,18 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
return positionSignal.Date < tenCandleAgo.Date;
|
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
|
// If trade is the 2nd Take profit
|
||||||
tradeToClose.Quantity = position.TakeProfit2.Quantity;
|
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}");
|
$"- Closing Position : {tradeClosingPosition}");
|
||||||
|
|
||||||
// Get status of position before closing it. The position might be already close by the exchange
|
// 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);
|
var command = new ClosePositionCommand(position, lastPrice);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var closedPosition = await (new ClosePositionCommandHandler(ExchangeService, AccountService, TradingService))
|
var closedPosition =
|
||||||
.Handle(command);
|
await (new ClosePositionCommandHandler(ExchangeService, AccountService, TradingService))
|
||||||
|
.Handle(command);
|
||||||
|
|
||||||
if (closedPosition.Status == (PositionStatus.Finished | PositionStatus.Flipped))
|
if (closedPosition.Status == (PositionStatus.Finished | PositionStatus.Flipped))
|
||||||
{
|
{
|
||||||
@@ -536,7 +570,6 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
await SetPositionStatus(signal.Identifier, PositionStatus.Finished);
|
await SetPositionStatus(signal.Identifier, PositionStatus.Finished);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,7 +582,8 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
position.SignalIdentifier = previousPosition.SignalIdentifier;
|
position.SignalIdentifier = previousPosition.SignalIdentifier;
|
||||||
Positions[positionIndex] = position;
|
Positions[positionIndex] = position;
|
||||||
SetSignalStatus(position.SignalIdentifier, SignalStatus.Expired);
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -689,6 +723,12 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
Signals = data.Signals;
|
Signals = data.Signals;
|
||||||
Positions = data.Positions;
|
Positions = data.Positions;
|
||||||
WalletBalances = data.WalletBalances;
|
WalletBalances = data.WalletBalances;
|
||||||
|
MoneyManagement = data.MoneyManagement;
|
||||||
|
Timeframe = data.Timeframe;
|
||||||
|
Ticker = data.Ticker;
|
||||||
|
Scenario = data.Scenario;
|
||||||
|
AccountName = data.AccountName;
|
||||||
|
IsForWatchingOnly = data.IsForWatchingOnly;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,29 @@
|
|||||||
using Managing.Application.Abstractions;
|
using Managing.Application.Abstractions;
|
||||||
using Managing.Application.Bots;
|
using Managing.Application.Bots;
|
||||||
using Managing.Common;
|
using Managing.Common;
|
||||||
|
using Managing.Core;
|
||||||
|
using Managing.Domain.Bots;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Managing.Application.ManageBot
|
namespace Managing.Application.ManageBot
|
||||||
{
|
{
|
||||||
public class BotService : IBotService
|
public class BotService : IBotService
|
||||||
{
|
{
|
||||||
private readonly IBotRepository _botRepository;
|
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;
|
_botRepository = botRepository;
|
||||||
|
_taskCache = taskCache;
|
||||||
|
_botFactory = botFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void SaveBotBackup(BotBackup botBackup)
|
public async void SaveBotBackup(BotBackup botBackup)
|
||||||
{
|
{
|
||||||
await _botRepository.InsertBotAsync(botBackup);
|
await _botRepository.InsertBotAsync(botBackup);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BotBackup GetBotBackup(string name)
|
public BotBackup GetBotBackup(string name)
|
||||||
@@ -43,5 +51,70 @@ namespace Managing.Application.ManageBot
|
|||||||
|
|
||||||
_botRepository.InsertBotAsync(botBackup);
|
_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<ITradingBot> GetActiveBots()
|
||||||
|
{
|
||||||
|
var cachedTask = _taskCache.GetCache<AsyncLazy<ITradingBot>>();
|
||||||
|
return cachedTask.Select(item => item.Value.Result).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<BotBackup> GetSavedBots()
|
||||||
|
{
|
||||||
|
return _botRepository.GetBots();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartBot(BotBackup backupBot)
|
||||||
|
{
|
||||||
|
switch (backupBot.BotType)
|
||||||
|
{
|
||||||
|
case Enums.BotType.SimpleBot:
|
||||||
|
Func<Task<IBot>> 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<TradingBotBackup>(backupBot.Data);
|
||||||
|
Func<Task<ITradingBot>> 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<TradingBotBackup>(backupBot.Data);
|
||||||
|
Func<Task<ITradingBot>> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,15 @@
|
|||||||
using Managing.Application.Abstractions;
|
using Managing.Application.Abstractions;
|
||||||
using Managing.Application.ManageBot.Commands;
|
using Managing.Application.ManageBot.Commands;
|
||||||
using Managing.Core;
|
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
|
||||||
namespace Managing.Application.ManageBot
|
namespace Managing.Application.ManageBot
|
||||||
{
|
{
|
||||||
public class GetActiveBotsCommandHandler : IRequestHandler<GetActiveBotsCommand, List<ITradingBot>>
|
public class GetActiveBotsCommandHandler(IBotService botService)
|
||||||
|
: IRequestHandler<GetActiveBotsCommand, List<ITradingBot>>
|
||||||
{
|
{
|
||||||
private readonly ITaskCache taskCache;
|
|
||||||
|
|
||||||
public GetActiveBotsCommandHandler(ITaskCache taskCache)
|
|
||||||
{
|
|
||||||
this.taskCache = taskCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<ITradingBot>> Handle(GetActiveBotsCommand request, CancellationToken cancellationToken)
|
public Task<List<ITradingBot>> Handle(GetActiveBotsCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var cachedTask = taskCache.GetCache<AsyncLazy<ITradingBot>>();
|
return Task.FromResult(botService.GetActiveBots());
|
||||||
var result = new List<ITradingBot>();
|
|
||||||
|
|
||||||
foreach (var item in cachedTask)
|
|
||||||
{
|
|
||||||
result.Add(item.Value.Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.FromResult(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,30 +11,21 @@ namespace Managing.Application.ManageBot;
|
|||||||
|
|
||||||
public class LoadBackupBotCommandHandler : IRequestHandler<LoadBackupBotCommand, string>
|
public class LoadBackupBotCommandHandler : IRequestHandler<LoadBackupBotCommand, string>
|
||||||
{
|
{
|
||||||
private readonly IBotFactory _botFactory;
|
private readonly IBotService _botService;
|
||||||
private readonly ITaskCache _taskCache;
|
|
||||||
private readonly IMoneyManagementService _moneyManagementService;
|
|
||||||
private readonly IBotRepository _botRepository;
|
|
||||||
private readonly ILogger<LoadBackupBotCommandHandler> _logger;
|
private readonly ILogger<LoadBackupBotCommandHandler> _logger;
|
||||||
|
|
||||||
public LoadBackupBotCommandHandler(
|
public LoadBackupBotCommandHandler(
|
||||||
IBotFactory botFactory,
|
ILogger<LoadBackupBotCommandHandler> logger, IBotService botService)
|
||||||
ITaskCache taskCache,
|
|
||||||
IMoneyManagementService moneyManagementService,
|
|
||||||
IBotRepository botRepository,
|
|
||||||
ILogger<LoadBackupBotCommandHandler> logger)
|
|
||||||
{
|
{
|
||||||
_botFactory = botFactory;
|
|
||||||
_taskCache = taskCache;
|
|
||||||
_moneyManagementService = moneyManagementService;
|
|
||||||
_botRepository = botRepository;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_botService = botService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<string> Handle(LoadBackupBotCommand request, CancellationToken cancellationToken)
|
public Task<string> Handle(LoadBackupBotCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
BotStatus botStatus = BotStatus.Down;
|
BotStatus botStatus = BotStatus.Down;
|
||||||
var backupBots = _botRepository.GetBots();
|
var backupBots = _botService.GetSavedBots();
|
||||||
|
var activeBots = _botService.GetActiveBots();
|
||||||
var result = new Dictionary<string, BotStatus>();
|
var result = new Dictionary<string, BotStatus>();
|
||||||
|
|
||||||
_logger.LogInformation($"Loading {backupBots.Count()} backup bots");
|
_logger.LogInformation($"Loading {backupBots.Count()} backup bots");
|
||||||
@@ -47,12 +38,11 @@ public class LoadBackupBotCommandHandler : IRequestHandler<LoadBackupBotCommand,
|
|||||||
switch (backupBot.BotType)
|
switch (backupBot.BotType)
|
||||||
{
|
{
|
||||||
case BotType.SimpleBot:
|
case BotType.SimpleBot:
|
||||||
var simpleBot = _taskCache.Get<IBot>(backupBot.Name);
|
var simpleBot = activeBots.FirstOrDefault(b => b.GetName() == backupBot.Name);
|
||||||
if (simpleBot == null)
|
if (simpleBot == null)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Starting backup bot {backupBot.Name}");
|
_logger.LogInformation($"Starting backup bot {backupBot.Name}");
|
||||||
StartBot(backupBot);
|
_botService.StartBot(backupBot);
|
||||||
simpleBot.LoadBackup(backupBot);
|
|
||||||
result.Add(simpleBot.GetName(), BotStatus.Backup);
|
result.Add(simpleBot.GetName(), BotStatus.Backup);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -63,19 +53,18 @@ public class LoadBackupBotCommandHandler : IRequestHandler<LoadBackupBotCommand,
|
|||||||
break;
|
break;
|
||||||
case BotType.ScalpingBot:
|
case BotType.ScalpingBot:
|
||||||
case BotType.FlippingBot:
|
case BotType.FlippingBot:
|
||||||
var scalpingBot = _taskCache.Get<ITradingBot>(backupBot.Name);
|
var scalpingBot = activeBots.FirstOrDefault(b => b.GetName() == backupBot.Name);
|
||||||
if (scalpingBot == null)
|
if (scalpingBot == null)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Starting backup bot {backupBot.Name}");
|
_logger.LogInformation($"Starting backup bot {backupBot.Name}");
|
||||||
StartBot(backupBot);
|
_botService.StartBot(backupBot);
|
||||||
scalpingBot = _taskCache.Get<ITradingBot>(backupBot.Name);
|
|
||||||
scalpingBot.LoadBackup(backupBot);
|
|
||||||
result.Add(scalpingBot.GetName(), BotStatus.Backup);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.Add(scalpingBot.GetName(), MiscExtensions.ParseEnum<BotStatus>(scalpingBot.GetStatus()));
|
result.Add(scalpingBot.GetName(),
|
||||||
|
MiscExtensions.ParseEnum<BotStatus>(scalpingBot.GetStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result.Add(backupBot.Name, BotStatus.Down);
|
result.Add(backupBot.Name, BotStatus.Down);
|
||||||
@@ -91,47 +80,6 @@ public class LoadBackupBotCommandHandler : IRequestHandler<LoadBackupBotCommand,
|
|||||||
|
|
||||||
return Task.FromResult(botStatus.ToString());
|
return Task.FromResult(botStatus.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartBot(BotBackup backupBot)
|
|
||||||
{
|
|
||||||
switch (backupBot.BotType)
|
|
||||||
{
|
|
||||||
case BotType.SimpleBot:
|
|
||||||
Func<Task<IBot>> 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<TradingBotBackup>(backupBot.Data);
|
|
||||||
Func<Task<ITradingBot>> 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<TradingBotBackup>(backupBot.Data);
|
|
||||||
Func<Task<ITradingBot>> 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<string>
|
public class LoadBackupBotCommand : IRequest<string>
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ namespace Managing.Application.ManageBot
|
|||||||
public class StartBotCommandHandler : IRequestHandler<StartBotCommand, string>
|
public class StartBotCommandHandler : IRequestHandler<StartBotCommand, string>
|
||||||
{
|
{
|
||||||
private readonly IBotFactory _botFactory;
|
private readonly IBotFactory _botFactory;
|
||||||
private readonly ITaskCache _taskCache;
|
private readonly IBotService _botService;
|
||||||
private readonly IMoneyManagementService _moneyManagementService;
|
private readonly IMoneyManagementService _moneyManagementService;
|
||||||
|
|
||||||
public StartBotCommandHandler(IBotFactory botFactory, ITaskCache taskCache, IMoneyManagementService moneyManagementService)
|
public StartBotCommandHandler(IBotFactory botFactory, IBotService botService,
|
||||||
|
IMoneyManagementService moneyManagementService)
|
||||||
{
|
{
|
||||||
_botFactory = botFactory;
|
_botFactory = botFactory;
|
||||||
_taskCache = taskCache;
|
_botService = botService;
|
||||||
_moneyManagementService = moneyManagementService;
|
_moneyManagementService = moneyManagementService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,19 +29,23 @@ namespace Managing.Application.ManageBot
|
|||||||
case BotType.SimpleBot:
|
case BotType.SimpleBot:
|
||||||
var bot = _botFactory.CreateSimpleBot(request.Name, null);
|
var bot = _botFactory.CreateSimpleBot(request.Name, null);
|
||||||
bot.Start();
|
bot.Start();
|
||||||
Func<Task<IBot>> simpleBot = () => Task.FromResult(bot);
|
_botService.AddSimpleBotToCache(bot);
|
||||||
return Task.FromResult(_taskCache.AddOrGetExisting(request.Name, simpleBot).Result.GetStatus());
|
return Task.FromResult(bot.GetStatus());
|
||||||
case BotType.ScalpingBot:
|
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();
|
sBot.Start();
|
||||||
Func<Task<ITradingBot>> scalpingBot = () => Task.FromResult(sBot);
|
_botService.AddTradingBotToCache(sBot);
|
||||||
return Task.FromResult(_taskCache.AddOrGetExisting(request.Name, scalpingBot).Result.GetStatus());
|
return Task.FromResult(sBot.GetStatus());
|
||||||
case BotType.FlippingBot:
|
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();
|
fBot.Start();
|
||||||
Func<Task<ITradingBot>> flippingBot = () => Task.FromResult(fBot);
|
_botService.AddTradingBotToCache(fBot);
|
||||||
return Task.FromResult(_taskCache.AddOrGetExisting(request.Name, flippingBot).Result.GetStatus());
|
return Task.FromResult(fBot.GetStatus());
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
return Task.FromResult(botStatus.ToString());
|
return Task.FromResult(botStatus.ToString());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user