Add min and max balance filters to bot management
- Introduced optional parameters for minimum and maximum BotTradingBalance in BotController, DataController, and related services. - Updated interfaces and repository methods to support filtering by BotTradingBalance. - Enhanced TradingBotResponse and BotEntity models to include BotTradingBalance property. - Adjusted database schema to accommodate new BotTradingBalance field. - Ensured proper mapping and handling of BotTradingBalance in PostgreSQL repository and mappers.
This commit is contained in:
@@ -441,6 +441,8 @@ public class BotController : BaseController
|
||||
string? name = null,
|
||||
string? ticker = null,
|
||||
string? agentName = null,
|
||||
decimal? minBalance = null,
|
||||
decimal? maxBalance = null,
|
||||
BotSortableColumn sortBy = BotSortableColumn.CreateDate,
|
||||
SortDirection sortDirection = SortDirection.Desc)
|
||||
{
|
||||
@@ -468,6 +470,8 @@ public class BotController : BaseController
|
||||
name,
|
||||
ticker,
|
||||
agentName,
|
||||
minBalance,
|
||||
maxBalance,
|
||||
sortBy,
|
||||
sortDirection,
|
||||
showOnlyProfitable);
|
||||
@@ -545,6 +549,7 @@ public class BotController : BaseController
|
||||
Name = item.Name,
|
||||
Ticker = item.Ticker,
|
||||
TradingType = item.TradingType,
|
||||
BotTradingBalance = item.BotTradingBalance,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -908,6 +908,8 @@ public class DataController : ControllerBase
|
||||
/// <param name="name">Filter by name (partial match, case-insensitive)</param>
|
||||
/// <param name="ticker">Filter by ticker (partial match, case-insensitive)</param>
|
||||
/// <param name="agentName">Filter by agent name (partial match, case-insensitive)</param>
|
||||
/// <param name="minBalance">Filter by minimum BotTradingBalance (optional)</param>
|
||||
/// <param name="maxBalance">Filter by maximum BotTradingBalance (optional)</param>
|
||||
/// <param name="sortBy">Sort field (defaults to CreateDate)</param>
|
||||
/// <param name="sortDirection">Sort direction - Asc or Desc (defaults to Desc)</param>
|
||||
/// <returns>A paginated list of strategies excluding Saved status bots</returns>
|
||||
@@ -918,6 +920,8 @@ public class DataController : ControllerBase
|
||||
string? name = null,
|
||||
string? ticker = null,
|
||||
string? agentName = null,
|
||||
decimal? minBalance = null,
|
||||
decimal? maxBalance = null,
|
||||
BotSortableColumn sortBy = BotSortableColumn.CreateDate,
|
||||
SortDirection sortDirection = SortDirection.Desc)
|
||||
{
|
||||
@@ -946,6 +950,8 @@ public class DataController : ControllerBase
|
||||
name,
|
||||
ticker,
|
||||
agentName,
|
||||
minBalance,
|
||||
maxBalance,
|
||||
sortBy,
|
||||
sortDirection,
|
||||
showOnlyProfitable);
|
||||
@@ -1031,6 +1037,7 @@ public class DataController : ControllerBase
|
||||
Ticker = item.Ticker,
|
||||
TradingType = item.TradingType,
|
||||
MasterAgentName = item.MasterBotUser?.AgentName,
|
||||
BotTradingBalance = item.BotTradingBalance,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -92,5 +92,11 @@ namespace Managing.Api.Models.Responses
|
||||
/// The agent name of the master bot's owner (for copy trading bots)
|
||||
/// </summary>
|
||||
public string MasterAgentName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The trading balance configured for this bot
|
||||
/// </summary>
|
||||
[Required]
|
||||
public decimal BotTradingBalance { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:15000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"DOTNET_ENVIRONMENT": "Development",
|
||||
"DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL": "http://localhost:19000",
|
||||
"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,8 @@ public interface IBotRepository
|
||||
/// <param name="name">Filter by name (partial match, case-insensitive)</param>
|
||||
/// <param name="ticker">Filter by ticker (partial match, case-insensitive)</param>
|
||||
/// <param name="agentName">Filter by agent name (partial match, case-insensitive)</param>
|
||||
/// <param name="minBalance">Filter by minimum BotTradingBalance (optional)</param>
|
||||
/// <param name="maxBalance">Filter by maximum BotTradingBalance (optional)</param>
|
||||
/// <param name="sortBy">Sort field</param>
|
||||
/// <param name="sortDirection">Sort direction ("Asc" or "Desc")</param>
|
||||
/// <param name="showOnlyProfitable">Whether to show only profitable bots (ROI > 0)</param>
|
||||
@@ -36,6 +38,8 @@ public interface IBotRepository
|
||||
string? name = null,
|
||||
string? ticker = null,
|
||||
string? agentName = null,
|
||||
decimal? minBalance = null,
|
||||
decimal? maxBalance = null,
|
||||
BotSortableColumn sortBy = BotSortableColumn.CreateDate,
|
||||
SortDirection sortDirection = SortDirection.Desc,
|
||||
bool showOnlyProfitable = false);
|
||||
|
||||
@@ -46,6 +46,8 @@ public interface IBotService
|
||||
/// <param name="name">Filter by name (partial match, case-insensitive)</param>
|
||||
/// <param name="ticker">Filter by ticker (partial match, case-insensitive)</param>
|
||||
/// <param name="agentName">Filter by agent name (partial match, case-insensitive)</param>
|
||||
/// <param name="minBalance">Filter by minimum BotTradingBalance (optional)</param>
|
||||
/// <param name="maxBalance">Filter by maximum BotTradingBalance (optional)</param>
|
||||
/// <param name="sortBy">Sort field</param>
|
||||
/// <param name="sortDirection">Sort direction</param>
|
||||
/// <param name="showOnlyProfitable">Whether to show only profitable bots (ROI > 0)</param>
|
||||
@@ -57,6 +59,8 @@ public interface IBotService
|
||||
string? name = null,
|
||||
string? ticker = null,
|
||||
string? agentName = null,
|
||||
decimal? minBalance = null,
|
||||
decimal? maxBalance = null,
|
||||
BotSortableColumn sortBy = BotSortableColumn.CreateDate,
|
||||
SortDirection sortDirection = SortDirection.Desc,
|
||||
bool showOnlyProfitable = false);
|
||||
|
||||
@@ -1062,6 +1062,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
Roi = 0,
|
||||
Volume = 0,
|
||||
Fees = 0,
|
||||
BotTradingBalance = _state.State.Config.BotTradingBalance,
|
||||
MasterBotUserId = _state.State.Config.MasterBotUserId
|
||||
};
|
||||
}
|
||||
@@ -1127,6 +1128,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
Fees = agentMetrics.TotalFees,
|
||||
LongPositionCount = longPositionCount,
|
||||
ShortPositionCount = shortPositionCount,
|
||||
BotTradingBalance = _state.State.Config.BotTradingBalance,
|
||||
MasterBotUserId = _state.State.Config.MasterBotUserId
|
||||
};
|
||||
}
|
||||
|
||||
@@ -375,7 +375,8 @@ namespace Managing.Application.ManageBot
|
||||
|| existingBot.LastStartTime != bot.LastStartTime
|
||||
|| existingBot.LastStopTime != bot.LastStopTime
|
||||
|| existingBot.Ticker != bot.Ticker
|
||||
|| existingBot.TradingType != bot.TradingType)
|
||||
|| existingBot.TradingType != bot.TradingType
|
||||
|| existingBot.BotTradingBalance != Math.Round(bot.BotTradingBalance, 8))
|
||||
{
|
||||
_tradingBotLogger.LogInformation("Update bot statistics for bot {BotId}",
|
||||
bot.Identifier);
|
||||
@@ -486,6 +487,8 @@ namespace Managing.Application.ManageBot
|
||||
string? name = null,
|
||||
string? ticker = null,
|
||||
string? agentName = null,
|
||||
decimal? minBalance = null,
|
||||
decimal? maxBalance = null,
|
||||
BotSortableColumn sortBy = BotSortableColumn.CreateDate,
|
||||
SortDirection sortDirection = SortDirection.Desc,
|
||||
bool showOnlyProfitable = false)
|
||||
@@ -501,6 +504,8 @@ namespace Managing.Application.ManageBot
|
||||
name,
|
||||
ticker,
|
||||
agentName,
|
||||
minBalance,
|
||||
maxBalance,
|
||||
sortBy,
|
||||
sortDirection,
|
||||
showOnlyProfitable);
|
||||
|
||||
@@ -98,7 +98,8 @@ public static class Enums
|
||||
Roi,
|
||||
Pnl,
|
||||
WinRate,
|
||||
AgentName
|
||||
AgentName,
|
||||
BotTradingBalance
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace Managing.Domain.Bots
|
||||
public decimal Fees { get; set; }
|
||||
public int LongPositionCount { get; set; }
|
||||
public int ShortPositionCount { get; set; }
|
||||
|
||||
public decimal BotTradingBalance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user ID of the master bot's owner when this bot is for copy trading
|
||||
|
||||
1791
src/Managing.Infrastructure.Database/Migrations/20260101142151_AddBotTradingBalanceToBots.Designer.cs
generated
Normal file
1791
src/Managing.Infrastructure.Database/Migrations/20260101142151_AddBotTradingBalanceToBots.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Managing.Infrastructure.Databases.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddBotTradingBalanceToBots : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "BotTradingBalance",
|
||||
table: "Bots",
|
||||
type: "numeric",
|
||||
nullable: false,
|
||||
defaultValue: 0m);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "BotTradingBalance",
|
||||
table: "Bots");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,6 +305,9 @@ namespace Managing.Infrastructure.Databases.Migrations
|
||||
b.Property<long>("AccumulatedRunTimeSeconds")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<decimal>("BotTradingBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("CreateDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ public class BotEntity
|
||||
public decimal Fees { get; set; }
|
||||
public int LongPositionCount { get; set; }
|
||||
public int ShortPositionCount { get; set; }
|
||||
|
||||
public decimal BotTradingBalance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user ID of the master bot's owner when this bot is for copy trading
|
||||
|
||||
@@ -205,6 +205,8 @@ public class PostgreSqlBotRepository : IBotRepository
|
||||
string? name = null,
|
||||
string? ticker = null,
|
||||
string? agentName = null,
|
||||
decimal? minBalance = null,
|
||||
decimal? maxBalance = null,
|
||||
BotSortableColumn sortBy = BotSortableColumn.CreateDate,
|
||||
SortDirection sortDirection = SortDirection.Desc,
|
||||
bool showOnlyProfitable = false)
|
||||
@@ -237,6 +239,17 @@ public class PostgreSqlBotRepository : IBotRepository
|
||||
query = query.Where(b => b.User != null && EF.Functions.ILike(b.User.AgentName, $"%{agentName}%"));
|
||||
}
|
||||
|
||||
// Apply balance filtering if specified
|
||||
if (minBalance.HasValue)
|
||||
{
|
||||
query = query.Where(b => b.BotTradingBalance >= minBalance.Value);
|
||||
}
|
||||
|
||||
if (maxBalance.HasValue)
|
||||
{
|
||||
query = query.Where(b => b.BotTradingBalance <= maxBalance.Value);
|
||||
}
|
||||
|
||||
// Apply profitable bots filtering if specified
|
||||
if (showOnlyProfitable)
|
||||
{
|
||||
@@ -275,6 +288,9 @@ public class PostgreSqlBotRepository : IBotRepository
|
||||
BotSortableColumn.AgentName => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.User.AgentName)
|
||||
: query.OrderByDescending(b => b.User.AgentName),
|
||||
BotSortableColumn.BotTradingBalance => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.BotTradingBalance)
|
||||
: query.OrderByDescending(b => b.BotTradingBalance),
|
||||
_ => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.CreateDate)
|
||||
: query.OrderByDescending(b => b.CreateDate)
|
||||
|
||||
@@ -793,6 +793,7 @@ public static class PostgreSqlMappers
|
||||
Fees = entity.Fees,
|
||||
LongPositionCount = entity.LongPositionCount,
|
||||
ShortPositionCount = entity.ShortPositionCount,
|
||||
BotTradingBalance = entity.BotTradingBalance,
|
||||
MasterBotUserId = entity.MasterBotUserId,
|
||||
MasterBotUser = entity.MasterBotUser != null ? Map(entity.MasterBotUser) : null
|
||||
};
|
||||
@@ -826,6 +827,7 @@ public static class PostgreSqlMappers
|
||||
Fees = bot.Fees,
|
||||
LongPositionCount = bot.LongPositionCount,
|
||||
ShortPositionCount = bot.ShortPositionCount,
|
||||
BotTradingBalance = bot.BotTradingBalance,
|
||||
MasterBotUserId = bot.MasterBotUserId,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user