3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 ptrade 平台中,您遇到的 UnboundLocalError 是因为 get_fundamentals 返回了 NaN(空值),导致您的 if 条件判断未能覆盖所有情况,从而使得 int_LabelPettm 变量未被赋值就被引用。
导致 get_fundamentals 返回 NaN 的根本原因在于 valuation(估值数据表)的特殊机制。
根据 ptrade API 文档中关于 valuation 估值数据的说明:
关于 date 字段的说明
- 场景一:date 字段不入参(即
date=None)。回测中默认是获取context.blotter.current_dt交易日收盘后更新的数据,因此会产生未来函数,交易和研究会返回当日数据,若在盘中时间由于数据未更新将返回字段为 NAN 的数据,因此建议获取最新数据的场景都使用 date 参数入参上一个交易日日期。- 场景二:date 字段入参日期。回测和交易中若 date 为非交易日,将返回字段为 NAN 的数据;研究中若 date 为非交易日,将返回往前最近一个交易日的数据。
因此,当您在非交易日运行,或者在数据尚未更新的时间点运行,且 date=None 时,系统就会返回 NaN。
为了保证策略的健壮性,建议采取以下两步进行优化:
不要使用 date=None,而是使用 get_trading_day(-1) 获取上一个确定的交易日,并将其格式化后传入 date 参数。
在读取出数值后,先判断其是否为 NaN,如果是,则赋予一个默认值或直接跳过该标的。
import pandas as pd
def handle_data(context, data):
security = '300437.SZ'
# 1. 获取上一个交易日,格式化为 YYYYMMDD
pre_date = get_trading_day(-1).strftime('%Y%m%d')
# 2. 传入确定的交易日日期
df_valuation = get_fundamentals(security, 'valuation', date=pre_date, fields=['pe_ttm'])
if df_valuation is not None and not df_valuation.empty:
int_pettm = df_valuation.loc[security, 'pe_ttm']
# 3. 增加对 NaN 的判断
if pd.isna(int_pettm):
print(f"{security} PE_TTM 数据为空 (NaN),跳过处理")
int_LabelPettm = -1 # 赋予一个默认的异常标识
else:
if int_pettm > 35 or int_pettm <= 0:
print(f"{security} PE_TTM={int_pettm},大于35或小于等于0,剔除")
int_LabelPettm = 3
else:
print(f"{security} PE_TTM={int_pettm},符合要求")
int_LabelPettm = 1 # 正常情况的赋值
# 后续使用 int_LabelPettm 的逻辑...
print(f"最终分类标签: {int_LabelPettm}")
else:
print(f"未能获取到 {security} 的估值数据")
valuation 表,强烈建议 date 参数传入 get_trading_day(-1)。pd.isna() 或 math.isnan() 检查空值的习惯,防止因数据源缺失导致策略崩溃。