Dual Thrust策略介绍
Dual Thrust是一个趋势跟踪系统,由Michael Chalek在20世纪80年代开发,曾被Future Thruth杂志评为最赚钱的策略之一。Dual Thrust系统具有简单易用、适用度广的特点,其思路简单、参数很少,配合不同的参数、止盈止损和仓位管理,可以为投资者带来长期稳定的收益,被投资者广泛应用于股票、货币、贵金属、债券、能源及股指期货市场等。
在Dual Thrust交易系统中,对于震荡区间的定义非常关键,这也是该交易系统的核心和精髓。它的逻辑原型是较为常见的日内交易策略之一开盘区间突破策略,以今日开盘价加减一定比例的昨日振幅,确定上下轨。日内突破上轨时平空做多,突破下轨时平多做空。Dual Thrust系统使用Range = Max(HH-LC,HC-LL)来描述震荡区间的大小。其中HH是N日High(最高价)的最高价,LC是N日Close(收盘价)的最低价,HC是N日Close的最高价,LL是N日Low(最低价)的最低价。
开盘区间突破策略基本原理
- 在今天的收盘,计算两个值:最高价-收盘价,和收盘价-最低价。然后取这两个值较大的那个,乘以k值。把结果称为触发值。
- 在明天的开盘,记录开盘价,然后在价格超过上轨(开盘+触发值)时马上买入,或者价格低于下轨(开盘-触发值)时马上卖空。
- 没有明确止损。这个系统是反转系统,也就是说,如果在价格超过(开盘+触发值)时手头有一口空单,则买入两口。同理,如果在价格低于(开盘-触发值)时手上有一口多单,则卖出两口。
策略实现
计算
- HH:N日High的最高价
- LC:N日Close的最低价
- LL:N日Close的最高价HC,N日Low的最低价
- 范围:Range = Max( HH – LC , HC – LL )
- 上轨(买入):BuyLine = Open + K1 * Range ;(其中Open为开盘价)
- 下轨(卖出):SellLine = Open + K2 * Range
def dual_thrust(quote, klines): current_open = klines.iloc[-1]["open"] HH = max(klines.high.iloc[-NDAY - 1:-1]) # N日最高价的最高价 HC = max(klines.close.iloc[-NDAY - 1:-1]) # N日收盘价的最高价 LC = min(klines.close.iloc[-NDAY - 1:-1]) # N日收盘价的最低价 LL = min(klines.low.iloc[-NDAY - 1:-1]) # N日最低价的最低价 range = max(HH - LC, HC - LL) buy_line = current_open + range * K1 # 上轨 sell_line = current_open - range * K2 # 下轨 print("当前开盘价: %f, 上轨: %f, 下轨: %f" % (current_open, buy_line, sell_line)) return buy_line, sell_line
(策略源码在文章最后)
构造系统
- 当价格向上突破上轨时,如果当时持有空仓,则先平仓,再开多仓;如果没有仓位,则直接开多仓。
- 当价格向下突破下轨时,如果当时持有多仓,则先平仓,再开空仓;如果没有仓位,则直接开空仓。
if api.is_changing(quote, "last_price"): if quote.last_price > buy_line: # 高于上轨 print("高于上轨,目标持仓 多头3手") target_pos.set_target_volume(3) # 交易 elif quote.last_price < sell_line: # 低于下轨 print("低于下轨,目标持仓 空头3手") target_pos.set_target_volume(-3) # 交易 else: print('未穿越上下轨,不调整持仓')
回测
回测初始设置
- 初始账户资金:100万
- 回测日期:2018.11.13 —— 2018.11.28
- 策略参数:过去N日天数:5; 上轨K1:0.2; 下轨K2:0.5
- 多头、空头开仓手数:30手
- 回测时盘口行情quote的更新频率:和订阅的tick的更新频率一致
回测结果
Dual Thrust 策略回测结果 | |||||
合约代码 | 合约品种 | 收益率 | 风险度 | 最大回撤 | 年化夏普率 |
SHFE.au1812 | 金 | 13.71% | 84.95% | 2.04% | 8.87 |
SHFE.rb1812 | 螺纹钢 | 11.50% | 6.30% | 4.99% | 5.93 |
上表回测结果中SHFE.au1812的累计收益走势图
天勤中Dual Thrust源码:
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'limin' ''' Dual Thrust策略 参考: https://www.shinnytech.com/blog/dual-thrust ''' from tqsdk import TqApi, TargetPosTask SYMBOL = "DCE.jd2001" # 合约代码 NDAY = 5 # 天数 K1 = 0.2 # 上轨K值 K2 = 0.2 # 下轨K值 api = TqApi() print("策略开始运行") quote = api.get_quote(SYMBOL) klines = api.get_kline_serial(SYMBOL, 24 * 60 * 60) # 86400使用日线 target_pos = TargetPosTask(api, SYMBOL) def dual_thrust(quote, klines): current_open = klines.iloc[-1]["open"] HH = max(klines.high.iloc[-NDAY - 1:-1]) # N日最高价的最高价 HC = max(klines.close.iloc[-NDAY - 1:-1]) # N日收盘价的最高价 LC = min(klines.close.iloc[-NDAY - 1:-1]) # N日收盘价的最低价 LL = min(klines.low.iloc[-NDAY - 1:-1]) # N日最低价的最低价 range = max(HH - LC, HC - LL) buy_line = current_open + range * K1 # 上轨 sell_line = current_open - range * K2 # 下轨 print("当前开盘价: %f, 上轨: %f, 下轨: %f" % (current_open, buy_line, sell_line)) return buy_line, sell_line buy_line, sell_line = dual_thrust(quote, klines) # 获取上下轨 while True: api.wait_update() if api.is_changing(klines.iloc[-1], ["datetime", "open"]): # 新产生一根日线或开盘价发生变化: 重新计算上下轨 buy_line, sell_line = dual_thrust(quote, klines) if api.is_changing(quote, "last_price"): if quote.last_price > buy_line: # 高于上轨 print("高于上轨,目标持仓 多头3手") target_pos.set_target_volume(3) # 交易 elif quote.last_price < sell_line: # 低于下轨 print("低于下轨,目标持仓 空头3手") target_pos.set_target_volume(-3) # 交易 else: print('未穿越上下轨,不调整持仓')
点击了解天勤量化程序
一个回复
回测成交记录导不出