🚀 AI 一键生成 ptrade 策略代码

PTrade 高频交易:如何编写一个简单的 Tick 级做市商策略?

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

问题描述

请帮我编写一个简单的 Tick 级做市商策略

解决方案

这是一个基于 PTrade 平台的简单 Tick 级做市商(Market Maker)策略。

策略逻辑说明

做市商策略的核心在于提供流动性并赚取买卖价差(Spread)

  1. 运行频率:使用 tick_data 函数,策略会在每一个 Tick(行情快照更新,通常为3秒)触发一次。
  2. 撤单逻辑:在每次 Tick 开始时,先撤销上一时刻未成交的挂单,防止订单堆积占用资金或持仓。
  3. 盘口挂单
    • 买单:以当前的**买一价(Bid 1)**挂单买入。
    • 卖单:以当前的**卖一价(Ask 1)**挂单卖出。
  4. 仓位控制:为了防止单边持仓过重,策略中加入了简单的库存管理(Inventory Control),当持仓超过上限时不买,低于下限时不卖。
  5. 底仓设置:为了在回测开始时就能进行卖出操作,我们在 initialize 中设置了底仓。

策略代码

# 简单的 Tick 级做市商策略

def initialize(context):
    """
    初始化函数,设置股票池、全局变量和底仓
    """
    # 1. 设置要操作的标的(这里以恒生电子为例)
    g.security = '600570.SS'
    set_universe(g.security)
    
    # 2. 策略参数设置
    g.trade_vol = 100       # 每次挂单数量(股)
    g.max_position = 20000  # 最大持仓上限(防止买太多)
    g.min_position = 1000   # 最小持仓下限(防止卖空)
    
    # 3. 设置回测时的初始底仓(实盘中请忽略或根据实际情况调整)
    # 格式:[{'sid':代码, 'amount':数量, 'enable_amount':可用数量, 'cost_basis':成本}]
    # 做市商需要有底仓才能挂卖单
    pos = {
        'sid': g.security,
        'amount': 10000,
        'enable_amount': 10000,
        'cost_basis': 40.0
    }
    set_yesterday_position([pos])
    
    log.info("策略初始化完成,标的:%s,初始底仓:10000" % g.security)

def tick_data(context, data):
    """
    Tick 数据处理函数,由系统每隔约3秒调用一次
    """
    security = g.security
    
    # ----------------------------------------------------------------
    # 1. 撤单逻辑:撤销当前标的的所有未完成订单
    # 做市商需要跟随盘口价格跳动,旧的挂单如果未成交需要及时撤销
    # ----------------------------------------------------------------
    open_orders = get_open_orders(security)
    if open_orders:
        for order_obj in open_orders:
            # 仅撤销未成交或部分成交的订单
            if order_obj.status in ['0', '1', '2', '3', '4', '7']:
                cancel_order(order_obj.id)
    
    # ----------------------------------------------------------------
    # 2. 获取当前持仓和资金情况
    # ----------------------------------------------------------------
    position = get_position(security)
    current_amount = position.amount  # 当前持仓数量
    
    # ----------------------------------------------------------------
    # 3. 盘口挂单逻辑 (Market Making)
    # 使用 order_tick 接口,priceGear 参数可以直接指定盘口档位
    # priceGear='1' 代表买一价,priceGear='-1' 代表卖一价
    # ----------------------------------------------------------------
    
    # --- 挂买单逻辑 ---
    # 如果当前持仓未达到上限,则在【买一价】挂单买入
    if current_amount < g.max_position:
        # order_tick: amount为正数代表买入
        # priceGear='1': 以当前盘口买一价委托
        order_tick(security, g.trade_vol, priceGear='1')
        
    # --- 挂卖单逻辑 ---
    # 如果当前持仓大于下限,则在【卖一价】挂单卖出
    if current_amount > g.min_position:
        # order_tick: amount为负数代表卖出
        # priceGear='-1': 以当前盘口卖一价委托
        order_tick(security, -g.trade_vol, priceGear='-1')

def handle_data(context, data):
    """
    必须实现的函数,但在 Tick 策略中通常留空,
    因为主要逻辑在 tick_data 中执行。
    """
    pass

代码关键点解析

  1. order_tick(sid, amount, priceGear=...):

    • 这是 PTrade 专门用于 Tick 级交易的函数。
    • priceGear='1':表示以买一价委托。
    • priceGear='-1':表示以卖一价委托。
    • 这种方式比手动获取 get_snapshot 里的价格再填入 limit_price 要快且方便,能确保你的挂单始终贴在盘口上。
  2. get_open_orders & cancel_order:

    • 做市策略必须具备高频的撤单能力。如果盘口价格变动(例如买一价从 10.00 变为 10.01),旧的 10.00 的买单就失去了做市意义(变成了买二或更后),因此需要撤单并重新挂在新的买一价上。
  3. set_yesterday_position:

    • 在回测环境中,默认资金账号是空仓的。做市商策略需要双向报价(既买也卖)。如果没有底仓,策略一开始只能挂买单,无法挂卖单。因此使用此函数虚拟建立底仓。

风险提示

这是一个最基础的做市模型,实盘中做市商策略会面临以下风险,需要更复杂的逻辑来处理:

  • 单边行情风险:如果股价快速单边上涨,你可能会过早卖光筹码;如果快速下跌,你可能会接满仓位的“飞刀”。
  • 成交不平衡:需要动态调整买卖价差或停止单边报价来平衡库存。
  • 手续费:高频的买卖会产生大量手续费,策略的价差利润必须覆盖交易成本。

Q&A

Q1: 为什么使用 order_tick 而不是普通的 order 函数?
A1: order_tick 是 PTrade 专门为 Tick 级别高频场景设计的。它支持 priceGear 参数(如 '1', '-1'),可以直接锁定盘口档位(买一、卖一等),无需先查询行情再手动输入价格,执行效率更高,代码更简洁。

Q2: tick_data 函数的运行频率是多少?
A2: 在 PTrade 中,tick_data 通常跟随交易所的行情快照推送频率,大约每 3 秒执行一次。

Q3: 如何避免在单边下跌行情中买入过多股票?
A3: 可以在代码中加入趋势判断逻辑。例如,计算过去 N 个 Tick 的价格均值,如果当前价格显著低于均值(急跌),则暂停挂买单;或者引入库存倾斜逻辑(Inventory Skew),当持仓过多时,大幅降低买单报价(挂在买三、买五)或停止买入,同时积极挂卖单。