Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consolidator of 5m for live-data will always miss last minute trading bar, is it a bug? #8363

Open
iSkywalker168 opened this issue Oct 6, 2024 · 0 comments
Assignees

Comments

@iSkywalker168
Copy link

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:
image

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants