量化交易中判断持仓分为两种,一种是真实的账户持仓,另一种就是虚拟持仓,还有一种是真实持仓和虚拟持仓联合判断 。实盘时我们只使用真实持仓就足够了,但这里为了简化策略,作为演示使用虚拟持仓 。
mp = 0 # 用于控制虚拟持仓使用虚拟持仓的原理很简单,策略运行之初默认是空仓mp=0,当开多单后把虚拟持仓重置为mp=1,当开空单后把虚拟持仓重置为,mp=-1,当平多单或空单后把虚拟持仓重置为mp=0 。这样我们在判断构建逻辑获取仓位时,只需要判断mp的值就可以了 。
第四步:计算阿隆指标
计算阿隆指标,首先要获取基础数据,但前提是先要订阅数据,也就是订阅具体的合约代码,你可以订阅指数或者主力连续,甚至还可以订阅具体交割月份的合约代码 。然后是获取K线数组,K线数组是一个包含开高低收、成交量和时间的序列数据,同时也是计算大部分指标的基础数据 。
在获取K线数组之后,紧接着就需要判断一下K线数组的长度,因为如果K线数组太短,不足以计算指标时就会出现异常 。所以我们在这里使用if语句,判断如果K线数组小于指标参数时,就直接返回 。
在使用talib计算指标时,它所传入的参数是numpy.array类型数据,所以还要把K线数组中的必要数据提取出来,并转换成numpy.array类型数据 。这里我们自定义一个get_data函数,先别必要的数据提取出来 。
# 把K线数组转换成最高价和最低价数组,用于转换为numpy.array类型数据def get_data(bars): arr = [[], []] for i in bars: arr[0].Append(i['High']) arr[1].append(i['Low']) return arrexchange.SetContractType("ZC000") # 订阅期货品种bars = exchange.GetRecords() # 获取K线数组if len(bars) < cycle_length + 1: # 如果K线数组的长度太小,所以直接返回 returnnp_arr = np.array(get_data(bars)) # 把列表转换为numpy.array类型数据,用于计算AROON的值aroon = talib.AROON(np_arr[0], np_arr[1], 20); # 计算阿隆指标aroon_up = aroon[1][len(aroon[1]) - 2]; # 阿隆指标上线倒数第2根数据aroon_down = aroon[0][len(aroon[0]) - 2]; # 阿隆指标下线倒数第2根数据talib在计算阿隆指标时,需要三个参数,依次是:最高价numpy.array类型数据、最低价numpy.array类型数据、时间周期 。所以我们在自定义get_data函数中只需要把K线数组中的最高价和最低价提取出来就可以了,并把它们都转换成numpy.array类型数据 。
紧接着,就可以计算阿隆指标了,直接调用talib.AROON方法并传入参数 。计算后的阿隆指标是一个二维数组,所以我们分别把阿隆指标上线和下线分别提取出来,以便于判断开平仓逻辑 。
第五步:下单交易
在下单交易之前,我们要先获取当前最新价格,因为在下单时需要在函数中传入下单价格 。还需要引入全局变量mp,主要用于控制虚拟仓位 。
close0 = bars[len(bars) - 1].Close; # 获取当根K线收盘价global mp # 全局变量,用于控制虚拟仓位if mp == 0 and aroon_up > aroon_down and aroon_up > 50: # 如果当前空仓,并且阿隆上线大于下线,并且阿隆上线大于50 exchange.SetDirection("buy") # 设置交易方向和类型 exchange.Buy(close0, 1) # 开多单 mp = 1 # 设置虚拟持仓的值,即有多单 if mp == 0 and aroon_down > aroon_up and aroon_down > 50: # 如果当前空仓,并且阿隆下线大于上线,并且阿隆下线小于50 exchange.SetDirection("sell") # 设置交易方向和类型 exchange.Sell(close0 - 1, 1) # 开空单 mp = -1 # 设置虚拟持仓的值,即有空单 if mp > 0 and (aroon_up < aroon_down or aroon_up < 50): # 如果当前持有多单,并且阿隆上线小于下线或者阿隆上线小于50 exchange.SetDirection("closebuy") # 设置交易方向和类型 exchange.Sell(close0 - 1, 1) # 平多单 mp = 0 # 设置虚拟持仓的值,即空仓 if mp < 0 and (aroon_down < aroon_up or aroon_down < 50): # 如果当前持有空单,并且阿隆下线小于上线或者阿隆下线小于50 exchange.SetDirection("closesell") # 设置交易方向和类型 exchange.Buy(close0, 1) # 平空单 mp = 0 # 设置虚拟持仓的值,即空仓万事俱备之后,就可以判断策略逻辑并开平仓下单交易了 。在判断策略逻辑时肯定是使用if语句,先判断mp的持仓状态,然后再判断阿隆上线和下线的相互位置关系 。需要注意的是在期货交易下单之前,先指定交易的方向类型,即:开多、开空、平多、平空 。调用exchange.SetDirection()函数,分别传入:“buy”、“sell”、“closebuy”、“closesell” 。最后下单之后重置持仓状态mp的值 。
完整策略'''backteststart: 2015-02-22 00:00:00end: 2019-10-29 00:00:00period: 1dexchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]'''import talibimport numpy as np# 外部参数# cycle_length = 100# 定义全局变量mp = 0 # 用于控制虚拟持仓# 把K线数组转换成最高价和最低价数组,用于转换为numpy.array类型数据def get_data(bars): arr = [[], []] for i in bars: arr[0].append(i['High']) arr[1].append(i['Low']) return arr# 策略主函数def onTick(): exchange.SetContractType("ZC000") # 订阅期货品种 bars = exchange.GetRecords() # 获取K线数组 if len(bars) < cycle_length + 1: # 如果K线数组的长度太小,所以直接返回 return np_arr = np.array(get_data(bars)) # 把列表转换为numpy.array类型数据,用于计算AROON的值 aroon = talib.AROON(np_arr[0], np_arr[1], 20); # 计算阿隆指标 aroon_up = aroon[1][len(aroon[1]) - 2]; # 阿隆指标上线倒数第2根数据 aroon_down = aroon[0][len(aroon[0]) - 2]; # 阿隆指标下线倒数第2根数据 close0 = bars[len(bars) - 1].Close; # 获取当根K线收盘价 global mp # 全局变量,用于控制虚拟仓位 if mp == 0 and aroon_up > aroon_down and aroon_up > 50: # 如果当前空仓,并且阿隆上线大于下线,并且阿隆上线大于50 exchange.SetDirection("buy") # 设置交易方向和类型 exchange.Buy(close0, 1) # 开多单 mp = 1 # 设置虚拟持仓的值,即有多单if mp == 0 and aroon_down > aroon_up and aroon_down > 50: # 如果当前空仓,并且阿隆下线大于上线,并且阿隆下线小于50 exchange.SetDirection("sell") # 设置交易方向和类型 exchange.Sell(close0 - 1, 1) # 开空单 mp = -1 # 设置虚拟持仓的值,即有空单if mp > 0 and (aroon_up < aroon_down or aroon_up < 50): # 如果当前持有多单,并且阿隆上线小于下线或者阿隆上线小于50 exchange.SetDirection("closebuy") # 设置交易方向和类型 exchange.Sell(close0 - 1, 1) # 平多单 mp = 0 # 设置虚拟持仓的值,即空仓if mp < 0 and (aroon_down < aroon_up or aroon_down < 50): # 如果当前持有空单,并且阿隆下线小于上线或者阿隆下线小于50 exchange.SetDirection("closesell") # 设置交易方向和类型 exchange.Buy(close0, 1) # 平空单 mp = 0 # 设置虚拟持仓的值,即空仓 # 程序入口def main(): while True: # 进入无限循环模式 onTick() # 执行策略主函数 Sleep(1000) # 休眠1秒
推荐阅读
- java多线程,静态方法加锁后,调用该方法会影响其它方法吗?
- 3种中药茶 老年人别长期饮用
- APP应用的安全保护指南
- 如何在 Go 中使用 TLS 连接 MongoDB
- PyQt5安装与环境配置方法
- CenterOS 7.5下Mysql Cluster 7.6.12高可用集群搭建
- C/C++连接MySql数据库使用总结
- Python自动化报错:IndentationError-unindent does not match
- 前端开发WebStorm常用快捷键
- 各种茶功效各异 恰当搭配饮用 让健康美丽加分