🚀 AI 一键生成 ptrade 策略代码

如何在 PTrade 中编写 Tick 级别的高频交易策略?(tick_data)

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

问题描述

我想写一个高频策略,需要根据最新的 tick 数据(比如买一卖一价)来做决策和下单,该怎么实现?

解决方案

在 PTrade 中实现基于 Tick 数据的高频策略,核心在于使用 tick_data 事件函数。与 handle_data(通常用于分钟或日线)不同,tick_data 专门用于处理高频快照数据(通常每 3 秒触发一次)。

以下是实现该策略的关键点和完整代码示例:

核心实现步骤

  1. 使用 tick_data(context, data):这是策略的主入口,系统会推送最新的 Tick 数据到 data 参数中。
  2. 解析盘口数据
    • data[code]['tick']['bid_grp']:买盘档位(买一到买十)。
    • data[code]['tick']['offer_grp']:卖盘档位(卖一到卖十)。
    • 数据结构通常为字典,Key 为档位(1 代表买一/卖一),Value 为列表 [价格, 数量, 笔数]
  3. 使用 order_tick 下单:这是专门配合 Tick 数据的下单接口,支持通过 priceGear 参数快速指定以“买一价”或“卖一价”下单,无需手动输入具体价格。

策略代码示例

这个示例策略会监控一只股票,当买一价低于某个值时买入,当卖一价高于某个值时卖出。

def initialize(context):
    # 1. 设置要操作的标的
    g.security = '600570.SS'
    # 2. 设置股票池
    set_universe(g.security)
    
    # 设置一个简单的标志位,防止示例代码在回测中无限下单
    g.bought = False

def tick_data(context, data):
    """
    Tick级别行情推送函数,每3秒触发一次(取决于行情推送频率)
    """
    symbol = g.security
    
    # 1. 获取该标的的 tick 数据
    # 注意:需确保 data 中包含该标的的数据
    if symbol not in data:
        return
        
    tick = data[symbol]['tick']
    
    # 2. 获取买一价和卖一价
    # bid_grp: 买盘档位, offer_grp: 卖盘档位
    # 结构: {1: [价格, 数量, 笔数], 2: [...], ...}
    # 下标说明: [0]是价格, [1]是数量
    
    # 获取买一价 (Bid Price 1)
    if 1 in tick['bid_grp']:
        bid_1_price = tick['bid_grp'][1][0]
        bid_1_vol = tick['bid_grp'][1][1]
    else:
        return # 数据不完整则跳过

    # 获取卖一价 (Ask/Offer Price 1)
    if 1 in tick['offer_grp']:
        ask_1_price = tick['offer_grp'][1][0]
        ask_1_vol = tick['offer_grp'][1][1]
    else:
        return

    # 获取最新成交价
    last_price = tick['last_px']

    # 打印日志方便调试 (生产环境请减少日志量)
    # log.info("代码:%s, 买一:%s, 卖一:%s, 最新:%s" % (symbol, bid_1_price, ask_1_price, last_price))

    # 3. 交易逻辑示例
    
    # 示例逻辑:如果买一价低于 40.0 且尚未买入,则以卖一价(对手价)买入
    if bid_1_price < 40.0 and not g.bought:
        log.info("触发买入信号,当前买一价: %s" % bid_1_price)
        
        # order_tick 下单函数
        # 参数说明: 
        # amount: 正数买入,负数卖出
        # priceGear: 价格档位。'-1'代表卖一价,'1'代表买一价。
        # 这里我们想立即成交,所以买入时挂卖一价 ('-1')
        order_tick(symbol, 100, priceGear='-1')
        
        g.bought = True

    # 示例逻辑:如果卖一价高于 42.0 且持有仓位,则以买一价(对手价)卖出
    elif ask_1_price > 42.0 and g.bought:
        # 检查持仓(可选)
        position = get_position(symbol)
        if position.enable_amount >= 100:
            log.info("触发卖出信号,当前卖一价: %s" % ask_1_price)
            
            # 卖出时,为了立即成交,通常挂买一价 ('1')
            order_tick(symbol, -100, priceGear='1')
            
            g.bought = False

def handle_data(context, data):
    # 在Tick策略中,handle_data 可以留空,或者用于处理非Tick级别的定时任务
    pass

关键参数说明

  1. priceGear (盘口档位)
    order_tick 函数中,priceGear 是一个非常方便的参数:

    • '1' ~ '5':对应 买一买五
    • '-1' ~ '-5':对应 卖一卖五
    • 买入技巧:如果想快速成交(吃单),通常使用 priceGear='-1'(以卖一价买入)。如果想挂单排队,使用 priceGear='1'(以买一价挂单)。
    • 卖出技巧:如果想快速成交,通常使用 priceGear='1'(以买一价卖出)。
  2. 运行频率

    • PTrade 的 tick_data 并不是毫秒级的,通常是 3秒 一次快照(Snapshot)。
    • 如果需要处理逐笔委托(Order)或逐笔成交(Transaction)数据,需要开通 Level-2 行情权限,并在 tick_datadata 参数中解析 ordertranscation 字段。
  3. 回测注意事项

    • 在回测界面选择频率时,必须选择 Tick级别
    • Tick 回测数据量巨大,速度会比分钟级慢很多。
  4. 数据获取方式

    • tick_data 内部,直接使用 data[security]['tick'] 获取数据是最快的。
    • 不要在 tick_data 里频繁调用 get_snapshot(),因为 data 参数里已经包含了当前的快照信息。