def update_bar(self, bar: BarData) -> None:
"""
Update 1 minute bar into generator
"""
# If not inited, creaate window bar object
if not self.window_bar:
# Generate timestamp for bar data
if self.interval == Interval.MINUTE:
dt = bar.datetime.replace(second=0, microsecond=0)
else:
dt = bar.datetime.replace(minute=0, second=0, microsecond=0)
self.window_bar = BarData(
symbol=bar.symbol,
exchange=bar.exchange,
datetime=dt,
gateway_name=bar.gateway_name,
open_price=bar.open_price,
high_price=bar.high_price,
low_price=bar.low_price
)
# Otherwise, update high/low price into window bar
else:
self.window_bar.high_price = max(
self.window_bar.high_price, bar.high_price)
self.window_bar.low_price = min(
self.window_bar.low_price, bar.low_price)
# Update close price/volume into window bar
self.window_bar.close_price = bar.close_price
self.window_bar.volume += int(bar.volume)
self.window_bar.open_interest = bar.open_interest
# Check if window bar completed
finished = False
if self.interval == Interval.MINUTE:
# x-minute bar
if not (bar.datetime.minute + 1) % self.window:
finished = True
elif self.interval == Interval.HOUR:
if self.last_bar:
new_hour = bar.datetime.hour != self.last_bar.datetime.hour
last_minute = bar.datetime.minute == 59
if new_hour or last_minute:
# 1-hour bar
if self.window == 1:
finished = True
# x-hour bar
else:
self.interval_count += 1
if not self.interval_count % self.window:
finished = True
self.interval_count = 0
if finished:
self.on_window_bar(self.window_bar)
self.window_bar = None
# Cache last bar object
self.last_bar = bar
print('bar:',bar)
print('window_bar:',self.window_bar)
print('')
尝试合成5分钟k线,我在每次update_bar时将bar和self.window_bar打印出来,结果如下:
米筐的分钟数据是从9:01开始打时间戳的,代表9:00到9:01这一分钟的数据。测试发现k线合成走到9:04分的时候就结束了(finished=True,self.window_bar=None),只用了9:00~9:04这四根1分钟k线就合成了第一根5分钟k线,而9:04-9:05这一分钟最新数据完全没有用到。依次类推,第二根5分钟k线用的是9:05~9:09的数据,而9:09~9:10这一分钟也被忽略了。回测模式下,合成k线时总是会漏掉最新的一分钟k线,这个影响还是挺大的吧。