概念介绍
-
移动平均值(EMA)
EMA(12)=前一日EMA(12)×11/13+今日收盘价×2/13 EMA(26)=前一日EMA(26)×25/27+今日收盘价×2/27
计算移动均值是一个不断累加并调整系数的过程。与传统均值的区别在于:移动均值参考到该股票自上市以来每一天的收盘价,并在每次累计上新的收盘价时,弱化之前收盘价的比重,以实现动态累计的效果。
-
离差值(DIF)
DIF=今日EMA(12)-今日EMA(26)
离差值是双均线策略的核心指标。计算离差值的意义在于:反映该股票的发展势头。理论上,当DIF>0,则发展势头向好。
-
离差平均值(EMA)
今日DEA(MACD)=前一日DEA×8/10+今日DIF×2/10
-
MACD柱
MACD柱值=(DIF-DEA)×2
此处做差的原理与DIF相同,这里的DIF也就相当于周期为1日的DEA。因此,如果说DIF的正负是衡量发展势头是否向好,那么MACD柱则反应发展势头有多猛,数学意义相当于对DIF求导。
-
几个参数之间的关系
对该指标的一些想法与分析
1、移动平均线的优势
- 参考到更多的历史数据
- 动态赋权:近则影响大,远则影响小
2、分析股票主要有两个角度:长期和短期。如均线只能反映股票的历史价格,但通过两条不同周期的均线比较,从而判断当前参数近期内的发展趋势。MACD柱的原理同理。
3、为什么需要MACD指标?MACD是对股价的抽象,意在发现其涨跌周期律。那么如何来进行高层抽象呢?其主要通过平均和不同周期做差这两个操作来实现。
- 平均是将新数据与历史数据进行合并,起到过滤噪声、平缓变化的作用。由于每日收盘价太过起伏,对近期股价的判断具有较高的随机性。所以我们进行一次抽象,计算平均值,应用均线策略来帮助判断。但均线策略仍具有较高的随机性,所以对均线再做平均,即对股价的二次抽象,得到MACD指标。
- 不同周期做差用于判断参数的发展势头。新股价的合并对不同周期参数产生不同影响,根据运算规则可知,对短期参数必然影响更大。而长期参数则可视为参考对象,其变化为必然变化,短期参数变化-必然变化=超额变化,也就是我们所说的趋势。
4、根据第三点的阐述,可知MACD的作用原理在于通过两层抽象来尝试挖掘股价的周期变化律。因此MACD的提出是基于这样一个假设的:股价存在涨跌周期律。而事实上我们也会发现:尽管每日收盘价是阴晴不定的,就算昨天涨今天也可能跌,具有跳跃性,但MACD柱都是渐变的,类似于正弦函数。理论而言,这具有合理性也我们的常识一致,因为势头由盛转衰、由衰转盛都不是突变的,但股价涨跌是突变的,致使在实际操作上存在问题。
5、第四点提出:由于MACD成立存在假设,所以理论与实际存在偏差。具体而言,其偏差主要体现在滞后性。当一只股票上涨一段时间后开始下跌,但下跌后的股价仍高于历史平均,就会使得DIF和DEA仍在上涨,导致MACD无法捕捉到这段下跌趋势。为了补足这个缺陷,在交易时合理的买入点为DIF超过DEA时产生的金叉,但合理的卖出点应为MACD柱的最高点。
6、缺陷情况补充:先下跌在上涨,综合第五点即为两种极值情况;适用情况:先平滑再上涨。
MACD策略回测
常规MACD策略为在0轴上金叉买入,在0轴之下死叉卖出
策略模板代码
import numpy as np
import pandas as pd
# 导入技术分析库
import talib as tb
def initialize(context):# 初始化
g.security = '600160.XSHG'# 股票代码,XSHG:上海证券交易所,XSHE:深圳证券交易所
def handle_data(context, data):# 每日循环
prices = attribute_history(g.security, 300, '1d', ['close'])
price = np.array(prices['close'])
cash = context.portfolio.cash# 取得当前的现金
DIF, DEA, MACD = tb.MACD(
price,
fastperiod=12,
slowperiod=26,
signalperiod=9)
# 在0轴上金叉买入
if DIF[-1] > 0 and DEA[-1] > 0:
if (DIF[-2] <= DEA[-2]) and (DIF[-1] > DEA[-1]):
order_value(g.security, cash)
# 在0轴之下死叉卖出
elif DIF[-1] < 0 and DEA[-1] < 0:
if (DIF[-2] >= DEA[-2]) and (DIF[-1] < DEA[-1]):
order_target(g.security, 0)
经过上述分析,我认为将卖出点设置为MACD柱最高点更为合适,即将上面代码的卖出部分改为
# 在MACD最高点卖出
if MACD[-1] < MACD[-2] * 0.95:
order_target(g.security, 0)
以下为对部分行业的股票进行回测的结果
回测时间:2018/1/1-2020/3/1
基准收益:-2.25%
房地产股
股票代码 | 股票名称 | 传统策略 | 修改策略 |
---|---|---|---|
000002 | 万科A | 8.78% | 3.78% |
000402 | 金融街 | -23.48% | 5.27% |
002146 | 荣盛发展 | 7.57% | 8.64% |
600048 | 保利地产 | 14.02% | -2.70% |
银行股
股票代码 | 股票名称 | 传统策略 | 修改策略 |
---|---|---|---|
601398 | 工商银行 | -12.35% | -6.00% |
601328 | 交通银行 | -7.95% | -0.37% |
601288 | 农业银行 | -9.57% | 3.76% |
601818 | 光大银行 | -12.09% | -2.67% |
医药股
股票代码 | 股票名称 | 传统策略 | 修改策略 |
---|---|---|---|
000538 | 云南白药 | -20.76% | -2.45% |
600276 | 恒瑞医药 | 62.98% | 1.20% |
601607 | 上海医药 | 0.00% | 0.00% |
600056 | 中国医药 | -48.37% | -11.24% |
在几组简单的测试条件下,修改策略在多数情况表现优于传统策略,但似乎也失去了一次大赚的机会。总体而言,修改策略相对传统策略更为保守和稳健。当然,上述测试尚不完全,有待进一步测试完善。