3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在PTrade量化交易平台中,策略的运行是基于事件驱动的。这意味着策略代码并非从头到尾线性执行,而是根据市场的时间状态(盘前、盘中、盘后)触发特定的函数。
以下是PTrade策略在不同时间点的运行机制、主要功能及区别的详细解释:
盘前阶段主要用于每日交易开始前的准备工作,如数据更新、股票池调整和变量重置。
before_trading_start(context, data)set_universe 或 get_index_stocks 来确定当天要关注或交易的股票列表。get_fundamentals (财务数据) 或 get_history (历史行情) 来计算当天的静态指标(如均线、因子值)。g.buy_count = 0),应在此处重置。get_snapshot 获取的实时行情(如开盘价、成交量)可能为0或无效数据。这是策略最核心的阶段,负责实时监控行情、生成交易信号并执行买卖操作。
handle_data(context, data):核心驱动函数。tick_data(context, data):Tick级高频驱动(仅实盘)。run_daily(context, func, time='...'):定时任务。run_interval(context, func, seconds=...):间隔任务(仅实盘)。handle_data 每分钟运行一次;日线回测中,handle_data 每天 15:00 运行一次(即收盘时)。data 对象或 get_snapshot 获取当前的最新价格、成交量、五档盘口等。order、order_target、order_value 等接口发送交易指令。handle_data 在分钟回测是每分钟K线结束时触发;tick_data 是每3秒(或有新Tick时)触发,适合高频策略。run_daily 设置在 9:15~9:25 之间运行函数,用于处理集合竞价逻辑(需券商支持)。盘后阶段用于当天的总结、数据整理、文件导出或盘后固定价格交易。
after_trading_end(context, data)get_trades_file 导出对账单,或将自定义数据保存到本地(如使用 pickle 持久化全局变量 g)。after_trading_order 接口,且通常在盘中或盘后特定时间段调用。order 函数通常无效,因为连续竞价市场已关闭。| 特性 | 盘前 (Before Market) | 盘中 (Intra-Day) | 盘后 (After Market) |
|---|---|---|---|
| 核心函数 | before_trading_start |
handle_data, tick_data |
after_trading_end |
| 典型时间 | 08:30 (回测) / 09:10 (实盘) | 09:30 ~ 15:00 | 15:30 |
| 主要任务 | 选股、取财务数据、重置变量 | 择时、计算信号、下单交易 | 总结、归档、持久化数据 |
| 行情数据 | 仅历史数据,实时数据可能无效 | 实时推送 (Tick/Bar) | 当日收盘数据已确定 |
| 能否交易 | 否 (通常) | 是 | 否 (除盘后固定价业务外) |
Q1: initialize 函数属于哪个阶段?
A: initialize 不属于上述任何一个每日循环阶段。它只在策略启动时运行一次。用于初始化全局变量(如 g.security)和设置运行参数(如 set_commission)。它是在第一天的 before_trading_start 之前执行的。
Q2: 我可以在盘前阶段使用 get_snapshot 吗?
A: 可以调用,但返回值可能没有意义。在实盘9:10分时,交易所尚未产生当天的开盘价或成交量,返回的可能是0或者昨日收盘数据。建议在9:25集合竞价结束后或9:30开盘后获取实时快照。
Q3: 日线回测中,handle_data 是在什么时候运行的?
A: 在日线级别回测中,handle_data 默认在 15:00 运行。这意味着策略是基于当天的收盘价(Close)进行判断的。如果你的策略逻辑是“基于昨日收盘价在今日开盘买入”,在日线回测中可能无法精确模拟(因为代码执行时今天已经收盘了),这种情况下建议使用分钟级别回测。
Q4: 盘后固定价格交易(如科创板)应该写在哪里?
A: 盘后固定价格交易(15:05-15:30)通常建议通过 run_daily 定时任务在 15:05 之后触发,或者在 handle_data 中判断时间触发。虽然它发生在连续竞价结束后,但通常不直接写在 after_trading_end 中,因为 after_trading_end 往往在 15:30 之后才运行,此时盘后交易也已经结束了。