Use usdc balance instead usdc value for ensuring balance check
This commit is contained in:
@@ -19,7 +19,7 @@ public interface IEvmManager
|
|||||||
string VerifySignature(string signature, string message);
|
string VerifySignature(string signature, string message);
|
||||||
Task<List<EvmBalance>> GetBalances(Chain chain, int page, int pageSize, string publicAddress);
|
Task<List<EvmBalance>> GetBalances(Chain chain, int page, int pageSize, string publicAddress);
|
||||||
Task<List<EvmBalance>> GetAllBalances(Chain chain, string publicAddress);
|
Task<List<EvmBalance>> GetAllBalances(Chain chain, string publicAddress);
|
||||||
Task<List<EvmBalance>> GetAllBalancesOnAllChain(string publicAddress);
|
Task<List<Balance>> GetAllBalancesOnAllChain(string publicAddress);
|
||||||
|
|
||||||
Task<List<Candle>> GetCandles(Ticker ticker, DateTime startDate,
|
Task<List<Candle>> GetCandles(Ticker ticker, DateTime startDate,
|
||||||
Timeframe interval, bool isFirstCall = false);
|
Timeframe interval, bool isFirstCall = false);
|
||||||
@@ -68,7 +68,7 @@ public interface IEvmManager
|
|||||||
Task<string> SignMessageAsync(string embeddedWalletId, string address, string message);
|
Task<string> SignMessageAsync(string embeddedWalletId, string address, string message);
|
||||||
|
|
||||||
Task<List<Position>> GetPositions(Account account);
|
Task<List<Position>> GetPositions(Account account);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears the cached balances for a specific chain and address
|
/// Clears the cached balances for a specific chain and address
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -590,7 +590,7 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userAccounts = await _accountService.GetAccountsByUserAsync(user, hideSecrets: true, true);
|
var userAccounts = await _accountService.GetAccountsByUserAsync(user, hideSecrets: true, false);
|
||||||
var account = userAccounts.FirstOrDefault(a => a.Name == accountName);
|
var account = userAccounts.FirstOrDefault(a => a.Name == accountName);
|
||||||
if (account == null)
|
if (account == null)
|
||||||
{
|
{
|
||||||
@@ -604,7 +604,7 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
var usdcBalance = balances.FirstOrDefault(b => b.TokenName?.ToUpper() == "USDC");
|
var usdcBalance = balances.FirstOrDefault(b => b.TokenName?.ToUpper() == "USDC");
|
||||||
|
|
||||||
var ethValueInUsd = ethBalance?.Amount * ethBalance?.Price ?? 0;
|
var ethValueInUsd = ethBalance?.Amount * ethBalance?.Price ?? 0;
|
||||||
var usdcValue = usdcBalance?.Value ?? 0;
|
var usdc = usdcBalance?.Amount ?? 0;
|
||||||
|
|
||||||
// Cache the balance data
|
// Cache the balance data
|
||||||
var balanceData = new CachedBalanceData
|
var balanceData = new CachedBalanceData
|
||||||
@@ -612,7 +612,7 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
LastFetched = DateTime.UtcNow,
|
LastFetched = DateTime.UtcNow,
|
||||||
AccountName = accountName,
|
AccountName = accountName,
|
||||||
EthValueInUsd = ethValueInUsd,
|
EthValueInUsd = ethValueInUsd,
|
||||||
UsdcValue = usdcValue
|
UsdcValue = usdc
|
||||||
};
|
};
|
||||||
|
|
||||||
_state.State.CachedBalanceData = balanceData;
|
_state.State.CachedBalanceData = balanceData;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace Managing.Application.Bots.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the cached data is still valid (less than 1 minute old)
|
/// Whether the cached data is still valid (less than 1 minute old)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsValid => DateTime.UtcNow - LastFetched < TimeSpan.FromMinutes(1.5);
|
public bool IsValid => DateTime.UtcNow - LastFetched < TimeSpan.FromMinutes(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -394,35 +394,28 @@ namespace Managing.Application.ManageBot
|
|||||||
var totalAllocatedForAccount = 0m;
|
var totalAllocatedForAccount = 0m;
|
||||||
var usdcBalance = account.Balances.FirstOrDefault(b => b.TokenName == Ticker.USDC.ToString());
|
var usdcBalance = account.Balances.FirstOrDefault(b => b.TokenName == Ticker.USDC.ToString());
|
||||||
|
|
||||||
if (botsForUser.Any())
|
foreach (var bot in botsForUser)
|
||||||
{
|
{
|
||||||
foreach (var bot in botsForUser)
|
if (excludeIdentifier != default && bot.Identifier == excludeIdentifier)
|
||||||
{
|
{
|
||||||
if (excludeIdentifier != default && bot.Identifier == excludeIdentifier)
|
continue;
|
||||||
{
|
}
|
||||||
continue;
|
|
||||||
}
|
var grain = _grainFactory.GetGrain<ILiveTradingBotGrain>(bot.Identifier);
|
||||||
|
TradingBotConfig config;
|
||||||
var grain = _grainFactory.GetGrain<ILiveTradingBotGrain>(bot.Identifier);
|
try
|
||||||
TradingBotConfig config;
|
{
|
||||||
try
|
config = await grain.GetConfiguration();
|
||||||
{
|
}
|
||||||
config = await grain.GetConfiguration();
|
catch
|
||||||
}
|
{
|
||||||
catch
|
continue;
|
||||||
{
|
}
|
||||||
continue;
|
|
||||||
}
|
if (string.Equals(config.AccountName, account.Name, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
if (string.Equals(config.AccountName, account.Name, StringComparison.OrdinalIgnoreCase))
|
totalAllocatedForAccount += config.BotTradingBalance;
|
||||||
{
|
|
||||||
totalAllocatedForAccount += config.BotTradingBalance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
totalAllocatedForAccount = usdcBalance?.Value ?? 0m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var usdcValue = usdcBalance?.Value ?? 0m;
|
var usdcValue = usdcBalance?.Value ?? 0m;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using Managing.Common;
|
using Managing.Common;
|
||||||
using Managing.Domain.Accounts;
|
using Managing.Domain.Accounts;
|
||||||
using Managing.Domain.Candles;
|
using Managing.Domain.Candles;
|
||||||
using Managing.Domain.Evm;
|
|
||||||
using Managing.Domain.Statistics;
|
using Managing.Domain.Statistics;
|
||||||
using Managing.Domain.Trades;
|
using Managing.Domain.Trades;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -45,21 +44,7 @@ public class EvmProcessor : BaseProcessor
|
|||||||
|
|
||||||
public override async Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false)
|
public override async Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false)
|
||||||
{
|
{
|
||||||
var balances = await _evmManager.GetAllBalancesOnAllChain(account.Key);
|
return await _evmManager.GetAllBalancesOnAllChain(account.Key);
|
||||||
return Map(balances);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Balance> Map(List<EvmBalance> balances)
|
|
||||||
{
|
|
||||||
return balances.ConvertAll(balance => new Balance
|
|
||||||
{
|
|
||||||
TokenName = balance.TokenName,
|
|
||||||
Price = balance.Price,
|
|
||||||
Value = balance.Value,
|
|
||||||
Amount = balance.Balance,
|
|
||||||
TokenAdress = balance.TokenAddress,
|
|
||||||
Chain = balance.Chain
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<Candle> GetCandle(Account account, Ticker ticker, DateTime date)
|
public override async Task<Candle> GetCandle(Account account, Ticker ticker, DateTime date)
|
||||||
@@ -73,7 +58,8 @@ public class EvmProcessor : BaseProcessor
|
|||||||
return await _evmManager.GetCandles(ticker, startDate, interval);
|
return await _evmManager.GetCandles(ticker, startDate, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe interval, bool isFirstCall)
|
public async Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe interval,
|
||||||
|
bool isFirstCall)
|
||||||
{
|
{
|
||||||
return await _evmManager.GetCandles(ticker, startDate, interval, isFirstCall);
|
return await _evmManager.GetCandles(ticker, startDate, interval, isFirstCall);
|
||||||
}
|
}
|
||||||
@@ -86,11 +72,13 @@ public class EvmProcessor : BaseProcessor
|
|||||||
public override async Task<decimal> GetPrice(Account account, Ticker ticker, DateTime date)
|
public override async Task<decimal> GetPrice(Account account, Ticker ticker, DateTime date)
|
||||||
{
|
{
|
||||||
var candles = await GetCandles(account, ticker, date, Timeframe.OneMinute, true);
|
var candles = await GetCandles(account, ticker, date, Timeframe.OneMinute, true);
|
||||||
|
|
||||||
if (candles == null || !candles.Any())
|
if (candles == null || !candles.Any())
|
||||||
{
|
{
|
||||||
_logger.LogError($"No candles available for ticker {ticker} at date {date:yyyy-MM-dd HH:mm:ss}. This could indicate a data source issue or invalid ticker.");
|
_logger.LogError(
|
||||||
throw new InvalidOperationException($"Cannot get price for {ticker} - no candle data available for the requested date {date:yyyy-MM-dd HH:mm:ss}. Please check if the ticker is valid and data source is accessible.");
|
$"No candles available for ticker {ticker} at date {date:yyyy-MM-dd HH:mm:ss}. This could indicate a data source issue or invalid ticker.");
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
$"Cannot get price for {ticker} - no candle data available for the requested date {date:yyyy-MM-dd HH:mm:ss}. Please check if the ticker is valid and data source is accessible.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return candles.Last().Close;
|
return candles.Last().Close;
|
||||||
@@ -110,7 +98,7 @@ public class EvmProcessor : BaseProcessor
|
|||||||
// Try to get the most recent candle data (last 5 minutes)
|
// Try to get the most recent candle data (last 5 minutes)
|
||||||
var recentDate = DateTime.UtcNow.AddMinutes(-5);
|
var recentDate = DateTime.UtcNow.AddMinutes(-5);
|
||||||
var candles = await GetCandles(account, ticker, recentDate, Timeframe.OneMinute, true);
|
var candles = await GetCandles(account, ticker, recentDate, Timeframe.OneMinute, true);
|
||||||
|
|
||||||
if (candles != null && candles.Any())
|
if (candles != null && candles.Any())
|
||||||
{
|
{
|
||||||
var latestCandle = candles.OrderByDescending(c => c.Date).First();
|
var latestCandle = candles.OrderByDescending(c => c.Date).First();
|
||||||
@@ -121,17 +109,19 @@ public class EvmProcessor : BaseProcessor
|
|||||||
// Fallback: Try to get price from a broader time range
|
// Fallback: Try to get price from a broader time range
|
||||||
var fallbackDate = DateTime.UtcNow.AddHours(-1);
|
var fallbackDate = DateTime.UtcNow.AddHours(-1);
|
||||||
var fallbackCandles = await GetCandles(account, ticker, fallbackDate, Timeframe.OneMinute, true);
|
var fallbackCandles = await GetCandles(account, ticker, fallbackDate, Timeframe.OneMinute, true);
|
||||||
|
|
||||||
if (fallbackCandles != null && fallbackCandles.Any())
|
if (fallbackCandles != null && fallbackCandles.Any())
|
||||||
{
|
{
|
||||||
var latestFallbackCandle = fallbackCandles.OrderByDescending(c => c.Date).First();
|
var latestFallbackCandle = fallbackCandles.OrderByDescending(c => c.Date).First();
|
||||||
_logger.LogWarning($"Using fallback price {latestFallbackCandle.Close} for {ticker} from 1-hour old data");
|
_logger.LogWarning(
|
||||||
|
$"Using fallback price {latestFallbackCandle.Close} for {ticker} from 1-hour old data");
|
||||||
return latestFallbackCandle.Close;
|
return latestFallbackCandle.Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all else fails, throw a descriptive error
|
// If all else fails, throw a descriptive error
|
||||||
_logger.LogError($"No price data available for {ticker} from any source");
|
_logger.LogError($"No price data available for {ticker} from any source");
|
||||||
throw new InvalidOperationException($"Cannot get current price for {ticker} - no price data available from broker. Please check if the ticker is valid and the broker is accessible.");
|
throw new InvalidOperationException(
|
||||||
|
$"Cannot get current price for {ticker} - no price data available from broker. Please check if the ticker is valid and the broker is accessible.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -162,7 +152,7 @@ public class EvmProcessor : BaseProcessor
|
|||||||
|
|
||||||
public override async Task<IEnumerable<Position>> GetPositions(Account account)
|
public override async Task<IEnumerable<Position>> GetPositions(Account account)
|
||||||
{
|
{
|
||||||
return await _evmManager.GetPositions(account);
|
return await _evmManager.GetPositions(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override decimal GetVolume(Account account, Ticker ticker)
|
public override decimal GetVolume(Account account, Ticker ticker)
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ public class EvmManager : IEvmManager
|
|||||||
"https://api.coingecko.com/api/v3/simple/price?ids=" + idsCombined + "&vs_currencies=usd");
|
"https://api.coingecko.com/api/v3/simple/price?ids=" + idsCombined + "&vs_currencies=usd");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<EvmBalance>> GetAllBalancesOnAllChain(string publicAddress)
|
public async Task<List<Balance>> GetAllBalancesOnAllChain(string publicAddress)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -352,44 +352,17 @@ public class EvmManager : IEvmManager
|
|||||||
var chains = new[] { "arbitrum" };
|
var chains = new[] { "arbitrum" };
|
||||||
|
|
||||||
// Get balances from Web3Proxy service
|
// Get balances from Web3Proxy service
|
||||||
var balances = await _web3ProxyService.GetWalletBalanceAsync(publicAddress, assets, chains);
|
return await _web3ProxyService.GetWalletBalanceAsync(publicAddress, assets, chains);
|
||||||
|
|
||||||
// Convert Balance objects to EvmBalance objects
|
// TODO : Update here to get all different chains
|
||||||
var evmBalances = new List<EvmBalance>();
|
// var othersChains = ChainService.GetChains();
|
||||||
|
//
|
||||||
foreach (var balance in balances)
|
// foreach (var chain in othersChains)
|
||||||
{
|
// {
|
||||||
if (balance.Amount > 0)
|
// evmBalances.AddRange(await GetAllBalances(chain, publicAddress));
|
||||||
{
|
// }
|
||||||
var evmBalance = new EvmBalance
|
//
|
||||||
{
|
// return evmBalances;
|
||||||
Balance = balance.Amount,
|
|
||||||
TokenName = balance.TokenName ?? "Unknown",
|
|
||||||
TokenAddress = balance.TokenAdress ?? "",
|
|
||||||
TokenImage = balance.TokenImage ?? "",
|
|
||||||
Price = balance.Price,
|
|
||||||
Value = balance.Value,
|
|
||||||
Chain = new Chain
|
|
||||||
{
|
|
||||||
Id = balance.Chain?.Id ?? "",
|
|
||||||
Name = balance.Chain?.Name ?? "Unknown",
|
|
||||||
ChainId = balance.Chain?.ChainId ?? 0,
|
|
||||||
RpcUrl = balance.Chain?.RpcUrl ?? ""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
evmBalances.Add(evmBalance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var othersChains = ChainService.GetChains();
|
|
||||||
|
|
||||||
foreach (var chain in othersChains)
|
|
||||||
{
|
|
||||||
evmBalances.AddRange(await GetAllBalances(chain, publicAddress));
|
|
||||||
}
|
|
||||||
|
|
||||||
return evmBalances;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -404,7 +377,7 @@ public class EvmManager : IEvmManager
|
|||||||
chainBalances.AddRange(await GetAllBalances(chain, publicAddress));
|
chainBalances.AddRange(await GetAllBalances(chain, publicAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
return chainBalances;
|
return EvmMappers.Map(chainBalances);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
20
src/Managing.Infrastructure.Web3/EvmMappers.cs
Normal file
20
src/Managing.Infrastructure.Web3/EvmMappers.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Managing.Domain.Accounts;
|
||||||
|
using Managing.Domain.Evm;
|
||||||
|
|
||||||
|
namespace Managing.Infrastructure.Evm;
|
||||||
|
|
||||||
|
public static class EvmMappers
|
||||||
|
{
|
||||||
|
public static List<Balance> Map(List<EvmBalance> balances)
|
||||||
|
{
|
||||||
|
return balances.ConvertAll(balance => new Balance
|
||||||
|
{
|
||||||
|
TokenName = balance.TokenName,
|
||||||
|
Price = balance.Price,
|
||||||
|
Value = balance.Value,
|
||||||
|
Amount = balance.Balance,
|
||||||
|
TokenAdress = balance.TokenAddress,
|
||||||
|
Chain = balance.Chain
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user