问题描述
解决方案
在PTrade中处理Tick数据并实现快速追单(以对手价/卖一价买入),核心在于使用 tick_data 函数配合 order_tick 接口。
为了实现“以卖一价买入”,最直接且高效的方法是利用 order_tick 函数中的 priceGear 参数。
核心逻辑说明
- 运行频率:代码必须运行在
tick_data(context, data)函数中,该函数在交易时段每3秒触发一次(取决于行情推送)。 - 下单接口:使用
order_tick(sid, amount, priceGear, limit_price)。 - 对手价参数:
priceGear='-1':代表卖一价(Ask 1)。priceGear='1':代表买一价(Bid 1)。- 如果要更激进地追单(确保成交),可以使用
priceGear='-5'(卖五价)或者在卖一价基础上增加滑点。
策略代码实现
以下是一个完整的策略示例。该策略在检测到Tick数据更新时,以**卖一价(对手价)**快速买入指定股票。
def initialize(context):
# 初始化策略,设置要操作的股票
g.security = '600570.SS'
# 设置股票池
set_universe(g.security)
# 设置一个标志位,防止demo策略无限买入,实际使用时请根据逻辑控制
g.traded = False
def tick_data(context, data):
"""
Tick级别行情推送处理函数,每3秒触发一次
"""
# 获取当前股票代码
security = g.security
# 校验数据有效性:确保当前股票有Tick数据推送
if security not in data or 'tick' not in data[security]:
return
# 示例逻辑:如果尚未交易,则以对手价(卖一价)买入100股
if not g.traded:
# ---------------------------------------------------
# 核心代码:快速追单
# priceGear='-1' 表示以盘口卖一价下单
# amount=100 表示买入100股
# ---------------------------------------------------
order_id = order_tick(security, 100, priceGear='-1')
if order_id:
log.info("已触发Tick级追单,以卖一价买入 %s,委托编号: %s" % (security, order_id))
g.traded = True
# --- 进阶:如果需要获取具体的卖一价格进行逻辑判断 ---
# 获取卖一档信息
# 注意:根据券商接口不同,offer_grp可能是字典或需要eval解析的字符串
# 这里演示标准字典获取方式
try:
tick_info = data[security]['tick']
# offer_grp key为1代表卖一,value为列表 [价格, 数量, 笔数]
# 部分环境可能需要使用 eval(tick_info['offer_grp'])
offer_grp = tick_info.get('offer_grp', {})
if 1 in offer_grp:
ask_1_price = offer_grp[1][0] # 获取卖一价
# log.info("当前卖一价为: %s" % ask_1_price)
# 你可以在这里添加逻辑,例如:只有当卖一价低于某个阈值时才追单
# if ask_1_price < 50.00:
# order_tick(security, 100, priceGear='-1')
except Exception as e:
log.error("获取盘口价格异常: %s" % e)
def handle_data(context, data):
# tick策略中,handle_data通常留空或处理日线级别辅助逻辑
pass
关键参数详解
在 order_tick(sid, amount, priceGear='1', limit_price=None) 中:
-
priceGear(盘口档位):- 字符串类型。
'1'~'5':对应 买一 到 买五。'-1'~'-5':对应 卖一 到 卖五。- 追涨买入通常使用
'-1'(卖一) 或'-2'(卖二) 以提高成交概率。 - 止损卖出通常使用
'1'(买一) 或'2'(买二)。
-
limit_price(保护限价):- 即使使用了
priceGear,你依然可以传入limit_price。 - 如果传入了
limit_price,系统会以priceGear对应的档位价格和limit_price中的更有利于成交(或受限)的价格进行报单,或者作为价格笼子的保护。通常在单纯追求速度的追单中,可以不传此参数,直接按盘口价成交。
- 即使使用了
注意事项
- 环境限制:
tick_data和order_tick仅在交易模块(实盘或仿真交易)中生效,普通的回测(日线/分钟线)通常不支持Tick级回调。 - 数据解析:在
tick_data的data参数中,offer_grp(卖盘)和bid_grp(买盘)的数据结构在不同券商的PTrade版本中可能略有差异(部分返回字符串需用eval()解析,部分直接返回字典),建议先打印log.info(data[security]['tick'])确认结构。 - 风控:Tick级别运行频率极高(3秒一次),务必在代码中设置这就标志位(如示例中的
g.traded)或持仓判断逻辑,防止瞬间重复下单耗尽资金。
Q&A
Q: 如果我想以涨停价抢筹,应该怎么写?
A: 可以直接使用 order_tick 并指定 limit_price 为涨停价,或者获取快照中的 up_px 字段。
# 获取涨停价
up_price = data[g.security]['tick']['up_px']
# 以涨停价买入
order_tick(g.security, 100, limit_price=up_price)
Q: order_tick 和普通的 order 函数有什么区别?
A: order 是通用接口,通常用于 handle_data (分钟/日线);order_tick 是专用接口,只能在 tick_data 函数中使用,且支持 priceGear 这种针对盘口的快速参数。
Q: 为什么我的 tick_data 没有运行?
A: 请检查两点:1. 策略运行频率是否选择了“Tick级别”;2. 是否处于交易时间段(9:30-11:30, 13:00-15:00)。非交易时间段Tick数据不会推送。