使用Elasticsearch构建MACD直方图

转贴作者原创于CSDN相关文章

Moving Average Convergence Divergence (MACD) 有几个中文翻译,移动平均收敛发散属于直接翻译,比较接近原意。由 Gerald Appel 在 1979 年创建,用于股票价格(通常是收盘价,这里使用Daily来表示它)技术分析的交易指标。MACD涉及一个短周期和一个长周期的移动平均值。一般来说短周期为 12,长周期为26,而移动平均函数则使用指数加权移动平均(EWMA)。MACD的计算方法为Daily的短周期与长周期指数加权移动平均值的距离。距离趋于减少为收敛,反之则为发散。当MACD为零时,它是处于收敛和发散之间的过渡状态。计算公式如下: ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021063009202486.jpg#pic_center)

MACD为正值而远离零,可意味着价格上涨动量正在增加。若为负值而远离零,可意味着价格下行动量加大。下表描述了MACD值与趋势组合的含义。

MACD趋势 MACD(正值) MACD(负值)
收敛 (值趋向零) 下行动量增加 上涨动量增加
发散 (值远离零) 上涨动量增加 下行动量增加

一般来说,MACD指标常用于股票市场,在本文中,我们尝试将其用于股票型公募基金。下图为工银前沿医疗股票C基金(代码为010685.OF) 从2021年12月01日到2021年04月30日每日的复权单位净值和对应的MACD值。
在这里插入图片描述
MACD值从零下上升穿过零时,市场被认为是看涨,而MACD值从零上,下降穿过零时,市场被认为是看跌。上图中可以看到MACD与Y轴(零线)交叉点会滞后于价格转变一段时间后才产生信号,故此交易者经常批评这个缺陷。在1986 年由 Thomas Aspray引入MACD 直方图(MACD Histogram/Momentum)来解决这个问题,并且广泛被使用。MACD 直方图可以提供更早期的信号,但后来被认定其可靠性较低,需要由其他指标确认。计算方法为MACD 与其信号线(signal)之间的距离,(信号线是MACD周期为9的EWMA),公式如下:

在这里插入图片描述

当MACD_HISTOGRAM为零时(两线交叉),也就是说上涨与下行即将互相转变的信号。下图为代码010685.OF从2021年01月01日到2021年04月30日每日的MACD和对应的信号线。观察MACD与Y轴(零线)交叉点出现的时间,你会发现其前期有一个相应的MACD和信号线之间的交叉点。

在这里插入图片描述

由于MACD 和其信号线的折线图不是那么容易理解,为了更容易反映市场趋势,可以使用条形图描绘MACD_HISTOGRAM 。下图为代码010685.OF从2021年01月01日到2021年04月30日每日的MACD_HISTOGRAM。当 MACD 高于信号线时,柱线为正值,反之为负值。 柱线的高度是 MACD 和信号线之间的差值。水蓝色代表柱线为正值而且呈现上升趋势,蓝色代表柱线为正值但呈现下降趋势,橙色代表柱线为负值但呈现正增长趋势,红色代表柱线为负值而呈现负增长趋势。

在这里插入图片描述

以下步骤说明如何使用 Elasticsearch 构建MACD直方图的流程,同时演示REST API请求主体的代码。数据选自Tushare大数据开放社区,时间范围为2020 年 12 月 01 日至 2021 年 4 月 30 日之间。 假设已经有一个存在数据的 Elasticsearch 索引,使用的数据映射与之前发表的文章(使用Elasticsearch计算布林带宽度指标)相同。

  1. 通过搜索操作收集所有相关文档:
    使用带有必要条件(must)子句的布林查询(bool query)来收集基金代码为010685.OF,和公告截止日期从2021年01月01日到2021年04月30日的文档。 由于需要计算26天的移动平均值,因此增加了一个月的数据(从2020年12月01日到2020年12月31日)。
{
    "query": {
        "bool": {
		     "must": [
		         {"range": {"end_date": {"gte": "20201201", "lte": "20210430"}}},
		         {"term": {"ts_code": "010685.OF"}}
		     ]
		}
	},
  1. 提取每日的复权单位净值:
    使用名为MACD_Histogram日期直方图(date_histogram)存储桶聚合,并配合参数field(字段)为end_date和interval(间隔)为 1d(1天),提取每日的复权单位净值(adj_nav)。由于子聚合使用管道(pipeline)聚合而无法直接采用文档字段,所以额外使用平均值(avg)聚合获取每日的复权单位净值,聚合名称为Daily。(若当天基金没有公布的值,其值的计算方法是从其前后公布的值推算而来。)
    "aggs": {
        "MACD_Histogram": {
            "date_histogram": {
                "field": "end_date",
                "interval": "1d",
                "format": "yyyyMMdd"
            },
            "aggs": {
                "Daily": {
                    "avg": {"field": "adj_nav"}
                }, 
  1. 提取存储桶的日期
    由于增加了一个月的数据,而后续操作需要过滤掉额外的文档,因此以存储桶的日期作为筛选限制条件。我们可以使用名为DateStr的最小值聚合间接取得日期,Elasticsearch的日期用新纪元时间(Epoch Time) 表示,并且以毫秒为单位,时区为UTC。
                "DateStr": {
                    "min": { "field": "end_date"}
                },
  1. 计算12 天和 26 天的指数加权移动平均值:
    使用名为EWMA12的移动函数(moving_fn)聚合,并配合参数window为12和参数buckets_path(存储桶路径)为Daily来计算adj_nav的12天简单移动平均值。指数加权平均函数使用(MovingFunctions.ewma)并配合参数alpha为2/(window+1)来计算。
                "EWMA12": {
                    "moving_fn": {"script": "MovingFunctions.ewma(values, 2/(12+1))", "window": 12, "buckets_path": "Daily"}
                },
                "EWMA26": {
                    "moving_fn" : {"script": "MovingFunctions.ewma(values, 2/(26+1))", "window": 26, "buckets_path": "Daily"}
                },
  1. 计算MACD
    使用名为MACD的存储桶脚本(bucket_script)聚合,并配合参数buckets_path指定使用EWMA12和EWMA26聚合的值,并根据前述方程来计算MACD指标。
               "MACD": {
                    "bucket_script": {
                        "buckets_path": {
                            "EWMA12": "EWMA12",
                            "EWMA26": "EWMA26"
                        },
                        "script": "params.EWMA12 - params.EWMA26"
                    }
                },
  1. 计算MACD 信号线
    使用名为Signal的移动函数(moving_fn)聚合,并配合参数window为9和参数buckets_path(存储桶路径)为macd来计算信号线signal。MACD的9天EWMA使用指数加权平均函数(MovingFunctions.ewma)并配合参数alpha为2/(9+1)来计算。
            "Signal": {
                "moving_fn": {"script": "MovingFunctions.ewma(values, 2/(9+1))", "window": 9, "buckets_path": "MACD"}
            },
  1. 计算MACD直方图
    使用名为macd_histogram的存储桶脚本(bucket_script)聚合,并配合参数buckets_path指定使用MACD和signal聚合的值,并根据前述方程来计算MACD直方图指标。
               "MACD_histogram": {
                    "bucket_script": {
                        "buckets_path": {
                            "MACD": "MACD",
                            "Signal": "Signal"
                        },
                        "script": "params.MACD - params.Signal"
                    }
                },
  1. 确定MACD_Histogram 值是在上升趋势还是下降趋势内
    使用名为MACD_HistogramDiff的导数(derivative)聚合,并配合参数buckets_path指定MACD_Histogram聚合的值来确定它与前一个时间戳的值,是增量还是减量。
                "MACD_HistogramDiff" :{
                    "derivative": {
                        "buckets_path": "MACD_Histogram" 
                     }
                },
  1. 确定MACD_Histogram值的类型
    使用名为MACD_HistogramType的存储桶脚本(bucket_script)聚合,并配合参数buckets_path指定使用MACD_Histogram和MACD_HistogramDiff聚合的值,对 MACD_Histogram 值的类型进行分类。
    ➤ MACD_HistogramDiff是减量并且 MACD_Histogram < 0,则为类型1
    ➤ 如果MACD_HistogramDiff是增量并且 MACD_Histogram < 0,则为类型 2
    ➤ 如果MACD_HistogramDiff是增量并且 MACD_Histogram > 0,则为类型 3
    ➤ 如果MACD_HistogramDiff是减量并且 MACD_Histogram > 0,则为类型 4
    ➤ 其他情况为类型 0
                "MACD_HistogramType": {
                    "bucket_script": {
                        "buckets_path": {
                            " MACD_Histogram": "MACD_Histogram",
                            " MACD_HistogramDiff": "MACD_HistogramDiff"
                        },
                        "script": "(params.MACD_Histogram > 0) ? (params.MACD_HistogramDiff > 0 ? 3 : 4) : ((params.MACD_Histogram < 0) ? (params.MACD_HistogramDiff > 0 ? 2 : 1): 0)"
                    }
                },
  1. 输出前过滤掉额外的文档
    使用名为 SMACD_Histogram 的“bucket_selector”聚合,并配合参数“buckets_path”为“DateStr”,“script”语句中指定存储桶的选择条件。 选择标准是日期在 2021 年 1 月 1 日及之后的存储桶(以毫秒为单位指定纪元时间 1609459200000)。
                "SMACD_Histogram": {
   		            "bucket_selector": {
                          "buckets_path": {"DateStr":"DateStr"},
                          "script": "params.DateStr >= 1609459200000L"
                    }
                }
            }
        }
    },
    "size": 0
}
  1. 收集结果后,可以绘制图形前所示。

本文中所使用的 Elasticsearch 实例显示无缝整合且易于理解。读者可以进一步参考Gitee上的开源项目(使用 Elasticsearch 构建MACD直方图)。

备注:
I. 感谢Tushare大数据开放社区提供相关数据及Gitee开源社区提供存储开源项目。
II. 本文基于公开发布技术和研究观点,并不构成任何投资建议,读者在使用时须自行承担责任。
III. 文中可能还存在疏漏和错误之处,恳请广大读者批评和指正。
IV. 作者的中文著作Elasticsearch 数据分析与实战应用(ISBN 978-7-113-27886-1号)将于2021 年 7 月出版。
V. 作者的英文著作Advanced Elasticsearch 7.0(ISBN 978-1-789-95775-4号)被bookauthority评为 2021 年最值得阅读的 4 本 Elasticsearch 新书之一。

posted on 2021-07-06 13:28  王博分享  阅读(174)  评论(0编辑  收藏  举报