问题描述
最近几次的集合竞价都没有卖出成功。
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
解决方案
在 ptrade 平台中参与 A 股的集合竞价交易,时间设置是非常关键的。您遇到的问题是因为对交易所的集合竞价撮合机制和程序的执行耗时理解存在偏差。
问题原因分析
A 股早盘集合竞价的时间是 9:15 - 9:25。其中:
- 9:15 - 9:20:可以接收申报,也可以撤销申报。
- 9:20 - 9:25:可以接收申报,但不能撤销申报。
- 9:25:00:交易所系统进行集合竞价撮合,产生开盘价。
当您使用 run_daily(context, func, time='9:25') 时,ptrade 引擎会在 9:25:00 触发该函数。但是,获取行情、执行策略逻辑、生成订单并发送到柜台这一系列操作是需要耗费时间的(通常在毫秒到秒级)。
因此,当您的委托单真正到达交易所时,时间已经变成了 9:25:01 或更晚。此时,9:25 的集合竞价撮合已经结束,交易所系统会将您的委托单视为连续竞价阶段的订单,自动排队等待 9:30 开盘后进行撮合。这就是为什么您没有成功参与到集合竞价的原因。
解决方案
为了精确参与 9:25 的集合竞价,您必须确保委托单在 9:25:00 之前到达交易所。正确的做法是将 run_daily 的触发时间提前。
建议将时间设置为 9:23 或 9:24。这样既能获取到相对成熟的集合竞价盘口数据,又有充足的时间让程序执行并完成报单。
正确的代码示例
参考 ptrade 官方文档中的“集合竞价追涨停策略”,您可以这样设置:
def initialize(context):
# 初始化此策略
g.security = '600570.SS'
set_universe(g.security)
# 关键修改:将运行时间提前到 9:23 或 9:24
run_daily(context, aggregate_auction_func, time='9:24')
def aggregate_auction_func(context):
stock = g.security
# 获取集合竞价期间的最新快照数据
snapshot = get_snapshot(stock)
if snapshot is None or stock not in snapshot:
log.warning("未获取到行情快照")
return
price = snapshot[stock].get('last_px', 0)
# 执行您的卖出逻辑
if get_position(stock).amount > 0:
# 假设以跌停价挂单以确保卖出(根据实际策略调整)
down_limit = snapshot[stock].get('down_px', 0)
if down_limit > 0:
order_target(stock, 0, limit_price=down_limit)
log.info(f"在集合竞价阶段下达卖出委托,价格: {down_limit}")
def handle_data(context, data):
pass
参与集合竞价的注意事项
- 行情数据的有效性:在 9:15-9:25 期间调用
get_snapshot,获取到的是集合竞价的虚拟撮合价格和量。越接近 9:25,这个价格越接近最终的开盘价。 - 撤单限制:如果您在 9:20 之后下达了委托,请记住在此期间是无法撤单的。如果您的策略包含撤单逻辑,请务必避开 9:20-9:25 这个时间段。
- 价格设置:为了确保在集合竞价中成交,买入时通常挂涨停价,卖出时通常挂跌停价(最终成交价为集合竞价产生的单一开盘价)。如果挂限价单,可能会因为价格不满足撮合条件而无法成交。
- 网络与系统延迟:实盘交易中,网络延迟和券商柜台处理速度也会影响报单到达时间,因此提前 1-2 分钟触发函数是最稳妥的做法。