Backtest opti (#10)

* Opti backtest

* clean
This commit is contained in:
Oda
2025-02-06 15:47:24 +07:00
committed by GitHub
parent 0987fa76cf
commit 9819fe014e
9 changed files with 78 additions and 47 deletions

View File

@@ -2,6 +2,7 @@
using Managing.Application.Abstractions.Services;
using Managing.Application.Trading;
using Managing.Application.Trading.Commands;
using Managing.Core.FixedSizedQueue;
using Managing.Domain.Accounts;
using Managing.Domain.Bots;
using Managing.Domain.Candles;
@@ -27,6 +28,7 @@ public class TradingBot : Bot, ITradingBot
public Account Account { get; set; }
public HashSet<IStrategy> Strategies { get; set; }
public FixedSizeQueue<Candle> OptimizedCandles { get; set; }
public HashSet<Candle> Candles { get; set; }
public HashSet<Signal> Signals { get; set; }
public List<Position> Positions { get; set; }
@@ -80,6 +82,7 @@ public class TradingBot : Bot, ITradingBot
Strategies = new HashSet<IStrategy>();
Signals = new HashSet<Signal>();
OptimizedCandles = new FixedSizeQueue<Candle>(600);
Candles = new HashSet<Candle>();
Positions = new List<Position>();
WalletBalances = new Dictionary<DateTime, decimal>();
@@ -160,13 +163,13 @@ public class TradingBot : Bot, ITradingBot
Logger.LogInformation(
$"Time : {DateTime.Now} - Server time {DateTime.Now.ToUniversalTime()} - Bot : {Name} - Type {BotType} - Ticker : {Ticker}");
var previousCandleCount = Candles.Count;
var previousCandleCount = OptimizedCandles.Count;
if (!IsForBacktest)
await UpdateCandles();
if (Candles.Count > previousCandleCount || IsForBacktest)
await UpdateSignals(Candles);
if (OptimizedCandles.Count > previousCandleCount || IsForBacktest)
await UpdateSignals(OptimizedCandles);
else
Logger.LogInformation($"No need to update signals for {Ticker}");
@@ -177,35 +180,38 @@ public class TradingBot : Bot, ITradingBot
SaveBackup();
await UpdateWalletBalances();
Logger.LogInformation($"Candles : {Candles.Count}");
Logger.LogInformation($"Signals : {Signals.Count}");
Logger.LogInformation($"ExecutionCount : {ExecutionCount}");
Logger.LogInformation($"Positions : {Positions.Count}");
Logger.LogInformation("__________________________________________________");
if (OptimizedCandles.Count % 100 == 0) // Log every 10th execution
{
Logger.LogInformation($"Candle date : {OptimizedCandles.Last().Date:u}");
Logger.LogInformation($"Signals : {Signals.Count}");
Logger.LogInformation($"ExecutionCount : {ExecutionCount}");
Logger.LogInformation($"Positions : {Positions.Count}");
Logger.LogInformation("__________________________________________________");
}
}
private async Task PreloadCandles()
{
if (Candles.Any())
if (OptimizedCandles.Any())
return;
var candles = await ExchangeService.GetCandlesInflux(Account.Exchange, Ticker, PreloadSince, Timeframe);
foreach (var candle in candles.Where(c => c.Date < DateTime.Now.ToUniversalTime()))
{
if (!Candles.Any(c => c.Date == candle.Date))
if (!OptimizedCandles.Any(c => c.Date == candle.Date))
{
Candles.Add(candle);
await UpdateSignals(Candles);
OptimizedCandles.Enqueue(candle);
await UpdateSignals(OptimizedCandles);
}
}
PreloadedCandlesCount = Candles.Count();
PreloadedCandlesCount = OptimizedCandles.Count();
}
private async Task UpdateSignals(HashSet<Candle> candles)
private async Task UpdateSignals(FixedSizeQueue<Candle> candles)
{
var signal = TradingBox.GetSignal(candles, Strategies, Signals);
var signal = TradingBox.GetSignal(candles.ToHashSet(), Strategies, Signals);
if (signal == null) return;
@@ -236,15 +242,15 @@ public class TradingBot : Bot, ITradingBot
protected async Task UpdateCandles()
{
if (Candles.Count == 0 || ExecutionCount == 0)
if (OptimizedCandles.Count == 0 || ExecutionCount == 0)
return;
var lastCandle = Candles.Last();
var lastCandle = OptimizedCandles.Last();
var newCandle = await ExchangeService.GetCandlesInflux(Account.Exchange, Ticker, lastCandle.Date, Timeframe);
foreach (var candle in newCandle.Where(c => c.Date < DateTime.Now.ToUniversalTime()))
{
Candles.Add(candle);
OptimizedCandles.Enqueue(candle);
}
}
@@ -269,17 +275,25 @@ public class TradingBot : Bot, ITradingBot
private async Task UpdateWalletBalances()
{
var lastCandle = OptimizedCandles.LastOrDefault();
if (lastCandle == null) return;
var date = lastCandle.Date;
if (WalletBalances.Count == 0)
{
WalletBalances.Add(Candles.LastOrDefault().Date, await ExchangeService.GetBalance(Account, IsForBacktest));
WalletBalances[date] = await ExchangeService.GetBalance(Account, IsForBacktest);
return;
}
else if (!WalletBalances.Any(w => w.Key == Candles.LastOrDefault().Date))
if (!WalletBalances.ContainsKey(date))
{
var walletBalance = WalletBalances.FirstOrDefault().Value + GetProfitAndLoss();
WalletBalances.Add(Candles.LastOrDefault().Date, walletBalance);
var previousBalance = WalletBalances.First().Value;
WalletBalances[date] = previousBalance + GetProfitAndLoss();
}
}
private async Task UpdatePosition(Signal signal, Position positionForSignal)
{
try
@@ -293,7 +307,6 @@ public class TradingBot : Bot, ITradingBot
if (position.Status == (PositionStatus.Finished | PositionStatus.Flipped))
{
await HandleClosedPosition(positionForSignal);
return;
}
else if (position.Status == PositionStatus.Filled)
{
@@ -301,7 +314,7 @@ public class TradingBot : Bot, ITradingBot
// check if position is still open
// Check status, if still open update the status of the position
var lastCandle = IsForBacktest
? Candles.Last()
? OptimizedCandles.Last()
: ExchangeService.GetCandle(Account, Ticker, DateTime.UtcNow);
if (positionForSignal.OriginDirection == TradeDirection.Long)
@@ -401,7 +414,7 @@ public class TradingBot : Bot, ITradingBot
&& p.SignalIdentifier != signal.Identifier);
var lastPrice = IsForBacktest
? Candles.Last().Close
? OptimizedCandles.Last().Close
: ExchangeService.GetPrice(Account, Ticker, DateTime.UtcNow);
// If position open
@@ -511,7 +524,7 @@ public class TradingBot : Bot, ITradingBot
if (lastPosition == null)
return true;
var tenCandleAgo = Candles.TakeLast(10).First();
var tenCandleAgo = OptimizedCandles.TakeLast(10).First();
var positionSignal = Signals.FirstOrDefault(s => s.Identifier == lastPosition.SignalIdentifier);
return positionSignal.Date < tenCandleAgo.Date;
@@ -543,8 +556,8 @@ public class TradingBot : Bot, ITradingBot
try
{
var closedPosition =
await (new ClosePositionCommandHandler(ExchangeService, AccountService, TradingService))
.Handle(command);
(new ClosePositionCommandHandler(ExchangeService, AccountService, TradingService)
.Handle(command)).Result;
if (closedPosition.Status == (PositionStatus.Finished | PositionStatus.Flipped))
{