Warning: file_exists(): open_basedir restriction in effect. File(/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-content/db.php) is not within the allowed path(s): (/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/:/tmp/:/proc/:/var/log/nginx/:/www/wwwroot/com.xiximiao.oa/com.cmstop/public/:/www/wwwroot/com.xiximiao.oa/com.cmstop/vendor/:/www/wwwroot/com.xiximiao.oa/com.cmstop/ppk/) in /www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-includes/load.php on line 707
2074 迪马克TD趋势反转指标.py » 轻知量化 QMT、PTrade、聚宽策略分享交流平台

2074 迪马克TD趋势反转指标.py

策略名称:**迪马克TD趋势反转策略**

策略说明:

本策略基于迪马克(Tom DeMark)的TD序列理论,通过识别市场的趋势反转信号进行交易决策。策略的核心思想是通过计算价格的高低点和趋势的延续性,捕捉市场的反转机会,并结合止损和止盈机制控制风险。

策略核心逻辑:

1. **TD序列计算**:
- **Setup阶段**:识别连续4天的价格变化方向(上升或下降),并确定趋势的起始点。
- **Count阶段**:在Setup阶段完成后,继续计算价格的高低点,直到达到设定的计数条件(如13天)。

2. **趋势反转信号**:
- **做空信号**:在下降Setup完成后,价格跌破前3天的收盘价时,触发做空信号。
- **做多信号**:在上升Setup完成后,价格突破前3天的收盘价时,触发做多信号。

3. **止损与止盈**:
- **顺势交易**:当价格达到设定的止损或止盈条件时,平仓并反手开仓。
- **反转交易**:当价格达到设定的止损或止盈条件时,平仓并结束交易。

4. **移仓机制**:
- 当合约临近到期时,自动移仓至下一个主力合约。

策略特点:

- **趋势反转捕捉**:通过TD序列理论捕捉市场的趋势反转信号,适合震荡市和趋势反转行情。
- **动态止损止盈**:根据价格变化动态调整止损和止盈条件,控制风险。
- **自动移仓**:在合约到期前自动移仓,避免交割风险。

适用场景:

- 适用于股指期货市场,能够有效捕捉市场的趋势反转机会。
- 适合中短线交易者,通过趋势反转信号进行快速交易。

风险提示:

- 在趋势延续性较强的市场中,TD序列可能产生较多的错误信号,导致频繁交易。
- 策略依赖于历史数据的有效性,需定期优化参数以适应市场变化。

策略代码结构:

1. **初始化函数(`initialize`)**:
- 设定基准指数(沪深300)。
- 配置交易手续费和滑点。
- 定义每日运行的函数(开盘前、开盘时、收盘后)。

2. **开盘前运行函数(`before_market_open`)**:
- 获取当前交易日的主力合约和次主力合约。
- 计算当前合约的持仓手数。

3. **开盘时运行函数(`market_open`)**:
- 根据TD序列信号进行交易决策。
- 触发做多或做空信号时,开仓并设置止损止盈条件。
- 当价格达到止损或止盈条件时,平仓并反手开仓。

4. **收盘后运行函数(`after_market_close`)**:
- 计算当日的TD序列信号,更新Setup和Count阶段的状态。

5. **辅助函数**:
- **`calc_setup`**:计算TD序列的Setup和Count阶段。
- **`reverse_posi`**:在达到止损或止盈条件时,反手开仓。
- **`calc_hands`**:根据账户资金计算开仓手数。

策略优化建议:

1. **参数优化**:
- 可对TD序列的Setup和Count参数(如4天、13天)进行优化,以适应不同的市场周期。
- 调整止损和止盈条件(如5%、10%),以更好地控制风险。

2. **风险控制**:
- 增加最大回撤限制,当回撤超过一定比例时暂停交易。
- 设置单笔交易的最大亏损比例,避免单笔交易亏损过大。

3. **多品种扩展**:
- 可将策略应用于其他期货品种(如商品期货),测试其普适性。
- 通过多品种分散风险,提高策略的稳定性。

总结:

本策略通过迪马克TD序列理论捕捉市场的趋势反转信号,结合止损和止盈机制控制风险,适合中短线交易者在股指期货市场中获取收益。策略逻辑清晰,适合有一定编程基础的投资者进行进一步优化和实盘测试。

策略代码

# 标题:迪马克TD趋势反转指标
# 作者:魔术先生
# 回测资金选择 100万

# 导入函数库
from jqdata import *

## 初始化函数,设定基准等等
def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    set_option("avoid_future_data", True)
    # 过滤掉order系列API产生的比error级别低的log
    # log.set_level('order', 'error')
    # 输出内容到日志 log.info()
    log.info('初始函数开始运行且全局只运行一次')
    g.code = '000300.XSHG'
    g.n1 = 8
    g.n2 = 13
    g.count = 0    # setup完成后开始count
    g.stop = 0
    g.setup_high = 0 #下跌setup中的最高价
    g.setup_low = 0 #上升setup中的最低价
    g.setup = 0 #1:上升;-1:下降;0:无
    g.flag = 0
    g.price = 0
    g.p = 0
    g.hold = ''
    g.lc = False
    g.trend = 0  # -1:反转 0:空仓 1:顺势
    
    ### 期货相关设定 ###
    # 设定账户为金融账户
    set_subportfolios([SubPortfolioConfig(cash=context.portfolio.starting_cash, type='index_futures')])
    # 期货类每笔交易时的手续费是:买入时万分之0.23,卖出时万分之0.23,平今仓为万分之23
    set_order_cost(OrderCost(open_commission=0.000023, close_commission=0.000023,close_today_commission=0.0023), type='index_futures')
    # 设定保证金比例
    set_option('futures_margin_rate', 0.15)

    # 设置期货交易的滑点
    set_slippage(StepRelatedSlippage(2))
    # 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'IF8888.CCFX'或'IH1602.CCFX'是一样的)
    # 注意:before_open/open/close/after_close等相对时间不可用于有夜盘的交易品种,有夜盘的交易品种请指定绝对时间(如9:30)
      # 开盘前运行
    run_daily( before_market_open, time='09:00', reference_security='IF8888.CCFX')
      # 开盘时运行
    run_daily( market_open, time='09:30', reference_security='IF8888.CCFX')
      # 收盘后运行
    run_daily( after_market_close, time='15:30', reference_security='IF8888.CCFX')


## 开盘前运行函数
def before_market_open(context):
    # 输出运行时间
    # log.info('函数运行时间(before_market_open):'+str(context.current_dt.time()))
    g.today = context.current_dt.date()
    g.hands = calc_hands(context)
    g.c = get_future_contracts('IF')
    g.sub = g.c[1]
    g.main = g.c[0]
    if (get_security_info(g.main).end_date - context.current_dt.date()).days < 10:
        g.main = g.sub

## 开盘时运行函数
def market_open(context):
    # if g.lc and g.stop!=0:
    #     g.stop += 1
    #     return
    # elif g.lc and g.stop==0:
    #     g.stop = 0
    #     g.lc = False
    current_data = get_current_data()
    last = current_data[g.code].last_price
    if g.hold:
        end = get_security_info(g.hold).end_date
        if (end - context.current_dt.date()).days < 5: gap = current_data[g.sub].last_price - last g.price += gap g.p += gap if g.trend == 1: if g.setup==-1: print('顺势移仓空头') order_target(g.hold,0,None,'short') order(g.sub,g.hands,None,'short') g.hold = g.sub elif g.setup==1: print('顺势移仓多头') order_target(g.hold,0,None,'long') order(g.sub,g.hands,None,'long') g.hold = g.sub elif g.trend == -1: if g.setup==1: print('反转移仓空头') order_target(g.hold,0,None,'short') order(g.sub,g.hands,None,'short') g.hold = g.sub elif g.setup==-1: print('反转移仓多头') order_target(g.hold,0,None,'long') order(g.sub,g.hands,None,'long') g.hold = g.sub if g.setup==-1 and g.count==g.n2 and not g.flag: pre3close = attribute_history(g.code,3,'1d','close').close.values[0] pre1low = attribute_history(g.code,1,'1d','low').low.values[0] if pre1low > pre3close:
            print('做空信号----------------')
            g.price = last
            g.p = last
            g.hold = g.main
            g.flag = 1
            g.trend = 1
            order(g.main,g.hands,None,'short')
    elif g.setup==1 and g.count==g.n2 and not g.flag:
        pre3close = attribute_history(g.code,3,'1d','close').close.values[0]
        pre1high = attribute_history(g.code,1,'1d','high').high.values[0]
        if pre1high < pre3close: print('做多信号----------------') g.flag = 1 g.price = last g.p = last g.hold = g.main g.trend = 1 order(g.main,g.hands,None,'long') if g.setup==-1 and g.flag==1 and g.trend == 1: if g.price/last >1.05 or g.price/last <0.95: if g.price/last >1.05:
                print('顺势空头止盈')
            else:
                print('顺势空头止损')
            g.price = last
            g.p = last
            reverse_posi()
            
    elif g.setup==1 and g.flag==1 and g.trend == 1:
        if last/g.price >1.05 or last/g.price <0.95: order_target(g.hold,0,None,'long') if last/g.price >1.05:
                print('顺势多头止盈')
            else:
                print('顺势多头止损')
            g.price = last
            g.p = last
            reverse_posi()

    if g.setup==1 and g.flag==1 and g.trend == -1:
        if g.price>last:
            g.price = last
        elif g.price < 0.9*last or g.p > 1.2*last:
            
        # if g.price/last >1.15 or g.price/last <0.85: order_target(g.hold,0,None,'long') if g.p > 1.2*last:
                print('反转空头止盈')
            else:
                print('反转空头止损')
                g.lc = True
            g.trend = 0 
            g.price = 0
            g.p = 0
            g.setup = 0
            g.setup_high = 0
            g.hold = ''
            g.count = 0
            g.flag = 0
    elif g.setup==-1 and g.flag==1 and g.trend == -1:
        if g.price < last: g.price = last elif g.price > 1.2*last or g.p < 0.8*last: # if last/g.price >1.15 or last/g.price <0.85:
            order_target(g.hold,0,None,'short')
            if g.p < 0.9*last:
                print('反转多头止盈')
            else:
                print('反转多头止损')
                g.lc = True
            g.trend = 0
            g.price = 0
            g.p = 0
            g.setup = 0
            g.setup_low = 0
            g.hold = ''
            g.count = 0
            g.flag = 0            
## 收盘后运行函数
def after_market_close(context):
    calc_setup()
    # print(g.count)

def reverse_posi():
    if g.setup==-1:
        print('空头反手')
        order_target(g.hold,0,None,'short')
        order(g.hold,g.hands,None,'long')
        g.trend = -1
        
    elif g.setup==1:
        print('多头反手')
        order_target(g.hold,0,None,'long')
        order(g.hold,g.hands,None,'short')
        g.trend = -1

    
def calc_setup():
    close = get_price(g.code,end_date=g.today,count=g.n1+5,fields='close')
    diff4 = close.diff(4).dropna().values
    first = g.setup
    #setup
    if (diff4[:-1]<0).all() and diff4[-1]>0 and not g.setup: #下降setup
        g.setup = -1
        high = get_price(g.code,end_date=g.today,count=g.n1,fields='high').values.max()
        g.setup_high = high
    elif (diff4[:-1]>0).all() and diff4[-1]<0 and not g.setup: #上升setup
        g.setup = 1
        low = get_price(g.code,end_date=g.today,count=g.n1,fields='low').values.min()
        g.setup_low = low
        
    #count
    if g.setup == -1 and g.count!=g.n2:
        pre2low = get_price(g.code,end_date=g.today,count=3,fields='low').values[0]
        if close.values[-1]pre2high:
            g.count+=1
            print('上升setup完成,count加1,当前数量:【{}】'.format(g.count))
    
    
    
    #cancel    
    if g.setup==-1 and g.count!=g.n2:
        info = '下跌setup完成,'
        if close.values[-1] > g.setup_high:
            info += '当日收盘价大于setup中的最高价,停止'
            g.setup = 0
            g.setup_high = 0
            g.count = 0
            print(info)
        elif (diff4>0).all():
            info += '出现反向setup,优先新setup'
            g.setup = 1
            g.count = 0
            g.setup_high = 0
            low = get_price(g.code,end_date=g.today,count=g.n1,fields='low').values.min()
            g.setup_low = low
            print(info)
        elif not first and (diff4<0).all():
            info += '出现同向setup,重新计数'
            g.count = 0
            print(info)
    elif g.setup==1 and g.count!=g.n2:
        info = '上升setup完成,'
        if close.values[-1] < g.setup_low:
            info += '当日收盘价小于setup中最低价,停止'
            g.setup = 0
            g.setup_low = 0
            g.count = 0
            print(info)
        elif (diff4<0).all(): info += '出现反向setup,优先新setup' g.setup = -1 g.count = 0 g.setup_low = 0 high = get_price(g.code,end_date=g.today,count=g.n1,fields='high').values.max() g.setup_high = high print(info) elif not first and (diff4>0).all():
            info += '出现同向setup,重新计数'
            g.count = 0
            print(info)
        


2025-02-21
⚠️
本站资源大多来自网络,仅供网友学习交流,未经作者或上传书面授权,请勿作他用。
站长 vx: xiangyin615 或者 留言反馈 ,我们将尽快处理。
Notice: When you of the legal rights be violate, please stir to vx: xiangyin615
个人中心
购物车
优惠劵
搜索