Lean
Lean copied to clipboard
consolidator of 5m for live-data will always miss last minute trading bar, is it a bug?
from AlgorithmImports import *
import datetime
import os
import ctypes
class QuantConnectVilla(QCAlgorithm):
def initialize(self):
self.set_time_zone(TimeZones.UTC)
self.set_account_currency("FDUSD")
# for backtesting
self.set_start_date(2024, 6, 24)
self.set_end_date(2024, 6, 26)
self.set_cash("FDUSD", 100)
self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN)
self.symbol = self.add_crypto(ticker="DOGEFDUSD", resolution=Resolution.MINUTE, leverage=5).symbol
self.set_benchmark(self.symbol)
self.add_data(CustomCryptoData, self.symbol, Resolution.MINUTE).symbol
self._consolidator = TradeBarConsolidator(datetime.timedelta(minutes=5))
self._consolidator.data_consolidated += self.bar_handler
# indicators
self.rsi = RelativeStrengthIndex(period=16, movingAverageType=MovingAverageType.WILDERS)
self.atr = AverageTrueRange(period=7, movingAverageType=MovingAverageType.WILDERS)
self.register_indicator(self.symbol, self.rsi, self._consolidator)
self.register_indicator(self.symbol, self.atr, self._consolidator)
def on_data(self, slice: Slice):
if not slice.has_data:
return
trade_bar = slice.bars.get(self.symbol)
quote_bar = slice.quote_bars.get(self.symbol)
bar_start_time = trade_bar.time.strftime("%Y-%m-%d %H:%M:%S")
bar_end_time = trade_bar.end_time.strftime("%Y-%m-%d %H:%M:%S")
self.log(f"trade_bar: `{bar_start_time}-{bar_end_time}`, {trade_bar}")
def bar_handler(self, sender: object, bar: TradeBar):
bar_start_time = bar.time.strftime("%Y-%m-%d %H:%M:%S")
bar_end_time = bar.end_time.strftime("%Y-%m-%d %H:%M:%S")
self.log(f"fkbar: `{bar_start_time}-{bar_end_time}`, {bar}")
if self.rsi.is_ready:
rsi_value = self.rsi.current.value
self.log(f"rsi_value: {rsi_value}")
if self.atr.is_ready:
atr_value = self.atr.current.value
self.log(f"atr_value: {atr_value}")
class CustomCryptoData(PythonData):
def get_source(self, config, date, is_live_mode):
tick_type_string = Extensions.tick_type_to_lower(config.tick_type)
formatted_date = date.strftime("%Y%m%d")
source = os.path.join(Globals.DataFolder, "crypto", "binance", "minute", config.symbol.value.lower(), f"{formatted_date}_{tick_type_string}.zip")
return SubscriptionDataSource(source, SubscriptionTransportMedium.LOCAL_FILE, FileFormat.CSV)
def reader(self, config, line, date, is_live_mode):
csv = line.split(",")
data = CustomCryptoData()
data.symbol = config.symbol
data_datetime = datetime.datetime.combine(date.date(), datetime.time()) + datetime.timedelta(milliseconds=int(csv[0]))
data.time = Extensions.convert_to(data_datetime, config.data_time_zone, config.exchange_time_zone)
data.end_time = data.time + datetime.timedelta(minutes=1)
data["Open"] = float(csv[1])
data["High"] = float(csv[2])
data["Low"] = float(csv[3])
data["Close"] = float(csv[4])
data["Volume"] = float(csv[5])
data.value = float(csv[4])
return data
for above code, if set live-binance mode, bar_handler will be triggered every 5 minutes. when compared the bar with Binance data, the provided bar from bar_handler will always miss the fifth-minute trading data. that's to say, bar_handler will got me a TradeBar only contains the first 4 minutes trading data.
The related code is as follows:
after changing currentLocalTime - _workingBar.Time >= _period.Value && GetRoundedBarTime(currentLocalTime) > _lastEmit) as currentLocalTime - _workingBar.Time > _period.Value && GetRoundedBarTime(currentLocalTime) > _lastEmit), I will get exactly identical living 5-minute candles with Binance.
please help have a check, is it a bug?