Clean code, remove warning for future and spot
This commit is contained in:
@@ -94,7 +94,7 @@ public class SpotBot : TradingBotBase
|
||||
// Try to get current price from exchange
|
||||
currentPrice = await ServiceScopeHelpers.WithScopedService<IExchangeService, decimal>(
|
||||
_scopeFactory,
|
||||
async exchangeService => { return await exchangeService.GetCurrentPrice(Account, Config.Ticker); });
|
||||
async exchangeService => await exchangeService.GetCurrentPrice(Account, Config.Ticker));
|
||||
}
|
||||
|
||||
if (currentPrice == 0)
|
||||
@@ -144,10 +144,7 @@ public class SpotBot : TradingBotBase
|
||||
{
|
||||
// For live trading, get real-time candle from exchange
|
||||
return await ServiceScopeHelpers.WithScopedService<IExchangeService, Candle>(_scopeFactory,
|
||||
async exchangeService =>
|
||||
{
|
||||
return await exchangeService.GetCandle(Account, Config.Ticker, DateTime.UtcNow);
|
||||
});
|
||||
async exchangeService => await exchangeService.GetCandle(Account, Config.Ticker, DateTime.UtcNow));
|
||||
}
|
||||
|
||||
protected override async Task<bool> CheckBrokerPositions()
|
||||
@@ -164,7 +161,7 @@ public class SpotBot : TradingBotBase
|
||||
if (hasOpenPosition)
|
||||
{
|
||||
// We have an internal position - verify it matches broker balance
|
||||
if (tokenBalance != null && tokenBalance.Amount > 0)
|
||||
if (tokenBalance is { Amount: > 0 })
|
||||
{
|
||||
await LogDebugAsync(
|
||||
$"✅ Spot Position Verified\n" +
|
||||
@@ -174,17 +171,16 @@ public class SpotBot : TradingBotBase
|
||||
$"Position matches broker balance");
|
||||
return false; // Position already open, cannot open new one
|
||||
}
|
||||
else
|
||||
{
|
||||
await LogWarningAsync(
|
||||
$"⚠️ Position Mismatch\n" +
|
||||
$"Ticker: {Config.Ticker}\n" +
|
||||
$"Internal position exists but no token balance found\n" +
|
||||
$"Position may need synchronization");
|
||||
return false; // Don't allow opening new position until resolved
|
||||
}
|
||||
|
||||
await LogWarningAsync(
|
||||
$"⚠️ Position Mismatch\n" +
|
||||
$"Ticker: {Config.Ticker}\n" +
|
||||
$"Internal position exists but no token balance found\n" +
|
||||
$"Position may need synchronization");
|
||||
return false; // Don't allow opening new position until resolved
|
||||
}
|
||||
else if (tokenBalance != null && tokenBalance.Value > 1m)
|
||||
|
||||
if (tokenBalance is { Value: > 1m })
|
||||
{
|
||||
// We have a token balance but no internal position - orphaned position
|
||||
await LogWarningAsync(
|
||||
@@ -212,7 +208,7 @@ public class SpotBot : TradingBotBase
|
||||
if (Config.TradingType == TradingType.BacktestSpot) return;
|
||||
await ServiceScopeHelpers.WithScopedService<IAccountService>(_scopeFactory, async accountService =>
|
||||
{
|
||||
var account = await accountService.GetAccountByAccountName(Config.AccountName, false, false);
|
||||
var account = await accountService.GetAccountByAccountName(Config.AccountName, false);
|
||||
Account = account;
|
||||
});
|
||||
}
|
||||
@@ -227,7 +223,7 @@ public class SpotBot : TradingBotBase
|
||||
_scopeFactory,
|
||||
async exchangeService => await exchangeService.GetBalance(Account, Config.Ticker));
|
||||
|
||||
if (tokenBalance != null && tokenBalance.Amount > 0)
|
||||
if (tokenBalance is { Amount: > 0 })
|
||||
{
|
||||
// Verify that the token balance matches the position amount with 0.1% tolerance
|
||||
var positionQuantity = internalPosition.Open.Quantity;
|
||||
@@ -281,7 +277,7 @@ public class SpotBot : TradingBotBase
|
||||
// Calculate and update PnL based on current price
|
||||
var currentPrice = await ServiceScopeHelpers.WithScopedService<IExchangeService, decimal>(
|
||||
_scopeFactory,
|
||||
async exchangeService => { return await exchangeService.GetCurrentPrice(Account, Config.Ticker); });
|
||||
async exchangeService => await exchangeService.GetCurrentPrice(Account, Config.Ticker));
|
||||
|
||||
if (currentPrice > 0)
|
||||
{
|
||||
@@ -353,17 +349,16 @@ public class SpotBot : TradingBotBase
|
||||
await LogDebugAsync(
|
||||
$"🔍 Checking Spot Position History for Position: `{position.Identifier}`\nTicker: `{Config.Ticker}`");
|
||||
|
||||
List<Position> positionHistory = null;
|
||||
await ServiceScopeHelpers.WithScopedService<IExchangeService>(_scopeFactory,
|
||||
var positionHistory = await ServiceScopeHelpers.WithScopedService<IExchangeService, List<Position>>(
|
||||
_scopeFactory,
|
||||
async exchangeService =>
|
||||
{
|
||||
var fromDate = DateTime.UtcNow.AddHours(-24);
|
||||
var toDate = DateTime.UtcNow;
|
||||
positionHistory =
|
||||
await exchangeService.GetSpotPositionHistory(Account, Config.Ticker, fromDate, toDate);
|
||||
return await exchangeService.GetSpotPositionHistory(Account, Config.Ticker, fromDate, toDate);
|
||||
});
|
||||
|
||||
if (positionHistory != null && positionHistory.Any())
|
||||
if (positionHistory != null && positionHistory.Count != 0)
|
||||
{
|
||||
var recentPosition = positionHistory
|
||||
.OrderByDescending(p => p.Date)
|
||||
@@ -415,28 +410,28 @@ public class SpotBot : TradingBotBase
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task MonitorSynthRisk(LightSignal signal, Position position)
|
||||
protected override Task MonitorSynthRisk(LightSignal signal, Position position)
|
||||
{
|
||||
// Spot trading doesn't use Synth risk monitoring (futures-specific feature)
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
protected override async Task<bool> RecoverOpenPositionFromBroker(LightSignal signal, Position positionForSignal)
|
||||
protected override Task<bool> RecoverOpenPositionFromBroker(LightSignal signal, Position positionForSignal)
|
||||
{
|
||||
// Spot trading doesn't have broker positions to recover
|
||||
// Positions are token balances, not tracked positions
|
||||
return false;
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
protected override async Task<bool> ReconcileWithBrokerHistory(Position position, Candle currentCandle)
|
||||
protected override Task<bool> ReconcileWithBrokerHistory(Position position, Candle currentCandle)
|
||||
{
|
||||
// Spot trading doesn't have broker position history like futures
|
||||
// Return false to continue with candle-based calculation
|
||||
return false;
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
protected override async Task<(decimal closingPrice, bool pnlCalculated)> CalculatePositionClosingFromCandles(
|
||||
Position position, Candle currentCandle, bool forceMarketClose, decimal? forcedClosingPrice)
|
||||
protected override Task<(decimal closingPrice, bool pnlCalculated)> CalculatePositionClosingFromCandles(
|
||||
Position position, Candle? currentCandle, bool forceMarketClose, decimal? forcedClosingPrice)
|
||||
{
|
||||
decimal closingPrice = 0;
|
||||
bool pnlCalculated = false;
|
||||
@@ -529,7 +524,7 @@ public class SpotBot : TradingBotBase
|
||||
? closingPrice > position.Open.Price
|
||||
: closingPrice < position.Open.Price;
|
||||
|
||||
if (isManualCloseProfitable)
|
||||
if (isManualCloseProfitable && position.TakeProfit1 != null)
|
||||
{
|
||||
position.TakeProfit1.SetPrice(closingPrice, 2);
|
||||
position.TakeProfit1.SetDate(currentCandle.Date);
|
||||
@@ -542,9 +537,9 @@ public class SpotBot : TradingBotBase
|
||||
}
|
||||
else
|
||||
{
|
||||
position.StopLoss.SetPrice(closingPrice, 2);
|
||||
position.StopLoss.SetDate(currentCandle.Date);
|
||||
position.StopLoss.SetStatus(TradeStatus.Filled);
|
||||
position.StopLoss?.SetPrice(closingPrice, 2);
|
||||
position.StopLoss?.SetDate(currentCandle.Date);
|
||||
position.StopLoss?.SetStatus(TradeStatus.Filled);
|
||||
|
||||
if (position.TakeProfit1 != null)
|
||||
{
|
||||
@@ -561,11 +556,11 @@ public class SpotBot : TradingBotBase
|
||||
pnlCalculated = true;
|
||||
}
|
||||
|
||||
return (closingPrice, pnlCalculated);
|
||||
return Task.FromResult((closingPrice, pnlCalculated));
|
||||
}
|
||||
|
||||
protected override async Task UpdateSignalsCore(IReadOnlyList<Candle> candles,
|
||||
Dictionary<IndicatorType, IndicatorsResultBase> preCalculatedIndicatorValues = null)
|
||||
Dictionary<IndicatorType, IndicatorsResultBase>? preCalculatedIndicatorValues = null)
|
||||
{
|
||||
// For spot trading, always fetch signals regardless of open positions
|
||||
// Check if we're in cooldown period
|
||||
@@ -625,7 +620,7 @@ public class SpotBot : TradingBotBase
|
||||
return !await IsInCooldownPeriodAsync() && await CheckLossStreak(signal);
|
||||
}
|
||||
|
||||
protected override async Task<Position> HandleFlipPosition(LightSignal signal, Position openedPosition,
|
||||
protected override async Task<Position?> HandleFlipPosition(LightSignal signal, Position openedPosition,
|
||||
LightSignal previousSignal, decimal lastPrice)
|
||||
{
|
||||
// For spot trading, SHORT signals should close the open LONG position
|
||||
@@ -694,10 +689,8 @@ public class SpotBot : TradingBotBase
|
||||
.WithScopedServices<IExchangeService, IAccountService, ITradingService, Position>(
|
||||
_scopeFactory,
|
||||
async (exchangeService, accountService, tradingService) =>
|
||||
{
|
||||
return await new OpenSpotPositionCommandHandler(exchangeService, accountService, tradingService)
|
||||
.Handle(command);
|
||||
});
|
||||
await new OpenSpotPositionCommandHandler(exchangeService, accountService, tradingService)
|
||||
.Handle(command));
|
||||
|
||||
return position;
|
||||
}
|
||||
@@ -725,7 +718,7 @@ public class SpotBot : TradingBotBase
|
||||
await SetPositionStatus(signal.Identifier, PositionStatus.Finished);
|
||||
}
|
||||
|
||||
await HandleClosedPosition(closedPosition, forceMarketClose ? lastPrice : (decimal?)null,
|
||||
await HandleClosedPosition(closedPosition, forceMarketClose ? lastPrice : null,
|
||||
forceMarketClose);
|
||||
}
|
||||
else
|
||||
@@ -742,7 +735,7 @@ public class SpotBot : TradingBotBase
|
||||
// Trade close on exchange => Should close trade manually
|
||||
await SetPositionStatus(signal.Identifier, PositionStatus.Finished);
|
||||
// Ensure trade dates are properly updated even for canceled/rejected positions
|
||||
await HandleClosedPosition(position, forceMarketClose ? lastPrice : (decimal?)null,
|
||||
await HandleClosedPosition(position, forceMarketClose ? lastPrice : null,
|
||||
forceMarketClose);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user