问题描述
/
解决方案
在 ptrade 量化平台中,如果将二八轮动策略(或其他需要计算历史指标的策略)的回测起始日期设置为最早的 2005年1月1日,通常会遇到报错。这主要是由于平台底层数据的限制以及策略计算历史指标的需求冲突导致的。
报错原因分析
- API 数据时间限制:根据 ptrade 官方 API 文档说明,获取历史行情的接口(如
get_history和get_price)只能获取2005年后的数据。 - 历史数据窗口越界:二八轮动策略通常需要计算过去一段时间(例如过去20个交易日)的收益率或均线来判断动量。如果你的回测起始日期是 2005年1月1日,策略在第一天运行时,会尝试调用
get_history获取 2004年12月 的数据。由于底层数据库没有 2005年之前的数据,接口会返回空数据或引发越界异常(如IndexError或KeyError),从而导致策略崩溃。
解决方案
要解决这个问题,可以采用以下两种方法:
方法一:推迟回测起始日期(最简单有效)
既然策略需要一定的历史数据作为“预热期”,最直接的方法是将回测的起始日期向后推迟。例如,如果你的策略需要 20 个交易日的历史数据,建议将回测起始日期设置为 2005年2月1日 或更晚。这样在回测的第一天,系统就能顺利获取到 2005年1月份的合法数据。
方法二:在代码中增加数据有效性校验(推荐的编程习惯)
为了让策略更加健壮,避免因为数据缺失导致程序崩溃,应该在调用历史数据后增加长度校验。如果获取到的数据长度不足,则直接 return 跳过当天的交易逻辑,等待数据充足后再开始交易。
代码示例:
def handle_data(context, data):
# 假设二八轮动需要获取沪深300和中证500过去20天的收盘价
history_data = get_history(20, '1d', 'close', ['000300.SS', '000905.SS'])
# 增加异常处理和数据长度校验
if history_data is None or len(history_data) == 0:
log.warning("未获取到历史数据,跳过今日交易")
return
# 校验沪深300的数据长度是否满足20天
hs300_close = history_data.query('code == "000300.SS"')['close']
if len(hs300_close) < 20:
log.warning("历史数据不足20天,当前长度:%s,跳过今日交易" % len(hs300_close))
return
# 数据充足,继续执行二八轮动逻辑
# ... 计算动量并下单 ...
总结
在 ptrade 中编写策略时,务必牢记 “只能获取2005年后的数据” 这一限制。在进行长周期回测时,合理设置回测起始日期,并在代码中加入数据长度的容错判断,可以有效避免此类报错,提升策略的稳定性。