230 lines
9.5 KiB
C#
230 lines
9.5 KiB
C#
using Discord;
|
|
using Discord.Commands;
|
|
using Managing.Application.Abstractions;
|
|
using Managing.Application.Abstractions.Services;
|
|
using Managing.Application.Trading.Commands;
|
|
using Managing.Common;
|
|
using Managing.Core;
|
|
using Managing.Domain.MoneyManagements;
|
|
using Managing.Domain.Trades;
|
|
using Managing.Domain.Users;
|
|
using static Managing.Common.Enums;
|
|
|
|
namespace Managing.Infrastructure.Messengers.Discord
|
|
{
|
|
public class DiscordCommands : ModuleBase
|
|
{
|
|
private readonly DiscordSettings _settings;
|
|
private readonly IBacktester _backtester;
|
|
private readonly string[] _separator = new[] { " " };
|
|
private readonly string _messagePrefix = "Bro, ";
|
|
private readonly ICommandHandler<OpenPositionRequest, Position> _openTradeCommandHandler;
|
|
|
|
public DiscordCommands(DiscordSettings settings,
|
|
IBacktester backtester,
|
|
ICommandHandler<OpenPositionRequest, Position> openTradeCommandHandler)
|
|
{
|
|
_settings = settings;
|
|
_backtester = backtester;
|
|
_openTradeCommandHandler = openTradeCommandHandler;
|
|
}
|
|
|
|
|
|
[Command("openposition")]
|
|
public async Task OpenPosition([Remainder] string rest)
|
|
{
|
|
Typing();
|
|
|
|
var parameters = rest.Split(_separator, StringSplitOptions.None);
|
|
|
|
var exchange = MiscExtensions.ParseEnum<TradingExchanges>(parameters[0]);
|
|
var ticker = parameters[1];
|
|
var direction = MiscExtensions.ParseEnum<TradeDirection>(parameters[2]);
|
|
var timeframe = MiscExtensions.ParseEnum<Timeframe>(parameters[3]);
|
|
var expirationDate = DateTime.Now.AddMinutes(_settings.ButtonExpirationMinutes).ToString("G");
|
|
|
|
var builder = new ComponentBuilder().WithButton("Open Position",
|
|
$"{Constants.DiscordButtonAction.OpenPosition}-{exchange}-{ticker}-{direction}-{timeframe}-{expirationDate}");
|
|
await Context.Channel.SendMessageAsync(
|
|
_messagePrefix + $"you can now click on this button to open a position on {ticker}"
|
|
, components: builder.Build());
|
|
}
|
|
|
|
[Command("open")]
|
|
public async Task Open([Remainder] string rest)
|
|
{
|
|
await Context.Channel.SendMessageAsync("Let met few seconds to open a position");
|
|
|
|
Typing();
|
|
try
|
|
{
|
|
var parameters = rest.Split(_separator, StringSplitOptions.None);
|
|
var accountName = parameters[0];
|
|
var ticker = MiscExtensions.ParseEnum<Ticker>(parameters[1]);
|
|
var direction = MiscExtensions.ParseEnum<TradeDirection>(parameters[2]);
|
|
var riskLevel = MiscExtensions.ParseEnum<RiskLevel>(parameters[3]);
|
|
var timeframe = MiscExtensions.ParseEnum<Timeframe>(parameters[4]);
|
|
decimal? stopLoss = parameters[5] != null ? Convert.ToDecimal(parameters[5]) : null;
|
|
decimal? takeProfit = parameters[6] != null ? Convert.ToDecimal(parameters[6]) : null;
|
|
|
|
var moneymanagement = new MoneyManagement
|
|
{
|
|
BalanceAtRisk = 5,
|
|
StopLoss = stopLoss.GetValueOrDefault(),
|
|
TakeProfit = takeProfit.GetValueOrDefault(),
|
|
};
|
|
var tradeCommand = new OpenPositionRequest(accountName, moneymanagement, direction, ticker,
|
|
PositionInitiator.User, DateTime.UtcNow, new User());
|
|
var result = await _openTradeCommandHandler.Handle(tradeCommand);
|
|
var builder = new ComponentBuilder().WithButton("Close Position",
|
|
$"{Constants.DiscordButtonAction.ClosePosition}|{result.Open.ExchangeOrderId}");
|
|
await Context.Channel.SendMessageAsync(MessengerHelpers.GetPositionMessage(result),
|
|
components: builder.Build());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await Context.Channel.SendMessageAsync($"Something weird happen bro, {ex.Message}");
|
|
}
|
|
}
|
|
|
|
[Command("bot")]
|
|
public async Task Bot([Remainder] string rest)
|
|
{
|
|
Typing();
|
|
|
|
if (string.Equals(rest, "enable", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
_settings.BotEnabled = true;
|
|
}
|
|
|
|
if (string.Equals(rest, "disable", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
_settings.BotEnabled = false;
|
|
}
|
|
|
|
await Context.Channel.SendMessageAsync("Bot is "
|
|
+ (_settings.BotEnabled ? "enabled" : "disabled"));
|
|
}
|
|
|
|
//[Command("backtest")]
|
|
//public async Task Backtest([Remainder] string rest)
|
|
//{
|
|
// Typing();
|
|
|
|
// var parameters = rest.Split(_separator, StringSplitOptions.None);
|
|
// var ticker = MiscExtensions.ParseEnum<Ticker>(parameters[0]);
|
|
// var exchange = MiscExtensions.ParseEnum<TradingExchanges>(parameters[1]);
|
|
// var timeframe = MiscExtensions.ParseEnum<Timeframe>(parameters[2]);
|
|
// var days = parameters[3];
|
|
// var scenario = new Scenario("ScalpingScenario");
|
|
// var strategy = ScenarioHelpers.BuildStrategy(StrategyType.RsiDivergence, timeframe, "RsiDiv", period: 14);
|
|
// scenario.AddStrategy(strategy);
|
|
// var account = new Account() { Exchange = exchange };
|
|
|
|
// var backtestResult = _backtester.RunScalpingBotBacktest(account, ticker, scenario, timeframe, Convert.ToDouble(days), 1000);
|
|
// await Context.Channel.SendMessageAsync(backtestResult.GetStringReport());
|
|
//}
|
|
|
|
[Command("run")]
|
|
public async Task Run([Remainder] string rest)
|
|
{
|
|
Typing();
|
|
var parameters = rest.Split(_separator, StringSplitOptions.None);
|
|
var botType = MiscExtensions.ParseEnum<BotType>(parameters[0]);
|
|
var accountName = MiscExtensions.ParseEnum<string>(parameters[1]);
|
|
var botName = parameters[2];
|
|
var ticker = MiscExtensions.ParseEnum<Ticker>(parameters[3]);
|
|
var timeframe = MiscExtensions.ParseEnum<Timeframe>(parameters[4]);
|
|
|
|
var message = _messagePrefix;
|
|
|
|
// TODO : Fix remove mediator
|
|
//var result = await _mediator.Send(new StartBotCommand(botType,
|
|
// botName,
|
|
// ticker,
|
|
// "scenario",
|
|
// timeframe,
|
|
// accountName,
|
|
// true));
|
|
|
|
var result = "down";
|
|
message += $"I tried to start the bot called {botName}, his status is now {result}. ";
|
|
|
|
if (result == "Up")
|
|
{
|
|
await Context.Message.AddReactionAsync(new Emoji("👌"));
|
|
message += $"this bot gonna watch {ticker} on {timeframe} timeframe.";
|
|
}
|
|
else
|
|
{
|
|
await Context.Message.AddReactionAsync(new Emoji("😒"));
|
|
message += $"something wrong happen, the bot status is down";
|
|
}
|
|
|
|
await Context.Channel.SendMessageAsync(message);
|
|
}
|
|
|
|
[Command("stop")]
|
|
public async Task Stop([Remainder] string rest)
|
|
{
|
|
Typing();
|
|
var parameters = rest.Split(_separator, StringSplitOptions.None);
|
|
var botType = MiscExtensions.ParseEnum<BotType>(parameters[0]);
|
|
var botName = parameters[1];
|
|
var result = "down";
|
|
//var result = await _mediator.Send(new StopBotCommand(botType, botName));
|
|
|
|
await Context.Channel.SendMessageAsync(_messagePrefix + $"the {botType} called {botName} is now {result}");
|
|
}
|
|
|
|
[Command("hi")]
|
|
public async Task Hi([Remainder] string rest)
|
|
{
|
|
Typing();
|
|
await Context.Channel.SendMessageAsync("I don't understand yet : " + rest);
|
|
}
|
|
|
|
[Command("help")]
|
|
public async Task Help([Remainder] string rest)
|
|
{
|
|
Typing();
|
|
|
|
var message = _messagePrefix;
|
|
switch (rest)
|
|
{
|
|
case "backtest":
|
|
message +=
|
|
"to run a backtest you should use this pattern : !trader backtest ticker exchange timeframe startFromDays";
|
|
break;
|
|
case "run":
|
|
message +=
|
|
"to run a bot you should use this pattern : !trader run botType botName ticker timeframe";
|
|
break;
|
|
case "stop":
|
|
message += "to stop a bot you should use this pattern : !trader stop botType botName";
|
|
break;
|
|
case "botType":
|
|
message += $"the bot type available are : {BotType.FlippingBot}, {BotType.ScalpingBot}";
|
|
break;
|
|
case "timeframe":
|
|
message += $"the bot can currently handle only those timeframes : " +
|
|
$"{Timeframe.FifteenMinutes}, {Timeframe.ThirtyMinutes}, {Timeframe.OneDay}";
|
|
break;
|
|
case "risklevel":
|
|
message += $"the bot can currently handle only those riskLevel : " +
|
|
$"{RiskLevel.High}";
|
|
break;
|
|
default:
|
|
message += "I don't no the command";
|
|
break;
|
|
}
|
|
|
|
await Context.Channel.SendMessageAsync(message);
|
|
}
|
|
|
|
private async void Typing()
|
|
{
|
|
await Context.Channel.TriggerTypingAsync();
|
|
}
|
|
}
|
|
} |