问题描述
使用get_history获取某只股票的历史数据时,提示没有数据或数据不完整,是什么原因?
解决方案
在 ptrade 量化交易平台中,使用 get_history 接口获取历史 K 线数据时,如果遇到获取不到 2005 年之前的数据,或者提示数据为空、数据不完整的情况,通常是由以下几个官方设定的机制和限制引起的:
1. 接口时间范围限制(2005年限制)
根据 ptrade API 文档的明确规定,get_history 接口只能获取 2005 年之后的数据。如果您尝试获取 2005 年之前的历史行情,接口将无法返回有效数据。这是底层数据源的限制,建议在编写策略时,将回测或数据获取的起始时间设置在 2005 年 1 月 1 日之后。
2. 停牌数据的处理机制
如果您发现获取的数据中包含一些“异常”的 K 线(例如价格不变、成交量为 0),这通常是因为股票在特定日期停牌。
- 不跳过停牌日:ptrade 针对停牌场景,没有跳过停牌的日期。无论对单只股票还是多只股票进行调用,时间轴均为二级市场交易日日历。
- 数据填充规则:停牌时,系统会使用停牌前最后一个交易日的数据进行填充,并且当天的成交量(volume)为 0。
- 处理建议:在日 K 线策略中,您可以通过判断
volume == 0的逻辑来过滤掉停牌日的数据。
3. 多线程同时调用导致数据为空(偶现)
如果您在策略中发现 get_history 偶尔返回空数据,可能是因为多线程调用冲突。
- 冲突原因:
get_history与get_price接口不支持多线程同时调用。 - 避免方法:请勿在定时任务函数(如
run_daily或run_interval)中,与盘中处理框架模块(如handle_data)在同一时刻调用get_history或get_price接口。如果必须在多个地方获取数据,建议错开执行时间,或者在before_trading_start中统一获取并存入全局变量g中。
4. 板块指数数据的差异
如果您获取的是证监会行业、聚源行业、概念板块、地域板块等标的行情数据,需要注意:
- 这些数据为非标准的交易所下发数据,是由数据源自行按照成分股分类规则进行计算的。
- 因此,可能会存在与第三方数据源不一致的情况,导致您认为数据“不完整”或“有误”。在使用这类数据时,应自行评估其合理性。
总结与代码建议
为了确保稳定获取历史数据,建议采用如下规范的代码结构:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 确保获取的数据在2005年之后
# 获取过去5天的日K线数据
his = get_history(5, '1d', ['close', 'volume'], security_list=g.security)
if his is not None and not his.empty:
# 过滤停牌数据(成交量为0)
valid_data = his[his['volume'] > 0]
if not valid_data.empty:
latest_close = valid_data['close'].iloc[-1]
log.info(f"最新有效收盘价: {latest_close}")
else:
log.info("近期全部停牌")
遵循以上规则,可以有效避免 `get_history` 获取数据失败或不完整的问题。