3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant (聚宽) 量化平台上,get_current_data() 是一个非常常用的 API,用于获取当前单位时间(当天或当前分钟)的快照数据,包括最新价 (last_price)、涨跌停价、是否停牌等。
在很多严谨的量化策略中,开发者会在买入前检查 last_price 是否大于 0 且不为 None。之所以会出现 last_price 为 None 或 <= 0 的情况,主要有以下几个原因:
如果你在策略中生成了一个包含多只股票的股票池(例如通过某些条件筛选出了一批代码),但在回测运行到某一天时,其中某只股票还未正式上市交易。此时系统无法获取到该股票的有效交易价格,last_price 就会返回 None 或 NaN。
与未上市类似,如果股票池中包含了已经退市的股票,在退市日期之后,该股票不再有交易行情,获取其最新价时也会返回无效值。
虽然通常情况下,股票停牌时 last_price 会返回停牌前的最后一个收盘价,但在某些极端情况下(例如停牌时间过长、跨越了某些数据调整期,或者底层数据源在特定历史日期存在缺失),可能会导致获取到的价格异常(如为 0 或 None)。
根据官方文档,在 09:30 之前调用 get_current_data(),last_price 会返回昨日收盘价。但如果是新股上市首日的集合竞价阶段,由于没有“昨日收盘价”,此时获取的价格可能会出现异常。
在开启了动态复权(use_real_price = True)的情况下,如果遇到极端的拆合股或分红事件,历史数据在某些特定时间点的映射可能会出现计算上的极小值甚至异常值。
在代码中加入 if last_price <= 0 or last_price is None: 的判断,是一种非常好的防御性编程习惯:
None 或 0 作为价格去计算买入数量(如 cash / last_price),会导致 ZeroDivisionError 或类型错误,直接让整个策略崩溃。def handle_data(context, data):
current_data = get_current_data()
for stock in g.buy_list:
# 获取当前数据对象
stock_data = current_data[stock]
# 1. 检查是否停牌、是否退市/未上市
if stock_data.paused:
continue
# 2. 获取最新价
last_price = stock_data.last_price
# 3. 防御性检查:价格必须有效且大于0
if last_price is None or last_price <= 0:
log.warn(f"股票 {stock} 的最新价无效: {last_price},放弃买入")
continue
# 4. 计算买入数量并下单
cash = context.portfolio.available_cash
if cash > 0:
order_value(stock, cash)
总结来说,出现 None 或 <= 0 主要是因为标的在当前时间点处于非正常交易生命周期(未上市/已退市)或底层数据缺失。加上这层判断可以显著提升策略在长周期回测和实盘模拟中的健壮性。