3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 ptrade 量化交易平台中,回测环境和实盘(交易)环境的撮合机制存在本质区别:
Position)和资金(Cash)会立即更新。当使用目标数量/市值下单接口(如 order_target 或 order_target_value)时,系统会读取当前的持仓量来计算需要买卖的差额。如果在实盘中,第一笔订单刚下达,柜台持仓尚未更新(处于6秒延迟期内),策略逻辑再次触发 order_target,系统会认为持仓依然为0(或旧值),从而再次下达相同的订单,造成重复下单。
为了在实盘中安全地使用目标下单逻辑,建议采用以下几种解决方案:
g 进行状态标记(适用于低频策略)对于日线级别或低频触发的策略,可以使用全局变量 g 来记录当日是否已经下过单,避免在同一周期内反复触发。
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
# 初始化下单标记
g.order_placed = False
def before_trading_start(context, data):
# 每天盘前重置标记
g.order_placed = False
def handle_data(context, data):
if not g.order_placed:
# 仅在未下单时执行目标数量委托
order_target(g.security, 1000)
g.order_placed = True
log.info(f"已对 {g.security} 下达目标委托,锁定当日下单状态。")
如果策略需要频繁调整仓位,建议放弃使用 order_target,改为使用基础的 order 接口,并结合 get_position 和 get_open_orders 手动计算真实仓位(实际持仓 + 在途未成交订单)。
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
target_amount = 1000 # 目标持仓量
# 1. 获取当前已确认的持仓
current_position = get_position(g.security).amount
# 2. 获取当前在途(未成交)的订单数量
open_orders = get_open_orders(g.security)
pending_amount = sum([order.amount - order.filled for order in open_orders])
# 3. 计算真实的差额
# 真实差额 = 目标数量 - (当前持仓 + 在途数量)
diff_amount = target_amount - (current_position + pending_amount)
# 4. 只有当差额达到一定阈值(如100股)时才下单
if abs(diff_amount) >= 100:
order(g.security, diff_amount)
log.info(f"目标:{target_amount}, 持仓:{current_position}, 在途:{pending_amount}, 补单:{diff_amount}")
on_order_response 维护本地账本对于对速度要求极高的 tick 级策略,可以通过 on_order_response 和 on_trade_response 实时维护一个本地的虚拟持仓账本,完全绕过柜台查询的延迟。
handle_data(尤其是分钟或 tick 级别)中无条件地连续调用 order_target 和 order_target_value。order_target 前,必须先调用 cancel_order 撤销前序订单,否则引擎不会计算在途委托,必然导致重复下单。