赞
踩
MACD又称为异同移动平均线,用来度量不同频率移动平均线的变化情况。MACD指标主要包括3根线,分别为DIF、DEA和MACD。
12
日
E
M
A
:
E
M
A
(
12
)
=
2
12
+
1
∗
今
日
收
盘
价
(
12
)
+
11
12
+
1
∗
昨
日
E
M
A
(
12
)
12日EMA:EMA(12) = \frac{2}{12+1} * 今日收盘价(12) + \frac{11}{12+1} * 昨日EMA(12)
12日EMA:EMA(12)=12+12∗今日收盘价(12)+12+111∗昨日EMA(12)
26
日
E
M
A
:
E
M
A
(
26
)
=
2
26
+
1
∗
今
日
收
盘
价
(
26
)
+
25
26
+
1
∗
昨
日
E
M
A
(
26
)
26日EMA:EMA(26) = \frac{2}{26+1} * 今日收盘价(26) + \frac{25}{26+1} * 昨日EMA(26)
26日EMA:EMA(26)=26+12∗今日收盘价(26)+26+125∗昨日EMA(26)
D
I
F
F
:
D
I
F
F
=
E
M
A
(
12
)
−
E
M
A
(
26
)
DIFF:DIFF=EMA(12) - EMA(26)
DIFF:DIFF=EMA(12)−EMA(26)
D
E
A
:
D
E
A
=
2
9
+
1
∗
今
日
D
I
F
F
+
8
9
+
1
∗
昨
日
D
E
A
DEA: DEA = \frac{2}{9+1} * 今日DIFF + \frac{8}{9+1} * 昨日DEA
DEA:DEA=9+12∗今日DIFF+9+18∗昨日DEA
M
A
C
D
:
M
A
C
D
=
2
∗
(
D
I
F
F
−
D
E
A
)
MACD:MACD = 2 * (DIFF-DEA )
MACD:MACD=2∗(DIFF−DEA)
DIFF表示长周期均线和短周期均线的差值,DIFF > 0则表示短周期均线处于长周期均线上方,DIFF < 0则表示短周期均线处于长周期均线下方。DEA是DIFF的简单移动平均线,MACD是移动平均线和移动平均线的移动平均线的差值。
在应用过程中,常用其中的MACD指标或其中多个组合进行判断。
同时使用DIFF和DEA进行判断
当DIFF>0时,说明短周期均线处于长周期均线上方,近期价格呈现上涨趋势;当DEA>0时,说明短周期均线在近几期一直处于长周期均线的上方。如果DIFF上穿DEA,表示DIFF近期也处于上涨趋势,这两者叠加,说明该标的近期价格已经处于一个很高的价位。
若单独使用MACD指标
和同时使用DIFF和DEA相差不大,MACD是将DIFF和DEA差值以数值的形式表现出来。MACD有绿柱和红柱,柱体越长,说明近期价格上涨或下跌的程度越强,可以视作上涨或下跌力量的强弱。
在python中可以利用第三方库talib计算MACD指标,但发现怎么都无法和通达信等行情软件对上,所以自己按照原理写了一个。
由于原始数据难以获得,所以以下代码基于掘金量化平台的sdk查询标的原始数据。如果本地有数据或有其他的数据来源,只需要将data数据集变成输入参数,将函数中获取data的部分删除即可。
这里用到pandas库里面特别好用的两个函数:rolling/expanding和ewm,前者是滚动窗口,后者是求加权平均。rolling(N)可以实现每N个求一次平均,expanding(N)可以实现从N个窗口开始,求逐渐扩大窗口的平均。
# coding=utf-8 from __future__ import print_function, absolute_import from gm.api import * import pandas as pd import numpy as np def MACD(symbol, start_time, end_time): '''计算MACD指标 输入参数:symbol <- str 标的代码 (2005年以前上市的不可用) start_time <- str 起始时间 end_time <- str 结束时间 输出数据: macd <- dataframe macd指标,包括DIFF、DEA、MACD ''' # 取历史数据,取到上市首日 data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close', df=True) # 将数据转化为dataframe格式 data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist() # 计算EMA(12)和EMA(16) data['EMA12'] = data['close'].ewm(alpha=2 / 13, adjust=False).mean() data['EMA26'] = data['close'].ewm(alpha=2 / 27, adjust=False).mean() # 计算DIFF、DEA、MACD data['DIFF'] = data['EMA12'] - data['EMA26'] data['DEA'] = data['DIFF'].ewm(alpha=2 / 10, adjust=False).mean() data['MACD'] = 2 * (data['DIFF'] - data['DEA']) # 上市首日,DIFF、DEA、MACD均为0 data['DIFF'].iloc[0] = 0 data['DEA'].iloc[0] = 0 data['MACD'].iloc[0] = 0 # 按照起止时间筛选 MACD = data[(data['bob'] >= start_time)] return MACD # 测试一下 a = MACD(symbol = 'DCE.y2101',start_time = '2020-01-01',end_time = '2020-10-22')
注:通达信等软件是从上市第一天开始算起的,只有当原始数据是从上市日期开始时,得到的结果才和通达信等软件相同。在进行验证时,最好用期货验证。
KDJ中文名称是随机指标,是利用N日内最高价、最低价、收盘价计算得到的,常用来判断标的超买超卖、价格波动。
计
算
N
日
R
S
V
=
今
日
收
盘
−
N
日
最
低
N
日
最
高
−
N
日
最
低
)
∗
100
计算N日RSV = \frac{今日收盘 - N日最低}{N日最高-N日最低)}* 100
计算N日RSV=N日最高−N日最低)今日收盘−N日最低∗100
K
=
(
1
−
1
M
1
)
∗
前
一
日
K
值
+
1
M
1
∗
R
S
V
K = (1- \frac{1}{M1})*前一日K值 + \frac{1}{M1} * RSV
K=(1−M11)∗前一日K值+M11∗RSV
D
=
(
1
−
1
M
1
)
∗
前
一
日
D
值
+
1
M
1
∗
K
值
D = (1-\frac{1}{M1})*前一日D值 + \frac{1}{M1} * K值
D=(1−M11)∗前一日D值+M11∗K值
J
=
3
∗
K
−
2
∗
D
J = 3 * K - 2 * D
J=3∗K−2∗D
RSV是(今收与最低的差值)与(最高与最低的差值比),可以想象成今天价格涨势占N日内涨得最凶的比例,也是一种衡量今日价格走势的指标。K是根据RSV进行加权得到的,D是根据K加权得到的。当RSV较高时,说明今天标的价格走势不错。但今天走势不错并非意味着已经形成较为明确的上涨趋势,只有当最近一段时间一直上涨,才能说明标的有了非常明显的上涨趋势。因此,只有RSV判断不够准确,需要对其加权平均,由此衍生出K和D。
K可以想象成度量过去一段时间收盘价涨跌情况,距离当前日期越近,所占权重越高,K越大说明近期收盘价的涨势越明显。D是对K的加权,减少了当前RSV的权重。(我通常将K和D理解为短周期均线和长周期均线)J是3倍的K减去2倍的D,(我将其理解为短周期均线和长周期均线的差值)。
KDJ上行,且J值达到较高水平时,说明上涨趋势形成,短期价格持续走高,多头力量强。
KDJ下行,且J只为负且越来越低,说明下跌趋势形成,短期价格持续走低,空头力量强。
由于原始数据难以获得,所以以下代码基于掘金量化平台的sdk查询标的原始数据。如果本地有数据或有其他的数据来源,只需要将data数据集变成输入参数,将函数中获取data的部分删除即可。
# KDJ指标计算 # 原理:计算N日RSV = (今日收盘 - N日最低)/(N日最高-N日最低) * 100 # K = (1-(1/M1))*前一日K值 + 1/M1 * RSV # D = (1-(1/M1))*前一日D值 + 1/M1 * K值 # J = 3 * K - 2 * D def KDJ(symbol, N, M1, M2,end_time): ''' 计算KDJ指标公式 输入: data <- dataframe,需包含开盘、收盘、最高、最低价 N、M1、M2 <- int end_time <- str 结束时间 输出: 将K、D、J合并到data后的dataframe ''' # 取历史数据,取到上市首日 data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close,low,high', df=True) # 计算前N日最低和最高,缺失值用前n日(n<N)最小值替代 lowList = data['low'].rolling(N).min() lowList.fillna(value=data['low'].expanding().min(), inplace=True) highList = data['high'].rolling(N).max() highList.fillna(value=data['high'].expanding().max(), inplace=True) # 计算rsv rsv = (data['close'] - lowList) / (highList - lowList) * 100 # 计算k,d,j data['kdj_k'] = rsv.ewm(alpha=1/M1, adjust=False).mean() # ewm是指数加权函数 data['kdj_d'] = data['kdj_k'].ewm(alpha=1/M2, adjust=False).mean() data['kdj_j'] = 3.0 * data['kdj_k'] - 2.0 * data['kdj_d'] return data # 测试一下 d = KDJ('DCE.y2101',9,3,3,'2020-12-31')
DMA又称平行线差,是一种用来判断价格变化、买点卖点的指标体系。包括DIF和AMA两个指标,用来描述不同频率均线的变化情况。
D
I
F
=
c
l
o
s
e
的
N
1
日
移
动
平
均
−
c
l
o
s
e
的
N
2
日
移
动
平
均
DIF = close的N1日移动平均-close的N2日移动平均
DIF=close的N1日移动平均−close的N2日移动平均
A
M
A
=
D
I
F
的
M
日
移
动
平
均
AMA = DIF的M日移动平均
AMA=DIF的M日移动平均
DIF描述的是收盘价“快线”的移动平均线与收盘价“慢线”的移动平均线之差。DIF>0说明短周期均线处于长周期均线上方,DIF<0说明短周期均线处于长周期均线下方。AMA是DIF的M日移动平均,DIF上穿AMA说明近期DIF呈现上涨趋势,DIF上涨又可以说明短周期均线处于长周期均线上方且越来越高,表明当前标的价格已经呈现不断上涨的趋势,反之也成立。
由于原始数据难以获得,所以以下代码基于掘金量化平台的sdk查询标的原始数据。如果本地有数据或有其他的数据来源,只需要将data数据集变成输入参数,将函数中获取data的部分删除即可。
# DMA指标计算 # 计算DIF: close的N1日移动平均-close的N2日移动平均 # 计算AMA: DIF的M日移动平均 def DMA(symbol, start_time, end_time, N1, N2, M): ''' 计算DMA 输入参数: symbol <- str 标的代码 start_time <- str 开始时间 end_time <- 结束时间 N1 <- 大周期均值 N2 <- 小周期均值 输出参数: DMA <- dataframe ''' # 取历史数据,取到上市首日 data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close', df=True) data['MA1'] = data['close'].rolling(N1).mean() data['MA2'] = data['close'].rolling(N2).mean() data['DIF'] = data['MA1'] - data['MA2'] data['AMA'] = data['DIF'].rolling(M).mean() # 将数据转化为dataframe格式 data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist() # 按起止时间筛选 DMA = data[(data['bob'] >= start_time)] return DMA # 检验一下 d1 = DMA(symbol = 'DCE.y2101',start_time = '2020-01-01',end_time = '2020-10-22',N1 = 10,N2 = 50,M = 6)
Bias又称乖离率,描述收盘价距离均线的百分比,常用来衡量收盘价偏离程度。格兰维尔八大法则中有一条“乖离过大”就是描述乖离率这一指标。
B I A S 1 : C L O S E − N 1 日 的 平 均 值 C L O S E N 1 日 的 平 均 值 C L O S E ∗ 100 BIAS1 : \frac{CLOSE-N1日的平均值CLOSE}{N1日的平均值CLOSE}*100 BIAS1:N1日的平均值CLOSECLOSE−N1日的平均值CLOSE∗100
B I A S 2 : C L O S E − N 2 日 的 平 均 值 C L O S E N 2 日 的 平 均 值 C L O S E ∗ 100 BIAS2 : \frac{CLOSE-N2日的平均值CLOSE}{N2日的平均值CLOSE}*100 BIAS2:N2日的平均值CLOSECLOSE−N2日的平均值CLOSE∗100
B I A S 3 : C L O S E − N 3 日 的 平 均 值 C L O S N 3 日 的 平 均 值 C L O S E ∗ 100 BIAS3 : \frac{CLOSE-N3日的平均值CLOS}{N3日的平均值CLOSE}*100 BIAS3:N3日的平均值CLOSECLOSE−N3日的平均值CLOS∗100
由于原始数据难以获得,所以以下代码基于掘金量化平台的sdk查询标的原始数据。如果本地有数据或有其他的数据来源,只需要将data数据集变成输入参数,将函数中获取data的部分删除即可。
# BIAS:乖离率指标计算 # BIAS1 : (CLOSE-N1日的平均值CLOSE)/N1日的平均值CLOSE*100 # BIAS2 : (CLOSE-N2日的平均值CLOSE)/N2日的平均值CLOSE*100 # BIAS3 : (CLOSE-N3日的平均值CLOSE)/N3日的平均值CLOSE*100 def BIAS(symbol, start_time, end_time, N1, N2, N3): '''计算乖离率指标 输入值:symbol <- str 标的代码 start_time <- str 开始时间 end_time <- str 结束时间 N1、N2、N3 <- 移动平均数 输出值: BIAS <- dataframe ''' # 取历史数据,取到上市首日 data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close', df=True) # 将数据转化为dataframe格式 data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist() # 计算指标 data['BIAS1'] = (data['close'] - data['close'].rolling(N1).mean())/data['close'].rolling(N1).mean() * 100 data['BIAS2'] = (data['close'] - data['close'].rolling(N2).mean())/data['close'].rolling(N2).mean() * 100 data['BIAS3'] = (data['close'] - data['close'].rolling(N3).mean())/data['close'].rolling(N3).mean() * 100 # 按时间筛选 BIAS = data[(data['bob'] >= start_time)] return BIAS # 测试一下 d2 = BIAS(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N1=6, N2=12, N3=24)
布林线指标,是指利用统计学上均线及正负二倍标准差计算得到的。布林线理论认为,标的资产的价格总会在布林线形成的布林带内运动,一旦偏离此区域,长期一定会回到布林带内。
中
轨
线
=
N
日
收
盘
价
平
均
值
中轨线 = N日收盘价平均值
中轨线=N日收盘价平均值
上
轨
线
=
中
轨
线
+
N
日
收
盘
价
标
准
差
上轨线 = 中轨线 + N日收盘价标准差
上轨线=中轨线+N日收盘价标准差
下
轨
线
=
中
轨
线
−
N
日
收
盘
价
标
准
差
下轨线 = 中轨线 - N日收盘价标准差
下轨线=中轨线−N日收盘价标准差
统计学中有一个3σ原则,即对于正态分布来讲,落在均值正负2倍标准差之间的概率为95.5%。布林带的设计类似于这个原则:股价会在布林带围成的区域不断变动,即使短期偏离此区域,长期来看也会回归到布林带中。
当股价上穿布林带上轨线,预计未来价格会下跌,此时宜卖出或做空。
当股价下穿布林带下轨线,预计未来价格会上涨,此时宜买入或平空。
由于原始数据难以获得,所以以下代码基于掘金量化平台的sdk查询标的原始数据。如果本地有数据或有其他的数据来源,只需要将data数据集变成输入参数,将函数中获取data的部分删除即可。
# BOLL:BOLL带指标计算 # 中轨线 = N日收盘价平均值 # 上轨线 = 中轨线 + N日收盘价标准差 # 下轨线 = 中轨线 - N日收盘价标准差 def BOLL(symbol, start_time, end_time, N): ''' 计算布林带 输入参数:symbol <- str 标的代码 start_time <- str 开始日期 end_time <- str 结束日期 N <- N日移动平均线 输出参数: BOLL <- dataframe ''' # 取历史数据,取到上市首日 data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close', adjust=ADJUST_PREV, adjust_end_time=end_time, df=True) # 将数据转化为dataframe格式 data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist() # 计算指标 data['BOLL'] = data['close'].rolling(N).mean() data['UB'] = data['BOLL'] + 2 * data['close'].rolling(N).std() data['LB'] = data['BOLL'] - 2 * data['close'].rolling(N).std() # 按时间筛选 BOLL = data[(data['bob'] >= start_time)] return BOLL # 测试一下 d3 = BOLL(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N=20)
RSI称为相对强弱指标,用来描述多空方力量对比情况。
S M A ( M A X ( C L O S E − L C , 0 ) , N , 1 ) / S M A ( A B S ( C L O S E − L C ) , N , 1 ) SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N,1) SMA(MAX(CLOSE−LC,0),N,1)/SMA(ABS(CLOSE−LC),N,1)
其中LC表示前一日收盘价。SMA(x,N,M)表示x的加权平均,计算方法为:
S
M
A
(
X
,
N
,
M
)
=
X
∗
N
M
+
(
1
−
N
M
)
∗
前
一
期
S
M
A
SMA(X,N,M) = X * \frac{N}{M}+ (1-\frac{N}{M})*前一期SMA
SMA(X,N,M)=X∗MN+(1−MN)∗前一期SMA
具体计算方法可以参考知乎上的提问
RSI实际上就是将收盘价上涨的点数之和除以收盘价上涨和下跌绝对值的点数之和求加权平均。上涨的点数之和可以理解为多方力量,上涨和下跌点数之和可以理解为多方力量和空方力量之和。RSI就是描述多方力量占(多方+空方)的比值。RSI越接近100,说明多方力量越强,价格上涨的可能性越高,适合买入。RSI越接近0说明空方力量越强,价格下跌的可能性越高,适合卖出。
# RSI指标计算 # RSI = N日内收盘价涨数和的均值/N日内收盘价涨和跌的均值*100 def RSI(symbol, start_time, end_time, N1, N2, N3): ''' 计算RSI相对强弱指数 输入参数:symbol <- str 标的代码 start_time <- str 开始日期 end_time <- str 结束日期 N <- N日移动平均线 输出参数: RSI <- dataframe ''' # 取历史数据,取到上市首日 data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close,pre_close', adjust=ADJUST_PREV, adjust_end_time=end_time, df=True) # 将数据转化为dataframe格式 data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist() # 计算指标 data['change'] = data['close'] - data['pre_close'] # 计算涨跌幅 data.loc[(data['pre_close'] == 0), 'change'] = 0 # 如果是首日,change记为0 data['x'] = data['change'].apply(lambda x: max(x, 0)) # 涨跌幅<0换为0 data['RSI1'] = data['x'].ewm(alpha=1 / N1, adjust=False).mean() / (np.abs(data['change']).ewm(alpha=1/N1, adjust=False).mean()) * 100 data['RSI2'] = data['x'].ewm(alpha=1 / N2, adjust=False).mean() / (np.abs(data['change']).ewm(alpha=1 / N2, adjust=False).mean()) * 100 data['RSI3'] = data['x'].ewm(alpha=1 / N3, adjust=False).mean() / (np.abs(data['change']).ewm(alpha=1 / N3, adjust=False).mean()) * 100 # 输出 RSI = data[(data['bob'] >= start_time)] return RSI # 测试一下 d4 = RSI(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N1=6, N2=12, N3=24)
威廉指标主要是衡量标的资产价格的波动情况,进而判断市场处于超买还是超卖状态。
W R ( N ) = 100 ∗ [ H I G H ( N ) − C ] [ H I G H ( N ) − L O W ( N ) ] WR(N) = \frac{100 * [HIGH(N)-C]}{[HIGH(N)-LOW(N)]} WR(N)=[HIGH(N)−LOW(N)]100∗[HIGH(N)−C]
利用威廉指标判断涨跌趋势时,常用两条不同周期的WR线。单根WR线会在0-100之间波动,0-20为超买区,80-100位超卖区。多根WR线的应用可参考知乎老林说股。
# WR威廉指标计算 # WR(N) = 100 * [HIGH(N)-C] / [HIGH(N)-LOW(N)] def WR(symbol, start_time, end_time, N1, N2): ''' 计算威廉指数 输入:symbol <- str 标的代码 start_time <- str 开始时间 end_time <- 结束时间 N <- 周期数 输出:WR <- dataframe ''' # 取历史数据,取到上市首日 data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close,high,low', adjust=ADJUST_PREV, adjust_end_time=end_time, df=True) # 计算指标 data['WR1'] = 100 * (data['high'].rolling(N1).max() - data['close']) / (data['high'].rolling(N1).max() - data['low'].rolling(N1).min()) data['WR2'] = 100 * (data['high'].rolling(N2).max() - data['close']) / (data['high'].rolling(N2).max() - data['low'].rolling(N2).min()) # 缺失值填充 data['WR1'].fillna(value=100 * (data['high'].expanding().max() - data['close']) / (data['high'].expanding().max() - data['low'].expanding().min()), inplace=True) data['WR2'].fillna(value=100 * (data['high'].expanding().max() - data['close']) / (data['high'].expanding().max() - data['low'].expanding().min()), inplace=True) # 输出 WR = data[(data['bob'] >= start_time)] return WR # 测试一下 d5 = WR(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N1 = 10,N2 = 6)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。