做过交易的人大概会有一种体会,有时候价格波动很有规律,但更多时候它呈现出随机游走的不稳定状态。正是这种不稳定才是市场风险和机会的地方。不稳定也就代表了不可预测,那么如何在不可预测的市场环境中让收益变得更稳定,也是每一位交易者的难题。本篇将介绍鳄鱼交易法则策略,希望对大家有所启发。
鳄鱼线其实就是三根特殊的均线,分别对应的是:蓝线鳄鱼的下巴、红线鳄鱼的牙齿、绿线鳄鱼的上唇。其中下巴是 13 周期均线,并向未来方向移动 8 根 K 线,牙齿是 8 周期均线,并向未来方向移动 5 根 K 线,上唇是 5 周期均线,并向未来方向移动 3 根 K 线。
鳄鱼线是根据几何学以及非线性动力学总结出来的一套技术分析方法,当鳄鱼的下巴、牙齿和上唇闭合,或者相互纠缠时,代表鳄鱼睡着啦。这时我们通常待在市场外面,直到碎形出现,这样我们就可以原理不确定的市场,并且只参与明显的趋势行情。
当鳄鱼睡觉时间越长,醒来时就会越饿,所以一旦醒来,就会张大嘴巴。如果上唇在牙齿以上,牙齿在下巴以上,表明市场进入多头行情,鳄鱼要吃牛肉了。如果上唇在牙齿以下,牙齿在下巴以下,表明市场进入空头行情,鳄鱼要吃熊肉了。直到吃饱为止,之后它会再次闭上嘴巴(持有并获取利润)。
第一步:编写策略框架
# 策略主函数
def onTick():
pass
# 程序入口
def main():
while True: # 进入无限循环模式
onTick() # 执行策略主函数
Sleep(1000) # 休眠1秒
优宽量化采用轮询模式,一个是onTick函数,另一个是main函数,其中在main函数中无限循环执行onTick函数。
第二步:导入Python库
import talib
import numpy as np
我们的策略中使用了SMA函数,SMA是算数平均数,在talib库中已经有现成的SMA函数,所以直接导入talib的Python库,然后直接调用就可以了。因为在调用该函数时,需要传入numpy格式的参数,所以我们要在策略开头使用import导入这两个Python库。 第三步:转换K线数组数据
# 把K线数组转换成最高价、最低价、收盘价数组,用于转换为numpy.array类型数据
def get_data(bars):
arr = []
for i in bars:
arr.append(i['Close'])
return arr
这里我们创建了一个get_data函数,这个函数的目的是将普通的K线数组,处理成numpy格式的数据。输入参数为K线数组,输出结果为处理好的numpy格式的数据。 第四步:获取持仓数据
# 获取持仓数量
def get_position():
# 获取持仓
position = 0 # 赋值持仓数量为0
position_arr = _C(exchange.GetPosition) # 获取持仓数组
if len(position_arr) > 0: # 如果持仓数组长度大于0
for i in position_arr:
if i['ContractType'] == 'rb000': # 如果持仓品种等于订阅品种
if i['Type'] % 2 == 0: # 如果是多单
position = i['Amount'] # 赋值持仓数量为正数
else:
position = -i['Amount'] # 赋值持仓数量为负数
return position
持仓状态牵涉到策略逻辑,我们前十节课程一直都是使用虚拟持仓,但在真实的交易环境中最好是使用GetPosition函数,获取真实的持仓信息,包括:持仓方向、持仓盈亏、持仓数量等等 ** 第五步:获取数据
exchange.SetContractType('rb000') # 订阅期货品种
bars_arr =exchange.GetRecords() # 获取K线数组
if len(bars_arr) < 22: # 如果K线数量小于22根
return
在获取数据之前首先要使用SetContractType函数订阅相关期货品种,优宽量化支持有所的国内商品期货品种。订阅完期货品种后就可以使用GetRecords函数获取K线数据,返回的是一个数组。
第六步:计算数据
np_arr = np.array(get_data(bars_arr)) # 转换收盘价数组
sma13 = talib.SMA(np_arr, 130)[-9] # 下巴
sma8 = talib.SMA(np_arr, 80)[-6] # 牙齿
sma5 = talib.SMA(np_arr, 50)[-4] # 上唇
current_price = bars_arr[-1]['Close'] # 最新价格
在使用talib库计算SMA之前,需要用numpy库把普通的K线数组处理为numpy数据。然后分别获取鳄鱼线的下巴、牙齿、上唇。另外在下单的时候需要传入价格参数,所以我们可以使用K线数组中的收盘价。
第七步、下单交易
position = get_position()
if position == 0: # 如果无持仓
if current_price > sma5: # 如果当前价格大于上唇
exchange.SetDirection("buy") # 设置交易方向和类型
exchange.Buy(current_price + 1, 1) # 开多单
if current_price < sma13: # 如果当前价格小于下巴
exchange.SetDirection("sell") # 设置交易方向和类型
exchange.Sell(current_price - 1, 1) # 开空单
if position > 0: # 如果持有多单
if current_price < sma8: # 如果当前价格小于牙齿
exchange.SetDirection("closebuy") # 设置交易方向和类型
exchange.Sell(current_price - 1, 1) # 平多单
if position < 0: # 如果持有空单
if current_price > sma8: # 如果当前价格大于牙齿
exchange.SetDirection("closesell") # 设置交易方向和类型
exchange.Buy(current_price + 1, 1) # 平空单
在下单交易之前,需要先获取真实的持仓量,我们之前定义的get_position函数会返回真实的持仓数量,如果当前是多单就返回正数,如果当前是空单就返回负数,如果当前无持仓就返回0。最后就是根据上面的交易逻辑使用buy和sell函数下单交易,但是在这之前需要先设置交易方向和类型。
鳄鱼交易法则最大的作用是不管当前市场价格如何变化,帮助我们在交易时保持与市场一致的方向,并且持续获利直到盘整行情出现为止。鳄鱼线与其他MACD、KDJ指标都可以很好的搭配使用。最后提醒大家本篇策略请勿用于实盘交易。
'''backtest start: 2019-01-01 00:00:00 end: 2020-01-01 00:00:00 period: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] ''' import talib import numpy as np # 把K线数组转换成最高价、最低价、收盘价数组,用于转换为numpy.array类型数据 def get_data(bars): arr = [] for i in bars: arr.append(i['Close']) return arr # 获取持仓数量 def get_position(): # 获取持仓 position = 0 # 赋值持仓数量为0 position_arr = _C(exchange.GetPosition) # 获取持仓数组 if len(position_arr) > 0: # 如果持仓数组长度大于0 for i in position_arr: if i['ContractType'] == 'rb000': # 如果持仓品种等于订阅品种 if i['Type'] % 2 == 0: # 如果是多单 position = i['Amount'] # 赋值持仓数量为正数 else: position = -i['Amount'] # 赋值持仓数量为负数 return position # 策略主函数 def onTick(): # 获取数据 exchange.SetContractType('rb000') # 订阅期货品种 bars_arr =exchange.GetRecords() # 获取K线数组 if len(bars_arr) < 22: # 如果K线数量小于22根 return # 计算 np_arr = np.array(get_data(bars_arr)) # 转换收盘价数组 sma13 = talib.SMA(np_arr, 130)[-9] # 下巴 sma8 = talib.SMA(np_arr, 80)[-6] # 牙齿 sma5 = talib.SMA(np_arr, 50)[-4] # 上唇 current_price = bars_arr[-1]['Close'] # 最新价格 position = get_position() if position == 0: # 如果无持仓 if current_price > sma5: # 如果当前价格大于上唇 exchange.SetDirection("buy") # 设置交易方向和类型 exchange.Buy(current_price + 1, 1) # 开多单 if current_price < sma13: # 如果当前价格小于下巴 exchange.SetDirection("sell") # 设置交易方向和类型 exchange.Sell(current_price - 1, 1) # 开空单 if position > 0: # 如果持有多单 if current_price < sma8: # 如果当前价格小于牙齿 exchange.SetDirection("closebuy") # 设置交易方向和类型 exchange.Sell(current_price - 1, 1) # 平多单 if position < 0: # 如果持有空单 if current_price > sma8: # 如果当前价格大于牙齿 exchange.SetDirection("closesell") # 设置交易方向和类型 exchange.Buy(current_price + 1, 1) # 平空单 # 程序主函数 def main(): while True: # 循环 onTick() # 执行策略主函数 Sleep(1000) # 休眠1秒