Dual Thrust策略(难度:中级)

Table of Contents

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.au181213.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('未穿越上下轨,不调整持仓')

点击了解天勤量化程序

策略参考:https://xueqiu.com/5256769224/32429363

一个回复