🚀 AI 一键生成 ptrade 策略代码

PTrade Tick 级交易核心:tick_data 函数中 order、tick、transcation 数据详解

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

问题描述

请帮我解析 tick 数据中的买一价、卖一量以及最近一笔逐笔成交的价格。

解决方案

在 PTrade 中,解析 Tick 数据主要是在 tick_data 函数中进行的。该函数仅在交易模块(实盘或模拟盘)中可用,且需要开通 Level-2 行情权限才能获取逐笔成交数据。

以下是具体的解析逻辑和代码示例:

解析逻辑说明

  1. 数据源 (data)
    tick_data(context, data) 中的 data 是一个字典。
    结构为:data['股票代码'] 包含 tick(快照)、order(逐笔委托)、transcation(逐笔成交,注意 PTrade 文档中拼写通常为 transcation 而非 transaction)。

  2. 买一价 (bid_grp)

    • 位于 data[security]['tick']['bid_grp']
    • 数据通常以字符串形式存储,需要使用 eval() 函数转换为字典。
    • 字典结构为 {档位: [价格, 数量, 笔数]}
    • 买一价即为字典中 Key 为 1 的 Value 的第 0 个元素。
  3. 卖一量 (offer_grp)

    • 位于 data[security]['tick']['offer_grp']
    • 处理方式同上。
    • 卖一量即为字典中 Key 为 1 的 Value 的第 1 个元素。
  4. 最近一笔逐笔成交价 (transcation)

    • 位于 data[security]['transcation']
    • 这是一个 DataFrame 对象。
    • 价格字段为 hq_px,取第 0 个元素即为最新一笔。

策略代码示例

def initialize(context):
    # 设置关注的股票,这里以恒生电子为例
    g.security = '600570.SS'
    set_universe(g.security)

def tick_data(context, data):
    security = g.security
    
    # 1. 获取 Tick 快照数据
    tick_info = data[security]['tick']
    
    # ---------------------------------------------------
    # 解析买一价
    # bid_grp 格式示例: "{1:[42.71,200,0], 2:[...], ...}"
    # 需要使用 eval 将字符串转为字典
    # ---------------------------------------------------
    if 'bid_grp' in tick_info and len(tick_info['bid_grp']) > 0:
        # 获取买档数据字符串并转为字典
        bid_grp_dict = eval(tick_info['bid_grp'][0])
        # 获取买一档数据 list: [价格, 数量, 笔数]
        bid_1_info = bid_grp_dict.get(1) 
        if bid_1_info:
            buy_1_price = bid_1_info[0] # 索引0为价格
        else:
            buy_1_price = 0.0
    else:
        buy_1_price = 0.0

    # ---------------------------------------------------
    # 解析卖一量
    # offer_grp 格式同上
    # ---------------------------------------------------
    if 'offer_grp' in tick_info and len(tick_info['offer_grp']) > 0:
        offer_grp_dict = eval(tick_info['offer_grp'][0])
        # 获取卖一档数据
        offer_1_info = offer_grp_dict.get(1)
        if offer_1_info:
            sell_1_vol = offer_1_info[1] # 索引1为数量
        else:
            sell_1_vol = 0
    else:
        sell_1_vol = 0

    # ---------------------------------------------------
    # 解析最近一笔逐笔成交价格
    # 注意:需开通 Level-2 行情才有此数据,否则返回 None
    # PTrade 中字段名为 'transcation' (注意拼写)
    # ---------------------------------------------------
    transaction_df = data[security]['transcation']
    last_transaction_price = 0.0
    
    if transaction_df is not None and len(transaction_df) > 0:
        # 获取最近一笔成交的价格 'hq_px'
        last_transaction_price = transaction_df['hq_px'][0]
    
    # ---------------------------------------------------
    # 打印结果
    # ---------------------------------------------------
    log.info("股票: %s" % security)
    log.info("买一价: %s" % buy_1_price)
    log.info("卖一量: %s" % sell_1_vol)
    log.info("最近逐笔成交价: %s" % last_transaction_price)

def handle_data(context, data):
    pass

注意事项

  1. 运行环境tick_data 函数仅在交易模块(实盘或仿真交易)中生效,普通的回测(日线/分钟线)不会触发此函数。
  2. Level-2 权限data[security]['transcation'] 中的逐笔成交数据需要券商端开通 Level-2 行情权限,否则该字段可能返回 None
  3. 数据类型bid_grpoffer_grp 返回的是字符串形式的字典,必须使用 eval() 进行转换才能通过 Key 获取具体的档位数据。
  4. 字段拼写:请务必注意 PTrade API 中逐笔成交的键名为 transcation(包含拼写错误),而非标准的 transaction

Q&A

Q: 为什么在回测中 tick_data 没有打印日志?
A: tick_data 函数仅在交易模块(实盘/仿真)中运行,普通回测通常只支持 handle_data(日线/分钟线)。如果需要测试 Tick 逻辑,需使用特定的 Tick 级别回测环境(如果券商支持)或在仿真交易中测试。

Q: bid_grp 中的 [42.71, 200, 0] 分别代表什么?
A: 列表中的三个元素依次代表:[委托价格, 委托数量, 委托笔数]

Q: 如果没有 Level-2 行情,如何获取最新价格?
A: 如果没有 L2 权限无法获取逐笔成交,可以使用 data[security]['tick']['last_px'][0] 来获取该 Tick 快照时的最新成交价。