Update balance tracking
This commit is contained in:
@@ -5,7 +5,7 @@ namespace Managing.Application.Abstractions.Repositories;
|
|||||||
public interface IAgentBalanceRepository
|
public interface IAgentBalanceRepository
|
||||||
{
|
{
|
||||||
void InsertAgentBalance(AgentBalance balance);
|
void InsertAgentBalance(AgentBalance balance);
|
||||||
Task<IList<AgentBalance>> GetAgentBalances(string agentName, DateTime start, DateTime? end = null);
|
Task<IList<AgentBalance>> GetAgentBalancesByUserId(int userId, DateTime start, DateTime? end = null);
|
||||||
|
|
||||||
Task<(IList<AgentBalanceHistory> result, int totalCount)> GetAllAgentBalancesWithHistory(DateTime start,
|
Task<(IList<AgentBalanceHistory> result, int totalCount)> GetAllAgentBalancesWithHistory(DateTime start,
|
||||||
DateTime? end);
|
DateTime? end);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace Managing.Application.Abstractions.Services;
|
|||||||
public interface IAgentService
|
public interface IAgentService
|
||||||
{
|
{
|
||||||
Task<AgentBalanceHistory> GetAgentBalances(string agentName, DateTime start, DateTime? end = null);
|
Task<AgentBalanceHistory> GetAgentBalances(string agentName, DateTime start, DateTime? end = null);
|
||||||
|
Task<AgentBalanceHistory> GetAgentBalancesByUserId(int userId, DateTime start, DateTime? end = null);
|
||||||
|
|
||||||
Task<(IList<AgentBalanceHistory> Agents, int TotalCount)> GetBestAgents(DateTime start, DateTime? end = null,
|
Task<(IList<AgentBalanceHistory> Agents, int TotalCount)> GetBestAgents(DateTime start, DateTime? end = null,
|
||||||
int page = 1,
|
int page = 1,
|
||||||
|
|||||||
@@ -31,9 +31,40 @@ public class AgentService : IAgentService
|
|||||||
|
|
||||||
public async Task<AgentBalanceHistory> GetAgentBalances(string agentName, DateTime start,
|
public async Task<AgentBalanceHistory> GetAgentBalances(string agentName, DateTime start,
|
||||||
DateTime? end = null)
|
DateTime? end = null)
|
||||||
|
{
|
||||||
|
// Get userId from agentName by looking up the user
|
||||||
|
var userId = await ServiceScopeHelpers.WithScopedService<IUserService, int?>(_serviceScopeFactory,
|
||||||
|
async (userService) =>
|
||||||
|
{
|
||||||
|
var user = await userService.GetUserByAgentName(agentName);
|
||||||
|
return user?.Id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userId.HasValue)
|
||||||
|
{
|
||||||
|
// Return empty result if user not found
|
||||||
|
return new AgentBalanceHistory
|
||||||
|
{
|
||||||
|
UserId = 0,
|
||||||
|
AgentName = agentName,
|
||||||
|
AgentBalances = new List<AgentBalance>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the UserId-based method internally
|
||||||
|
var result = await GetAgentBalancesByUserId(userId.Value, start, end);
|
||||||
|
|
||||||
|
// Override the AgentName to use the requested agentName instead of the default
|
||||||
|
result.AgentName = agentName;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AgentBalanceHistory> GetAgentBalancesByUserId(int userId, DateTime start,
|
||||||
|
DateTime? end = null)
|
||||||
{
|
{
|
||||||
var effectiveEnd = end ?? DateTime.UtcNow;
|
var effectiveEnd = end ?? DateTime.UtcNow;
|
||||||
string cacheKey = $"AgentBalances_{agentName}_{start:yyyyMMdd}_{effectiveEnd:yyyyMMdd}";
|
string cacheKey = $"AgentBalancesByUserId_{userId}_{start:yyyyMMdd}_{effectiveEnd:yyyyMMdd}";
|
||||||
|
|
||||||
// Check if the balances are already cached
|
// Check if the balances are already cached
|
||||||
var cachedBalances = _cacheService.GetValue<AgentBalanceHistory>(cacheKey);
|
var cachedBalances = _cacheService.GetValue<AgentBalanceHistory>(cacheKey);
|
||||||
@@ -43,12 +74,13 @@ public class AgentService : IAgentService
|
|||||||
return cachedBalances;
|
return cachedBalances;
|
||||||
}
|
}
|
||||||
|
|
||||||
var balances = await _agentBalanceRepository.GetAgentBalances(agentName, start, end);
|
var balances = await _agentBalanceRepository.GetAgentBalancesByUserId(userId, start, end);
|
||||||
|
|
||||||
// Create a single AgentBalanceHistory with all balances
|
// Create a single AgentBalanceHistory with all balances
|
||||||
var result = new AgentBalanceHistory
|
var result = new AgentBalanceHistory
|
||||||
{
|
{
|
||||||
AgentName = agentName,
|
UserId = userId,
|
||||||
|
AgentName = $"User_{userId}",
|
||||||
AgentBalances = balances.OrderBy(b => b.Time).ToList()
|
AgentBalances = balances.OrderBy(b => b.Time).ToList()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -193,8 +193,10 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
_ => 0
|
_ => 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate total balance (USDC + open positions value)
|
// Calculate total balance (USDC wallet + USDC in open positions value)
|
||||||
decimal totalBalance = 0;
|
decimal totalBalance = 0;
|
||||||
|
decimal usdcWalletValue = 0;
|
||||||
|
decimal usdcInPositionsValue = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userId = (int)this.GetPrimaryKeyLong();
|
var userId = (int)this.GetPrimaryKeyLong();
|
||||||
@@ -209,20 +211,25 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
// Get USDC balance
|
// Get USDC balance
|
||||||
var usdcBalances = await GetOrRefreshBalanceDataAsync(account.Name);
|
var usdcBalances = await GetOrRefreshBalanceDataAsync(account.Name);
|
||||||
var usdcBalance = usdcBalances?.UsdcValue ?? 0;
|
var usdcBalance = usdcBalances?.UsdcValue ?? 0;
|
||||||
totalBalance += usdcBalance;
|
usdcWalletValue += usdcBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var position in positions.Where(p => !p.IsFinished()))
|
foreach (var position in positions.Where(p => !p.IsFinished()))
|
||||||
{
|
{
|
||||||
totalBalance += position.Open.Price * position.Open.Quantity;
|
var positionUsd = position.Open.Price * position.Open.Quantity;
|
||||||
totalBalance += position.ProfitAndLoss?.Realized ?? 0;
|
var realized = position.ProfitAndLoss?.Realized ?? 0;
|
||||||
|
usdcInPositionsValue += positionUsd + realized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalBalance = usdcWalletValue + usdcInPositionsValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error calculating total balance for agent {UserId}", this.GetPrimaryKeyLong());
|
_logger.LogError(ex, "Error calculating total balance for agent {UserId}", this.GetPrimaryKeyLong());
|
||||||
totalBalance = 0; // Set to 0 if calculation fails
|
totalBalance = 0; // Set to 0 if calculation fails
|
||||||
|
usdcWalletValue = 0;
|
||||||
|
usdcInPositionsValue = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bots = await ServiceScopeHelpers.WithScopedService<IBotService, IEnumerable<Bot>>(_scopeFactory,
|
var bots = await ServiceScopeHelpers.WithScopedService<IBotService, IEnumerable<Bot>>(_scopeFactory,
|
||||||
@@ -269,7 +276,7 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
await _agentService.SaveOrUpdateAgentSummary(summary);
|
await _agentService.SaveOrUpdateAgentSummary(summary);
|
||||||
|
|
||||||
// Insert balance tracking data
|
// Insert balance tracking data
|
||||||
InsertBalanceTrackingData(totalBalance, botsAllocationUsdValue, netPnL);
|
InsertBalanceTrackingData(totalBalance, botsAllocationUsdValue, netPnL, usdcWalletValue, usdcInPositionsValue);
|
||||||
|
|
||||||
_logger.LogDebug(
|
_logger.LogDebug(
|
||||||
"Updated agent summary from position data for user {UserId}: NetPnL={NetPnL}, TotalPnL={TotalPnL}, Fees={Fees}, Volume={Volume}, Wins={Wins}, Losses={Losses}",
|
"Updated agent summary from position data for user {UserId}: NetPnL={NetPnL}, TotalPnL={TotalPnL}, Fees={Fees}, Volume={Volume}, Wins={Wins}, Losses={Losses}",
|
||||||
@@ -626,14 +633,16 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Inserts balance tracking data into the AgentBalanceRepository
|
/// Inserts balance tracking data into the AgentBalanceRepository
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void InsertBalanceTrackingData(decimal totalAccountUsdValue, decimal botsAllocationUsdValue, decimal pnl)
|
private void InsertBalanceTrackingData(decimal totalAccountUsdValue, decimal botsAllocationUsdValue, decimal pnl, decimal usdcWalletValue, decimal usdcInPositionsValue)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var agentBalance = new AgentBalance
|
var agentBalance = new AgentBalance
|
||||||
{
|
{
|
||||||
AgentName = _state.State.AgentName,
|
UserId = (int)this.GetPrimaryKeyLong(),
|
||||||
TotalBalanceValue = totalAccountUsdValue,
|
TotalBalanceValue = totalAccountUsdValue,
|
||||||
|
UsdcWalletValue = usdcWalletValue,
|
||||||
|
UsdcInPositionsValue = usdcInPositionsValue,
|
||||||
BotsAllocationUsdValue = botsAllocationUsdValue,
|
BotsAllocationUsdValue = botsAllocationUsdValue,
|
||||||
PnL = pnl,
|
PnL = pnl,
|
||||||
Time = DateTime.UtcNow
|
Time = DateTime.UtcNow
|
||||||
@@ -642,13 +651,13 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
_agentBalanceRepository.InsertAgentBalance(agentBalance);
|
_agentBalanceRepository.InsertAgentBalance(agentBalance);
|
||||||
|
|
||||||
_logger.LogDebug(
|
_logger.LogDebug(
|
||||||
"Inserted balance tracking data for agent {AgentName}: TotalBalanceValue={TotalBalanceValue}, BotsAllocationUsdValue={BotsAllocationUsdValue}, PnL={PnL}",
|
"Inserted balance tracking data for user {UserId}: TotalBalanceValue={TotalBalanceValue}, BotsAllocationUsdValue={BotsAllocationUsdValue}, PnL={PnL}",
|
||||||
agentBalance.AgentName, agentBalance.TotalBalanceValue, agentBalance.BotsAllocationUsdValue,
|
agentBalance.UserId, agentBalance.TotalBalanceValue, agentBalance.BotsAllocationUsdValue,
|
||||||
agentBalance.PnL);
|
agentBalance.PnL);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error inserting balance tracking data for agent {AgentName}", _state.State.AgentName);
|
_logger.LogError(ex, "Error inserting balance tracking data for user {UserId}", (int)this.GetPrimaryKeyLong());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,10 @@ namespace Managing.Domain.Statistics;
|
|||||||
|
|
||||||
public class AgentBalance
|
public class AgentBalance
|
||||||
{
|
{
|
||||||
public string AgentName { get; set; }
|
public int UserId { get; set; }
|
||||||
public decimal TotalBalanceValue { get; set; }
|
public decimal TotalBalanceValue { get; set; }
|
||||||
|
public decimal UsdcWalletValue { get; set; }
|
||||||
|
public decimal UsdcInPositionsValue { get; set; }
|
||||||
public decimal BotsAllocationUsdValue { get; set; }
|
public decimal BotsAllocationUsdValue { get; set; }
|
||||||
public decimal PnL { get; set; }
|
public decimal PnL { get; set; }
|
||||||
public DateTime Time { get; set; }
|
public DateTime Time { get; set; }
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ namespace Managing.Domain.Statistics;
|
|||||||
|
|
||||||
public class AgentBalanceHistory
|
public class AgentBalanceHistory
|
||||||
{
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
public string AgentName { get; set; }
|
public string AgentName { get; set; }
|
||||||
|
|
||||||
public List<AgentBalance> AgentBalances { get; set; }
|
public List<AgentBalance> AgentBalances { get; set; }
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ public class AgentBalanceRepository : IAgentBalanceRepository
|
|||||||
{
|
{
|
||||||
var balanceDto = new AgentBalanceDto
|
var balanceDto = new AgentBalanceDto
|
||||||
{
|
{
|
||||||
AgentName = balance.AgentName,
|
UserId = balance.UserId,
|
||||||
TotalBalanceValue = balance.TotalBalanceValue,
|
TotalBalanceValue = balance.TotalBalanceValue,
|
||||||
|
UsdcWalletValue = balance.UsdcWalletValue,
|
||||||
|
UsdcInPositionsValue = balance.UsdcInPositionsValue,
|
||||||
BotsAllocationUsdValue = balance.BotsAllocationUsdValue,
|
BotsAllocationUsdValue = balance.BotsAllocationUsdValue,
|
||||||
PnL = balance.PnL,
|
PnL = balance.PnL,
|
||||||
Time = balance.Time
|
Time = balance.Time
|
||||||
@@ -40,7 +42,7 @@ public class AgentBalanceRepository : IAgentBalanceRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IList<AgentBalance>> GetAgentBalances(string agentName, DateTime start, DateTime? end = null)
|
public async Task<IList<AgentBalance>> GetAgentBalancesByUserId(int userId, DateTime start, DateTime? end = null)
|
||||||
{
|
{
|
||||||
var results = await _influxDbRepository.QueryAsync(async query =>
|
var results = await _influxDbRepository.QueryAsync(async query =>
|
||||||
{
|
{
|
||||||
@@ -48,15 +50,17 @@ public class AgentBalanceRepository : IAgentBalanceRepository
|
|||||||
$"|> range(start: {start:s}Z" +
|
$"|> range(start: {start:s}Z" +
|
||||||
(end.HasValue ? $", stop: {end.Value:s}Z" : "") +
|
(end.HasValue ? $", stop: {end.Value:s}Z" : "") +
|
||||||
$") " +
|
$") " +
|
||||||
$"|> filter(fn: (r) => r[\"agent_name\"] == \"{agentName}\") " +
|
$"|> filter(fn: (r) => r[\"user_id\"] == \"{userId}\") " +
|
||||||
$"|> pivot(rowKey: [\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")";
|
$"|> pivot(rowKey: [\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")";
|
||||||
|
|
||||||
var result = await query.QueryAsync<AgentBalanceDto>(flux, _influxDbRepository.Organization);
|
var result = await query.QueryAsync<AgentBalanceDto>(flux, _influxDbRepository.Organization);
|
||||||
|
|
||||||
return result.Select(balance => new AgentBalance
|
return result.Select(balance => new AgentBalance
|
||||||
{
|
{
|
||||||
AgentName = balance.AgentName,
|
UserId = balance.UserId,
|
||||||
TotalBalanceValue = balance.TotalBalanceValue,
|
TotalBalanceValue = balance.TotalBalanceValue,
|
||||||
|
UsdcWalletValue = balance.UsdcWalletValue,
|
||||||
|
UsdcInPositionsValue = balance.UsdcInPositionsValue,
|
||||||
BotsAllocationUsdValue = balance.BotsAllocationUsdValue,
|
BotsAllocationUsdValue = balance.BotsAllocationUsdValue,
|
||||||
PnL = balance.PnL,
|
PnL = balance.PnL,
|
||||||
Time = balance.Time
|
Time = balance.Time
|
||||||
@@ -81,20 +85,31 @@ public class AgentBalanceRepository : IAgentBalanceRepository
|
|||||||
|
|
||||||
var balances = await query.QueryAsync<AgentBalanceDto>(flux, _influxDbRepository.Organization);
|
var balances = await query.QueryAsync<AgentBalanceDto>(flux, _influxDbRepository.Organization);
|
||||||
|
|
||||||
// Group balances by agent name
|
// Group balances by user ID
|
||||||
var agentGroups = balances
|
var agentGroups = balances
|
||||||
.GroupBy(b => b.AgentName)
|
.GroupBy(b => b.UserId)
|
||||||
.Select(g => new AgentBalanceHistory
|
.Select(g =>
|
||||||
{
|
{
|
||||||
AgentName = g.Key,
|
var userBalances = g.Select(b => new AgentBalance
|
||||||
AgentBalances = g.Select(b => new AgentBalance
|
|
||||||
{
|
{
|
||||||
AgentName = b.AgentName,
|
UserId = b.UserId,
|
||||||
TotalBalanceValue = b.TotalBalanceValue,
|
TotalBalanceValue = b.TotalBalanceValue,
|
||||||
|
UsdcWalletValue = b.UsdcWalletValue,
|
||||||
|
UsdcInPositionsValue = b.UsdcInPositionsValue,
|
||||||
BotsAllocationUsdValue = b.BotsAllocationUsdValue,
|
BotsAllocationUsdValue = b.BotsAllocationUsdValue,
|
||||||
PnL = b.PnL,
|
PnL = b.PnL,
|
||||||
Time = b.Time
|
Time = b.Time
|
||||||
}).OrderBy(b => b.Time).ToList()
|
}).OrderBy(b => b.Time).ToList();
|
||||||
|
|
||||||
|
// Use a default agent name since we don't store it in AgentBalance anymore
|
||||||
|
var mostRecentAgentName = $"User_{g.Key}";
|
||||||
|
|
||||||
|
return new AgentBalanceHistory
|
||||||
|
{
|
||||||
|
UserId = g.Key,
|
||||||
|
AgentName = mostRecentAgentName,
|
||||||
|
AgentBalances = userBalances
|
||||||
|
};
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
return (agentGroups, agentGroups.Count);
|
return (agentGroups, agentGroups.Count);
|
||||||
|
|||||||
@@ -5,10 +5,14 @@ namespace Managing.Infrastructure.Databases.InfluxDb.Models;
|
|||||||
[Measurement("agent_balance")]
|
[Measurement("agent_balance")]
|
||||||
public class AgentBalanceDto
|
public class AgentBalanceDto
|
||||||
{
|
{
|
||||||
[Column("agent_name", IsTag = true)] public string AgentName { get; set; }
|
[Column("user_id", IsTag = true)] public int UserId { get; set; }
|
||||||
|
|
||||||
[Column("total_balance_value")] public decimal TotalBalanceValue { get; set; }
|
[Column("total_balance_value")] public decimal TotalBalanceValue { get; set; }
|
||||||
|
|
||||||
|
[Column("usdc_wallet_value")] public decimal UsdcWalletValue { get; set; }
|
||||||
|
|
||||||
|
[Column("usdc_in_positions_value")] public decimal UsdcInPositionsValue { get; set; }
|
||||||
|
|
||||||
[Column("bots_allocation_usd_value")] public decimal BotsAllocationUsdValue { get; set; }
|
[Column("bots_allocation_usd_value")] public decimal BotsAllocationUsdValue { get; set; }
|
||||||
|
|
||||||
[Column("pnl")] public decimal PnL { get; set; }
|
[Column("pnl")] public decimal PnL { get; set; }
|
||||||
|
|||||||
@@ -4588,13 +4588,16 @@ export enum SortableFields {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentBalanceHistory {
|
export interface AgentBalanceHistory {
|
||||||
|
userId?: number;
|
||||||
agentName?: string | null;
|
agentName?: string | null;
|
||||||
agentBalances?: AgentBalance[] | null;
|
agentBalances?: AgentBalance[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentBalance {
|
export interface AgentBalance {
|
||||||
agentName?: string | null;
|
userId?: number;
|
||||||
totalBalanceValue?: number;
|
totalBalanceValue?: number;
|
||||||
|
usdcWalletValue?: number;
|
||||||
|
usdcInPositionsValue?: number;
|
||||||
botsAllocationUsdValue?: number;
|
botsAllocationUsdValue?: number;
|
||||||
pnL?: number;
|
pnL?: number;
|
||||||
time?: Date;
|
time?: Date;
|
||||||
|
|||||||
@@ -1071,13 +1071,16 @@ export enum SortableFields {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentBalanceHistory {
|
export interface AgentBalanceHistory {
|
||||||
|
userId?: number;
|
||||||
agentName?: string | null;
|
agentName?: string | null;
|
||||||
agentBalances?: AgentBalance[] | null;
|
agentBalances?: AgentBalance[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentBalance {
|
export interface AgentBalance {
|
||||||
agentName?: string | null;
|
userId?: number;
|
||||||
totalBalanceValue?: number;
|
totalBalanceValue?: number;
|
||||||
|
usdcWalletValue?: number;
|
||||||
|
usdcInPositionsValue?: number;
|
||||||
botsAllocationUsdValue?: number;
|
botsAllocationUsdValue?: number;
|
||||||
pnL?: number;
|
pnL?: number;
|
||||||
time?: Date;
|
time?: Date;
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
const latestBalance = balances[balances.length - 1]
|
const latestBalance = balances[balances.length - 1]
|
||||||
return {
|
return {
|
||||||
totalBalanceValue: latestBalance.totalBalanceValue || 0,
|
totalBalanceValue: latestBalance.totalBalanceValue || 0,
|
||||||
|
usdcWalletValue: latestBalance.usdcWalletValue || 0,
|
||||||
|
usdcInPositionsValue: latestBalance.usdcInPositionsValue || 0,
|
||||||
botsAllocation: latestBalance.botsAllocationUsdValue || 0,
|
botsAllocation: latestBalance.botsAllocationUsdValue || 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,12 +141,16 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
|
|
||||||
const dates = sortedBalances.map(balance => new Date(balance.time || 0))
|
const dates = sortedBalances.map(balance => new Date(balance.time || 0))
|
||||||
const totalBalanceValues = sortedBalances.map(balance => balance.totalBalanceValue || 0)
|
const totalBalanceValues = sortedBalances.map(balance => balance.totalBalanceValue || 0)
|
||||||
|
const usdcWalletValues = sortedBalances.map(balance => balance.usdcWalletValue || 0)
|
||||||
|
const usdcInPositionsValues = sortedBalances.map(balance => balance.usdcInPositionsValue || 0)
|
||||||
const botsAllocationValues = sortedBalances.map(balance => balance.botsAllocationUsdValue || 0)
|
const botsAllocationValues = sortedBalances.map(balance => balance.botsAllocationUsdValue || 0)
|
||||||
const pnlValues = sortedBalances.map(balance => balance.pnL || 0)
|
const pnlValues = sortedBalances.map(balance => balance.pnL || 0)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dates,
|
dates,
|
||||||
totalBalanceValues,
|
totalBalanceValues,
|
||||||
|
usdcWalletValues,
|
||||||
|
usdcInPositionsValues,
|
||||||
botsAllocationValues,
|
botsAllocationValues,
|
||||||
pnlValues
|
pnlValues
|
||||||
}
|
}
|
||||||
@@ -247,11 +253,19 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
{currentBalance && (
|
{currentBalance && (
|
||||||
<div className="mb-6 p-4 bg-primary/10 rounded-lg border border-primary/20">
|
<div className="mb-6 p-4 bg-primary/10 rounded-lg border border-primary/20">
|
||||||
<h3 className="text-lg font-semibold mb-2">Current Balance</h3>
|
<h3 className="text-lg font-semibold mb-2">Current Balance</h3>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<div className="text-sm opacity-70">Total Balance Value</div>
|
<div className="text-sm opacity-70">Total Balance Value</div>
|
||||||
<div className="text-2xl font-bold">${currentBalance.totalBalanceValue.toLocaleString(undefined, { maximumFractionDigits: 2 })}</div>
|
<div className="text-2xl font-bold">${currentBalance.totalBalanceValue.toLocaleString(undefined, { maximumFractionDigits: 2 })}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-sm opacity-70">USDC in Wallet</div>
|
||||||
|
<div className="text-xl font-semibold text-blue-500">${currentBalance.usdcWalletValue.toLocaleString(undefined, { maximumFractionDigits: 2 })}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-sm opacity-70">USDC in Positions</div>
|
||||||
|
<div className="text-xl font-semibold text-green-500">${currentBalance.usdcInPositionsValue.toLocaleString(undefined, { maximumFractionDigits: 2 })}</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="text-sm opacity-70">Bots Allocation</div>
|
<div className="text-sm opacity-70">Bots Allocation</div>
|
||||||
<div className="text-xl font-semibold">${currentBalance.botsAllocation.toLocaleString(undefined, { maximumFractionDigits: 2 })}</div>
|
<div className="text-xl font-semibold">${currentBalance.botsAllocation.toLocaleString(undefined, { maximumFractionDigits: 2 })}</div>
|
||||||
@@ -275,14 +289,32 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
line: { color: theme.primary, width: 3 },
|
line: { color: theme.primary, width: 3 },
|
||||||
marker: { size: 6 }
|
marker: { size: 6 }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
x: chartData.dates,
|
||||||
|
y: chartData.usdcWalletValues,
|
||||||
|
type: 'scatter' as const,
|
||||||
|
mode: 'lines+markers' as const,
|
||||||
|
name: 'USDC in Wallet',
|
||||||
|
line: { color: '#3b82f6', width: 2 },
|
||||||
|
marker: { size: 5 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: chartData.dates,
|
||||||
|
y: chartData.usdcInPositionsValues,
|
||||||
|
type: 'scatter' as const,
|
||||||
|
mode: 'lines+markers' as const,
|
||||||
|
name: 'USDC in Positions',
|
||||||
|
line: { color: '#10b981', width: 2 },
|
||||||
|
marker: { size: 5 }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
x: chartData.dates,
|
x: chartData.dates,
|
||||||
y: chartData.botsAllocationValues,
|
y: chartData.botsAllocationValues,
|
||||||
type: 'scatter' as const,
|
type: 'scatter' as const,
|
||||||
mode: 'lines+markers' as const,
|
mode: 'lines+markers' as const,
|
||||||
name: 'Bots Allocation',
|
name: 'Bots Allocation',
|
||||||
line: { color: theme.success, width: 3 },
|
line: { color: theme.success, width: 2 },
|
||||||
marker: { size: 6 }
|
marker: { size: 5 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
x: chartData.dates,
|
x: chartData.dates,
|
||||||
@@ -290,8 +322,8 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
type: 'scatter' as const,
|
type: 'scatter' as const,
|
||||||
mode: 'lines+markers' as const,
|
mode: 'lines+markers' as const,
|
||||||
name: 'PnL',
|
name: 'PnL',
|
||||||
line: { color: theme.warning, width: 3 },
|
line: { color: theme.warning, width: 2 },
|
||||||
marker: { size: 6 }
|
marker: { size: 5 }
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
layout={{
|
layout={{
|
||||||
|
|||||||
Reference in New Issue
Block a user