本文为“小黎说财经”原创文章,转载需获得同意,并在显要位置标明文章来源。

38e6911e500f7762850c41e65a88fcd1118.gif

关注小黎的朋友们大家好!

今后本公众号将会陆续推送一些基于tqsdk(天勤)编译的程序化交易策略。今天推送的是"基于均线交叉与通道突破相结合的交易系统"。

策略的基本原理

首先根据K线的历史数据构建短周期和长周期(快、慢)均线,进一步再使用N个周期内的最高、最低点构建大、小价格通道。当快慢均线形成金叉且当前价格突破大通道上轨的时候是为做多信号,买入。当快慢均线形成死叉且当前价格突破大通道下轨时候视为做空信号,卖出。之后价格再次突破小通道上/下轨是为加仓信号,再次进场。持仓后价格跌破/上涨小通道的下/上轨时出场。等待下一次均线交叉和通道突破。

核心逻辑

以均线的金叉死叉判断行情走势,以N根K线的高低价确定关键阻力/压力位,均线交叉结合关键价位的突破,后面行情往往都会走出一段趋势。

代码实现步骤

-核心逻辑的实现

获取历史K线数据后,只要每产生一根新的K线,我们就要计算一次快/慢均线和各种阻力/压力的值,所以我们需要封装一个函数,让我们每次接收到新的K线数据的时候能够判断上述的各种值。

def calculate_indexes(klines,chLen=12,fastLen=9,slowLen=18,reEntryChLen=10,trailBar=8):

"""

传入一个天勤的K线对象,返回策略所需各种指标的值,其中除了klines参数外均为各种指标的参数值

所需的K线不包括最新产生的K线,思考一下为什么?

"""

close = klines['close'][:-1] #获取K线收盘价序列

high = klines['high'][-(chLen + 1): -1] #获取K线最高价序列

low = klines['low'][-(chLen + 1): -1] #获取K线最低价序列

fastMa = close[-fastLen:].mean() #计算快速均线的值

slowMa = close[-slowLen:].mean() #计算慢速均线的值

HH_12 = max(high) #N1根K线的最高点

HH_10 = max(high[-reEntryChLen:]) #N2根K线的最高点

HH_8 = min(high[-trailBar:]) #N3根K线最高点

LL_12 = min(low) #N1根K线最低点

LL_10 = min(low[-reEntryChLen:]) #N2根K线最低点

LL_8 = min(low[-trailBar:]) #N3根K线最低点

return fastMa,slowMa,HH_12,HH_10,HH_8,LL_12,LL_10,LL_8

-交易规则设置

'''

多头部分

'''

#如果均线金叉

if fastMa > slowMa:

#且当前K线最高价突破前12根K线最高点一定幅度

if klines.iloc[-1].high > HH_12 * (1 + extraPercentage):

#开多仓

targetPos.set_target_volume(initalLots)

'''

空头部分

'''

#如果均线死叉

if fastMa < slowMa:

#且当前K线最低价突破前12根K线最低点一定幅度

if klines.iloc[-1].low < LL_12 * (1 - extraPercentage):

#开空仓

targetPos.set_target_volume(-initalLots)

'''

加仓、平仓部分

'''

#如果多头持仓

if position.pos_long > 0:

#且当前K线最低点小于前8根K线最低点

if klines.iloc[-1].low < LL_8:

#平仓

targetPos.set_target_volume(0)

#且取最近25根K线,新的15根K线最高点大于旧的10根K线最高点

elif newHH_15 > oldHH_10:

#加多仓

targetPos.set_target_volume(initalLots+reEntryLots)

#如果空头持仓

if position.pos_short > 0:

#且当前K线最高点大于前8根K线最高点

if klines.iloc[-1].high > HH_8:

#平仓

targetPos.set_target_volume(0)

#且取最近25根K线,新的15根K线最低点小于旧的10根K线最低点

elif newLL_15 < oldLL_10:

#加空仓

targetPos.set_target_volume(-initalLots-reEntryLots)

-框架构建

想要策略能够跑起来,必须按照Python基本语法将天勤量化框架搭建起来。

万事第一步,导入python库。

from tqsdk import TqApi,TargetPosTask

接着创建策略所需变量

exchangeId = 'SHFE'

instrumentId = 'rb2005'

symbol = exchangeId + '.' + instrumentId #交易标的

fastLen = 9 # 快速均线周期数

slowLen = 18 # 慢速均线周期数

chLen = 12 # 通道突破的周期数

extraPercentage = 0.001 # 通道突破的幅度(百分比)

trailBar = 8 # 多少根 Bar 的最低价作为跟踪止损价

initalLots = 1 # 初始进场头寸

reBars = 15 # 再进场必须在出厂后多少根 Bar内

reEntryChLen = 10 # 再进场通道突破的周期数

reEntryLots = 1 # 再进场头寸

创建api、K线、持仓、下单(调仓)实例

api = TqApi()

klines = api.get_kline_serial(symbol=symbol,duration_seconds=86400)

position = api.get_position(symbol=symbol)

targetPos = TargetPosTask(api,symbol)

必不可少的一步:接收行情数据

api.wait_update()

使用循环让规则运行

while True:

api.wait_update()

if api.is_changing(klines):

交易规则

-回测效果

b91aa18c40589b23ae4254f78101e072679.jpg

总结

从回测中来看,策略在不设置止盈止损的前提下策略依旧取得了正向的收益以及较高的盈亏比,趋势判断的思路值得借鉴。如果设置止盈止损,策略的效果可能会有所折扣,这也从一个侧面说明了趋势类策略要求较大的承受亏损的能力,因为在趋势走势中行情也是会有所反复的。

回测完整版代码

from tqsdk import TqApi,TargetPosTask,TqBacktest

from datetime import date

exchangeId = 'SHFE'

instrumentId = 'rb2005'

symbol = exchangeId + '.' + instrumentId #交易标的

fastLen = 9 # 快速均线周期数

slowLen = 18 # 慢速均线周期数

chLen = 12 # 通道突破的周期数

extraPercentage = 0.001 # 通道突破的幅度(百分比)

trailBar = 8 # 多少根 Bar 的最低价作为跟踪止损价

initalLots = 1 # 初始进场头寸

reBars = 15 # 再进场必须在出厂后多少根 Bar内

reEntryChLen = 10 # 再进场通道突破的周期数

reEntryLots = 1 # 再进场头寸

api = TqApi(backtest=TqBacktest(start_dt=date(2019, 10, 1), end_dt=date(2020, 2, 16)),web_gui=True)

klines = api.get_kline_serial(symbol=symbol,duration_seconds=86400)

position = api.get_position(symbol=symbol)

targetPos = TargetPosTask(api,symbol)

def calculate_indexes(klines,chLen=12,fastLen=9,slowLen=18,reEntryChLen=10,trailBar=8):

"""

传入一个天勤的K线对象,返回策略所需各种指标的值,其中除了klines参数外均为各种指标的参数值

所需的K线不包括最新产生的K线,思考一下为什么?

"""

close = klines['close'][:-1] #获取K线收盘价序列

high = klines['high'][-(chLen + 1): -1] #获取K线最高价序列

low = klines['low'][-(chLen + 1): -1] #获取K线最低价序列

fastMa = close[-fastLen:].mean() #计算快速均线的值

slowMa = close[-slowLen:].mean() #计算慢速均线的值

HH_12 = max(high) #N1根K线的最高点

HH_10 = max(high[-reEntryChLen:]) #N2根K线的最高点

HH_8 = min(high[-trailBar:]) #N3根K线最高点

LL_12 = min(low) #N1根K线最低点

LL_10 = min(low[-reEntryChLen:]) #N2根K线最低点

LL_8 = min(low[-trailBar:]) #N3根K线最低点

return fastMa,slowMa,HH_12,HH_10,HH_8,LL_12,LL_10,LL_8

while True:

api.wait_update()

if api.is_changing(klines):

fastMa,slowMa,HH_12,HH_10,HH_8,LL_12,LL_10,LL_8 = calculate_indexes(klines,chLen,fastLen,slowLen,reEntryChLen,trailBar)

'''

取25根K线为一个周期,计算前10根K线和后15根K线的高低点,以此为再进场的依据

思考一下,为什么在这里又要取最新一根K线

'''

newHH_15 = max(klines.iloc[-15:].high) #后15根K线高点

oldHH_10 = max(klines.iloc[-25:-15].high) #前10根K线高点

newLL_15 = min(klines.iloc[-15:].low) #后15根K线的低点

oldLL_10 = min(klines.iloc[-25:-15].low) #前10根K线低点

'''

多头部分

'''

#如果均线金叉

if fastMa > slowMa:

#且当前K线最高价突破前12根K线最高点一定幅度

if klines.iloc[-1].high > HH_12 * (1 + extraPercentage):

#开多仓

targetPos.set_target_volume(initalLots)

'''

空头部分

'''

#如果均线死叉

if fastMa < slowMa:

#且当前K线最低价突破前12根K线最低点一定幅度

if klines.iloc[-1].low < LL_12 * (1 - extraPercentage):

#开空仓

targetPos.set_target_volume(-initalLots)

'''

加仓、平仓部分

'''

#如果多头持仓

if position.pos_long > 0:

#且当前K线最低点小于前8根K线最低点

if klines.iloc[-1].low < LL_8:

#平仓

targetPos.set_target_volume(0)

#且取最近25根K线,新的15根K线最高点大于旧的10根K线最高点

elif newHH_15 > oldHH_10:

#加多仓

targetPos.set_target_volume(initalLots+reEntryLots)

#如果空头持仓

if position.pos_short > 0:

#且当前K线最高点大于前8根K线最高点

if klines.iloc[-1].high > HH_8:

#平仓

targetPos.set_target_volume(0)

#且取最近25根K线,新的15根K线最低点小于旧的10根K线最低点

elif newLL_15 < oldLL_10:

#加空仓

targetPos.set_target_volume(-initalLots-reEntryLots)

c405e47cc371cd3ece2cca4264fa6fe8b3b.png

写在最后

如果您不知道如何在电脑上部署实现天勤量化的Python环境、想获取完整版的py代码文件、或者您有交易经验和想法却又不知道如何实现,又或者您想学习Python量化投资课程……

不论您有各种迫切的需求,请撩小黎⬇️

d97008305ee89e1acd8897d7b073f7086dc.jpg

本文为“小黎说财经”原创文章,转载需获得同意,并在显要位置标明文章来源。

文章作者:小黎说财经

公众号设计/排版:宁晴

参考资料:米筐社区作者NeXT丶杨宗纬《【基石策略】第一期:基于均线交叉与通道突破相结合的交易系统》,原文地址:https://www.ricequant.com/community/topic/3823//2

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐