Fix close position
This commit is contained in:
@@ -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)
|
_scopeFactory,
|
||||||
{
|
async exchangeService => { return await exchangeService.GetCurrentPrice(Account, Config.Ticker); });
|
||||||
currentPrice = await ServiceScopeHelpers.WithScopedService<IExchangeService, decimal>(
|
|
||||||
_scopeFactory,
|
|
||||||
async exchangeService =>
|
|
||||||
{
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user