🚀 AI 一键生成 ptrade 策略代码
立即体验
👉 AI 生成代码 👈

ptrade 报错“仅限before_trading_start和after_trading_end中使用”怎么解决?

ptrade | 发布时间: 2026/6/4
以下内容由 EasyQuant 生成。

问题描述

在交易模块中使用get_market_detail()时报错“仅限before_trading_start和after_trading_end中使用”,这两个函数的限制一样吗?

/

解决方案

报错原因解析

在 ptrade 平台中,get_market_detail() 用于获取市场编码对应的详细信息(如产品名称、类型代码、时间规则等)。由于这些信息属于静态或极低频更新的数据,为了避免策略在盘中高频回调函数(如 handle_datatick_data)中反复调用该接口从而消耗系统资源,平台在底层做了严格的限制:该接口在回测和交易模块中,仅允许在盘前(before_trading_start)和盘后(after_trading_end)事件函数中调用。

如果你在 handle_data 中调用了它,就会触发你遇到的报错。


before_trading_startafter_trading_end 的限制对比

对于“这两个函数的限制一样吗?”这个问题,答案是:在调用 get_market_detail() 的权限上,它们的限制是完全一样的(都允许调用);但在自身的执行机制和使用场景上,它们有明显的区别。

1. 相同点(共性限制)

  • 调用权限:都可以合法调用 get_market_detail()get_market_list() 等静态信息获取接口。
  • 使用场景:都仅在回测交易模块中可用。
  • 执行频率:在每个交易日内,这两个函数都只会被触发执行一次(非高频循环)。
  • 可选性:这两个函数都是可选的,如果策略不需要盘前准备或盘后处理,可以不在代码中定义它们。

2. 不同点(核心区别)

特性 before_trading_start (盘前事件) after_trading_end (盘后事件)
执行时间 (回测) 每个回测交易日的 8:30 分执行。 每天交易结束之后调用(通常模拟 15:30)。
执行时间 (交易) 开启交易时立即执行,隔日开始每天 9:10 (默认) 执行。 由券商配置决定,一般为 15:30
主要用途 盘前初始化、获取当日股票池、获取静态市场信息、计算前一日指标等。 盘后数据统计、持仓核对、导出对账文件 (get_trades_file)、清理全局变量等。
注意事项 交易环境中,9:10前开启交易时,受行情未更新影响,调用实时行情接口可能数据有误。 此时市场已收盘,无法进行任何有效的委托下单操作。

正确的代码示例

为了解决你的报错,你应该将 get_market_detail() 的调用移至盘前或盘后函数中,并将获取到的结果存储在全局对象 g 中,以便在盘中 handle_data 使用。

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    g.market_info = None

def before_trading_start(context, data):
    # 正确用法:在盘前获取市场详细信息
    g.market_info = get_market_detail('XSHG')
    log.info("盘前获取到的上海市场信息:\n%s" % g.market_info)

def handle_data(context, data):
    # 错误用法:在这里调用 get_market_detail 会报错!
    # info = get_market_detail('XSHG') 
    
    # 正确用法:使用盘前已经获取并存储在 g 中的数据
    if g.market_info is not None:
        pass # 执行你的策略逻辑

def after_trading_end(context, data):
    # 这里也可以合法调用
    market_info_after = get_market_detail('XSHE')
    log.info("盘后获取到的深圳市场信息:\n%s" % market_info_after)

总结:将静态数据的获取前置到 before_trading_start 是 ptrade 策略编写的最佳实践,既能解决报错,又能提升盘中 handle_data 的执行效率。