算法:
===========================================================① 蓝线:MACD Line,也称DIF离差率,快线
EMA(close,12) = 最近12日收盘价平均数
EMA(close,26) = 最近26日收盘价平均数
DIF = EMA(close,12) - EMA(close,26)
1.股价在一段时间内上升时,涨幅越来越大,最近12天的平均数大于最近26天平均数,DIF大于0,且数值越来越大,离0轴越来越远。
市场平均持仓成本升高,且数额较大。
2.股价在一段时间内上升时,涨幅越来越小,最近12天的平均数大于最近26天平均数,DIF大于0,但数值越来越小,离0轴越来越近。
市场平均持仓成本升高,但数额较小。
3.股价在一段时间内下降时,跌幅越来越大,最近12天的平均数小于最近26天平均数,DIF小于0,且数值越来越小,离0轴越来越远。
市场平均持仓成本降低,且数额较大。
4.股价在一段时间内下降时,跌幅越来越小,最近12天的平均数小于最近26天平均数,DIF小于0,且数值越来越大,离0轴越来越近。
市场平均持仓成本降低,但数额较小。
===========================================================
② 红线:Signal Line,也称DEM,慢线
默认表示对MACD Line(DIF)求9日的平均值,计算公式如下:
DEM = EMA(DIF,9)
③ 柱状线:MACD Histogram,也称为OSC,
表示的是DIF与DEM的差值,公式如下:
OSC = DIF-DEM
有时为了方便我们查看,会把DIF和DEM的差乘2,这时柱体增高两倍,辨识度更高。
OSC表示了今日平均持仓成本的变化量与平均持仓成本变化量平均数之间的差值。这个差值有什么意义呢?我们可以通过这个差值的大小、正负情况,反应市场的涨跌趋势与意愿的强弱。OSC可以认为是价格的“加速度”,表示势能的变化情况。
用法:金叉与死叉
当DIF自上而下穿越DEM时,形成死叉,整个市场随之进入下行趋势,
DIF自下而上穿越DEM,形成金叉,市场迎来一波反弹行情。
对于死叉来说,位置越高,下跌趋势概率越大,同理,对于金叉,位置越低,上行概率越大。
原理简介
KDJ所表述的是一个固定周期内(一般为9,例如9时,9日等),最高价、最低价以及当日收盘价之间的未成熟随机值(Row Stochastic Value,RSV),对其进行不同的移动平滑平均线的方法计算出K值、D值和J值,绘制曲线图,用以反应股票价格的动量趋势。
RSV
我们选择以9日为周期:
RSV = (收盘价-9日内最低价)/(9日内最高价-9日内最低价)*100
RSV值在0和100间波动,越靠近100表示当日收盘价在最近9日中处于比较高的价位,等于100时为9日内最高价;越靠近0表示当日收盘价在最近9日中处于比较低的价位,等于0时为9日内最低价。它反映了当日收盘价在最近9日中高低位置情况。
K、D、J值的计算方法
这三个值都是经过处理后的RSV值,同样以9日为一个周期
当日K值 = 2/3*前一日的K值+1/3*当日RSV
当日D值 = 2/3*前一日的D值+1/3*当日K值
说明:若无前1日的K值与D值,可以用50代替
公式中的平滑因子2/3和1/3是可以认为选定的,但现在已经约定俗成,固定为这个值了。
J值是反应K值和D值的乖离程度,公式:
J= 3D-2K
三值的使用方法有一个重要概念,超卖和超买。当他们的值大于80,我们称为超买;而当它们的值小于20,我们称为超卖。
我们通过分析K、D、J三条曲线的相互关系、发展趋势,判断买入和卖出的时机。比较常用的两种方法是KDJ中的金叉和死叉法以及J线卖出点判断法。
金叉和死叉法
上图为BTC4小时K线和KDJ的对照图。
正如前文介绍MACD中解释过的金叉和死叉概念,KDJ中也存在金叉和死叉的判断方法。图中K线为白的,D线为黄色,J线为紫色,横坐标为时间,纵坐标为数值。
当J线、K线之下而上穿过D线,且交叉点在20以下时,我们认为这是短期内有反转上升的信号,形成超卖,这样的现象我们称为金叉,应该快速跟进买入。
当J线、K线之上而下穿过D线,且交叉点在80以上时,我们认为这是短期内有反转下跌的信号,形成超买,这样的现象我们称为死叉,应该及时卖出。
对应图中的价格变化情况,我们可以很清晰的看到,伴随着两次金叉,市场迎来了2次小反弹,而伴随死叉的出现,市场进入了一波短暂的回调。
了解金叉死叉后,我们再看看非常容易辨别的第二种判断法,J线卖出点判断法。
J线卖出点判断法
依然是BTC4小时K线和KDJ的对照图。
看图中一条黑色的横线,划分了100的上下轴范围。其中J值3次突破100,并且回落。我们注意看两条垂直线条,分别标注了三次J值跌穿100的节点所对应价格,每当J值跌破100都伴随着价格下跌。
因此我们把价格J线从上往下跌穿100作为卖点的判断依据,因为J值大于100代表着超买情况的发生,当它开始向下调整时,很高的概率价格会进行下跌。
2、超买超卖信号
根据KDJ的取值,可将其划分为几个区域,即超买区、超卖区和徘徊区。按一般划分标准,(K、D、J这三值在20以下为超卖区,是买入信号);(K、D、J这三值在80以上为超买区,是卖出信号);(K、D、J这三值在20-80之间为徘徊区,宜观望。)
3、多空力量对比
一般而言,当K、D、J三值在50附近时,表示多空双方力量均衡;当K、D、J三值都大于50时,表示多方力量占优;当K、D、J三值都小于50时,表示空方力量占优。
KDJ曲线的交叉
KDJ曲线的交叉分为黄金交叉和死亡交叉两种形式。一般而言,在一个股票的完整的升势和跌势过程中,KDJ指标中的K、D、J线会出现两次或以上的“黄金交叉”和“死亡交叉”情况。
①当股价经过一段很长时间的低位盘整行情,并且K、D、J三线都处于50线以下时,一旦J线和K线几乎同时向上突破D线时,表明股市即将转强,股价跌势已经结束,将止跌朝上,可以开始买进股票,进行中长线建仓。这是KDJ指标“黄金交叉”的一种形式。
②当股价经过一段时间的上升过程中的盘整行情,并且K、D、J线都处于50线附近徘徊时,一旦J线和K线几乎同时再次向上突破D线,成交量再度放出时,表明股市处于一种强势之中,股价将再次上涨,可以加码买进股票或持股待涨,这就是KDJ指标“黄金交叉”的另一种形式。
③当股价经过前期一段很长时间的上升行情后,股价涨幅已经很大的情况下,一旦J线和K线在高位(80以上)几乎同时向下突破D线时,表明股市即将由强势转为弱势,股价将大跌,这时应卖出大部分股票而不能买股票,这就是KDJ指标的“死亡交叉”的一种形式。
④当股价经过一段时间的下跌后,而股价向上反弹的动力缺乏,各种均线对股价形成较强的压力时,KDJ曲线在经过短暂的反弹到80线附近,但未能重返80线以上时,一旦J线和K线再次向下突破D线时,表明股市将再次进入极度弱市中,股价还将下跌,可以再卖出股票或观望,这是KDJ指标“死亡交叉”的另一种形式。
代码:
以okex交易所btc_usdt为例,计算macd的方式,代码没进行封装,大佬们先试一下:
import numpy as np import requests import json def getkline(symbol): data = requests.get("https://www.okex.me/api/spot/v3/instruments/{}/candles?granularity={}".format(symbol.upper(),3600)) data = json.loads(data.content.decode()) return data data = getkline("btc_usdt") closeArray = [float(i[4]) for i in data] closeArray.reverse() def calculateEMA(period, closeArray, emaArray=[]): length = len(closeArray) nanCounter = np.count_nonzero(np.isnan(closeArray)) if not emaArray: emaArray.extend(np.tile([np.nan], (nanCounter + period - 1))) firstema = np.mean(closeArray[nanCounter:nanCounter + period - 1]) emaArray.append(firstema) for i in range(nanCounter + period, length): ema = (2 * closeArray[i] + (period - 1) * emaArray[-1]) / (period + 1) emaArray.append(ema) return np.array(emaArray) def calculateMACD(closeArray, shortPeriod=12, longPeriod=26, signalPeriod=9): ema12 = calculateEMA(shortPeriod, closeArray, []) ema26 = calculateEMA(longPeriod, closeArray, []) diff = ema12 - ema26 dea = calculateEMA(signalPeriod, diff, []) macd = (diff - dea)*2 fast_values = diff # 快线 slow_values = dea # 慢线 diff_values = macd # macd # return fast_values, slow_values, diff_values # 返回所有的快慢线和macd值 return fast_values[-1], slow_values[-1], diff_values[-1] # 返回最新的快慢线和macd值 # return round(fast_values[-1],5), round(slow_values[-1],5), round(diff_values[-1],5) print(calculateMACD(closeArray))