问题描述
解决方案
在聚宽(JoinQuant)中,要在回测结果页面画出自定义的指标曲线(如MACD),核心是使用 record() 函数。
record() 函数可以在每个单位时间(如每天或每分钟)记录数值,回测结束后,系统会自动将这些数值绘制成曲线图,显示在回测结果页面的“收益曲线”下方。
下面是一个完整的策略示例,展示了如何获取历史数据、使用 talib 库计算 MACD 指标,并通过 record() 将 DIF、DEA 和 MACD 柱状值绘制出来。
实现代码
# -*- coding: utf-8 -*-
import jqdata
import talib
import numpy as np
def initialize(context):
# 设定要操作的股票(以平安银行为例)
g.security = '000001.XSHE'
# 设定基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 每天运行一次
run_daily(market_open, time='every_bar')
def market_open(context):
security = g.security
# 1. 获取历史收盘价数据
# MACD计算通常需要较长的历史数据以保证EMA的准确性,这里取过去100天
# 注意:include_now=True 包含当前bar的数据(回测中视频率而定,日频通常指包含当日收盘价)
# 如果是在盘中运行,attribute_history 取的是前一分钟/前一天的数据,这里我们取过去100天
h_data = attribute_history(security, 100, '1d', ['close'], skip_paused=True)
# 提取收盘价为numpy数组,用于talib计算
close_prices = h_data['close'].values
# 2. 计算MACD指标
# 使用 talib 库计算 MACD
# 参数说明: close_prices, fastperiod=12, slowperiod=26, signalperiod=9
# 返回值: dif (快线), dea (慢线), macd (柱状图)
dif, dea, macd = talib.MACD(close_prices,
fastperiod=12,
slowperiod=26,
signalperiod=9)
# 3. 获取当天的指标值
# 数组的最后一个元素即为最新的计算结果
current_dif = dif[-1]
current_dea = dea[-1]
# 注意:talib计算出的macd通常是 (dif - dea),而国内看盘软件通常是 (dif - dea) * 2
# 如果你想和通达信/同花顺对齐,可以将 macd 值乘以 2
current_macd = macd[-1] * 2
# 4. 使用 record 函数绘图
# 这里的参数名(如 My_DIF)将作为图表中曲线的名称
# 注意:record 不支持绘制列表,只能绘制单个数值
# 如果计算结果是 NaN (数据不足时),record 会自动处理
if not np.isnan(current_dif):
record(My_DIF=current_dif,
My_DEA=current_dea,
My_MACD=current_macd)
# 简单的交易逻辑示例(仅为了让回测跑起来)
# 金叉买入
if current_dif > current_dea and context.portfolio.positions[security].total_amount == 0:
order_value(security, context.portfolio.available_cash)
# 死叉卖出
elif current_dif < current_dea and context.portfolio.positions[security].total_amount > 0:
order_target(security, 0)
关键点说明
-
attribute_history:- 用于获取计算指标所需的历史数据。
- MACD 依赖于指数移动平均(EMA),为了让计算结果稳定,建议获取的数据长度(
count)要大于slowperiod(26)的 3-4 倍以上,这里取了 100 天。
-
talib.MACD:- 聚宽环境内置了
talib库,这是计算技术指标最高效的方法。 - 它返回三个数组,分别是 DIF、DEA 和 MACD柱。
- 聚宽环境内置了
-
record(key=value, ...):- 这是绘图的核心函数。
key是你在图例中看到的名字(例如代码中的My_DIF)。value必须是一个具体的数字(float 或 int),不能是列表或数组。- 查看位置:回测完成后,在收益走势图的下方,会多出一个或多个图表区域,显示你记录的数据。
-
关于 MACD 的数值差异:
- 标准的
talib算法输出的 MACD 柱状值 =DIF - DEA。 - 国内大部分行情软件(如同花顺、通达信)显示的 MACD 柱状值 =
(DIF - DEA) * 2。 - 代码中我做了
* 2处理,以便符合国内习惯。
- 标准的