量化投资常用技能 系列文章目录
我们已经介绍了三篇关于量化投资方面绘图的文章,大家有兴趣可以了解一下
量化投资常用技能——指标篇1
前言
由于这一部分主要是给大家介绍指标的数学公式和计算方法,更深入的了解它们,其中有众多的数学公式和理论推导过程,我尽可能排版的工整,方便各位阅读。如果只想看代码实现可以跳到最后面“代码实现”部分
之前的绘图篇中,我们分三个篇章分别介绍如何绘制收盘价折线图、烛状图、基于收盘价绘制移动平均线、黄金分割线。在接下来的指标篇中,我们将详细介绍每个指标的计算方法以及算法实现,并绘制出指标供各位投资者使用、参考,并提供该指标的一些研判标准,希望各位学有所成!
大家可以关注我的GitHub:ExileSaber
虽然现在还没较高的水平,但是可以一起学习进步
一、需要提前了解的知识点
这一部分主要是为了让初学者更容易了解MACD指标的构成原理,大家也可以先阅读后面的MACD指标,如果发现有什么地方解释的不清楚可以看一下这一块有没有说明,也可以在最后面的评论提问,博主看到了都会认真解答。
MA指标: Moving Average(移动平均线)
该指标的计算公式:
M A = ( C 1 + C 2 + . . . + C n ) / n MA = (C_1+C_2+...+C_n)/n MA=(C1+C2+...+Cn)/n
其中C 为收盘价,n 为移动平均周期数。之前有介绍如何绘制移动平均线,可以查看我之前的文章:量化投资常用技能——绘图篇 2:绘制移动平均线
补充一个概念:一般将3天、7天的平均线称为短线,10天、30天的平均线称为中线,150天、250天平均线称为长线
EMA指标:Exponential Moving Average(指数移动平均值)
该指标的介绍来自于百度百科
定义式
这部分是讲解EMA指标的推导过程,需要一定的数学功底,大家也可以跳过,直接看递推式
- 对序列 { X n } \lbrace X_n \rbrace {Xn} 定义其截至第 n 项的周期为N 的指数移动平均 E M A N ( x n ) EMA_N(x_n) EMAN(xn)为:
E M A N ( x n ) = 2 N + 1 ∑ k = 0 ∞ ( N − 1 N + 1 ) k x n − k EMA_N(x_n) = \frac{2}{N+1} \sum^\infty_{k=0}\bigg (\frac{N-1}{N+1}\bigg )^kx_{n-k} EMAN(xn)=N+12k=0∑∞(N+1N−1)kxn−k
由于在我们的序列 { X n } \lbrace X_n \rbrace {Xn}中,没有 X 1 X_1 X1之前的数据,因此我们补充定义: X 0 = X − 1 = X − 2 = . . . = X 1 X_0=X_{-1}=X_{-2}=...=X_1 X0=X−1=X−2=...=X1
- 计算 E M A N ( x 1 ) EMA_N(x_1) EMAN(x1)的值,其中 x 1 − k x_{1-k} x1−k这一项我们可以全部替换为 x 1 x_1 x1,因此公式变为:
E M A N ( x 1 ) = 2 N + 1 ∑ k = 0 ∞ [ ( N − 1 N + 1 ) k x 1 ] EMA_N(x_1) = \frac{2}{N+1} \sum^\infty_{k=0}\bigg[\bigg (\frac{N-1}{N+1}\bigg )^kx_1\bigg] EMAN(x1)=N+12k=0∑∞[(N+1N−1)kx1]
- 可以发现中括号内是一个等比数列求和,因此根据等比数列求和公式知道:
其中 ( N − 1 N + 1 ) ∞ (\frac{N-1}{N+1})^\infty (N+1N−1)∞这一项由极限可知为0
∑ k = 0 ∞ [ ( N − 1 N + 1 ) k x 1 ] = x 1 ( 1 − ( N − 1 N + 1 ) ∞ ) 1 − N − 1 N + 1 = x 1 2 N + 1 = ( N + 1 ) x 1 2 \sum^\infty_{k=0}\bigg[\bigg (\frac{N-1}{N+1}\bigg )^kx_1\bigg]=\frac{x_1\big(1-(\frac{N-1}{N+1})^\infty\big)}{1-\frac{N-1}{N+1}}=\frac{x_1}{\frac{2}{N+1}}=\frac{(N+1)x_1}{2} k=0∑∞[(N+1N−1)kx1]=1−N+1N−1x1(1−(N+1N−1)∞)=N+12x1=2(N+1)x1
综上可知
E
M
A
N
(
x
1
)
=
x
1
EMA_N(x_1)=x_1
EMAN(x1)=x1
通过上述推导过程,我们很容易发现一个特点,当
k
k
k越小、
x
n
−
k
x_{n-k}
xn−k这一项的下标越大时,
x
n
−
k
x_{n-k}
xn−k前的系数
(
N
−
1
N
+
1
)
k
\big(\frac{N-1}{N+1}\big)^k
(N+1N−1)k越大。这说明当时间越靠近当前日期时(也就是
k
k
k越小、
n
−
k
n-k
n−k 越靠近
n
n
n时),
x
n
−
k
x_{n-k}
xn−k的权重越大,也就是EMA函数对近期的价格加强了权重比,更能及时反映近期价格波动情况
移动平均线MA指标对时间段内每天的价格都是同等权重,延后性较高
递推式
由EMA的定义式可以推导出如下的递推公式:
E
M
A
N
(
x
n
)
=
2
x
n
+
(
N
−
1
)
E
M
A
N
(
x
n
−
1
)
N
+
1
EMA_N(x_n) = \frac{2x_n + (N-1)EMA_N(x_{n-1})}{N+1}
EMAN(xn)=N+12xn+(N−1)EMAN(xn−1)
双指数(二重)EMA公式
以下为其定义式,了解一下,MACD指标是从该指标上发展来的
对序列 { X n } \lbrace X_n \rbrace {Xn} 的 N 周期 EMA 再取一个 M 周期 EMA,将得到
E M A M [ E M A N ( x n ) ] = ( M − 1 ) E M A M ( x n ) − ( N − 1 ) E M A N ( x n ) M − N EMA_M\big[EMA_N(x_n)\big] = \frac{(M-1)EMA_M(x_n)-(N-1)EMA_N(x_n)}{M-N} EMAM[EMAN(xn)]=M−N(M−1)EMAM(xn)−(N−1)EMAN(xn)
二、MACD指标
MACD指标,全称Moving Average Convergence / Divergence(指数平滑移动平均线)
该指标包含三个部分:两线一柱,快线称DIF,慢线称DEA,柱状图为MACD
MACD指标的数学计算过程
我们要获得第n天的MACD,那么我们的数学计算过程如下
- 计算第 n n n天的 12日EMA(N=12) 和 26日EMA(N=26):
E M A 12 ( x n ) = 11 13 E M A 12 ( x n − 1 ) + 2 13 x n EMA_{12}(x_n)=\frac{11}{13}EMA_{12}(x_{n-1})+\frac{2}{13}x_n EMA12(xn)=1311EMA12(xn−1)+132xn
其中 x n x_n xn表示第n天的价格, E M A 12 ( x n − 1 ) EMA_{12}(x_{n-1}) EMA12(xn−1)表示前一天(第 n-1 天)的12日EMA
E M A 26 ( x n ) = 25 27 E M A 26 ( x n − 1 ) + 2 27 x n EMA_{26}(x_n)=\frac{25}{27}EMA_{26}(x_{n-1})+\frac{2}{27}x_n EMA26(xn)=2725EMA26(xn−1)+272xn
-
计算离差值 DIF:
第n日的DIF:
D I F n = E M A 12 ( x n ) − E M A 26 ( x n ) DIF_n=EMA_{12}(x_n)-EMA_{26}(x_n) DIFn=EMA12(xn)−EMA26(xn)
- 计算 DIF 的 9 日 EMA(该指标一般被称为 DEA 或 DEM)
-
定义式:
- 第n天的DEA:
D
E
A
n
=
E
M
A
9
(
d
i
f
n
)
=
8
10
E
M
A
9
(
d
i
f
n
−
1
)
+
2
10
d
i
f
n
DEA_n=EMA_9(dif_n)=\frac{8}{10}EMA_9(dif_{n-1})+\frac{2}{10}dif_n
DEAn=EMA9(difn)=108EMA9(difn−1)+102difn
其中
d
i
f
n
dif_n
difn表示第n天的DIF值
- 递推式:
根据离差值计算其 9 日的EMA,即离差平均值,称为第 n n n 日DEA
D E A n = 8 10 D E A ( x n − 1 ) + 2 10 D I F ( x n ) DEA_n = \frac{8}{10}DEA(x_{n-1}) + \frac{2}{10}DIF({x_{n})} DEAn=108DEA(xn−1)+102DIF(xn)
- 计算MACD柱状图
( D I F n − D E A n ) × 2 (DIF_n-DEA_n)\times2 (DIFn−DEAn)×2
计算得到的值即为柱状图的值
代码实现各数值的计算
结合numpy库计算MACD指标十分简单,计算时使用递推公式即可很方便的从第一个值得到之后各个时刻的值。得到MACD指标的两线一柱只有一个需要实现的函数——EMA的计算函数
先加上部分库的导入,方便学习的过程可以直接运行
import abupy
import numpy as np
from abupy import ABuSymbolPd
# ———————————————————— #
# ———— 默认参数设置 ———— #
# ———————————————————— #
__colorup__ = "red"
__colordown__ = "green"
abupy.env.enable_example_env_ipython() # 使用沙盒数据,目的是和书中一样的数据环境,不使用会报错
tsla_df = ABuSymbolPd.make_kl_df('usTSLA', n_folds=2) # 固定导入tsla的行情数据
tsla_df = tsla_df[:100] # 选取前100个,数据过多不易观察
print(tsla_df[:10])
# ———————————————————— #
def EMA(data, window):
'''
计算EMA指标
:param data: 传入的数据,需要为list、ndarray、series类型数据
:param window: 对应着计算的是几日的EMA
:return: 返回ndarray的数据类型
'''
list_ema = [] # 用于存储计算得到的每个ema,也方便递推公式的使用
list_ema.append(data[0])
for i in range(1, len(data)):
list_ema.append(2 * data[i] / (window+1) + (window-1) * list_ema[-1] / (window+1)) # 这部分是递推公式的实现
return np.array(list_ema) # 最后转换为ndarray的数据类型,方便之后的两个ndarray的相减运算
有了计算EMA指标的函数后,我们就可以很方便的实现 E M A 12 EMA_{12} EMA12, E M A 26 EMA_{26} EMA26 、DIF指标、DIF指标的 E M A 9 EMA_9 EMA9 以及MACD柱状图的值
ema_12 = EMA(data=tsla_df['close'], window=12) # 12日EMA的值
ema_26 = EMA(data=tsla_df['close'], window=26) # 26日EMA的值
dif = ema_12 - ema_26 # 利用ndarray之间的减法运算即为各对应元素相减,得到DIF
dea = EMA(data=dif, window=9) # 再计算DIF的9日EMA(该值被称为DEA)
macd = (dif - dea) * 2 # 计算MACD柱状图的值
上面的两块代码放在一起就组成了我们MACD指标的计算过程,接下来实现MACD指标的绘制
绘制MACD指标:两线一柱
我们需要绘制的两线一柱,其中MACD柱状图会有正负两种情况,为了更好的区分正负情况,我们需要绘制两次柱状图,其中一次用红色绘制MACD值为正的情况,另外一次用绿色绘制MACD为负的情况。实现的函数如下:
def draw_macd(dif, dea, macd, axs=None, show=False):
'''
通过传入DIF、DEA、MACD的值绘制MACD指标的两线一柱
:param dif: DIF指标的list或者ndarray数据类型
:param dea: DEA指标的list或者ndarray数据类型
:param macd: 为了代码简洁,目前只支持ndarray类型的MACD数据
:param axs: 是否在子图绘制
:param show: 是否绘图
:return:
'''
x = np.arange(len(dif)) # 横坐标
drawer = axs if axs is not None else plt
drawer.plot(x, dif, label='DIF', color='b', linestyle='--') # 绘制DIF曲线
drawer.plot(x, dea, label='DEA', color='y', linestyle='-.') # 绘制DEA曲线
pos_index = x[macd >= 0] # 得到MACD值大于等于0的索引
neg_index = x[macd < 0] # 得到MACD值小于0的索引
drawer.bar(pos_index, macd[pos_index], color='r', label='macd bar', alpha=0.6) # 绘制MACD大于等于0部分的柱状图
drawer.bar(neg_index, macd[neg_index], color='g', label='macd bar', alpha=0.6) # 绘制MACD小于0部分的柱状图
drawer.legend()
if show:
plt.show()
完整的绘图代码
为了绘图全面,我们将“量化投资常用技能——绘图篇 1:绘制股票收盘价格曲线和ochl烛状图”中绘制烛状图的函数 p l o t plot plot_ o c h l ochl ochl 黏贴到这一部分代码中,即可完成多图绘制,完整代码如下
缺少的库直接 pip install 安装即可
import abupy
import numpy as np
from abupy import ABuSymbolPd, nd
import matplotlib.pyplot as plt
from matplotlib.dates import date2num
import mpl_finance as mpf
# ———————————————————— #
# ———— 默认参数设置 ———— #
# ———————————————————— #
__colorup__ = "red"
__colordown__ = "green"
abupy.env.enable_example_env_ipython() # 使用沙盒数据,目的是和书中一样的数据环境,不使用会报错
tsla_df = ABuSymbolPd.make_kl_df('usTSLA', n_folds=2) # 固定导入tsla的行情数据
tsla_df = tsla_df[:100] # 选取前100个,数据过多不易观察
print(tsla_df[:10])
# ———————————————————— #
def plot_ochl(data_df=tsla_df, axs=None, show=False):
'''
绘制烛状图
:param data_df: 输入的数据,默认采用tsla的历史行情数据,输入的数据类型目前只支持DataFrame类型
:param axs: 是否在子图上绘制
:param show: 是否显示图像
:return:
'''
drawer = plt if axs is None else axs
qutotes = []
for index, (d, o, c, h, l) in enumerate(
zip(data_df.index, data_df.open, data_df.close,
data_df.high, data_df.low)):
d = date2num(d) # 蜡烛图的日期要使用matplotlib.finance.date2num进行转换为特有的数字值
val = (d, o, c, h, l) # 日期,开盘,收盘,最高,最低组成tuple对象val
qutotes.append(val) # 加val加入qutotes
# 使用mpf.candlestick_ochl进行蜡烛绘制,ochl代表:open,close,high,low
mpf.candlestick_ochl(drawer, qutotes, width=0.6, colorup=__colorup__, colordown=__colordown__)
drawer.autoscale_view()
drawer.xaxis_date()
if show:
plt.show()
def EMA(data, window):
'''
:param data: 传入的数据,需要为list、ndarray、series类型数据
:param window: 对应着计算的是几日的EMA
:return: 返回ndarray的数据类型
'''
list_ema = []
list_ema.append(data[0])
for i in range(1, len(data)):
list_ema.append(2 * data[i] / (window+1) + (window-1) * list_ema[-1] / (window+1))
return np.array(list_ema)
def draw_macd(dif, dea, macd, axs=None, show=False):
'''
通过传入DIF、DEA、MACD的值绘制MACD指标的两线一柱
:param dif: DIF指标的list或者ndarray数据类型
:param dea: DEA指标的list或者ndarray数据类型
:param macd: 为了代码简洁,目前只支持ndarray类型的MACD数据
:param axs: 是否在子图绘制
:param show: 是否绘图
:return:
'''
x = np.arange(len(dif)) # 横坐标
drawer = axs if axs is not None else plt
drawer.plot(x, dif, label='DIF', color='b', linestyle='--') # 绘制DIF曲线
drawer.plot(x, dea, label='DEA', color='y', linestyle='-.') # 绘制DEA曲线
pos_index = x[macd >= 0] # 得到MACD值大于等于0的索引
neg_index = x[macd < 0] # 得到MACD值小于0的索引
drawer.bar(pos_index, macd[pos_index], color='r', label='macd bar', alpha=0.6) # 绘制MACD大于等于0部分的柱状图
drawer.bar(neg_index, macd[neg_index], color='g', label='macd bar', alpha=0.6) # 绘制MACD小于0部分的柱状图
drawer.legend()
if show:
plt.show()
if __name__ == '__main__':
# plot_ochl() # 绘制烛状图,会新建画布
ema_12 = EMA(data=tsla_df['close'], window=12) # 12日EMA的值
ema_26 = EMA(data=tsla_df['close'], window=26) # 26日EMA的值
dif = ema_12 - ema_26 # 利用ndarray之间的减法运算即为各对应元素相减,得到DIF
dea = EMA(data=dif, window=9) # 再计算DIF的9日EMA(该值被称为DEA)
macd = (dif - dea) * 2 # 计算MACD柱状图的值
fig, ax = plt.subplots(2, 1)
plot_ochl(tsla_df, axs=ax[0])
draw_macd(dif, dea, macd, axs=ax[1], show=True)
最后的绘制效果如下:
三、MACD指标的一般研判标准及代码判断
该部分主要介绍几个常见的研判标准,实际情况并不一定会和研判标准相符合,由MACD指标的数学公式以及数学计算过程可以了解到MACD指标有一定的延后性
这部分借鉴了百度百科和多个MACD指标研究文章,放在最后供大家学习代码后也可以了解一下一些MACD指标的研判标准
研判标准一:DIF和MACD的值及线的位置
- 当DIF和MACD均大于0(即在图形上表示为它们处于零线以上)并向上移动时,一般表示为股市处于多头行情中,可以买入开仓或多头持仓
- 当DIF和MACD均小于0(即在图形上表示为它们处于零线以下)并向下移动时,一般表示为股市处于空头行情中,可以卖出股票或观望
- 当DIF和MACD均大于0(即在图形上表示为它们处于零线以上)但都向下移动时,一般表示为股票行情处于退潮阶段,股票将下跌,可以卖出股票和观望
- 当DIF和MACD均小于0时(即在图形上表示为它们处于零线以下)但向上移动时,一般表示为行情即将启动,股票将上涨,可以买进股票或持股待涨。
研判标准二:DIF和MACD的交叉情况
- 当DIF与MACD都在零线以上,而DIF向上突破MACD时,表明股市处于一种强势之中,股价将再次上涨,可以加码买进股票或持股待涨,这就是MACD指标“黄金交叉”的一种形式
- 当DIF和MACD都在零线以下,而DIF向上突破MACD时,表明股市即将转强,股价跌势已尽将止跌朝上,可以开始买进股票或持股,这是MACD指标“黄金交叉”的另一种形式
- 当DIF与MACD都在零线以上,而DIF却向下突破MACD时,表明股市即将由强势转为弱势,股价将大跌,这时应卖出大部分股票而不能买股票,这就是MACD指标的“死亡交叉”的一种形式
- 当DIF和MACD都在零线以上,而DIF向下突破MACD时,表明股市将再次进入极度弱市中,股价还将下跌,可以再卖出股票或观望,这是MACD指标“死亡交叉”的另一种形式
研判标准三:MACD指标中的柱状图分析
- 当红柱状持续放大时,表明股市处于牛市行情中,股价将继续上涨,这时应持股待涨或短线买入股票,直到红柱无法再放大时才考虑卖出
- 当绿柱状持续放大时,表明股市处于熊市行情之中,股价将继续下跌,这时应持币观望或卖出股票,直到绿柱开始缩小时才可以考虑少量买入股票
- 当红柱状开始缩小时,表明股市牛市即将结束(或要进入调整期),股价将大幅下跌,这时应卖出大部分股票而不能买入股票
- 当绿柱状开始收缩时,表明股市的大跌行情即将结束,股价将止跌向上(或进入盘整),这时可以少量进行长期战略建仓而不要轻易卖出股票
- 当红柱开始消失、绿柱开始放出时,这是股市转市信号之一,表明股市的上涨行情(或高位盘整行情)即将结束,股价将开始加速下跌,这时应开始卖出大部分股票而不能买入股票
- 当绿柱开始消失、红柱开始放出时,这也是股市转市信号之一,表明股市的下跌行情(或低位盘整)已经结束,股价将开始加速上升,这时应开始加码买入股票或持股待涨
欢迎大家关注我的GitHub
GItHub:ExileSaber
目前自己也正处于学习的阶段,感谢各位的评论和建议!