diff --git a/src/Managing.Api/Controllers/DataController.cs b/src/Managing.Api/Controllers/DataController.cs
index 7c2e42a2..5e3acfbb 100644
--- a/src/Managing.Api/Controllers/DataController.cs
+++ b/src/Managing.Api/Controllers/DataController.cs
@@ -391,7 +391,7 @@ public class DataController : ControllerBase
try
{
// Get all agent summaries
- var allAgentSummaries = await _mediator.Send(new GetAllAgentSummariesCommand("Total"));
+ var allAgentSummaries = await _mediator.Send(new GetAllAgentSummariesCommand());
// Filter agents with valid PnL data and order by PnL
var agentsWithPnL = allAgentSummaries
@@ -638,6 +638,7 @@ public class DataController : ControllerBase
ActiveStrategiesCount = agentSummary.ActiveStrategiesCount,
TotalVolume = agentSummary.TotalVolume,
TotalBalance = agentSummary.TotalBalance,
+ TotalFees = agentSummary.TotalFees,
};
agentSummaryViewModels.Add(agentSummaryViewModel);
diff --git a/src/Managing.Api/Models/Responses/AgentSummaryViewModel.cs b/src/Managing.Api/Models/Responses/AgentSummaryViewModel.cs
index b5c69553..98c71755 100644
--- a/src/Managing.Api/Models/Responses/AgentSummaryViewModel.cs
+++ b/src/Managing.Api/Models/Responses/AgentSummaryViewModel.cs
@@ -47,6 +47,11 @@ namespace Managing.Api.Models.Responses
/// Total balance including USDC and open position values (without leverage, including PnL)
///
public decimal TotalBalance { get; set; }
+
+ ///
+ /// Total fees paid by this agent across all positions
+ ///
+ public decimal TotalFees { get; set; }
}
///
diff --git a/src/Managing.Application.Abstractions/Grains/IPlatformSummaryGrain.cs b/src/Managing.Application.Abstractions/Grains/IPlatformSummaryGrain.cs
index 38d828a6..62ff0ea6 100644
--- a/src/Managing.Application.Abstractions/Grains/IPlatformSummaryGrain.cs
+++ b/src/Managing.Application.Abstractions/Grains/IPlatformSummaryGrain.cs
@@ -26,6 +26,12 @@ public interface IPlatformSummaryGrain : IGrainWithStringKey
[OneWay]
Task UpdateActiveStrategyCountAsync(int newActiveCount);
+ ///
+ /// Increments the total agent count when a new agent is activated
+ ///
+ [OneWay]
+ Task IncrementAgentCountAsync();
+
[OneWay]
Task OnPositionClosedAsync(PositionClosedEvent evt);
diff --git a/src/Managing.Application.Tests/AgentGrainTests.cs b/src/Managing.Application.Tests/AgentGrainTests.cs
index 70790e37..82ddfaa0 100644
--- a/src/Managing.Application.Tests/AgentGrainTests.cs
+++ b/src/Managing.Application.Tests/AgentGrainTests.cs
@@ -1,14 +1,13 @@
using Managing.Application.Abstractions;
-using Managing.Application.Abstractions.Models;
using Managing.Application.Abstractions.Services;
using Managing.Application.Bots.Grains;
using Managing.Application.Bots.Models;
using Managing.Domain.Bots;
using Managing.Domain.Statistics;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;
-using static Managing.Common.Enums;
namespace Managing.Application.Tests;
@@ -22,6 +21,7 @@ public class AgentGrainTests
private readonly Mock _mockUserService;
private readonly Mock _mockAccountService;
private readonly Mock _mockTradingService;
+ private readonly Mock _mockScopeFactory;
public AgentGrainTests()
{
@@ -33,6 +33,7 @@ public class AgentGrainTests
_mockUserService = new Mock();
_mockAccountService = new Mock();
_mockTradingService = new Mock();
+ _mockScopeFactory = new Mock();
// Setup default state
_mockState.Setup(x => x.State).Returns(new AgentGrainState
@@ -42,51 +43,6 @@ public class AgentGrainTests
});
}
- [Fact]
- public async Task OnAgentSummaryUpdateAsync_WithValidBotId_ShouldCallUpdateSummary()
- {
- // Arrange
- var agentGrain = CreateAgentGrain();
- var botId = _mockState.Object.State.BotIds.First();
- var updateEvent = new AgentSummaryUpdateEvent
- {
- BotId = botId,
- EventType = NotificationEventType.PositionOpened,
- Timestamp = DateTime.UtcNow
- };
-
- // Setup mocks
- _mockBotService.Setup(x => x.GetBotsByIdsAsync(It.IsAny>()))
- .ReturnsAsync(new List());
- _mockAgentService.Setup(x => x.SaveOrUpdateAgentSummary(It.IsAny()))
- .Returns(Task.CompletedTask);
-
- // Act
- await agentGrain.OnAgentSummaryUpdateAsync(updateEvent);
-
- // Assert
- _mockAgentService.Verify(x => x.SaveOrUpdateAgentSummary(It.IsAny()), Times.Once);
- }
-
- [Fact]
- public async Task OnAgentSummaryUpdateAsync_WithInvalidBotId_ShouldNotCallUpdateSummary()
- {
- // Arrange
- var agentGrain = CreateAgentGrain();
- var updateEvent = new AgentSummaryUpdateEvent
- {
- BotId = Guid.NewGuid(), // Different bot ID
- EventType = NotificationEventType.PositionOpened,
- Timestamp = DateTime.UtcNow
- };
-
- // Act
- await agentGrain.OnAgentSummaryUpdateAsync(updateEvent);
-
- // Assert
- _mockAgentService.Verify(x => x.SaveOrUpdateAgentSummary(It.IsAny()), Times.Never);
- }
-
[Fact]
public async Task RegisterBotAsync_ShouldUpdateSummary()
{
@@ -137,6 +93,7 @@ public class AgentGrainTests
_mockExchangeService.Object,
_mockUserService.Object,
_mockAccountService.Object,
- _mockTradingService.Object);
+ _mockTradingService.Object,
+ _mockScopeFactory.Object);
}
}
\ No newline at end of file
diff --git a/src/Managing.Application/Bots/Grains/AgentGrain.cs b/src/Managing.Application/Bots/Grains/AgentGrain.cs
index fb07e3a0..010da85d 100644
--- a/src/Managing.Application/Bots/Grains/AgentGrain.cs
+++ b/src/Managing.Application/Bots/Grains/AgentGrain.cs
@@ -56,10 +56,10 @@ public class AgentGrain : Grain, IAgentGrain
_scopeFactory = scopeFactory;
}
- public override Task OnActivateAsync(CancellationToken cancellationToken)
+ public override async Task OnActivateAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("AgentGrain activated for user {UserId}", this.GetPrimaryKeyLong());
- return base.OnActivateAsync(cancellationToken);
+ await base.OnActivateAsync(cancellationToken);
}
public async Task InitializeAsync(int userId, string agentName)
@@ -86,6 +86,14 @@ public class AgentGrain : Grain, IAgentGrain
await _agentService.SaveOrUpdateAgentSummary(emptySummary);
_logger.LogInformation("Agent {UserId} initialized with name {AgentName} and empty summary", userId, agentName);
+
+ // Notify platform summary about new agent activation
+ await ServiceScopeHelpers.WithScopedService(_scopeFactory, async grainFactory =>
+ {
+ var platformGrain = grainFactory.GetGrain("platform-summary");
+ await platformGrain.IncrementAgentCountAsync();
+ _logger.LogDebug("Notified platform summary about new agent activation for user {UserId}", userId);
+ });
}
public async Task UpdateAgentNameAsync(string agentName)
@@ -162,14 +170,19 @@ public class AgentGrain : Grain, IAgentGrain
var totalVolume = positions.Sum(p => p.Open.Price * p.Open.Quantity * p.Open.Leverage);
var collateral = positions.Sum(p => p.Open.Price * p.Open.Quantity);
var totalFees = positions.Sum(p => p.CalculateTotalFees());
+
+ // Store total fees in grain state for caching
+ _state.State.TotalFees = totalFees;
// Calculate wins/losses from position PnL
var totalWins = positions.Count(p => (p.ProfitAndLoss?.Realized ?? 0) > 0);
var totalLosses = positions.Count(p => (p.ProfitAndLoss?.Realized ?? 0) <= 0);
+ // Calculate ROI based on PnL minus fees
+ var netPnL = totalPnL - totalFees;
var totalROI = collateral switch
{
- > 0 => (totalPnL / collateral) * 100,
+ > 0 => (netPnL / collateral) * 100,
>= 0 => 0,
_ => 0
};
@@ -223,7 +236,7 @@ public class AgentGrain : Grain, IAgentGrain
{
UserId = (int)this.GetPrimaryKeyLong(),
AgentName = _state.State.AgentName,
- TotalPnL = totalPnL,
+ TotalPnL = totalPnL, // Use net PnL without fees
Wins = totalWins,
Losses = totalLosses,
TotalROI = totalROI,
@@ -231,13 +244,14 @@ public class AgentGrain : Grain, IAgentGrain
ActiveStrategiesCount = activeStrategiesCount,
TotalVolume = totalVolume,
TotalBalance = totalBalance,
+ TotalFees = totalFees,
};
// Save summary to database
await _agentService.SaveOrUpdateAgentSummary(summary);
- _logger.LogDebug("Updated agent summary from position data for user {UserId}: PnL={PnL}, Volume={Volume}, Wins={Wins}, Losses={Losses}",
- this.GetPrimaryKeyLong(), totalPnL, totalVolume, totalWins, totalLosses);
+ _logger.LogDebug("Updated agent summary from position data for user {UserId}: NetPnL={NetPnL}, TotalPnL={TotalPnL}, Fees={Fees}, Volume={Volume}, Wins={Wins}, Losses={Losses}",
+ this.GetPrimaryKeyLong(), netPnL, totalPnL, totalFees, totalVolume, totalWins, totalLosses);
}
catch (Exception ex)
{
diff --git a/src/Managing.Application/Bots/Models/AgentGrainState.cs b/src/Managing.Application/Bots/Models/AgentGrainState.cs
index 568499f8..dd5ef2a2 100644
--- a/src/Managing.Application/Bots/Models/AgentGrainState.cs
+++ b/src/Managing.Application/Bots/Models/AgentGrainState.cs
@@ -24,6 +24,12 @@ namespace Managing.Application.Bots.Models
///
[Id(4)]
public CachedBalanceData? CachedBalanceData { get; set; } = null;
+
+ ///
+ /// Total fees paid by this agent across all positions
+ ///
+ [Id(5)]
+ public decimal TotalFees { get; set; } = 0;
}
///
diff --git a/src/Managing.Application/Bots/TradingBotBase.cs b/src/Managing.Application/Bots/TradingBotBase.cs
index e6279b47..063d6361 100644
--- a/src/Managing.Application/Bots/TradingBotBase.cs
+++ b/src/Managing.Application/Bots/TradingBotBase.cs
@@ -406,10 +406,13 @@ public class TradingBotBase : ITradingBot
await UpdatePositionDatabase(internalPosition);
- if (previousPositionStatus != PositionStatus.Filled && internalPosition.Status == PositionStatus.Filled)
+ if (previousPositionStatus != PositionStatus.Filled &&
+ internalPosition.Status == PositionStatus.Filled)
{
await NotifyAgentAndPlatformGrainAsync(NotificationEventType.PositionOpened, internalPosition);
- }else{
+ }
+ else
+ {
await NotifyAgentAndPlatformGrainAsync(NotificationEventType.PositionUpdated, internalPosition);
}
}
@@ -750,8 +753,6 @@ public class TradingBotBase : ITradingBot
currentPrice, true);
}
}
-
-
}
catch (Exception ex)
{
@@ -763,10 +764,8 @@ public class TradingBotBase : ITradingBot
private async Task UpdatePositionDatabase(Position position)
{
- await ServiceScopeHelpers.WithScopedService(_scopeFactory, async tradingService =>
- {
- await tradingService.UpdatePositionAsync(position);
- });
+ await ServiceScopeHelpers.WithScopedService(_scopeFactory,
+ async tradingService => { await tradingService.UpdatePositionAsync(position); });
}
private async Task OpenPosition(LightSignal signal)
@@ -1347,6 +1346,7 @@ public class TradingBotBase : ITradingBot
// Update position in database with all trade changes
if (!Config.IsForBacktest)
{
+ position.Status = PositionStatus.Finished;
await UpdatePositionDatabase(position);
await NotifyAgentAndPlatformGrainAsync(NotificationEventType.PositionClosed, position);
}
@@ -1468,10 +1468,13 @@ public class TradingBotBase : ITradingBot
{
if (Positions[identifier].ProfitAndLoss == null)
{
- Positions[identifier].ProfitAndLoss = new ProfitAndLoss(){
+ Positions[identifier].ProfitAndLoss = new ProfitAndLoss()
+ {
Realized = realized
};
- }else{
+ }
+ else
+ {
Positions[identifier].ProfitAndLoss.Realized = realized;
}
}
diff --git a/src/Managing.Application/Grains/PlatformSummaryGrain.cs b/src/Managing.Application/Grains/PlatformSummaryGrain.cs
index e71f2da9..bfff2253 100644
--- a/src/Managing.Application/Grains/PlatformSummaryGrain.cs
+++ b/src/Managing.Application/Grains/PlatformSummaryGrain.cs
@@ -76,11 +76,16 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
_state.State.DailySnapshots.Add(initialSnapshot);
_state.State.LastSnapshot = initialSnapshot.Date;
_state.State.LastUpdated = initialSnapshot.Date;
+
_logger.LogInformation("Created initial empty daily snapshot for {Date}", today);
}
+ _state.State.TotalAgents = await _agentService.GetTotalAgentCount();
+
await RefreshDataAsync();
}
+
+ await base.OnActivateAsync(cancellationToken);
}
public async Task GetPlatformSummaryAsync()
@@ -129,7 +134,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
// Calculate fees and PnL for all positions
totalFees += position.CalculateTotalFees();
totalPnL += position.ProfitAndLoss?.Realized ?? 0;
-
+
// Count all positions
totalPositionCount++;
@@ -142,6 +147,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
{
_state.State.VolumeByAsset[ticker] = 0;
}
+
_state.State.VolumeByAsset[ticker] += positionVolume;
// Position count breakdown by asset - update state directly
@@ -149,6 +155,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
{
_state.State.PositionCountByAsset[ticker] = 0;
}
+
_state.State.PositionCountByAsset[ticker]++;
// Position count breakdown by direction - update state directly
@@ -156,10 +163,10 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
{
_state.State.PositionCountByDirection[direction] = 0;
}
+
_state.State.PositionCountByDirection[direction]++;
}
- _state.State.TotalAgents = await _agentService.GetTotalAgentCount();
_state.State.TotalPlatformVolume = totalVolume;
_state.State.TotalPlatformFees = totalFees;
_state.State.TotalPlatformPnL = totalPnL;
@@ -169,7 +176,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
_logger.LogDebug(
"Updated position breakdown from positions: {AssetCount} assets, Long={LongPositions}, Short={ShortPositions}",
- _state.State.PositionCountByAsset.Count,
+ _state.State.PositionCountByAsset.Count,
_state.State.PositionCountByDirection.GetValueOrDefault(TradeDirection.Long, 0),
_state.State.PositionCountByDirection.GetValueOrDefault(TradeDirection.Short, 0));
@@ -207,6 +214,24 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
}
}
+ public async Task IncrementAgentCountAsync()
+ {
+ try
+ {
+ _logger.LogInformation("Incrementing agent count from {CurrentCount} to {NewCount}",
+ _state.State.TotalAgents, _state.State.TotalAgents + 1);
+
+ _state.State.TotalAgents++;
+ await _state.WriteStateAsync();
+
+ _logger.LogInformation("Agent count incremented to: {NewCount}", _state.State.TotalAgents);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error incrementing agent count");
+ }
+ }
+
public async Task OnPositionClosedAsync(PositionClosedEvent evt)
{
try
@@ -282,20 +307,6 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
await _state.WriteStateAsync();
}
- private async Task RefreshPnLFromDatabaseAsync()
- {
- try
- {
- var totalPnL = await _tradingService.GetGlobalPnLFromPositionsAsync();
- _state.State.TotalPlatformPnL = totalPnL;
- _logger.LogDebug("Refreshed PnL from database: {TotalPnL}", totalPnL);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error refreshing PnL from database");
- }
- }
-
private bool IsDataStale()
{
var timeSinceLastUpdate = DateTime.UtcNow - _state.State.LastUpdated;
diff --git a/src/Managing.Application/ManageBot/Commands/GetAllAgentSummariesCommand.cs b/src/Managing.Application/ManageBot/Commands/GetAllAgentSummariesCommand.cs
index f1bc8e86..cda39d2d 100644
--- a/src/Managing.Application/ManageBot/Commands/GetAllAgentSummariesCommand.cs
+++ b/src/Managing.Application/ManageBot/Commands/GetAllAgentSummariesCommand.cs
@@ -8,14 +8,8 @@ namespace Managing.Application.ManageBot.Commands
///
public class GetAllAgentSummariesCommand : IRequest>
{
- ///
- /// Optional time filter to apply (24H, 3D, 1W, 1M, 1Y, Total)
- ///
- public string TimeFilter { get; }
-
- public GetAllAgentSummariesCommand(string timeFilter = "Total")
+ public GetAllAgentSummariesCommand()
{
- TimeFilter = timeFilter;
}
}
}
\ No newline at end of file
diff --git a/src/Managing.Application/ManageBot/Commands/GetAllAgentsCommand.cs b/src/Managing.Application/ManageBot/Commands/GetAllAgentsCommand.cs
index c728cd40..368b2687 100644
--- a/src/Managing.Application/ManageBot/Commands/GetAllAgentsCommand.cs
+++ b/src/Managing.Application/ManageBot/Commands/GetAllAgentsCommand.cs
@@ -9,14 +9,8 @@ namespace Managing.Application.ManageBot.Commands
///
public class GetAllAgentsCommand : IRequest>>
{
- ///
- /// Optional time filter to apply (24H, 3D, 1W, 1M, 1Y, Total)
- ///
- public string TimeFilter { get; }
-
- public GetAllAgentsCommand(string timeFilter = "Total")
+ public GetAllAgentsCommand()
{
- TimeFilter = timeFilter;
}
}
}
\ No newline at end of file
diff --git a/src/Managing.Application/ManageBot/GetAllAgentSummariesCommandHandler.cs b/src/Managing.Application/ManageBot/GetAllAgentSummariesCommandHandler.cs
index 2d139883..528c9829 100644
--- a/src/Managing.Application/ManageBot/GetAllAgentSummariesCommandHandler.cs
+++ b/src/Managing.Application/ManageBot/GetAllAgentSummariesCommandHandler.cs
@@ -24,31 +24,8 @@ namespace Managing.Application.ManageBot
// Get all agent summaries from the database
var allAgentSummaries = await _agentService.GetAllAgentSummaries();
- if (request.TimeFilter != "Total")
- {
- var cutoffDate = GetCutoffDate(request.TimeFilter);
- allAgentSummaries = allAgentSummaries.Where(a =>
- a.UpdatedAt >= cutoffDate ||
- (a.Runtime.HasValue && a.Runtime.Value >= cutoffDate));
- }
-
return allAgentSummaries;
}
- ///
- /// Gets the cutoff date based on the time filter
- ///
- private DateTime GetCutoffDate(string timeFilter)
- {
- return timeFilter switch
- {
- "24H" => DateTime.UtcNow.AddHours(-24),
- "3D" => DateTime.UtcNow.AddDays(-3),
- "1W" => DateTime.UtcNow.AddDays(-7),
- "1M" => DateTime.UtcNow.AddMonths(-1),
- "1Y" => DateTime.UtcNow.AddYears(-1),
- _ => DateTime.MinValue // Default to include all data
- };
- }
}
}
\ No newline at end of file
diff --git a/src/Managing.Application/ManageBot/GetAllAgentsCommandHandler.cs b/src/Managing.Application/ManageBot/GetAllAgentsCommandHandler.cs
index 0f4f8762..fa286798 100644
--- a/src/Managing.Application/ManageBot/GetAllAgentsCommandHandler.cs
+++ b/src/Managing.Application/ManageBot/GetAllAgentsCommandHandler.cs
@@ -35,35 +35,11 @@ namespace Managing.Application.ManageBot
var userBots = await _botService.GetBotsByUser(user.Id);
var botList = userBots.ToList();
- // Apply time filter if specified
- if (request.TimeFilter != "Total")
- {
- var cutoffDate = GetCutoffDate(request.TimeFilter);
- botList = botList.Where(bot =>
- bot.StartupTime >= cutoffDate ||
- bot.CreateDate >= cutoffDate).ToList();
- }
-
result[user] = botList;
}
return result;
}
- ///
- /// Gets the cutoff date based on the time filter
- ///
- private DateTime GetCutoffDate(string timeFilter)
- {
- return timeFilter switch
- {
- "24H" => DateTime.UtcNow.AddHours(-24),
- "3D" => DateTime.UtcNow.AddDays(-3),
- "1W" => DateTime.UtcNow.AddDays(-7),
- "1M" => DateTime.UtcNow.AddMonths(-1),
- "1Y" => DateTime.UtcNow.AddYears(-1),
- _ => DateTime.MinValue // Default to include all data
- };
- }
}
}
\ No newline at end of file
diff --git a/src/Managing.Application/Trading/Handlers/OpenPositionCommandHandler.cs b/src/Managing.Application/Trading/Handlers/OpenPositionCommandHandler.cs
index f98e1d9f..8d9d750a 100644
--- a/src/Managing.Application/Trading/Handlers/OpenPositionCommandHandler.cs
+++ b/src/Managing.Application/Trading/Handlers/OpenPositionCommandHandler.cs
@@ -45,25 +45,19 @@ namespace Managing.Application.Trading.Handlers
}
// Gas fee check for EVM exchanges
- decimal gasFeeUsd = 0;
if (!request.IsForPaperTrading)
{
if (account.Exchange == TradingExchanges.Evm || account.Exchange == TradingExchanges.GmxV2)
{
- gasFeeUsd = await exchangeService.GetFee(account);
- if (gasFeeUsd > Constants.GMX.Config.MaximumGasFeeUsd)
+ var currentGasFees = await exchangeService.GetFee(account);
+ if (currentGasFees > Constants.GMX.Config.MaximumGasFeeUsd)
{
throw new InsufficientFundsException(
- $"Gas fee too high for position opening: {gasFeeUsd:F2} USD (threshold: {Constants.GMX.Config.MaximumGasFeeUsd} USD). Position opening cancelled.",
+ $"Gas fee too high for position opening: {currentGasFees:F2} USD (threshold: {Constants.GMX.Config.MaximumGasFeeUsd} USD). Position opening cancelled.",
InsufficientFundsType.InsufficientEth);
}
}
}
- else
- {
- gasFeeUsd = Constants.GMX.Config.GasFeePerTransaction;
- }
-
var price = request.IsForPaperTrading && request.Price.HasValue
? request.Price.Value
@@ -94,19 +88,11 @@ namespace Managing.Application.Trading.Handlers
position.Open = trade;
// Calculate and set fees for the position
- var positionSizeUsd = (position.Open.Price * position.Open.Quantity) * position.Open.Leverage;
- // Set gas fees (only for EVM exchanges)
- if (account.Exchange == TradingExchanges.Evm || account.Exchange == TradingExchanges.GmxV2)
- {
- position.GasFees = gasFeeUsd;
- }
- else
- {
- position.GasFees = TradingHelpers.CalculateOpeningGasFees();
- }
+ position.GasFees = TradingHelpers.CalculateOpeningGasFees();
// Set UI fees for opening
+ var positionSizeUsd = TradingHelpers.GetVolumeForPosition(position);
position.UiFees = TradingHelpers.CalculateOpeningUiFees(positionSizeUsd);
var closeDirection = request.Direction == TradeDirection.Long
diff --git a/src/Managing.Application/Users/UserService.cs b/src/Managing.Application/Users/UserService.cs
index 21271250..b462335a 100644
--- a/src/Managing.Application/Users/UserService.cs
+++ b/src/Managing.Application/Users/UserService.cs
@@ -116,6 +116,8 @@ public class UserService : IUserService
var agentGrain = _grainFactory.GetGrain(user.Id);
await agentGrain.InitializeAsync(user.Id, string.Empty);
_logger.LogInformation("AgentGrain initialized for new user {UserId}", user.Id);
+
+
}
catch (Exception ex)
{
diff --git a/src/Managing.Docker/docker-compose.local.yml b/src/Managing.Docker/docker-compose.local.yml
index 039da6d8..32741e8b 100644
--- a/src/Managing.Docker/docker-compose.local.yml
+++ b/src/Managing.Docker/docker-compose.local.yml
@@ -55,7 +55,7 @@ services:
- managing-network
restart: unless-stopped
environment:
- - REDIS_PASSWORD=SuperSecretPassword
+ - REDIS_PASSWORD=
command: >
sh -c "
if [ -n \"$$REDIS_PASSWORD\" ]; then
@@ -65,4 +65,4 @@ services:
redis-server --appendonly yes
redis-cli
fi
- "
\ No newline at end of file
+ "SuperSecretPassword
\ No newline at end of file
diff --git a/src/Managing.Domain/Statistics/AgentSummary.cs b/src/Managing.Domain/Statistics/AgentSummary.cs
index 615987aa..086e3bdd 100644
--- a/src/Managing.Domain/Statistics/AgentSummary.cs
+++ b/src/Managing.Domain/Statistics/AgentSummary.cs
@@ -47,4 +47,7 @@ public class AgentSummary
[Id(13)]
public decimal TotalBalance { get; set; }
+
+ [Id(14)]
+ public decimal TotalFees { get; set; }
}
\ No newline at end of file
diff --git a/src/Managing.Infrastructure.Database/Migrations/ManagingDbContextModelSnapshot.cs b/src/Managing.Infrastructure.Database/Migrations/ManagingDbContextModelSnapshot.cs
index a6928b7d..4de32cff 100644
--- a/src/Managing.Infrastructure.Database/Migrations/ManagingDbContextModelSnapshot.cs
+++ b/src/Managing.Infrastructure.Database/Migrations/ManagingDbContextModelSnapshot.cs
@@ -99,6 +99,9 @@ namespace Managing.Infrastructure.Databases.Migrations
.HasPrecision(18, 8)
.HasColumnType("numeric(18,8)");
+ b.Property("TotalFees")
+ .HasColumnType("numeric");
+
b.Property("TotalPnL")
.HasColumnType("decimal(18,8)");
diff --git a/src/Managing.Infrastructure.Database/PostgreSql/AgentSummaryRepository.cs b/src/Managing.Infrastructure.Database/PostgreSql/AgentSummaryRepository.cs
index 7f64a4cc..9b9db661 100644
--- a/src/Managing.Infrastructure.Database/PostgreSql/AgentSummaryRepository.cs
+++ b/src/Managing.Infrastructure.Database/PostgreSql/AgentSummaryRepository.cs
@@ -249,7 +249,8 @@ public class AgentSummaryRepository : IAgentSummaryRepository
UpdatedAt = domain.UpdatedAt,
ActiveStrategiesCount = domain.ActiveStrategiesCount,
TotalVolume = domain.TotalVolume,
- TotalBalance = domain.TotalBalance
+ TotalBalance = domain.TotalBalance,
+ TotalFees = domain.TotalFees
};
}
@@ -265,6 +266,7 @@ public class AgentSummaryRepository : IAgentSummaryRepository
entity.ActiveStrategiesCount = domain.ActiveStrategiesCount;
entity.TotalVolume = domain.TotalVolume;
entity.TotalBalance = domain.TotalBalance;
+ entity.TotalFees = domain.TotalFees;
}
private static AgentSummary MapToDomain(AgentSummaryEntity entity)
@@ -284,6 +286,7 @@ public class AgentSummaryRepository : IAgentSummaryRepository
ActiveStrategiesCount = entity.ActiveStrategiesCount,
TotalVolume = entity.TotalVolume,
TotalBalance = entity.TotalBalance,
+ TotalFees = entity.TotalFees,
User = PostgreSqlMappers.Map(entity.User)
};
}
diff --git a/src/Managing.Infrastructure.Database/PostgreSql/Entities/AgentSummaryEntity.cs b/src/Managing.Infrastructure.Database/PostgreSql/Entities/AgentSummaryEntity.cs
index 67681afb..8445e7ad 100644
--- a/src/Managing.Infrastructure.Database/PostgreSql/Entities/AgentSummaryEntity.cs
+++ b/src/Managing.Infrastructure.Database/PostgreSql/Entities/AgentSummaryEntity.cs
@@ -15,6 +15,7 @@ public class AgentSummaryEntity
public int ActiveStrategiesCount { get; set; }
public decimal TotalVolume { get; set; }
public decimal TotalBalance { get; set; }
+ public decimal TotalFees { get; set; }
// Navigation property
public UserEntity User { get; set; }
diff --git a/src/Managing.WebApp/package.json b/src/Managing.WebApp/package.json
index e99c67c4..9ac3ed36 100644
--- a/src/Managing.WebApp/package.json
+++ b/src/Managing.WebApp/package.json
@@ -82,7 +82,7 @@
"prettier-plugin-tailwind-css": "^1.5.0",
"tailwindcss": "^3.0.23",
"typescript": "^5.7.3",
- "vite": "^6.3.5",
+ "vite": "^6.3.6",
"whatwg-fetch": "^3.6.2"
},
"msw": {