Bar data is always 2 minutes late

I printed the datetime of the current bar data been processed in backtrader next(). The live bar data is always 2 minutes, not 1m, late. I used the following code to add data

    data_1m = DataFactory(  dataname=symbol,
                            historical=False,
                            timeframe = bt.TimeFrame.Minutes,
                            compression = 1,
                            backfill_start=False,
                            #data_feed='iex'
                        )

    global_cerebro.adddata(data_1m, name=symbol)

I understand, that if current timestamp is 10:51, the last finished bar timestamp is 10:50, so i am okay with it being 1m late. but not sure why it’s always consistantly 2m late.

@yann I’m not familiar with backtrader but the issue may be in how bars are labeled? The industry convention is to label bars by their start time. As an example, the bar labeled 9:32 will have trades between 9:32 → 9:33. Alpaca waits 2-3 seconds after the end of the bar to publish it. So, at 9:33:03 (or after) the 9:32 bar would be available. Could that be the issue?

thanks for the reply. I am afraid that’s not the issue. The most recent bar returned is 2m late than the other real time app. I manually check the open close high low price of the latest bar returned by alpaca, it’s 2 bars delayed.

is it because the https://github.com/alpacahq/alpaca-trade-api-python is deprecated or unmaintaned?

@yann That must be something with how backtrader is fetching data. As mentioned above, Alpaca generates the latest bar 2-3 seconds after each minute and the most ‘delayed’ it would ever be is 1 minute past that (ie the bar doesn’t change until 2-3 seconds after the next minute). This probably isn’t the issue, but note that bars are only generated if there are trades. There can often be ‘missing’ bars simply because there were no trades during that time.

looks like history bar request is always 1m late then the stream bar.

bar_list = []
# async handler
async def bar_data_handler(data):
    # real-time data will be displayed here after every minute
    print(data)

    cur_timestamp = data.timestamp

    start_timestamp = cur_timestamp - datetime.timedelta(minutes=10)

    request_params = CryptoBarsRequest(
                            symbol_or_symbols=symbol,
                            timeframe=TimeFrame.Minute,
                            start=start_timestamp,
                            end=cur_timestamp
                        )

    history_bars = history_client.get_crypto_bars(request_params)

    print("latest history_bars: ",history_bars.df.iloc[-1])
    
    bar_list.append(data)

    print("==== len of bar_list: ", len(bar_list))
wsc_client.subscribe_bars(bar_data_handler,  "BTC/USD")
wsc_client.run()

the results are:

symbol='BTC/USD' timestamp=datetime.datetime(2023, 3, 28, 7, 7, tzinfo=datetime.timezone.utc) open=27080.72 high=27086.53 low=27066.47 close=27076.22 volume=6.14704 trade_count=200.0 vwap=27076.1932046969

latest history_bars:  open           27081.460000
high           27085.660000
low            27076.550000
close          27080.720000
volume             1.200450
trade_count       51.000000
vwap           27081.421364
Name: (BTC/USD, 2023-03-28 07:06:00+00:00), dtype: float64
==== len of bar_list:  3

@Dan_Whitnable_Alpaca