You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

交易系统回测遇TypeError报错:float对象不支持项赋值

搞定回测中的TypeError: 'float' object does not support item assignment错误

嘿,我一眼就看到问题出在哪了——你在初始化positions的时候犯了个语法小错误,直接导致了这个类型错误。咱们一步步来解决:

错误根源:positions初始化的语法错误

你写的这行代码:

positions = pd.DataFrame(index=signals.index).fillna=(0.0)

这里的问题是把fillna()方法调用写成了赋值操作!fillna=(0.0)是把DataFrame的fillna属性硬生生改成了浮点数0.0,结果positions不再是你想要的空DataFrame,反而变成了一个float对象。当你执行第三行positions['AAPL'] = 100*signals['signal']时,自然会报错——float对象可没法像DataFrame那样添加列。

第一步:修正positions的初始化

把代码改成正确的方法调用就行,甚至可以更简洁:

# 方法1:正确调用fillna方法
positions = pd.DataFrame(index=signals.index).fillna(0.0)
# 方法2:直接初始化带列的DataFrame(更推荐)
positions = pd.DataFrame(0.0, index=signals.index, columns=['AAPL'])

这样positions就是一个列名为'AAPL'、所有值都是0.0的DataFrame,后续赋值就没问题了。

第二步:补上portfolio缺失的cash列

你的代码里直接用了portfolio['cash'],但之前根本没初始化这个列!咱们得从初始资金出发,根据每次的持仓变化来计算剩余现金:

# 先计算持仓的市场价值
portfolio = positions.multiply(aapl['Adj Close'], axis=0)
# 计算持仓的变化量(用来算每次交易花了多少钱)
pos_diff = positions.diff()
# 初始化cash:初始资金减去所有交易的累计支出
portfolio['cash'] = initial_capital - (pos_diff.multiply(aapl['Adj Close'], axis=0)).sum(axis=1).cumsum()

第三步:修正holdings的计算错误

你当前的holdings计算加了cumsum(),这完全错了——持仓价值就是当前持仓数量乘以当前股价,不需要累加。正确的写法是:

# 因为只有AAPL一支股票,直接取对应列就行
portfolio['holdings'] = portfolio['AAPL']
# 如果以后有多支股票,就用sum(axis=1):
# portfolio['holdings'] = portfolio.drop('cash', axis=1).sum(axis=1)

完整修正后的回测代码

把这些修正整合起来,代码就正常运行了:

initial_capital = float(1000)
# 修正后的positions初始化
positions = pd.DataFrame(0.0, index=signals.index, columns=['AAPL'])
positions['AAPL'] = 100 * signals['signal']

portfolio = positions.multiply(aapl['Adj Close'], axis=0)
pos_diff = positions.diff()

# 初始化cash列
portfolio['cash'] = initial_capital - (pos_diff.multiply(aapl['Adj Close'], axis=0)).sum(axis=1).cumsum()
# 修正holdings计算
portfolio['holdings'] = portfolio['AAPL']
# 计算总账户价值
portfolio['total'] = portfolio['cash'] + portfolio['holdings']
# 计算每日收益率
portfolio['returns'] = portfolio['total'].pct_change()

额外小优化:避免信号生成的警告

你的信号生成代码里,直接给signals['signal'][short_window:]赋值可能会触发SettingWithCopyWarning,改用.loc更安全:

signals.loc[short_window:, 'signal'] = np.where(
    signals['short_mavg'][short_window:] > signals['long_mavg'][short_window:], 
    1.0, 
    0.0
)

内容的提问来源于stack exchange,提问作者Lucas Saladini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:49:19