雅虎财经量化交易信号代码报值与索引长度不匹配错误求解
报错原因排查
报错Length of values (9) does not match length of index (67)是因为赋值self.df['trigger']时,等号右侧返回的序列长度和原DataFrame行数不匹配,核心问题如下:
gettrigger方法返回值写错:循环中构建的存储各滞后周期信号的对象是dfx,但代码最后返回的是df.sum(axis=0)(实际读取原始行情df),原始行情df共9个数值列,按列求和后得到长度为9的Series,和原df67行的索引长度完全不匹配。- 代码使用了pandas已弃用的
DataFrame.append()方法,高版本pandas环境下会抛出弃用警告,运行逻辑也容易出现维度错位。 - 逻辑写法不严谨:原逻辑直接对结果求和没有做布尔判断,虽然
np.where会把非0值判定为True,但显式判断是否满足条件可读性更强。
可行修改方案
- 修正
gettrigger的返回对象,对循环构建的掩码集合按时间维度聚合,判断任意滞后周期是否满足KD同时低于20的条件 - 替换弃用的
append方法为pd.concat实现序列拼接,兼容所有pandas版本 - 显式判断聚合结果,返回和原df长度完全一致的布尔序列,避免长度不匹配报错
修改后的完整可运行代码:
import pandas as pd import numpy as np class Signals: def __init__(self, df, lags): self.df = df self.lags = lags def gettrigger(self): mask_list = [] for i in range(self.lags+1): # 计算每个滞后周期的KD超卖掩码 mask = (self.df['%K'].shift(i) < 20) & (self.df['%D'].shift(i) < 20) mask_list.append(mask) # 拼接所有滞后周期的掩码 dfx = pd.concat(mask_list, axis=1) # 返回长度和原df一致的布尔序列:过去lags周期内出现过KD同时低于20即为True return dfx.any(axis=1) def decide(self): self.df['trigger'] = np.where(self.gettrigger(),1,0) self.df['Buy'] = np.where( (self.df.trigger) & (self.df['%K'].between(20,80)) & (self.df['%D'].between(20,80)) & (self.df.rsi > 30) & (self.df.macd > 0), 1, 0 ) return self.df # 调用示例 inst = Signals(df, 5) df_with_signal = inst.decide()
最终信号逻辑
修改后代码的买入判定规则:
- 过去5个周期(含当前)曾出现过%K、%D同时低于20的超卖状态
- 当前周期%K、%D处于20~80的正常区间(确认从超卖区间回升)
- 当前RSI大于30(脱离超卖弱势区间)
- 当前MACD大于0(确认趋势转多)
同时满足以上条件时,标记买入信号为1。
内容的提问来源于stack exchange,提问作者aler
相关产品推荐
相关产品推荐

