Fix close position

This commit is contained in:
2025-12-11 12:23:01 +07:00
parent 8ff9437400
commit 292a48d108
3 changed files with 21 additions and 22 deletions

View File

@@ -1,4 +1,3 @@
using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Grains; using Managing.Application.Abstractions.Grains;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Application.Trading.Commands; using Managing.Application.Trading.Commands;
@@ -18,7 +17,7 @@ using static Managing.Common.Enums;
namespace Managing.Application.Bots; namespace Managing.Application.Bots;
public class SpotBot : TradingBotBase, ITradingBot public class SpotBot : TradingBotBase
{ {
public SpotBot( public SpotBot(
ILogger<TradingBotBase> logger, ILogger<TradingBotBase> logger,
@@ -288,16 +287,9 @@ public class SpotBot : TradingBotBase, ITradingBot
} }
// Calculate and update PnL based on current price // Calculate and update PnL based on current price
var currentPrice = LastCandle?.Close ?? 0; var currentPrice = await ServiceScopeHelpers.WithScopedService<IExchangeService, decimal>(
if (currentPrice == 0)
{
currentPrice = await ServiceScopeHelpers.WithScopedService<IExchangeService, decimal>(
_scopeFactory, _scopeFactory,
async exchangeService => async exchangeService => { return await exchangeService.GetCurrentPrice(Account, Config.Ticker); });
{
return await exchangeService.GetCurrentPrice(Account, Config.Ticker);
});
}
if (currentPrice > 0) if (currentPrice > 0)
{ {
@@ -728,14 +720,11 @@ public class SpotBot : TradingBotBase, ITradingBot
var command = new CloseSpotPositionCommand(position, position.AccountId, lastPrice); var command = new CloseSpotPositionCommand(position, position.AccountId, lastPrice);
try try
{ {
Position closedPosition = null; Position closedPosition = await ServiceScopeHelpers
await ServiceScopeHelpers.WithScopedServices<IExchangeService, IAccountService, ITradingService>( .WithScopedServices<IExchangeService, IAccountService, ITradingService, Position>(
_scopeFactory, async (exchangeService, accountService, tradingService) => _scopeFactory, async (exchangeService, accountService, tradingService) =>
{
closedPosition =
await new CloseSpotPositionCommandHandler(exchangeService, accountService, tradingService) await new CloseSpotPositionCommandHandler(exchangeService, accountService, tradingService)
.Handle(command); .Handle(command));
});
if (closedPosition.Status == PositionStatus.Finished || closedPosition.Status == PositionStatus.Flipped) if (closedPosition.Status == PositionStatus.Finished || closedPosition.Status == PositionStatus.Flipped)
{ {

View File

@@ -23,6 +23,7 @@ public class CloseSpotPositionCommandHandler(
{ {
// For backtest, use execution price directly // For backtest, use execution price directly
var lastPrice = request.ExecutionPrice.GetValueOrDefault(); var lastPrice = request.ExecutionPrice.GetValueOrDefault();
var amountToSwap = request.Position.Open.Quantity;
// Calculate closing direction (opposite of opening direction) // Calculate closing direction (opposite of opening direction)
var direction = request.Position.OriginDirection == TradeDirection.Long var direction = request.Position.OriginDirection == TradeDirection.Long
@@ -47,12 +48,21 @@ public class CloseSpotPositionCommandHandler(
{ {
// For live trading, call SwapGmxTokensAsync // For live trading, call SwapGmxTokensAsync
var account = await accountService.GetAccountById(request.AccountId); var account = await accountService.GetAccountById(request.AccountId);
var tokenBalance = await exchangeService.GetBalance(account, request.Position.Ticker);
if (tokenBalance == null || tokenBalance.Amount <= 0)
{
throw new InvalidOperationException(
$"No available balance to close spot position for {request.Position.Ticker}");
}
amountToSwap = tokenBalance.Amount;
swapResult = await tradingService.SwapGmxTokensAsync( swapResult = await tradingService.SwapGmxTokensAsync(
request.Position.User, request.Position.User,
account.Name, account.Name,
request.Position.Ticker, request.Position.Ticker,
Ticker.USDC, Ticker.USDC,
(double)request.Position.Open.Quantity, (double)amountToSwap,
"market", "market",
null, null,
0.5); 0.5);
@@ -68,7 +78,7 @@ public class CloseSpotPositionCommandHandler(
var closedTrade = exchangeService.BuildEmptyTrade( var closedTrade = exchangeService.BuildEmptyTrade(
request.Position.Open.Ticker, request.Position.Open.Ticker,
lastPrice, lastPrice,
request.Position.Open.Quantity, amountToSwap,
direction, direction,
1, // Spot trading has no leverage 1, // Spot trading has no leverage
TradeType.Market, TradeType.Market,

View File

@@ -15,7 +15,7 @@ describe('swap tokens implementation', () => {
sdk, sdk,
Ticker.BTC, Ticker.BTC,
Ticker.USDC, Ticker.USDC,
0.00007555 0.00007559
) )
assert.strictEqual(typeof result, 'string') assert.strictEqual(typeof result, 'string')