3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这个报错 IndexError: index -120 is out of bounds for axis 0 with size 76 的直接原因是:你获取到的这只股票的历史数据只有 76 天,而你试图去取倒数第 120 天的数据,导致了数组越界。 这通常是因为该股票上市时间较短,或者在回测的当前时间点,它存在的数据不足 583 天。
除了这个报错,你的代码中还有一个非常严重的逻辑错误:
close_data['close'][-5].mean() 这种写法是错误的。[-5] 表示取倒数第 5 天的单日收盘价,一个数字求均值还是它本身,这并不是“过去5天的平均价”。正确的切片写法应该是 [-5:],表示取最后 5 天的数据构成数组,然后再求 .mean()。
[-N] 改为 [-N:]。def initialize(context):
# 建议不要用 every_bar 跑全市场日线策略,极易超时。改为每天开盘运行一次即可
run_daily(period, time='09:30')
# 获取所有股票
g.security = list(get_all_securities(['stock']).index)
def period(context):
for stock in g.security:
# 获取数据,注意 get_bars 返回的是 numpy 数组或 DataFrame
close_data = get_bars(stock, count=583, unit='1d', fields=['close'], include_now=True)
# 1. 核心修改:判断数据长度是否足够 583 天,不足则跳过该股票
if len(close_data) < 583:
continue
# 2. 核心修改:修正切片语法,加上冒号 ':'
MA5 = close_data['close'][-5:].mean()
MA10 = close_data['close'][-10:].mean()
MA20 = close_data['close'][-20:].mean()
MA60 = close_data['close'][-60:].mean()
MA120 = close_data['close'][-120:].mean()
MA250 = close_data['close'][-250:].mean()
MA583 = close_data['close'].mean() # 已经是583个数据了,直接求均值
current_price = close_data['close'][-1]
cash = context.portfolio.available_cash
# 买入逻辑
if current_price > MA5 and MA5 > MA10 and MA10 > MA20 and MA20 > MA60 and MA60 > MA120 and MA120 > MA250 and MA250 > MA583 and (cash > 0):
# 注意:全市场选股时,如果多只股票满足条件,100万资金可能不够分,建议按比例或判断可用资金
order_value(stock, 1000000)
print(f"买入: {stock}")
# 卖出逻辑
elif current_price < MA5 and MA5 < MA10 and context.portfolio.positions[stock].closeable_amount > 0:
order_target(stock, 0)
print(f"卖出: {stock}")
你目前的策略逻辑是:每天遍历全市场 4000 多只股票,每只股票单独调用一次 get_bars 获取 583 天的数据。
在 JoinQuant 平台中,这种写法会导致极严重的性能问题(运行极慢甚至超时被系统强杀)。建议进行以下优化:
get_all_securities,建议使用 get_index_stocks('000300.XSHG') (沪深300) 或过滤掉 ST、停牌、上市不足两年的股票。history 或 get_price 传入股票列表(list),一次性获取多只股票的数据,而不是放在 for 循环里一只一只取。这能将运行速度提升几十倍。