Add automatic swap when low ETH
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using Managing.Application.Abstractions;
|
||||
using Managing.Application.Abstractions.Grains;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Common;
|
||||
using Managing.Core;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Bots;
|
||||
@@ -291,6 +293,70 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
return;
|
||||
}
|
||||
|
||||
// Check broker balance before running
|
||||
var balances = await ServiceScopeHelpers.WithScopedService<IExchangeService, List<Balance>>(_scopeFactory, async exchangeService =>
|
||||
{
|
||||
return await exchangeService.GetBalances(_tradingBot.Account, false);
|
||||
|
||||
});
|
||||
|
||||
var usdcBalance = balances.FirstOrDefault(b => b.TokenName == Ticker.USDC.ToString());
|
||||
var ethBalance = balances.FirstOrDefault(b => b.TokenName == Ticker.ETH.ToString());
|
||||
|
||||
// Check USDC balance first
|
||||
if (usdcBalance?.Value < Constants.GMX.Config.MinimumPositionAmount)
|
||||
{
|
||||
await _tradingBot.LogWarning(
|
||||
$"USDC balance is below {Constants.GMX.Config.MinimumPositionAmount} USD (actual: {usdcBalance?.Value:F2}). Stopping bot {_tradingBot.Identifier}.");
|
||||
|
||||
await StopAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check ETH balance and perform automatic swap if needed
|
||||
var ethValueInUsd = ethBalance?.Value * ethBalance?.Price ?? 0;
|
||||
if (ethValueInUsd < 2) // ETH balance below 2 USD
|
||||
{
|
||||
await _tradingBot.LogWarning(
|
||||
$"ETH balance is below 2 USD (actual: {ethValueInUsd:F2}). Attempting to swap USDC to ETH.");
|
||||
|
||||
// Check if we have enough USDC for the swap
|
||||
if (usdcBalance?.Value >= 5) // Need at least 5 USD for swap
|
||||
{
|
||||
try
|
||||
{
|
||||
var swapInfo = await ServiceScopeHelpers.WithScopedService<IAccountService, SwapInfos>(_scopeFactory, async accountService =>
|
||||
{
|
||||
return await accountService.SwapGmxTokensAsync(_state.State.User, _tradingBot.Account.Name, Ticker.USDC, Ticker.ETH, 5);
|
||||
});
|
||||
|
||||
if (swapInfo.Success)
|
||||
{
|
||||
await NotifyUserAboutSwap(true, 5, swapInfo.Hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
await NotifyUserAboutSwap(false, 5, null, swapInfo.Error ?? swapInfo.Message);
|
||||
await StopAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await NotifyUserAboutSwap(false, 5, null, ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Both USDC and ETH are low - stop the strategy
|
||||
await _tradingBot.LogWarning(
|
||||
$"Both USDC ({usdcBalance?.Value:F2}) and ETH ({ethValueInUsd:F2}) balances are low. Stopping bot {_tradingBot.Identifier}.");
|
||||
|
||||
await StopAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the bot's Run method
|
||||
await _tradingBot.Run();
|
||||
SyncStateFromBase();
|
||||
@@ -680,4 +746,37 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
_logger.LogError(ex, "Failed to save bot statistics for bot {BotId}", _state.State.Identifier);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the user about swap operations via webhook/telegram
|
||||
/// </summary>
|
||||
private async Task NotifyUserAboutSwap(bool isSuccess, decimal amount, string? transactionHash, string? errorMessage = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var message = isSuccess
|
||||
? $"🔄 **Automatic Swap Successful**\n\n" +
|
||||
$"🎯 **Bot:** {_tradingBot?.Identifier}\n" +
|
||||
$"💰 **Amount:** {amount} USDC → ETH\n" +
|
||||
$"✅ **Status:** Success\n" +
|
||||
$"🔗 **Transaction:** {transactionHash}\n" +
|
||||
$"⏰ **Time:** {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC"
|
||||
: $"❌ **Automatic Swap Failed**\n\n" +
|
||||
$"🎯 **Bot:** {_tradingBot?.Identifier}\n" +
|
||||
$"💰 **Amount:** {amount} USDC → ETH\n" +
|
||||
$"❌ **Status:** Failed\n" +
|
||||
$"⚠️ **Error:** {errorMessage}\n" +
|
||||
$"⏰ **Time:** {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC";
|
||||
|
||||
// Send notification via webhook service
|
||||
await ServiceScopeHelpers.WithScopedService<IWebhookService>(_scopeFactory, async webhookService =>
|
||||
{
|
||||
await webhookService.SendMessage(message, _state.State.User?.TelegramChannel);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to send swap notification for bot {BotId}", _tradingBot?.Identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user