QuantSTAT添加基准生成HTML Tearsheet时触发Series真值歧义错误
问题:添加基准SPY时QuantStats生成HTML报告触发Series真值歧义错误
单独生成单只股票收益的HTML Tearsheet报告正常,但添加基准(SPY)时触发错误,报错回溯信息如下:
Traceback (most recent call last): File "d:\Documents\112825123\QuantSTAT\portfolio.py", line 20, in <module> qs.reports.html(stock, benchmark="SPY", title='GOLD vs S&P 500', output='reports/gld_vs_spy.html') File "D:\Documents\112825123\environments\Quantvenv\Lib\site-packages\quantstats\reports.py", line 264, in html mtrx = metrics( ^^^^^^^^ File "D:\Documents\112825123\environments\Quantvenv\Lib\site-packages\quantstats\reports.py", line 1331, in metrics _stats.kelly_criterion(df, prepare_returns=False) * pct ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Documents\112825123\environments\Quantvenv\Lib\site-packages\quantstats\stats.py", line 2395, in kelly_criterion if win_loss_ratio == 0 or _pd.isna(win_loss_ratio): ^^^^^^^^^^^^^^^^^^^ File "D:\Documents\112825123\environments\Quantvenv\Lib\site-packages\pandas\core\generic.py", line 1577, in __nonzero__ raise ValueError( ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
使用的代码:
import quantstats as qs # 为股票对象扩展pandas的指标功能 qs.extend_pandas() # 使用yfinance下载黄金(GLD)的日收益率 stock = qs.utils.download_returns('GLD') # 生成对比黄金与标普500指数的HTML Tearsheet报告 qs.reports.html(stock, benchmark="SPY", title='GOLD vs S&P 500', output='reports/gld_vs_spy.html')
解决方案
错误核心是quantstats.stats.kelly_criterion函数中直接对Series对象进行真值判断导致歧义,需修改函数内的判断逻辑:
- 找到QuantStats库的
stats.py文件,路径为D:\Documents\112825123\environments\Quantvenv\Lib\site-packages\quantstats\stats.py - 定位到
kelly_criterion函数的报错行(第2395行) - 将原判断代码:
修改为以下两种方式之一:if win_loss_ratio == 0 or _pd.isna(win_loss_ratio):- 方式一(检查是否存在0或NA值):
if (win_loss_ratio == 0).any() or _pd.isna(win_loss_ratio).any(): - 方式二(提取标量值后判断,适用于
win_loss_ratio应为单个值的场景):win_loss_ratio_val = win_loss_ratio.iloc[0] if isinstance(win_loss_ratio, _pd.Series) else win_loss_ratio if win_loss_ratio_val == 0 or _pd.isna(win_loss_ratio_val):
- 方式一(检查是否存在0或NA值):
原因说明
原代码中win_loss_ratio是一个pandas Series对象,直接用win_loss_ratio == 0会返回一个布尔Series。在if条件中直接判断Series的真值会触发歧义错误,因为pandas无法确定是需要判断所有元素为真、任意元素为真还是其他逻辑,必须使用.any()/.all()明确逻辑,或者提取Series中的单个标量值后再进行判断。
内容的提问来源于stack exchange,提问作者Dame Skytower
相关产品推荐
相关产品推荐

