问题描述
为什么在回测模块中使用get_snapshot函数报错或无法获取数据?
解决方案
为什么 get_snapshot 在回测模块中无法使用?
在 ptrade 量化交易平台中,如果您在回测(Backtest)模块中调用 get_snapshot 函数,通常会遇到报错或返回空数据的情况。这是因为根据 ptrade 官方 API 文档规定:
get_snapshot 函数的使用场景仅限“交易模块”(实盘/模拟盘交易)。
核心原因解析
- 数据源差异:
get_snapshot的设计初衷是向券商柜台或实时行情服务器请求实时的行情快照(包含买卖五档/十档、实时成交量、内外盘等 Level-1/Level-2 字段)。在回测环境中,系统使用的是历史 K 线切片数据,并没有模拟这种高频的实时快照切片。 - 盘前调用限制:即使在实盘交易中,如果在盘前阶段(
before_trading_start)调用该函数,返回的数据中大部分字段(如成交量、当前价格、换手率等)也会是 0,因为此时市场尚未产生连续竞价数据。
回测模块中的替代方案
如果在回测中需要获取标的的价格、成交量等行情数据,请使用以下替代方案:
方案一:在 handle_data 中直接使用 data 对象
如果您只需要获取当前回测周期(如当前分钟或当前日)的最新价,可以直接通过 handle_data(context, data) 中的 data 字典获取。
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 获取当前回测周期的最新收盘价
current_price = data[g.security]['close']
log.info("当前价格: %s" % current_price)
方案二:使用 get_history 获取历史 K 线数据
如果您需要获取过去 N 个周期的开盘价、收盘价、最高价、最低价或成交量,get_history 是最常用的接口,它在回测和交易模块中均可使用。
def handle_data(context, data):
# 获取过去 5 天的日线收盘价
df = get_history(5, '1d', 'close', security_list=g.security, include=False)
if df is not None and not df.empty:
avg_price = df['close'].mean()
log.info("过去5日均价: %s" % avg_price)
方案三:使用 get_price 获取指定时间段的数据
get_price 允许您通过指定 start_date 和 end_date(或 count)来获取历史数据,同样完美支持回测环境。
def handle_data(context, data):
# 获取指定日期前的 10 根日线数据
price_data = get_price(g.security, count=10, frequency='1d', fields=['open', 'close'])
log.info(price_data)
总结
在编写兼容回测与实盘的策略时,建议使用 is_trade() 函数进行场景判断。如果在实盘中需要精细的盘口数据,则调用 get_snapshot;如果在回测中,则回退使用 get_history 或 data 对象,以保证策略在两个环境中都能顺利运行。