Trading bot grain (#33)
* Trading bot Grain * Fix a bit more of the trading bot * Advance on the tradingbot grain * Fix build * Fix db script * Fix user login * Fix a bit backtest * Fix cooldown and backtest * start fixing bot start * Fix startup * Setup local db * Fix build and update candles and scenario * Add bot registry * Add reminder * Updateing the grains * fix bootstraping * Save stats on tick * Save bot data every tick * Fix serialization * fix save bot stats * Fix get candles * use dict instead of list for position * Switch hashset to dict * Fix a bit * Fix bot launch and bot view * add migrations * Remove the tolist * Add agent grain * Save agent summary * clean * Add save bot * Update get bots * Add get bots * Fix stop/restart * fix Update config * Update scanner table on new backtest saved * Fix backtestRowDetails.tsx * Fix agentIndex * Update agentIndex * Fix more things * Update user cache * Fix * Fix account load/start/restart/run
This commit is contained in:
@@ -1,42 +1,38 @@
|
||||
using Managing.Application.Abstractions;
|
||||
using Managing.Application.Abstractions.Grains;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.ManageBot.Commands;
|
||||
using Managing.Common;
|
||||
using Managing.Domain.Bots;
|
||||
using MediatR;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Application.ManageBot
|
||||
{
|
||||
public class StartBotCommandHandler : IRequestHandler<StartBotCommand, string>
|
||||
public class StartBotCommandHandler : IRequestHandler<StartBotCommand, BotStatus>
|
||||
{
|
||||
private readonly IBotFactory _botFactory;
|
||||
private readonly IBotService _botService;
|
||||
private readonly IMoneyManagementService _moneyManagementService;
|
||||
private readonly IExchangeService _exchangeService;
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly IGrainFactory _grainFactory;
|
||||
|
||||
public StartBotCommandHandler(IBotFactory botFactory, IBotService botService,
|
||||
IMoneyManagementService moneyManagementService, IExchangeService exchangeService,
|
||||
IAccountService accountService)
|
||||
public StartBotCommandHandler(
|
||||
IAccountService accountService, IGrainFactory grainFactory)
|
||||
{
|
||||
_botFactory = botFactory;
|
||||
_botService = botService;
|
||||
_moneyManagementService = moneyManagementService;
|
||||
_exchangeService = exchangeService;
|
||||
_accountService = accountService;
|
||||
_grainFactory = grainFactory;
|
||||
}
|
||||
|
||||
public async Task<string> Handle(StartBotCommand request, CancellationToken cancellationToken)
|
||||
public async Task<BotStatus> Handle(StartBotCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
BotStatus botStatus = BotStatus.Down;
|
||||
|
||||
// Validate the configuration
|
||||
if (request.Config == null)
|
||||
{
|
||||
throw new ArgumentException("Bot configuration is required");
|
||||
}
|
||||
|
||||
if (request.Config.Scenario == null || !request.Config.Scenario.Indicators.Any())
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Scenario or indicators not loaded properly in constructor. This indicates a configuration error.");
|
||||
}
|
||||
|
||||
if (request.Config.BotTradingBalance <= Constants.GMX.Config.MinimumPositionAmount)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
@@ -59,68 +55,23 @@ namespace Managing.Application.ManageBot
|
||||
throw new Exception($"Account {request.Config.AccountName} has no USDC balance or not enough balance");
|
||||
}
|
||||
|
||||
// Ensure essential configuration values are properly set
|
||||
var configToUse = new TradingBotConfig
|
||||
{
|
||||
AccountName = request.Config.AccountName,
|
||||
MoneyManagement = request.Config.MoneyManagement,
|
||||
Ticker = request.Config.Ticker,
|
||||
ScenarioName = request.Config.ScenarioName,
|
||||
Scenario = request.Config.Scenario,
|
||||
Timeframe = request.Config.Timeframe,
|
||||
IsForWatchingOnly = request.Config.IsForWatchingOnly,
|
||||
BotTradingBalance = request.Config.BotTradingBalance,
|
||||
IsForBacktest = request.Config.IsForBacktest,
|
||||
CooldownPeriod =
|
||||
request.Config.CooldownPeriod > 0 ? request.Config.CooldownPeriod : 1, // Default to 1 if not set
|
||||
MaxLossStreak = request.Config.MaxLossStreak,
|
||||
MaxPositionTimeHours = request.Config.MaxPositionTimeHours, // Properly handle nullable value
|
||||
FlipOnlyWhenInProfit = request.Config.FlipOnlyWhenInProfit,
|
||||
FlipPosition = request.Config.FlipPosition, // Set FlipPosition
|
||||
Name = request.Config.Name ?? request.Name,
|
||||
CloseEarlyWhenProfitable = request.Config.CloseEarlyWhenProfitable
|
||||
};
|
||||
|
||||
var tradingBot = await _botFactory.CreateTradingBot(configToUse);
|
||||
tradingBot.User = request.User;
|
||||
|
||||
// Log the configuration being used
|
||||
LogBotConfigurationAsync(tradingBot, $"{configToUse.Name} created");
|
||||
|
||||
_botService.AddTradingBotToCache(tradingBot);
|
||||
return tradingBot.GetStatus();
|
||||
|
||||
return botStatus.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the bot configuration for debugging and audit purposes
|
||||
/// </summary>
|
||||
/// <param name="bot">The trading bot instance</param>
|
||||
/// <param name="context">Context information for the log</param>
|
||||
private void LogBotConfigurationAsync(ITradingBot bot, string context)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = bot.GetConfiguration();
|
||||
var logMessage = $"{context} - Bot: {config.Name}, " +
|
||||
$"Account: {config.AccountName}, " +
|
||||
$"Ticker: {config.Ticker}, " +
|
||||
$"Balance: {config.BotTradingBalance}, " +
|
||||
$"MaxTime: {config.MaxPositionTimeHours?.ToString() ?? "Disabled"}, " +
|
||||
$"FlipOnlyProfit: {config.FlipOnlyWhenInProfit}, " +
|
||||
$"FlipPosition: {config.FlipPosition}, " +
|
||||
$"Cooldown: {config.CooldownPeriod}, " +
|
||||
$"MaxLoss: {config.MaxLossStreak}";
|
||||
|
||||
// Log through the bot's logger (this will use the bot's logging mechanism)
|
||||
// For now, we'll just add a comment that this could be enhanced with actual logging
|
||||
// Console.WriteLine(logMessage); // Could be replaced with proper logging
|
||||
var botGrain = _grainFactory.GetGrain<ILiveTradingBotGrain>(Guid.NewGuid());
|
||||
await botGrain.CreateAsync(request.Config, request.User);
|
||||
|
||||
// Only start the bot if createOnly is false
|
||||
if (!request.CreateOnly)
|
||||
{
|
||||
await botGrain.StartAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Ignore logging errors to not affect bot creation
|
||||
throw new Exception($"Failed to start bot: {ex.Message}, {ex.StackTrace}");
|
||||
}
|
||||
|
||||
return request.CreateOnly ? BotStatus.None : BotStatus.Up;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user