MACD(指数平滑异同平均线)策略

简介
MACD指标应该是大家最常见的技术指标,在很多股票、比特币的软件中都是默认显示的。MACD是从双指数移动平均线发展而来的。意义和双移动平均线基本相同,即由快、慢均线的离散、聚合表征当前的多空状态和股价可能的发展变化趋势,但阅读起来更方便。

计算方法
MACD的中文名叫做指数平滑异同平均线,听起来很绕口,算起来也不简单。MACD需要先计算两条线:快速(一般选12日)指数移动平均值线EMA1与慢速(一般选26日)指数移动平均值线EMA2。然后用快线减去慢线,得到二者的离差值DIFF。再计算DIFF的指数移动平均线(一般选择9日),得到DEA。用每日的DIFF减去DEA,再乘以2,就得到了MACD的柱状图。

公式总结如下(以日为单位举例):
(1)计算快(12日)、慢(26日)两条EMA线:
     EMA(12)= 前一日EMA(12)X 11/13 + 今日收盘价 X 2/13
     EMA(26) = 前一日EMA(26)X 25/27 + 今日收盘价 X 2/27
(2)计算离差值DIFF
     DIFF = EMA(12)- EMA(26)
(3)计算DIFF的EMA(9日)值DEA:
     DEA = 前一日DEA X 8/10 + 今日DIF X 2/10
(4)计算MACD:
     MACD = (DIFF - DEA)* 2
大功告成!有些同学是不是已经绕晕了,这都是啥玩意,算起来好复杂。还好python的talib库帮我们实现了MACD的计算,所以我们只要关心MACD怎么用就好了(注意:talib采用的公式为 MACD = DIFF – DEA,没有乘以2)。

使用方法
MACD的值本身反映了股市多空力量的走势。MACD上升,说明多方力量在增强,MACD下降,说明空方力量在增强,平衡点在0轴。当MACD穿越0轴时(由正转负或由负转正),很有可能是价格反转的信号。
最基本,也是最常用的使用方法,是黄金交叉和死亡交叉方法。
(1) 黄金交叉:当DIFF由下向上穿破DEA时, 形成黄金交叉, MACD由负转正,产生买入信号。
(2) 死亡交叉:当DIFF由上向下穿破DEA时, 形成死亡交叉, MACD由正转负,产生卖出信号。

优点
MACD主要适于研判中长期走势.易判断上涨或下跌行情的开始与结束。利用MACD指标,可以判断出目前市况是多头市场还是空头市场,避免逆向操作。在确定趋势后,则可采用相应的买卖策略, 减少无谓频繁进出。

缺点
当价格在短时间内上下波动较大时,由于MACD反应迟缓,不能迅速产生买卖信号,所以不适于短线操作。从上面的图中我们也可以看出,发出卖出信号的时候,已经发生了3个比较大的下跌,损失了很大的收益,滞后性较为明显。

在价格处于盘局中波幅较小 时,MACD发出的买卖信号不明显。在价格波动没有明显的上升或下降趋势,而是保持水平方向的整理,此时DIFF线与DEA线的交叉将会十分频繁,同时MACD柱状线的收放也将频频出现,颜色也会常常由绿转红或者由红转绿,此时MACD指标处于失真状态,使用价值相应降低。如下图中,MACD柱频繁的穿越0轴,不停产生买入卖出信号。而在这种频繁变动的行情,由于MACD本身慢半拍的特性,很难获取收益。

传统MACD的参数,更适用于股票市场,而比特币市场相对来说更加不成熟,又没有涨跌停的限制,所以很容易发生迅速的暴涨暴跌。传统的MACD参数回看时间较长,难以及时对市场的变化做出反应。

我们可以尝试着,将DEA的回看时间窗口,由9天调整为5天,回测结果回测结果明显好于之前的,收益更高,回撤更小。所以,在使用MACD时,我们最好不要照搬参数,应当适当做出调整。

总结
MACD指标是很常见的技术指标,是基于均线原理构造出来的一种趋向类指标。 由于MACD指标通常比较滞后,所以更适用于在中长线的投资中使用。在数字货币市场中使用MACD时,应当对参数适当做出调整(通常是减小参数),不能照搬股票市场。当然,MACD指标还有许多更加复杂的使用方法,有兴趣的同学可以深入学习。

代码

  1. # !/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. # 策略代码总共分为三大部分,1)PARAMS变量 2)initialize函数 3)handle_data函数
  5. # 请根据指示阅读。或者直接点击运行回测按钮,进行测试,查看策略效果。
  6.  
  7. # 策略名称:MACD指标策略
  8. # 策略详细介绍:https://wequant.io/study/strategy.macd.html
  9. # 关键词:指数平滑移动均线、多空头预测。
  10. # 方法:
  11. # 1)利用talib库计算MACD值
  12. # 2)MACD柱>0时买入,MACD柱<0时卖出
  13.  
  14. import numpy as np
  15. import talib
  16.  
  17. # 阅读1,首次阅读可跳过:
  18. # PARAMS用于设定程序参数,回测的起始时间、结束时间、滑点误差、初始资金和持仓。
  19. # 可以仿照格式修改,基本都能运行。如果想了解详情请参考新手学堂的API文档。
  20. PARAMS = {
  21. "start_time": "2017-02-01 00:00:00",
  22. "end_time": "2017-08-01 00:00:00",
  23. "slippage": 0.003, # 此处“slippage"包含佣金(千二)+交易滑点(千一)
  24. "account_initial": {"huobi_cny_cash": 100000,
  25. "huobi_cny_btc": 0},
  26. }
  27.  
  28. # 阅读2,遇到不明白的变量可以跳过,需要的时候回来查阅:
  29. # initialize函数是两大核心函数之一(另一个是handle_data),用于初始化策略变量。
  30. # 策略变量包含:必填变量,以及非必填(用户自己方便使用)的变量
  31. def initialize(context):
  32. # 设置回测频率, 可选:"1m", "5m", "15m", "30m", "60m", "4h", "1d", "1w"
  33. context.frequency = "15m"
  34. # 设置回测基准, 比特币:"huobi_cny_btc", 莱特币:"huobi_cny_ltc", 以太坊:"huobi_cny_eth"
  35. context.benchmark = "huobi_cny_btc"
  36. # 设置回测标的, 比特币:"huobi_cny_btc", 莱特币:"huobi_cny_ltc", 以太坊:"huobi_cny_eth"
  37. context.security = "huobi_cny_btc"
  38.  
  39. # 设置使用talib计算MACD的参数
  40. # 周期快速移动平均
  41. context.user_data.fast_period = 12
  42. # 周期慢速移动平均
  43. context.user_data.slow_period = 26
  44. # 周期移动平均
  45. context.user_data.macd_window = 9
  46. # 历史数据要足够长,才能够拿到收敛的MACD
  47. context.user_data.longest_history = 100
  48.  
  49. # 阅读3,策略核心逻辑:
  50. # handle_data函数定义了策略的执行逻辑,按照frequency生成的bar依次读取并执行策略逻辑,直至程序结束。
  51. # handle_data和bar的详细说明,请参考新手学堂的解释文档。
  52. def handle_data(context):
  53. # 获取历史数据, 取后longest_history根bar
  54. hist = context.data.get_price(context.security, count=context.user_data.longest_history, frequency=context.frequency)
  55. if len(hist.index) < context.user_data.longest_history:
  56. context.log.warn("bar的数量不足, 等待下一根bar...")
  57. return
  58.  
  59. # 历史收盘价
  60. prices = np.array(hist["close"])
  61. # 初始化买入卖出信号
  62. long_signal_triggered = False
  63. short_signal_triggered = False
  64.  
  65. try:
  66. # talib计算MACD,返回三个数组,分别为DIF, DEA和MACD的值
  67. macd_tmp = talib.MACD(prices, fastperiod=context.user_data.fast_period, slowperiod=context.user_data.slow_period, signalperiod=context.user_data.macd_window)
  68. # 获取MACD值
  69. macd_hist = macd_tmp[2]
  70. # 获取最新一个MACD的值
  71. macd = macd_hist[-1]
  72. context.log.info("当前MACD为: %s" % macd)
  73. except:
  74. context.log.error("计算MACD出错...")
  75. return
  76.  
  77. # macd大于0时,产生买入信号
  78. if macd > 0:
  79. long_signal_triggered = True
  80. # macd小于0时,产生卖出信号
  81. elif macd < 0:
  82. short_signal_triggered = True
  83.  
  84. # 有卖出信号,且持有仓位,则市价单全仓卖出
  85. if short_signal_triggered:
  86. context.log.info("MACD小于0,产生卖出信号")
  87. if context.account.huobi_cny_btc >= HUOBI_CNY_BTC_MIN_ORDER_QUANTITY:
  88. # 卖出信号,且不是空仓,则市价单全仓清空
  89. context.log.info("正在卖出 %s" % context.security)
  90. context.log.info("卖出数量为 %s" % context.account.huobi_cny_btc)
  91. context.order.sell_limit(context.security, quantity=str(context.account.huobi_cny_btc), price=str(prices[-1]*0.98))
  92. else:
  93. context.log.info("仓位不足,无法卖出")
  94. # 有买入信号,且持有现金,则市价单全仓买入
  95. elif long_signal_triggered:
  96. context.log.info("MACD大于0,产生买入信号")
  97. if context.account.huobi_cny_cash >= HUOBI_CNY_BTC_MIN_ORDER_CASH_AMOUNT:
  98. # 买入信号,且持有现金,则市价单全仓买入
  99. context.log.info("正在买入 %s" % context.security)
  100. context.log.info("下单金额为 %s 元" % context.account.huobi_cny_cash)
  101. context.order.buy_limit(context.security, quantity=str(context.account.huobi_cny_cash/prices[-1]*0.98), price=str(prices[-1]*1.02))
  102. else:
  103. context.log.info("现金不足,无法下单")
  104. else:
  105. context.log.info("无交易信号,进入下一根bar")

回测 2017-02-01 —— 2017-08-01

15m

30m

60m

4h

1d

1w

WeQuant交易策略—MACD的更多相关文章

  1. WeQuant交易策略—网格交易

    网格交易策略(Grid Trading) 策略介绍 网格策略本质上是一种低吸高抛的策略.标的物价格越低,吸纳的头寸越多:标的物价格越高,卖出的头寸越多.网格策略巧妙地借鉴了日常生活中渔翁撒网扑鱼的思路 ...

  2. WeQuant交易策略—RSI

    RSI指标策略 策略介绍 RSI(相对强弱指标),是通过一段时期内的平均收盘上涨和下跌数,计算价格上涨所产生的波动占整个波动的百分比,来分析市场买卖盘的意向和实力. 计算公式(以日为单位举例) RSI ...

  3. WeQuant交易策略—Dual Thrust

    Dual Thrust策略 策略介绍 Dual Thrust是一个趋势跟踪系统,由Michael Chalek在20世纪80年代开发,曾被Future Thruth杂志评为最赚钱的策略之一. Dual ...

  4. WeQuant交易策略—ATR

    ATR(真实波幅均值)策略 策略介绍 ATR(average true range,真实波幅均值),是用来衡量一段时间内价格的真实的平均波动范围,ATR不是一个领先指标,但是它测量最重要的市场参数之一 ...

  5. WeQuant交易策略—BOLL

    BOLL(布林线指标)策略 简介 BOLL(布林线)指标是技术分析的常用工具之一,由美国股市分析家约翰•布林根据统计学中的标准差原理设计出来的一种非常简单实用的技术分析指标.一般而言,价格的运动总是围 ...

  6. WeQuant交易策略—KDJ

    KDJ随机指标策略策略介绍KDJ指标又叫随机指标,是一种相当新颖.实用的技术分析指标,它起先用于期货市场的分析,后被广泛用于股市的中短期趋势分析,是期货和股票市场上最常用的技术分析工具.随机指标KDJ ...

  7. WeQuant交易策略—简单均线

    简单双均线策略(Simple Moving Average) 策略介绍简单双均线策略,通过一短一长(一快一慢)两个回看时间窗口收盘价的简单移动平均绘制两条均线,利用均线的交叉来跟踪价格的趋势.这里说的 ...

  8. WeQuant交易策略—EMV

    EMV指标策略 简介 EMV(Ease of Movement Value, 简易波动指标),它是由RichardW.ArmJr.根据等量图和压缩图的原理设计而成, 目的是将价格与成交量的变化结合成一 ...

  9. WeQuant交易策略—Chaikin A/D

    策略名称:AD指标策略 多空双方力量浮标- AD(Chaikin A/D线)策略关键词:ChaikinA/D线.多空对比.AD指标是一种非常流行的平横交易量指标, 用于估定一段时间内该证券累积的资金流 ...

随机推荐

  1. rsync随机启动脚本

    服务端 #!/bin/sh # chkconfig: # description: Saves and restores system entropy pool for \ #create by xi ...

  2. CentOS-7.2安装SQuirreL SQL Client连接Hive

    一,SQuirreL SQL Client干吗的? SQuirreL SQL Client是一款功能强大的服务器配置管理软件,该软件能够帮助用户快速.高效的配置服务器,且支持用户查看数剧库的结构并发出 ...

  3. 关于华为P9手机的解锁、刷Recovery、获取Root、安装Busybox,以及升级降级的全过程(和一些错误的解决方法)

    我有一部华为P9手机,型号EVA-TL00,属于移动定制机.用了半年多了,想给手机添加一些功能,发现有些功能必须Root之后才能用代码实现,所以动了Root的打算. 一.手机解锁.(不解锁则无法对手机 ...

  4. POJ 2566 尺取法(进阶题)

    Bound Found Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4297   Accepted: 1351   Spe ...

  5. [权限相关]在PeopleSoft中查找可以使用DataMover的用户

    DataMover是一个功能非常强大的工具,它的访问权限应该被控制,特别是在PRD环境中.在每个公司,许多用户可能在一段时间内切换部门,角色和职责,所以每隔一段时间就应该检查这些用户的权限,以确认他们 ...

  6. (转)Spring3MVC 在JSP中使用@ModelAttribute

    原文连接:http://liukai.iteye.com/blog/973717,仅供自己参考. 在教程中,我们将创建一个简单的Spring3MVC simple CRUD应用程序. 什么是@Mode ...

  7. Maven常用的几个核心概念

    在使用Maven的过程中,经常会遇到几个核心的概念,准确的理解这些概念将会有莫大的帮助. 1. POM(Project Object Model)项目对象模型 POM 与 Java 代码实现了解耦,当 ...

  8. Mac下安装 MongoDB

    Mac 下安装 MongoDB 一般有两种方法,一种是通过源码安装,一种是直接使用 homebrew ,个人推荐使用 homebrew ,简单粗暴. 1.安装 homebrew : /usr/bin/ ...

  9. Angular页面选项卡切换要注意的toggleClass

    在第一,第二篇随笔中写到的选项卡切换,我回头看了看发现缺少了一个很重要的部分,那就是toggleClass. //在js控制器中必须写明指令,要不然在页面写了toggle-class="ac ...

  10. 43. leetcode 459. Repeated Substring Pattern

    459. Repeated Substring Pattern Given a non-empty string check if it can be constructed by taking a ...