\[2022-07-24 22:23:36.953216\] ERROR: moduleinvoker: module name: backtest, module version: v8, trackeback: IndexError: index 0 is out of bounds for axis 0 with size 0
\[2022-07-24 22:23:36.961486\] ERROR: moduleinvoker: module name: trade, module version: v4, trackeback: IndexError: index 0 is out of bounds for axis 0 with size 0
\
IndexError Traceback (most recent call last)
in
260 )
261
\--> 262 m4 = M.trade.v4(
263 instruments=m9.data,
264 options_data=m8.predictions,
in m4_handle_data_bigquant_run(context, data)
55 name_today = name_df\[name_df.date==today\]
56 for instrument in equities:
\---> 57 name_instrument = name_today\[name_today.instrument==instrument\]\['name'\].values\[0\]
58 # 如果股票状态变为了st 则卖出
59 if 'ST' in name_instrument or '退' in name_instrument:
IndexError: index 0 is out of bounds for axis 0 with size 0
\
除了日期其他的地方都没动,运行之后出现如上错误,’记录持仓中st的股票’这段应该是输入的矩阵有问题,但是应该怎么改呢?
如果持仓为空,这个程序就会报错。建议加上判别equities是否为空的逻辑
#
```
# 1. 资金分配
# 平均持仓时间是hold_days,每日都将买入股票,每日预期使用 1/hold_days 的资金
# 实际操作中,会存在一定的买入误差,所以在前hold_days天,等量使用资金;之后,尽量使用剩余资金(这里设置最多用等量的1.5倍)
is_staging = context.trading_day_index < context.options['hold_days'] # 是否在建仓期间(前 hold_days 天)
cash_avg = context.portfolio.portfolio_value / context.options['hold_days']
cash_for_buy = min(context.portfolio.cash, (1 if is_staging else 1.5) * cash_avg)
cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)
positions = {e.symbol: p.amount * p.last_sale_price
for e, p in context.portfolio.positions.items()}
equities = {e.symbol: e for e, p in context.portfolio.positions.items()}
if len(equities) == 0:
print("equities are empty :",today)
else:
# 记录持仓中st的股票
st_stock_list = []
name_df = context.name_df
name_today = name_df[name_df.date==today]
for instrument in equities:
name_instrument = name_today[name_today.instrument==instrument]['name'].values[0]
# 如果股票状态变为了st 则卖出
if 'ST' in name_instrument or '退' in name_instrument:
# 指定一个limit_price,此时会以开盘价成交,这是由于初始化函数中改写了下单价格
context.order_target(context.symbol(instrument), 0, limit_price=1.0)
st_stock_list.append(instrument)
cash_for_sell -= positions[instrument]
if st_stock_list!=[]:
print(today,'持仓出现st股/退市股',st_stock_list,'进行卖出处理')
# 2. 生成卖出订单:hold_days天之后才开始卖出;对持仓的股票,按机器学习算法预测的排序末位淘汰
if not is_staging and cash_for_sell > 0:
instruments = list(reversed(list(ranker_prediction.instrument[ranker_prediction.instrument.apply(
lambda x: x in equities)])))
price_limit_status = context.price_limit_status
status_today = price_limit_status[price_limit_status.date==today]
for instrument in instruments:
# 如果是st股票已经卖过了,就跳过
if instrument in st_stock_list:
continue
# 如果涨停就跳过股票
status_instrument = status_today[status_today.instrument==instrument]['price_limit_status'].values[0]
if status_instrument>2:
continue
context.order_target(context.symbol(instrument),0)
cash_for_sell -= positions[instrument]
if cash_for_sell <= 0:
break
# 3. 生成买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票
buy_cash_weights = context.stock_weights
buy_instruments = list(ranker_prediction.instrument[:len(buy_cash_weights)])
max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
for i, instrument in enumerate(buy_instruments):
cash = cash_for_buy * buy_cash_weights[i]
if cash > max_cash_per_instrument - positions.get(instrument, 0):
# 确保股票持仓量不会超过每次股票最大的占用资金量
cash = max_cash_per_instrument - positions.get(instrument, 0)
if cash > 0:
context.order_value(context.symbol(instrument), cash)
```
\