vn.py量化社区
By Traders, For Traders.
Member
avatar
加入于:
帖子: 10
声望: 0

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:
这样的判断条件

Administrator
avatar
加入于:
帖子: 4208
声望: 237

这里的切分逻辑是正确的,类似问题论坛上已经有很多人问过了,翻翻历史帖子吧。

Member
avatar
加入于:
帖子: 10
声望: 0

我看了一下,两周前确实有人问了[同样的问题],(http://www.vnpy.com/forum/topic/2148-vnpy2-0-8-bargenerator-zhong-shi-yong-update-bar-he-cheng-1xiao-shi-kxian-de-yi-wen-yi-si-yong-dao-liao-wei-lai-shu-ju-ying-shi-fou-shi-ge-bug)但是最后依然没有讨论出个所以然来,最后一句是1小时bar是60个1分钟bar组成的,但不是rqdata历史数据中那个小时的完整数据,而是缺失了那个小时的第一个分钟bar,多了下个小时的第一个分钟bar。
这样合成1小时K线显示是不符合实际历史数据的

Member
avatar
加入于:
帖子: 10
声望: 0

这个帖子别沉了啊,老大给个明确解释吧

Member
avatar
加入于:
帖子: 10
声望: 0

请详细解释下这个问题啊

Administrator
avatar
加入于:
帖子: 4208
声望: 237

历史数据没有符合不符合的说法,只是每个软件自己选择的合成方式不同。

只要所有数据点都反映在了合成出来的K线中,就是正确的结果。

Administrator
avatar
加入于:
帖子: 4208
声望: 237

如果觉得内置的BarGenerator合成方式不符合自己的需求,可以通过继承或者直接重写的方式做一个替代,很简单的

Member
avatar
加入于:
帖子: 10
声望: 0

这个不能如此理解的,因为每个品种在每天开盘的时候价格波动都会很大,如果将第二日开盘的第一分钟合成到了上一日收盘最后一小时K线中,势必扭曲上一日收盘K线的信息,我这也不是第一次提供对源代码的修改意见了,我是希望官方的代码能做到最精确无误,这样我们这些使用者也可以不用自己去修改和替换呀

Member
avatar
加入于:
帖子: 1
声望: 0

我也遇到这个问题,合成的小时线与交易所的K线有差异,查了好久。。。

Member
avatar
加入于:
帖子: 45
声望: 0

不错的贴子,有问题有解决方案。我回头改进一下我的。

不过开源的好处就是什么都能自己做,比如群主之前也提到过,tick数据合成1分钟K线,不一定非要在60秒的整倍数上切,其他时间也ok。

© 2015-2019 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3