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:
Oda
2025-08-04 23:07:06 +02:00
committed by GitHub
parent cd378587aa
commit 082ae8714b
215 changed files with 9562 additions and 14028 deletions

View File

@@ -4,10 +4,10 @@ namespace Managing.Application.ManageBot.Commands;
public class DeleteBotCommand : IRequest<bool>
{
public string Name { get; }
public Guid Identifier { get; }
public DeleteBotCommand(string name)
public DeleteBotCommand(Guid identifier)
{
Name = name;
Identifier = identifier;
}
}

View File

@@ -1,12 +1,16 @@
using Managing.Application.Abstractions;
using Managing.Domain.Bots;
using MediatR;
using static Managing.Common.Enums;
namespace Managing.Application.ManageBot.Commands
{
public class GetActiveBotsCommand : IRequest<List<ITradingBot>>
public class GetBotsByStatusCommand : IRequest<IEnumerable<Bot>>
{
public GetActiveBotsCommand()
public BotStatus Status { get; }
public GetBotsByStatusCommand(BotStatus status)
{
Status = status;
}
}
}

View File

@@ -0,0 +1,21 @@
using Managing.Domain.Statistics;
using MediatR;
namespace Managing.Application.ManageBot.Commands
{
/// <summary>
/// Command to retrieve all agent summaries with complete data
/// </summary>
public class GetAllAgentSummariesCommand : IRequest<IEnumerable<AgentSummary>>
{
/// <summary>
/// Optional time filter to apply (24H, 3D, 1W, 1M, 1Y, Total)
/// </summary>
public string TimeFilter { get; }
public GetAllAgentSummariesCommand(string timeFilter = "Total")
{
TimeFilter = timeFilter;
}
}
}

View File

@@ -1,4 +1,4 @@
using Managing.Application.Abstractions;
using Managing.Domain.Bots;
using Managing.Domain.Users;
using MediatR;
@@ -7,7 +7,7 @@ namespace Managing.Application.ManageBot.Commands
/// <summary>
/// Command to retrieve all active agents and their strategies
/// </summary>
public class GetAllAgentsCommand : IRequest<Dictionary<User, List<ITradingBot>>>
public class GetAllAgentsCommand : IRequest<Dictionary<User, List<Bot>>>
{
/// <summary>
/// Optional time filter to apply (24H, 3D, 1W, 1M, 1Y, Total)

View File

@@ -0,0 +1,18 @@
using Managing.Domain.Bots;
using MediatR;
using static Managing.Common.Enums;
namespace Managing.Application.ManageBot.Commands
{
public class GetBotsByUserAndStatusCommand : IRequest<IEnumerable<Bot>>
{
public int UserId { get; }
public BotStatus Status { get; }
public GetBotsByUserAndStatusCommand(int userId, BotStatus status)
{
UserId = userId;
Status = status;
}
}
}

View File

@@ -0,0 +1,51 @@
using Managing.Domain.Statistics;
using MediatR;
using static Managing.Common.Enums;
namespace Managing.Application.ManageBot.Commands
{
/// <summary>
/// Command to retrieve paginated agent summaries with sorting and filtering
/// </summary>
public class GetPaginatedAgentSummariesCommand : IRequest<(IEnumerable<AgentSummary> Results, int TotalCount)>
{
/// <summary>
/// Page number (1-based)
/// </summary>
public int Page { get; }
/// <summary>
/// Number of items per page
/// </summary>
public int PageSize { get; }
/// <summary>
/// Field to sort by
/// </summary>
public SortableFields SortBy { get; }
/// <summary>
/// Sort order (asc or desc)
/// </summary>
public string SortOrder { get; }
/// <summary>
/// Optional list of agent names to filter by
/// </summary>
public IEnumerable<string>? AgentNames { get; }
public GetPaginatedAgentSummariesCommand(
int page = 1,
int pageSize = 10,
SortableFields sortBy = SortableFields.TotalPnL,
string sortOrder = "desc",
IEnumerable<string>? agentNames = null)
{
Page = page;
PageSize = pageSize;
SortBy = sortBy;
SortOrder = sortOrder;
AgentNames = agentNames;
}
}
}

View File

@@ -1,4 +1,4 @@
using Managing.Application.Abstractions;
using Managing.Domain.Bots;
using MediatR;
namespace Managing.Application.ManageBot.Commands
@@ -6,13 +6,13 @@ namespace Managing.Application.ManageBot.Commands
/// <summary>
/// Command to retrieve all strategies owned by a specific user
/// </summary>
public class GetUserStrategiesCommand : IRequest<List<ITradingBot>>
public class GetUserStrategiesCommand : IRequest<List<Bot>>
{
public string UserName { get; }
public string AgentName { get; }
public GetUserStrategiesCommand(string userName)
public GetUserStrategiesCommand(string agentName)
{
UserName = userName;
AgentName = agentName;
}
}
}

View File

@@ -1,4 +1,4 @@
using Managing.Application.Abstractions;
using Managing.Domain.Bots;
using MediatR;
namespace Managing.Application.ManageBot.Commands
@@ -6,7 +6,7 @@ namespace Managing.Application.ManageBot.Commands
/// <summary>
/// Command to retrieve a specific strategy owned by a user
/// </summary>
public class GetUserStrategyCommand : IRequest<ITradingBot>
public class GetUserStrategyCommand : IRequest<Bot>
{
/// <summary>
/// The username of the agent/user that owns the strategy

View File

@@ -0,0 +1,16 @@
using Managing.Domain.Trades;
using MediatR;
namespace Managing.Application.ManageBot.Commands;
public class ManualPositionCommand : IRequest<Position>
{
public Guid PositionId { get; set; }
public Guid Identifier { get; set; }
public ManualPositionCommand(Guid identifier, Guid positionId)
{
Identifier = identifier;
PositionId = positionId;
}
}

View File

@@ -3,15 +3,13 @@ using static Managing.Common.Enums;
namespace Managing.Application.ManageBot.Commands
{
public class RestartBotCommand : IRequest<string>
public class RestartBotCommand : IRequest<BotStatus>
{
public string Name { get; }
public BotType BotType { get; }
public Guid Identifier { get; }
public RestartBotCommand(BotType botType, string name)
public RestartBotCommand(Guid identifier)
{
BotType = botType;
Name = name;
Identifier = identifier;
}
}
}

View File

@@ -1,20 +1,21 @@
using Managing.Domain.Bots;
using Managing.Domain.Users;
using MediatR;
using static Managing.Common.Enums;
namespace Managing.Application.ManageBot.Commands
{
public class StartBotCommand : IRequest<string>
public class StartBotCommand : IRequest<BotStatus>
{
public string Name { get; }
public TradingBotConfig Config { get; }
public User User { get; }
public User User { get; internal set; }
public bool CreateOnly { get; }
public StartBotCommand(TradingBotConfig config, string name, User user)
public StartBotCommand(TradingBotConfig config, User user, bool createOnly = false)
{
Config = config;
Name = name;
User = user;
CreateOnly = createOnly;
}
}
}

View File

@@ -1,12 +1,13 @@
using MediatR;
using static Managing.Common.Enums;
namespace Managing.Application.ManageBot.Commands
{
public class StopBotCommand : IRequest<string>
public class StopBotCommand : IRequest<BotStatus>
{
public string Identifier { get; }
public Guid Identifier { get; }
public StopBotCommand(string identifier)
public StopBotCommand(Guid identifier)
{
Identifier = identifier;
}

View File

@@ -1,14 +0,0 @@
using MediatR;
namespace Managing.Application.ManageBot.Commands
{
public class ToggleIsForWatchingCommand : IRequest<string>
{
public string Name { get; }
public ToggleIsForWatchingCommand(string name)
{
Name = name;
}
}
}

View File

@@ -6,12 +6,12 @@ namespace Managing.Application.ManageBot.Commands
/// <summary>
/// Command to update the configuration of a running trading bot
/// </summary>
public class UpdateBotConfigCommand : IRequest<string>
public class UpdateBotConfigCommand : IRequest<bool>
{
public string Identifier { get; }
public Guid Identifier { get; }
public TradingBotConfig NewConfig { get; }
public UpdateBotConfigCommand(string identifier, TradingBotConfig newConfig)
public UpdateBotConfigCommand(Guid identifier, TradingBotConfig newConfig)
{
Identifier = identifier;
NewConfig = newConfig;