3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
你好!欢迎来到量化交易的世界。这段代码结合了 pandas 数据处理和 talib 技术指标库,对于刚接触 Python 不久的新手来说,确实包含了一些进阶的用法。下面为你逐一详细解答这 6 个问题:
rows = (fast + slow + sign) * 5 这么多天的历史数据?解答:
这是基于数学计算原理和经验的结果。MACD 的核心是 EMA(指数移动平均线)。EMA 的计算公式会包含历史上所有的数据,越久远的数据权重越小。理论上需要无限长的数据才能算出绝对准确的 EMA,但在实际编程中,只要取周期之和的 3 到 5 倍长度的数据,早期数据的权重就会衰减到几乎为 0,从而保证算出来的 MACD 值与同花顺、通达信等行情软件上的数值基本一致。如果取的数据太短,算出来的 MACD 会有较大的初始误差。
grid['dif'] 是对 suit 字典赋值吗?解答:
不是的。这里涉及两个完全不同的数据结构:
suit 是一个 Python 字典 (dict),它的作用是作为这个函数的最终返回值,告诉策略这只股票当前的状态(是否金叉、是否背离等)。grid 是一个 Pandas DataFrame(数据框,类似于 Excel 表格)。attribute_history 返回的就是一个 DataFrame。grid['dif'] = ... 的意思是:在 grid 这个表格中,新增一列,列名叫做 'dif',并把 talib.MACD 计算出来的一整列 DIF 数据填进去。这和 suit 字典没有任何关系,grid 只是用来做中间计算的草稿纸。
mask = mask[mask==True][mask.shift(1)==False] 是什么意思?解答:
这行代码的目的是找出发生“金叉”的那一天。
mask = grid['macd'] > 0:这会生成一列布尔值(True/False),MACD 大于 0 的天数是 True,否则是 False。mask.shift(1):shift(1) 是 Pandas 的函数,意思是把数据往下平移一行。所以 mask.shift(1) 代表的是昨天的 MACD 是否大于 0。mask[mask==True]:选出今天 MACD > 0 的日子。[mask.shift(1)==False]:在上面的基础上,进一步筛选出昨天 MACD <= 0 的日子。总结: 今天 MACD > 0 且 昨天 MACD <= 0,这就是 MACD 由负转正的瞬间,也就是金叉日。两个中括号连在一起是 Pandas 的链式索引筛选,相当于“满足条件 A 的数据中,再筛选出满足条件 B 的数据”。
key2 = mask.keys()[-2] 中的 [-1] 和 [-2] 是指什么?解答:
经过 Q3 的筛选,mask 里现在只剩下发生过金叉的那些天了。mask.keys() 获取的是这些金叉日的日期索引(时间戳)。
[-1] 表示 Python 列表/数组中的倒数第一个元素,也就是**最近一次(本次)**发生金叉的日期。[-2] 表示倒数第二个元素,也就是上一次发生金叉的日期。grid.close[key2] 和 grid.macd[-2] 的区别是什么?解答:
这是两种不同的定位方式:
key1 和 key2 是具体的日期(比如 2023-10-15)。grid.close[key2] 的意思是:去 grid 表格里,把 key2 这一天(上一次金叉日)的收盘价取出来。grid.macd[-1] 和 grid.macd[-2] 中的 -1 和 -2 是指 grid 这个表格的最后一行(通常是今天/昨天)和倒数第二行(昨天/前天)。为什么文字说明说“不是昨天,是key2指定的日期”?
文字说明解释的是 grid.close[key2] > grid.close[key1] 这一句,意思是比较“上一次金叉日”和“本次金叉日”的收盘价,而不是比较昨天和今天的收盘价。
而 grid.macd[-2] < 0 < grid.macd[-1] 这一句,确实是在判断最近两天(倒数第二天和最后一天)是否刚刚发生了金叉。
grid['dif'] 和 mask 的值?系统报错怎么办?解答:
系统报错很可能是因为你在代码里加了这一句:
stock = '600010.XSHG.XSHE'
股票代码的后缀写错了,JoinQuant 里的上汽集团代码应该是 '600010.XSHG',多了一个 .XSHE 会导致 attribute_history 找不到数据从而报错。
正确的打印方法:
把那行错误的 stock 赋值删掉(或者改成正确的 '600010.XSHG'),然后在 try 语句块里面使用 print 或者 log.info:
# 修正股票代码
stock = '600010.XSHG'
grid = attribute_history(stock, rows, fields=['close']).dropna()
try:
grid['dif'], grid['dea'], grid['macd'] = talib.MACD(grid['close'].values, fast, slow, sign)
grid = grid.dropna()
# 打印查看数据
print("DIF数据:\n", grid['dif'].tail()) # tail() 只打印最后5行,避免数据太长
print("MACD数据:\n", grid['macd'].tail())
mask = grid['macd']>0
mask = mask[mask==True][mask.shift(1)==False]
print("金叉日期:\n", mask)
在 JoinQuant 的研究环境(Jupyter Notebook)或回测日志中,你就可以看到打印出来的具体数值了。
祝你量化学习之路顺利!多用 print 打印中间变量是学习 Python 数据处理最好的方法。