美文网首页
DMA指标的趋势与择时效应

DMA指标的趋势与择时效应

作者: 东南有大树 | 来源:发表于2019-02-23 19:56 被阅读82次
    """导入常用模块"""
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import datetime
    from environment import * # 导入大树工作室开发的回测模块
    

    计算DMA与画图的公用函数

    """公用函数"""
    
    def get_dma(security, start_date=None, end_date=None, count=1, n1=10, n2=50, m=10):
        price = get_price(security=security, 
                      start_date=start_date, 
                      end_date= end_date,
                      frequency='daily', 
                      fields=None, 
                      skip_paused=False, 
                      count=count+n2+m,
                      fq='pre')
        ma1 = price['close'].rolling(n1).mean()
        ma2 = price['close'].rolling(n2).mean()
        DMA = ma1 - ma2
        AMA = DMA.rolling(m).mean()
        return DMA[-count:].values, AMA[-count:].values
    
    def show_dma(DMA, AMA):
        plt.figure(figsize=(16, 3))
        plt.plot(DMA)
        plt.plot(AMA)
        plt.show()
    

    平行线差指标

    平行线差(DMA)指标是利用两条不同期间的平均线,来判断当前买卖能量的大小和未来价格趋势。DMA指标是一种中短期指标。

    计算公式

    • DMA=股价短期平均值—股价长期平均值
    • AMA=DMA短期平均值
    • 以求10日、50日为基准周期的DMA指标为例,其计算过程具体如下:
    • DMA(10)=10日股价平均值—50日股价平均值
    • AMA(10)=10日DMA平均值
    • 和其他指标的计算一样,由于选用的计算周期的不同,DMA指标也包括日DMA指标、周DMA指标、月DMA指标年DMA指标以及分钟DMA指标等各种类型。经常被用于股市研判的是日DMA指标和周DMA指标。虽然它们的计算时的取值有所不同,但基本的计算方法一样。

    常用的DMA分析方法如下:

    1. DMA线向上交叉AMA线,买进;DMA线向下交叉AMA线,卖出。
    2. 当DMA和AMA均>0(即在图形上表示为它们处于零线以上)并向上移动时,一般表示为股市处于多头行情中,为买入信号,可以买入或持股;当DMA和AMA均<0(即在图形上表示为它们处于零线以下)并向下移动时,一般表示为股市处于空头行情中,为卖出信号,可以卖出股票或观望。
    3. 当DMA和AMA均<0时,经过一段时间的下跌后,如果两者同时从低位向上移动时,为买进信号;当DMA和AMA均>0,在经过一段时间的上涨后,如果两者同时从高位向下移动时,为卖出信号。
    4. DMA指标与股价产生背离时的交叉信号,可信度较高。
    5. DMA指标亦适于结合形态理论进行分析。
      “”6. DMA指标、MACD指标、TRIX指标三者构成一组指标群,互相验证。

    展示沪深300一段时期的DMA曲线图

    trade_date = get_trade_days(end_date=datetime.datetime.now(), count=100)
    DMA, AMA = get_dma('000300.XSHG', end_date=trade_date[-1], count=300)
    show_dma(DMA, AMA)
    

    回测条件一

    DMA线向上交叉AMA线,买进;DMA线向下交叉AMA线,卖出。

    """初始化以下内容"""
    context = Context() # 账户对象
    order = Order(context) # 下单对象
    trade = Trade(context, order) # 回测对象
    context.start_date = '2005-05-01'
    context.end_date = '2018-12-31'
    context.universe = ['000300.XSHG']
    context.base = '000300.XSHG'
    
    """策略主体"""
    def handle(context, order):
        stock = '000300.XSHG'
        DMA, AMA = get_dma(stock, end_date=trade.context.current_dt, count=2)
        close = get_price(security=stock, 
                          end_date=context.current_dt,
                          frequency='daily', 
                          fields=None, 
                          skip_paused=False, 
                          fq='pre',
                          count=5)['close'][-1]
        if DMA[-2] < AMA[-2] and DMA[-1] > AMA[-1]:
            if stock in context.position.keys():
                return
            else:
                order.buy(stock, close, context.cash // close)
        elif DMA[-2] > AMA[-2] and DMA[-1] < AMA[-1]:
            if stock not in context.position.keys():
                return
            else:
                order.sell(stock, close, context.position[stock]['count'])
    """执行策略"""
    trade.trade(handle)
    
    2019-02-23 17:49:39.306499,回测完毕,用时0:00:17.551996
    

    上例中的金叉与死叉时间间隔只有一天,这个时间间隔可以是1~10天,因此可将这个时间间隔当作一个可被调节的参数,并回测最优的时间间隔。

    date_long = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 这里只测这几个吧
    trade_list = []
    for long in date_long:
        """初始化以下内容"""
        context = Context() # 账户对象
        order = Order(context) # 下单对象
        trade = Trade(context, order) # 回测对旬
        context.start_date = '2005-05-01'
        context.end_date = '2018-12-31'
        context.universe = ['000300.XSHG']
        context.base = '000300.XSHG'
    
        """策略主体"""
        def handle(context, order):
            stock = '000300.XSHG'
            DMA, AMA = get_dma(stock, end_date=trade.context.current_dt, count=long+1)
            close = get_price(security=stock, 
                              end_date=context.current_dt,
                              frequency='daily', 
                              fields=None, 
                              skip_paused=False, 
                              fq='pre',
                              count=long+1)['close'][-1]
            if DMA[-1-long] < AMA[-2] and DMA[-1] > AMA[-1]:
                if stock in context.position.keys():
                    return
                else:
                    order.buy(stock, close, context.cash // close)
            elif DMA[-1-long] > AMA[-2] and DMA[-1] < AMA[-1]:
                if stock not in context.position.keys():
                    return
                else:
                    order.sell(stock, close, context.position[stock]['count'])
        """执行策略"""
        trade.trade(handle, False)
        trade_list.append(trade)
    # 展示
    Trade.show_ratio_compare('date_long', date_long, trade_list, 3, 3)
    Trade.show_result('date_long', date_long, trade_list)
    
    2019-02-23 17:41:16.143275,回测完毕,用时0:00:17.396257
    2019-02-23 17:41:33.206154,回测完毕,用时0:00:17.062726
    2019-02-23 17:41:50.431428,回测完毕,用时0:00:17.225110
    2019-02-23 17:42:07.762340,回测完毕,用时0:00:17.330767
    2019-02-23 17:42:24.838906,回测完毕,用时0:00:17.076416
    2019-02-23 17:42:42.313726,回测完毕,用时0:00:17.474663
    2019-02-23 17:42:59.851819,回测完毕,用时0:00:17.537938
    2019-02-23 17:43:16.871338,回测完毕,用时0:00:17.019358
    2019-02-23 17:43:34.322078,回测完毕,用时0:00:17.450586
    

    结论:

    计算金叉死叉的时间间隔最优秀的是9,也就是10天之前。不过,整体回测效果并不好。看来单独使用这个指标,在金叉死叉的买卖方法上并不好使。

    回测条件二

    当发生背离时,即价格逐渐走低,而DMA逐渐走高时,买入;当价格逐渐走高,而DMA逐渐走低时,卖出。其中,判断背离需要有一个时间间隔,这里仍旧回测不同时间间隔下的效果。

    date_long = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 这里只测这几个吧
    trade_list = []
    for long in date_long:
        """初始化以下内容"""
        context = Context() # 账户对象
        order = Order(context) # 下单对象
        trade = Trade(context, order) # 回测对旬
        context.start_date = '2005-05-01'
        context.end_date = '2018-12-31'
        context.universe = ['000300.XSHG']
        context.base = '000300.XSHG'
    
        """策略主体"""
        def handle(context, order):
            stock = '000300.XSHG'
            DMA, AMA = get_dma(stock, end_date=trade.context.current_dt, count=long+2)
            close = get_price(security=stock, 
                              end_date=context.current_dt,
                              frequency='daily', 
                              fields=None, 
                              skip_paused=False, 
                              fq='pre',
                              count=long+2)['close']
            
            close1 = close[-1-long]
            close2 = close[-1]
            DMA1 = DMA[-1-long]
            DMA2 = DMA[-1]
            
            # 产生买入的背离信号
            if close2 < close1 and DMA2 > DMA1:
                if stock in context.position.keys():
                    return
                else:
                    order.buy(stock, close2, context.cash // close2)
            elif close2 > close1 and DMA2 < DMA1:
                if stock not in context.position.keys():
                    return
                else:
                    order.sell(stock, close2, context.position[stock]['count'])
        """执行策略"""
        trade.trade(handle, False)
        trade_list.append(trade)
    # 展示
    Trade.show_ratio_compare('date_long', date_long, trade_list, 3, 3)
    Trade.show_result('date_long', date_long, trade_list)
    
    2019-02-23 18:34:52.960845,回测完毕,用时0:00:16.602134
    2019-02-23 18:35:10.298780,回测完毕,用时0:00:17.337748
    2019-02-23 18:35:27.256697,回测完毕,用时0:00:16.957756
    2019-02-23 18:35:43.215573,回测完毕,用时0:00:15.958712
    2019-02-23 18:36:00.272317,回测完毕,用时0:00:17.056580
    2019-02-23 18:36:17.469745,回测完毕,用时0:00:17.197248
    2019-02-23 18:36:34.328112,回测完毕,用时0:00:16.858203
    2019-02-23 18:36:51.307217,回测完毕,用时0:00:16.978911
    2019-02-23 18:37:08.102706,回测完毕,用时0:00:16.795313
    

    结论:

    时间间隔为4天的背离计算,得到的回测结果最优,但整体来说,效果并不是很好。看来,单独使用DMA,效果并不理想。也许,与其他指标结合使用,效果会更好。

    这里只研究单一指标的择时效果,超出范围的不去涉猎,有兴趣的朋友,可以自行研究一下。

    相关文章

      网友评论

          本文标题:DMA指标的趋势与择时效应

          本文链接:https://www.haomeiwen.com/subject/scnpyqtx.html