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

发布于vn.py社区公众号【vnpy-community】
 
《30天解锁Python量化开发》课程已经更新过半(至25集),计划在9月底全部更新完毕,通过概念讲解和实践操作结合的方式,加上vn.py框架内部代码细节的梳理学习,来帮助你快速掌握Python量化开发能力,详情请戳

 

原文作者:NY | 发布时间:2020-09-10

 

很多刚接触期货的投资者可能会疑惑,为什么商品期货在10:15到10:30之间,要有一个15分钟的交易休市,而国内的其他金融市场(证券股票、银行间债券、金融期货等)却都没有。

但其实,上午的这个休盘15分钟还真有历史渊源。话说在基于电脑的自动化交易系统还没有诞生的“远古”时期,交易所内还存在着一群场内交易员,一旦进入工作时间,需要持续保持精神高度集中,边盯着报价板边帮客户喊单交易。

上午开盘时间比较早,可能早盘行情的价格波动相对剧烈,也可能场内交易员们还没有准备充分,所以大家就需要一小段休息时间来调整一下,比如去下洗手间、吃个点心等。时至今日,国内各家期货交易所虽然都已经取消了场内交易员的模式,但商品期货上午15分钟休市的习惯却保留了下来。

 

特殊分钟K线的合成

 

回归到正题,vn.py中的K线合成器工具BarGenerator(位于vnpy.trader.utility模块下),从Tick合成K线的标准逻辑是对当前时间戳的分钟数字求余来进行切片的,具体代码如下:

if self.interval == Interval.MINUTE: 
    # x-minute bar    
    if not (bar.datetime.minute + 1) % self.window:        
        finished = True

要准确的把60分钟完整切片到等份,切片区间必须是以下这些能够整除60的数字:

2、3、5、6、10、15、20、30

但对于商品期货来说,由于上午的15分钟休盘,会导致某些情况下合成K线数据的不正确。

以20分钟为例,正常应该在每小时的19分、39分和59分的分钟线走完时合成20分钟K线。因为10:19的分钟数据不存在(休盘时间),不会触发切片合成,而要等到10:39分才会触发,导致这跟K线中会包含10:00-10:14和10:30-10:49两段共计35分钟的数据,和交易策略中预期的逻辑不符。

解决方案也很简单,只需对三大商品期货交易所的品种都进行一条特殊的逻辑处理,当收到上午10:14的分钟数据更新时我们立刻进行切分,这样下一根K线中的数据就一定从10点30分开始了:

if self.interval == Interval.MINUTE:    
    # x-minute bar    
    if not (bar.datetime.minute + 1) % self.window:        
        finished = True    
    elif (        
        bar.datetime.time() == time(10, 14)        
        and bar.exchange in [            
            Exchange.SHFE, Exchange.DCE, Exchange.CZCE        
        ]
    ):        
        finished = True

完成修改后,我们可以通过使用1分钟的螺纹钢数据合成20分钟K线来测试下效果,如下图所示:

description

可以看到由于15分钟休盘时段的数据缺失,这个时刻的20分钟K线是从30分钟开始,该结果也和文华等其他期货软件中的K线数据一致。

 

日K线数据的合成

 

由于国情区别,每个国家的开收盘时间也不一定相同,下文中的日K线合成方法仅针对国内期货市场。

和前文中的特殊分钟K线切分逻辑类似,日K线合成的关键也在于找到正确的当日行情的结束点,即当日收盘时间。

需要注意的是,目前国内期货品种中除了国债期货收盘时间是15:15,其他都是15:00整点收盘。所以我们只需对国债期货进行特殊处理,代码如下:

elif self.interval == Interval.DAILY:    
    day_end = time(14, 59)    
    if bar.exchange == Exchange.CFFEX and not bar.symbol.startswith("I"):               
        day_end = time(15, 14)    
    if bar.datetime.time() == day_end:        
        finished = True        
        self.interval_count = 0

通过交易所为CFFEX,以及合约代码不以I开头(股指期货为IF、IC和IH前缀)两个条件即可判断是否为国债期货。

这样我们就完成了从分钟K线到日K线的合成切分逻辑,使用上只需在创建BarGenerator对象时,将interval参数设置为Interval.DAILY,即可直接合成日线。

我们也用3个不同类型的期货品种来进行测试,效果如下图所示,都能正常合成:

description

对于螺纹钢等存在夜盘交易时段的期货品种,上述合成逻辑会将其夜盘时段的行情合并到下一日行情中切分(日K线的开盘价是夜盘开盘价),该逻辑也符合交易所对于每日交易时段的划分规则。

 
 

 
9月26日社区线下活动:CTA策略复杂交易算法实现

内容:

  1. CTA策略复杂交易算法:

    a.回调函数细节:

    ​ i. on_tick的K线合成

    ​ ii. on_order的推送时机

    ​ iii. on_trade的持仓更新

    b. CTA交易中的算法状态机
    c. 替换频繁cancel_all模式的停止单

    d. 盘口连续挂单的交易执行逻辑

    e. 实现一个策略内的TWAP算法

  2. K线图表绘制回测买卖记录

    a.成交的逐笔对冲统计模式

    b. vnpy.chart模块的图层开发
    c. 实现买卖记录连线图层

报名请扫描下方二维码:

description

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

这个才是解决日线合成和15分钟切片数据丢失的终极版本吧,完美~

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

mark

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

日线合成注意事项
1 import datetime 原文的所有time函数, 譬如time(14, 59), 改为datetime.time(14, 59)
2 from vnpy.trader.constant import Interval, 导入后,才能调用Interval.DAILY
3 策略中初始化 self.bg_day = BarGenerator(self.on_bar, 1, self.on_day_bar, Interval.DAILY)
4 原文 if bar.exchange == Exchange.CFFEX and not bar.symbol.startswith("I"):
改为 if bar.exchange == Exchange.CFFEX and bar.symbol.startswith("T"): 国债以T字母开头

Member
avatar
加入于:
帖子: 57
声望: 3

学习了.

Member
avatar
加入于:
帖子: 57
声望: 3

请教xiaohe兄
我用相同的代码用1分钟生成20分钟线,
为啥截点和你的不同,,,我这儿生成的是10:00-10:15,10:15-10:40,

description

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

沪公网安备 31011502017034号