🚀 AI 一键生成 ptrade 策略代码

ptrade策略中委托状态一直返回0(未报)怎么办?

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

问题描述

量化交易委托返回状态为0!

进行量化 交易后,委托状态返回一直都是0,但是策略是使用的tick_data每3秒查询返回!

解决方案

在 ptrade 量化交易平台中,订单的 status 字段返回 0 代表该订单的状态为 “未报”(即订单已在本地生成,但尚未成功报送到券商柜台或交易所)。

如果您在使用 tick_data(每3秒运行一次)时发现委托状态一直停留在 0,通常是由以下几个原因导致的。以下是详细的排查方向与解决方案:

1. 频繁重复下单导致查询错位(最常见)

tick_data 函数每3秒触发一次。如果您在 tick_data 中编写了下单逻辑,但没有使用全局变量(如 g.flag)进行状态控制,策略会每隔3秒就下达一笔新订单。当您去查询订单状态时,可能查到的永远是刚刚生成、还未来得及报送的“最新一笔”订单,从而导致看到的永远是 0

解决方案:在下单逻辑中加入控制标识,确保同一信号只触发一次委托。

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    g.has_ordered = False # 增加下单控制标识

def tick_data(context, data):
    if not g.has_ordered:
        # 满足条件后下单
        order_tick(g.security, 100, limit_price=40.00)
        g.has_ordered = True # 下单后立即锁定,防止3秒后重复下单

2. 轮询查询存在延迟,建议改用主推回调

虽然 tick_data 每3秒执行一次,但主动调用 get_orders()get_order() 去轮询订单状态并不是最高效的做法。在订单刚发出的极短时间内,状态确实是 0

解决方案:ptrade 提供了专门的委托主推事件 on_order_response。该函数会在订单状态发生变化(如从“未报”变为“已报”、“部成”、“已成”等)时瞬间自动触发,速度远快于 tick_data 轮询。

def on_order_response(context, order_list):
    for order in order_list:
        log.info("委托单号: %s, 当前状态: %s" % (order['entrust_no'], order['status']))
        if order['status'] == '8':
            log.info("订单已完全成交!")
        elif order['status'] == '9':
            log.info("订单为废单,请检查价格或资金!")

3. 在非交易时间段下单

如果您在盘前(如 9:15 - 9:25 之间,或者中午休市期间)下达了非集合竞价支持的订单,订单会被 ptrade 引擎接收,但柜台可能暂不受理,此时状态会一直保持为 0(未报)或 1(待报),直到开盘后才会推送到交易所。

解决方案:确保下单动作发生在连续竞价交易时间段(9:30-11:30, 13:00-14:57)。可以使用 get_snapshot 获取 trade_status 字段,确保其为 'TRADE'(连续撮合交易状态)时再下单。

4. 价格精度或参数不合规导致被本地拦截

ptrade 对不同品种的价格精度有严格要求:

  • 股票:小数点后 2 位
  • 可转债、ETF、LOF:小数点后 3 位

如果传入的价格小数位数过多(例如 39.1234 买入股票),或者买入数量不符合规则(如股票买入不是100的整数倍),订单可能会在本地校验时失败,停留在“未报”状态,甚至直接转为废单。

解决方案:在下单前对价格进行 round(price, 2) 处理。

总结建议

针对您的场景,建议将**“下单逻辑”保留在 tick_data 中(并加好 g.flag 防重),而将“状态查询逻辑”**转移到 on_order_response 中。这样既能利用 tick 级别的高频行情捕捉交易机会,又能最实时、准确地获取订单的真实状态。