BarGenerator的update_bar中,小时线的finished的是需要一个新分钟bar的hour不同来触发的,这样的结果是,这个新分钟bar已经被合成到现有的window_bar中,造成所有的小时线总是会多出下个小时的一分钟数据而少了自己开始的一分钟数据。这个问题可以通过修改代码顺序避免,下面是我修改后的update_bar函数。
def update_bar(self, bar: BarData):
"""
Update 1 minute bar into generator
"""
# Check if window bar completed
if self.window_bar and self.last_bar:
finished = False
if self.interval == Interval.MINUTE:
# x-minute bar
if not bar.datetime.minute % self.window:
finished = True
elif self.interval == Interval.HOUR:
if self.last_bar and bar.datetime.hour != self.last_bar.datetime.hour:
# 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
# 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
# Cache last bar object
self.last_bar = bar
具体思路就是把切断和向外回调的代码前置了,这里需要注意的是分钟线的合成由于代码前置了,所以需要改成
if not bar.datetime.minute % self.window:
这样的判断条件