问题描述
大佬们,假如我获取了下午14.45分的价格,想把它当成今天的收盘价,去计算这只股票的今天日K线的MACD的值,代码是什么样的呢?我算了好几次都不对,麻了。谢谢大佬
解决方案
在 JoinQuant 聚宽平台上,想要用盘中特定时间(如 14:45)的价格作为当天的收盘价来计算日线 MACD,最简单且准确的方法是:获取过去 N 天的历史收盘价,将 14:45 的最新价追加到该序列的末尾,然后使用 TA-Lib 库进行计算。
这里有一个非常重要的细节导致很多人计算结果与看盘软件对不上:TA-Lib 计算出来的 MACD 柱状图(macdhist)是 DIF - DEA,而国内同花顺、通达信等看盘软件显示的 MACD 柱子是 (DIF - DEA) * 2。因此,我们需要对结果乘以 2。
完整策略代码示例
以下是一个完整的代码示例,每天 14:45 触发,计算指定股票的 MACD 值:
# 导入聚宽函数库
import jqdata
import talib
import numpy as np
# 初始化函数
def initialize(context):
# 设定要操作的股票,例如平安银行
g.security = '000001.XSHE'
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 设定在每天的 14:45 运行 MACD 计算函数
run_daily(calc_custom_macd, time='14:45')
def calc_custom_macd(context):
security = g.security
# 1. 获取过去 100 天的日线收盘价(不包含今天)
# 注意:EMA 的计算具有长记忆性,建议获取至少 100 天的数据以保证计算精度
history_data = attribute_history(security, 100, '1d', ['close'])
close_prices = history_data['close'].values
# 2. 获取当前 14:45 的最新价格
current_data = get_current_data()
current_price = current_data[security].last_price
# 3. 将当前价格追加到历史收盘价数组的末尾,作为“今天的收盘价”
new_close_prices = np.append(close_prices, current_price)
# 4. 使用 TA-Lib 计算 MACD
# 默认参数:fastperiod=12, slowperiod=26, signalperiod=9
dif, dea, macdhist = talib.MACD(new_close_prices, fastperiod=12, slowperiod=26, signalperiod=9)
# 5. 获取最新的指标值
# 注意:国内软件的 MACD 柱子通常是 (DIF - DEA) * 2
current_dif = dif[-1]
current_dea = dea[-1]
current_macd = macdhist[-1] * 2
# 打印结果
log.info(f"股票 {security} 在 14:45 的模拟日线 MACD 数据:")
log.info(f"DIF: {current_dif:.4f}, DEA: {current_dea:.4f}, MACD柱: {current_macd:.4f}")
# 接下来可以根据 current_macd, current_dif 等进行交易逻辑判断
# if current_dif > current_dea and current_macd > 0:
# order_value(security, context.portfolio.available_cash)
核心逻辑解析:
- 数据长度(
attribute_history取 100 天):MACD 是基于 EMA(指数移动平均)计算的,EMA 包含历史所有价格的权重。如果只取 30 天的数据,算出来的 MACD 会和软件上有较大误差。取 100 天或以上可以消除初始值带来的误差。 - 数据拼接(
np.append):attribute_history在盘中调用时,获取的是昨天及以前的日 K 线数据。我们通过get_current_data()拿到 14:45 的现价,拼接到数组最后,完美模拟了“将当前价作为今日收盘价”的场景。 - TA-Lib 乘 2 修正:
macdhist[-1] * 2是对齐国内看盘软件的关键步骤。