VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 420
声望: 181

1. 来看看BarGenerator的tick合成1分钟tick过程update_tick()

    def update_tick(self, tick: TickData) -> None:
        """
        Update new tick data into generator.
        """
        new_minute = False

        # Filter tick data with 0 last price
        if not tick.last_price:
            return

        # Filter tick data with older timestamp
        if self.last_tick and tick.datetime < self.last_tick.datetime:
            return

        if not self.bar:
            new_minute = True
        elif (
            (self.bar.datetime.minute != tick.datetime.minute)
            or (self.bar.datetime.hour != tick.datetime.hour)
        ):
            self.bar.datetime = self.bar.datetime.replace(
                second=0, microsecond=0
            )
            self.on_bar(self.bar)

            new_minute = True

        if new_minute:
            self.bar = BarData(
                symbol=tick.symbol,
                exchange=tick.exchange,
                interval=Interval.MINUTE,
                datetime=tick.datetime,
                gateway_name=tick.gateway_name,
                open_price=tick.last_price,
                high_price=tick.last_price,
                low_price=tick.last_price,
                close_price=tick.last_price,
                open_interest=tick.open_interest
            )
        else:
            self.bar.high_price = max(self.bar.high_price, tick.last_price)
            if tick.high_price > self.last_tick.high_price:
                self.bar.high_price = max(self.bar.high_price, tick.high_price)

            self.bar.low_price = min(self.bar.low_price, tick.last_price)
            if tick.low_price < self.last_tick.low_price:
                self.bar.low_price = min(self.bar.low_price, tick.low_price)

            self.bar.close_price = tick.last_price
            self.bar.open_interest = tick.open_interest
            self.bar.datetime = tick.datetime

        if self.last_tick:
            # a: 成交量累计
            volume_change = tick.volume - self.last_tick.volume
            self.bar.volume += max(volume_change, 0)
            # b: 成交额累计
            turnover_change = tick.turnover - self.last_tick.turnover
            self.bar.turnover += max(turnover_change, 0)

        # c: 记录最新tick
        self.last_tick = tick

2. tick的volume和turnover有什么特性?

交易所播报的tick这成交量和成交额是从每个交易日的集合竞价阶段开始累计的,它们都有单调递增的特性。
也就是说volume和turnover在一个交易日内只会增加,不会减少。

2.1 前后两个交易日之间有没有什么关系呢?

答案是没有的!

  • 这是通常情况下的两个交易日成交量的变化示意图:
description
图1

此时,前一天的最后收到的tick都volume为v2,当前天的集合竞价或者一个收到的tick都volume为v3,v3<v2。

  • 特别情况下的两个交易日成交量的变化示意图:
description
图2

此时,前一天的最后收到的tick都volume为v2,当前天的集合竞价或者一个收到的tick都volume为v3,v3>v2。
这种情况会发生吗?会的 !前一天的交易特别清淡,导致成交量非常小,而当前天因为收到什么特别因素刺激,开盘就非常火爆,光是集合竞价的成交量就比前一天的整体的成交量都大,就会出现此图所示的情况。

3. a,b两处代码是错误的

a处代码中的volume_change 是什么?它代表了从上一个tick到当前tick发生的成交量。
1分钟K线到成交量就是对这个volume_change的累计。但是有一个例外,当volume_change < 0时,累加的值就只能够为0了。
那么什么情况下会发生volume_change < 0呢?答案是发生在如图1所示的跨日的情况下!
可是还会发生如图2所示的跨日的情况,此时volume_change > 0,那么volume_change 就不应该是v3-v2,而应该是v3 !
所以a处成交量累计的代码是错误的,同理b处对成交额累计的代码也是错误的!

Member
avatar
加入于:
帖子: 1661
声望: 121

这里是因为每个交易日收盘后系统要重启,所以这么设计的吧

Member
avatar
加入于:
帖子: 420
声望: 181

MTF wrote:

这里是因为每个交易日收盘后系统要重启,所以这么设计的吧

答复:

每个交易日收盘后在下一个盘前系统要重启时,此时收到的第一个tick通常是上一个交易日收盘时最后一个tick,它的成交量是v2。随后进入集合竞价时段,在20:59时会收到一个集合竞价tick,它的成交量是v3。

  1. 当发生了v3-v2<0(图1所示,一般情况下是如此)的情况也是错误的,应该用V3来代替0,因为第一个tick往往是集合竞价的tick,而它的volume代表了在集合竞价时间段发生的成交量,如果用0来替代,则表示把集合竞价的成交量抛弃了,集合竞价期间的4分钟发生的成交量可一定不是个小数目,对吧?
  2. 如果发生了图2所示的情况,此时v3-v2>0(为什么会发生这种情况我已经在帖子里说过),那么volume_change代表什么?它是个无意义的值,直接累计volume_change到1分钟bar中,更是错的离谱,不是吗?
Member
avatar
加入于:
帖子: 2
声望: 0

hxxjava wrote:

MTF wrote:

这里是因为每个交易日收盘后系统要重启,所以这么设计的吧

答复:

每个交易日收盘后在下一个盘前系统要重启时,此时收到的第一个tick通常是上一个交易日收盘时最后一个tick,它的成交量是v2。随后进入集合竞价时段,在20:59时会收到一个集合竞价tick,它的成交量是v3。

  1. 当发生了v3-v2<0(图1所示,一般情况下是如此)的情况也是错误的,应该用V3来代替0,因为第一个tick往往是集合竞价的tick,而它的volume代表了在集合竞价时间段发生的成交量,如果用0来替代,则表示把集合竞价的成交量抛弃了,集合竞价期间的4分钟发生的成交量可一定不是个小数目,对吧?
  2. 如果发生了图2所示的情况,此时v3-v2>0(为什么会发生这种情况我已经在帖子里说过),那么volume_change代表什么?它是个无意义的值,直接累计volume_change到1分钟bar中,更是错的离谱,不是吗?

认同,应该给tickdata 添加TradingDay属性,在ctp return里具备该属性,结合交易日判断来解决本问题

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

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】