一起学量化之macd指标
macd指标
1. macd指标定义
MACD的组成要素MACD称为异同移动平均线,是从双指数移动平均线发展而来的。MACD由一根快线、一根慢线、一根0轴线和无数根红绿柱状线组成。
如下图所示,粉色的是快线,也称DIFF线;蓝色的是慢线,也称DEA线。快线波动较大,慢线相对平稳一些。分割上下红绿柱的横轴就是0轴。
2. macd使用
2.1 快线DIF与慢线DEA的数值以及它们所在的位置
- 当DIF和DEA均大于0(处于0轴之上)并且向上移动时,表示市场处于多头行情中,可以买人或持股
- 当DIF和DEA均小于0(处于0轴之下)并且向下移动时,表示市场处于空头行情中,可以卖出股票或观望
- 当DIF和DEA均大于0(处于0轴之上)但都向下移动时,表示市场行情处于退潮阶段,股票将下跌,可以卖出股票和观望
- 当DIF和DEA均小于0(处于0轴之下)但都向上移动时,表示行情即将启动,股票将上涨,可以买进股票或持股待涨
2.2 快线DIF与慢线DEA的交叉情况
- 当DIF与DEA都在0轴之上,而DIF向上突破DEA时,表明市场处于一种强势之中,股价将再次上涨,可以加码买进股票或持股待涨,这就是MACD指标黄金交叉的一种形式
- 当DIF和DEA都在0轴之下,而DIF向上突破DEA时,表明市场即将转强,股价将止跌反弹,可以开始买进股票或持股,这是MACD指标黄金交叉的另一种形式
- 当DIF与DEA都在0轴之上,而DIF却向下突破DEA时,表明市场即将由强势转为弱势,股价将下跌,这时应卖出大部分股票而不能买进股票,这就是MACD指标死亡交叉的一种形式
- 当DIF和DEA都在0轴之下,而DIF向下突破DEA时,表明市场将再次进入极度弱市中,股价还将下跌,可以再卖出股票或观望,这是MACD指标死亡交叉的另一种形式。
参考:https://www.sohu.com/a/663842634_120762329
2.3 MACD指标与价格的背离
如果MACD在运行的过程中和商品价格的运行节奏出现了不完全同步的情况,那么这有可能是比较重要的转向提示信号。
- 顶背离:经常出现在上涨趋势中,当商品价格高点不断变高,而同时MACD指标的高点却有所降低,那就表示多头力量有所减弱,价格可能会发生回调。
- 底背离:在价格下跌的过程中,当商品价格的低点比前一次低点要低,而同时MACD指标的低点比前一次的低点要高,说明空头力量减弱,那么价格可能会出现反弹或反转。
3. backtrader 代码与分析
import backtrader as bt
import os, sys
file_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(file_path + '/../')
class TestStrategy(bt.Strategy):
params = (('macd1', 12), ('macd2', 26), ('macdsig', 9), ('lookback_period', 30))
def __init__(self):
self.macd = bt.indicators.MACD(self.data.close,
period_me1=self.p.macd1,
period_me2=self.p.macd2,
period_signal=self.p.macdsig)
self.crossup = bt.indicators.CrossUp(self.macd.macd, self.macd.signal)
self.crossdown = bt.indicators.CrossDown(self.macd.macd, self.macd.signal)
self.lookback_period = self.p.lookback_period # 回溯周期
# 保存历史峰值和谷值
self.peak_price_list = []
self.peak_macd_list = []
def find_largest_and_second(self,price,macd,reverse=True):
if len(price) < self.lookback_period:
return None, None, None, None # 当列表中的元素不足两个时返回None
# 复制并排序
sorted_list = sorted(price, reverse=reverse)
# 找到第一大的数
largest_price = sorted_list[0]
# 在原始列表中找到该数的索引
largest_macd = macd[price.index(largest_price)]
# 找到第二大的数
second_largest_price = sorted_list[1]
# 在原始列表中找到该数的索引
second_largest_macd = macd[price.index(second_largest_price)]
return largest_price, largest_macd,second_largest_price,second_largest_macd
def next(self):
has_position = self.position.size > 0.01
has_cash = self.broker.get_cash()/self.data[0] > 0.01
dif = self.macd.macd[0]
dea = self.macd.signal[0]
dif_prev = self.macd.macd[-1]
dea_prev = self.macd.signal[-1]
###################### 2.1 章节 多头空头信号######################
# 多头行情判断
if dif > 0 and dea > 0 and dif > dif_prev and dea > dea_prev:
if has_cash:
self.buy(size=0.01)
# 空头行情判断
elif dif < 0 and dea < 0 and dif < dif_prev and dea < dea_prev:
if has_position:
self.sell(size=0.01)
# 退潮阶段判断
elif dif > 0 and dea > 0 and dif < dif_prev and dea < dea_prev:
if has_position:
self.sell(size=0.01)
# 行情即将启动判断
elif dif < 0 and dea < 0 and dif > dif_prev and dea > dea_prev:
if has_cash:
self.buy(size=0.01)
###################### 2.2 章节 黄金交叉和死亡交叉######################
# 黄金交叉
if self.crossup[0]:
if dif > 0 and dea > 0:
# 都在0轴之上时,市场处于强势
if has_cash:
self.buy(size=0.01)
elif dif < 0 and dea < 0:
# 都在0轴之下时,市场即将转强
if has_cash:
self.buy(size=0.03)
# 死亡交叉
elif self.crossdown[0]:
if dif > 0 and dea > 0:
# 都在0轴之上时,市场即将由强势转为弱势
if has_position:
self.sell(size=0.01)
elif dif < 0 and dea < 0:
# 都在0轴之下时,市场将再次进入极度弱市
if has_position:
self.sell(size=0.03)
###################### 2.3 章节 顶背离和底背离######################
current_price = self.data.close[0]
self.peak_price_list.append(current_price)
if len(self.peak_price_list) > self.lookback_period:
self.peak_price_list.pop(0)
self.peak_macd_list.append(dif)
if len(self.peak_macd_list) > self.lookback_period:
self.peak_macd_list.pop(0)
# 更新峰值
peak_price,peak_macd,pre_peak_price,pre_peak_macd = self.find_largest_and_second(self.peak_price_list,self.peak_macd_list,True)
# 更新谷值
valley_price,valley_macd,pre_valley_price,pre_valley_macd = self.find_largest_and_second(self.peak_price_list,self.peak_macd_list,False)
if valley_price is None or valley_macd is None:
return
if peak_price is None or peak_macd is None:
return
# 顶背离判断
if current_price > pre_peak_price and dif < pre_peak_macd and current_price ==peak_price:
# 执行交易逻辑
if has_position:
self.sell(size=0.01)
# 底背离判断
if current_price < pre_valley_price and dif > pre_valley_macd and current_price == valley_price:
# 执行交易逻辑
if has_cash:
self.buy(size=0.01)
3.1 多头空头信号
Final Portfolio Value: 26810.11
Sharpe Ratio: OrderedDict([(‘sharperatio’, 0.7067442967214198)])
从上图来看该算法没有跑赢大盘,这种情况有比较明显的追涨卖跌,如果macd的参数不理想会导致大量且频繁的买入卖出。这种只能作为一种辅助的评价指标
- 信号数量:频繁
- 信号质量:底下
- 需要信息:对零线比较敏感,不太适合长期持有操作。快线和慢线不太适合过长,否则有滞后性,例如将参数改为(‘macd1’, 30), (‘macd2’, 60), (‘macdsig’, 16),则结果只有12872.18
3.2 金叉死叉操作
Final Portfolio Value: 18197.17
Sharpe Ratio: OrderedDict([(‘sharperatio’, 0.5990693129804268)])
从上图来看该算法没有跑赢大盘,这类型号交易频率还是比较慢的,有比较明显的高点卖出,但是如果持续下跌,也需要注意快线和慢线参数信息,会出现骗信号的情况。
- 信号数量:中等
- 信号质量:较优
- 需要信息:适合长期持有操作。快线和慢线需要适中,太长有滞后性,太短会过多交易。将参数改为(‘macd1’, 30), (‘macd2’, 60), (‘macdsig’, 16),则结果只有14011.33
3.3 背离信号
Final Portfolio Value: 12537.66
Sharpe Ratio: OrderedDict([(‘sharperatio’, 0.3212700568278445)])
从上图来看该算法没有跑赢大盘,这类交易信号一般来说还是比较尴尬的,周期越长越难触发,这类算法感觉比较吃周期的,这类算法延续性感觉会更强一点,因为大币种会更符合规律,比如选取100*24天作为一个周期
- 信号数量:少
- 信号质量:较优
- 需要信息:周期,周期越长越难背离
目前改综合测试,macd的情况跑赢大盘,这个指标还是非常值得关注的
MACD指标,由快线、慢线、0轴线和红绿柱状线组成,是股票交易中的重要工具。它的使用包括观察快线DIF与慢线DEA的数值和位置,以及它们的交叉情况。MACD指标与价格的背离也是重要的转向提示信号。在Python中,可以通过backtrader库编写策略来利用MACD指标进行交易。测试结果显示,MACD指标在多头空头信号、金叉死叉操作和背离信号等方面都有一定的效果,但也存在一定的局限性,如信号数量、信号质量和需要的信息等。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!