问题描述
难绷。国盛感觉数据质量比较堪忧。
在实盘中,运行下面代码:
# author: 公众号:可转债量化分析
import datetime
def initialize(context):
# 初始化策略
pass
def before_trading_start(context, data):
log.info('盘前函数运行')
previous_tradeing_func(context) # 执行盘前函数
def previous_tradeing_func(context):
all_stock_set = get_Ashares(date=None)
print(all_stock_set)
def handle_data(context, data):
pass
运行结果:
2025-07-04 12:18:10 - INFO - 盘前函数运行
2025-07-04 12:18:10 - INFO - []
数据的是一个空的list.......
一个十分基础的数据。
反馈了几年,依然如是。。
解决方案
问题现象
在 Ptrade 实盘交易环境中,许多开发者在 before_trading_start (盘前函数) 中调用 get_Ashares(date=None) 时,会遇到返回空列表 [] 的情况。这不仅影响了股票池的初始化,还可能导致后续策略逻辑报错。
原因分析
根据 Ptrade API 文档,get_Ashares(date=None) 的行为如下:
- 默认日期机制:在交易模块中,如果
date不入参,系统默认取当天日期。 - 数据更新延迟:在盘前阶段(如 9:00 左右),当天的 A 股代码列表数据可能尚未在券商柜台或行情服务器中完全生成或同步。此时请求当天的列表,就会返回空数据。
- 非交易日测试:如果在周末或节假日运行实盘测试,默认取当天日期也会因为非交易日而获取不到数据。
解决方案
为了保证策略的稳定性,建议显式传入具体的日期,通常传入前一个交易日的日期,或者格式化后的当前日期。
方案一:获取前一个交易日的 A 股列表(推荐)
使用 get_trading_day(-1) 获取上一个交易日,并将其格式化为 YYYYmmdd 字符串传入 get_Ashares。
import datetime
def initialize(context):
pass
def before_trading_start(context, data):
log.info('盘前函数运行')
previous_tradeing_func(context)
def previous_tradeing_func(context):
# 获取前一个交易日
pre_date_obj = get_trading_day(-1)
pre_date_str = pre_date_obj.strftime('%Y%m%d')
# 显式传入日期
all_stock_set = get_Ashares(date=pre_date_str)
if not all_stock_set:
log.error(f"获取 {pre_date_str} 的 A 股列表失败!")
else:
log.info(f"成功获取 A 股数量: {len(all_stock_set)}")
# print(all_stock_set[:10]) # 打印前10个查看
def handle_data(context, data):
pass
方案二:显式传入当前日期
如果必须获取当天的列表,可以通过 context.blotter.current_dt 获取当前日期并格式化。但需注意,盘前过早调用仍可能为空。
def previous_tradeing_func(context):
# 获取当前日期并格式化为 YYYYmmdd
current_date = context.blotter.current_dt.strftime('%Y%m%d')
all_stock_set = get_Ashares(date=current_date)
log.info(f"{current_date} A股数量为: {len(all_stock_set)}")
进阶建议
- 增加容错机制:在获取基础数据时,始终检查返回值是否为空。如果为空,可以尝试
sleep几秒后重试,或者回退使用前一交易日的数据。 - 注意 API 限制:Ptrade 的部分数据接口在盘前阶段(特别是 9:10 之前)可能受行情未更新影响,建议将强依赖实时数据的逻辑放在
run_daily中指定 9:15 或 9:25 之后执行。