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

@@ -0,0 +1,55 @@
using static Managing.Common.Enums;
namespace Managing.Api.Models.Requests;
/// <summary>
/// Request model for getting paginated bots with filtering and sorting
/// </summary>
public class GetBotsPaginatedRequest
{
/// <summary>
/// Page number (1-based). Default is 1.
/// </summary>
public int PageNumber { get; set; } = 1;
/// <summary>
/// Number of items per page. Default is 10, maximum is 100.
/// </summary>
public int PageSize { get; set; } = 10;
/// <summary>
/// Filter by bot status. If null, returns bots of all statuses.
/// </summary>
public BotStatus? Status { get; set; }
/// <summary>
/// Filter by user ID. If null, returns bots for all users.
/// </summary>
public int? UserId { get; set; }
/// <summary>
/// Filter by bot name (partial match, case-insensitive). If null, no name filtering is applied.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Filter by ticker (partial match, case-insensitive). If null, no ticker filtering is applied.
/// </summary>
public string? Ticker { get; set; }
/// <summary>
/// Filter by agent name (partial match, case-insensitive). If null, no agent name filtering is applied.
/// </summary>
public string? AgentName { get; set; }
/// <summary>
/// Sort field. Valid values: "Name", "Ticker", "Status", "CreateDate", "StartupTime", "Pnl", "WinRate", "AgentName".
/// Default is "CreateDate".
/// </summary>
public string SortBy { get; set; } = "CreateDate";
/// <summary>
/// Sort direction. Default is "Desc" (descending).
/// </summary>
public string SortDirection { get; set; } = "Desc";
}

View File

@@ -13,7 +13,7 @@ public class UpdateBotConfigRequest
/// The unique identifier of the bot to update
/// </summary>
[Required]
public string Identifier { get; set; }
public Guid Identifier { get; set; }
/// <summary>
/// The new trading bot configuration request

View File

@@ -15,21 +15,11 @@ namespace Managing.Api.Models.Responses
/// </summary>
public decimal TotalPnL { get; set; }
/// <summary>
/// Profit and loss in the last 24 hours in USD
/// </summary>
public decimal PnLLast24h { get; set; }
/// <summary>
/// Total return on investment as a percentage
/// </summary>
public decimal TotalROI { get; set; }
/// <summary>
/// Return on investment in the last 24 hours as a percentage
/// </summary>
public decimal ROILast24h { get; set; }
/// <summary>
/// Number of winning trades
/// </summary>
@@ -40,10 +30,6 @@ namespace Managing.Api.Models.Responses
/// </summary>
public int Losses { get; set; }
/// <summary>
/// Average win rate as a percentage
/// </summary>
public int AverageWinRate { get; set; }
/// <summary>
/// Number of active strategies for this agent
@@ -54,11 +40,6 @@ namespace Managing.Api.Models.Responses
/// Total volume traded by this agent in USD
/// </summary>
public decimal TotalVolume { get; set; }
/// <summary>
/// Volume traded in the last 24 hours in USD
/// </summary>
public decimal VolumeLast24h { get; set; }
}
/// <summary>

View File

@@ -12,10 +12,11 @@ public class CandlesWithIndicatorsResponse
/// <summary>
/// The list of candles.
/// </summary>
public List<Candle> Candles { get; set; } = new List<Candle>();
public HashSet<Candle> Candles { get; set; } = new HashSet<Candle>();
/// <summary>
/// The calculated indicators values.
/// </summary>
public Dictionary<IndicatorType, IndicatorsResultBase> IndicatorsValues { get; set; } = new Dictionary<IndicatorType, IndicatorsResultBase>();
}
public Dictionary<IndicatorType, IndicatorsResultBase> IndicatorsValues { get; set; } =
new Dictionary<IndicatorType, IndicatorsResultBase>();
}

View File

@@ -1,3 +1,5 @@
using static Managing.Common.Enums;
namespace Managing.Api.Models.Responses;
/// <summary>
@@ -48,7 +50,7 @@ public class PaginatedAgentIndexResponse
/// <summary>
/// Field used for sorting
/// </summary>
public string SortBy { get; set; } = "TotalPnL";
public SortableFields SortBy { get; set; } = SortableFields.TotalPnL;
/// <summary>
/// Sort order (asc or desc)

View File

@@ -0,0 +1,43 @@
namespace Managing.Api.Models.Responses;
/// <summary>
/// Generic pagination response model
/// </summary>
/// <typeparam name="T">The type of items in the response</typeparam>
public class PaginatedResponse<T>
{
/// <summary>
/// The items for the current page
/// </summary>
public List<T> Items { get; set; } = new();
/// <summary>
/// Total number of items across all pages
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// Current page number (1-based)
/// </summary>
public int PageNumber { get; set; }
/// <summary>
/// Number of items per page
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// Total number of pages
/// </summary>
public int TotalPages { get; set; }
/// <summary>
/// Whether there is a previous page
/// </summary>
public bool HasPreviousPage { get; set; }
/// <summary>
/// Whether there is a next page
/// </summary>
public bool HasNextPage { get; set; }
}

View File

@@ -1,7 +1,8 @@
using System.ComponentModel.DataAnnotations;
using Managing.Domain.Bots;
using Managing.Domain.Candles;
using Managing.Domain.Indicators;
using Managing.Domain.Trades;
using static Managing.Common.Enums;
namespace Managing.Api.Models.Responses
{
@@ -14,16 +15,16 @@ namespace Managing.Api.Models.Responses
public string Status { get; internal set; }
/// <summary>
/// List of signals generated by the bot
/// Dictionary of signals generated by the bot, keyed by signal identifier
/// </summary>
[Required]
public List<LightSignal> Signals { get; internal set; }
public Dictionary<string, LightSignal> Signals { get; internal set; }
/// <summary>
/// List of positions opened by the bot
/// Dictionary of positions opened by the bot, keyed by position identifier
/// </summary>
[Required]
public List<Position> Positions { get; internal set; }
public Dictionary<Guid, Position> Positions { get; internal set; }
/// <summary>
/// Candles used by the bot for analysis
@@ -55,12 +56,6 @@ namespace Managing.Api.Models.Responses
[Required]
public string AgentName { get; set; }
/// <summary>
/// The full trading bot configuration
/// </summary>
[Required]
public TradingBotConfig Config { get; internal set; }
/// <summary>
/// The time when the bot was created
/// </summary>
@@ -72,5 +67,13 @@ namespace Managing.Api.Models.Responses
/// </summary>
[Required]
public DateTime StartupTime { get; internal set; }
[Required] public string Name { get; set; }
/// <summary>
/// The ticker/symbol being traded by this bot
/// </summary>
[Required]
public Ticker Ticker { get; set; }
}
}

View File

@@ -63,16 +63,12 @@ namespace Managing.Api.Models.Responses
public int Losses { get; set; }
/// <summary>
/// List of all positions executed by this strategy
/// Dictionary of all positions executed by this strategy, keyed by position identifier
/// </summary>
public List<Position> Positions { get; set; } = new List<Position>();
public Dictionary<Guid, Position> Positions { get; set; } = new Dictionary<Guid, Position>();
public string Identifier { get; set; }
/// <summary>
/// Name of the scenario used by this strategy
/// </summary>
public string ScenarioName { get; set; }
public Dictionary<DateTime, decimal> WalletBalances { get; set; }
public Dictionary<DateTime, decimal> WalletBalances { get; set; } = new Dictionary<DateTime, decimal>();
}
}