3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在PTrade量化交易平台中,处理Tick级别的逐笔委托(Order)和逐笔成交(Transaction)数据主要有两种方式:
tick_data 回调函数被动接收:这是处理高频策略最常用的方式,系统每隔3秒(或更短,取决于频率设置)推送一次数据。get_individual_entrust 和 get_individual_transaction 函数主动拉取数据。注意:获取逐笔数据通常需要开通 Level-2 行情权限,否则对应字段可能返回 None 或空数据。
以下是具体的实现代码和解析。
def initialize(context):
# 初始化策略
# 设置我们要操作的股票池,这里以恒生电子为例
g.security = '600570.SS'
set_universe(g.security)
# 开启Tick级别数据接收(通常在实盘或Tick回测模式下自动生效)
# 注意:确保账户有Level-2权限
# 设置日志打印频率,避免日志过多
g.log_counter = 0
def tick_data(context, data):
"""
Tick数据回调函数,每隔一定时间(如3秒)触发一次
data结构:
{
'股票代码': {
'order': DataFrame/None (最近一条逐笔委托),
'tick': DataFrame (当前快照),
'transcation': DataFrame/None (最近一条逐笔成交, 注意API文档中key可能拼写为transcation)
}
}
"""
security = g.security
# 1. 获取该股票的数据包
if security not in data:
return
stock_data = data[security]
# ------------------------------------------------------
# 解析逐笔委托 (Order)
# ------------------------------------------------------
# 注意:如果没有L2权限或该时刻无委托,可能为None
order_df = stock_data.get('order')
if order_df is not None and len(order_df) > 0:
# 由于是DataFrame,通常取第一行(最近的一笔)
latest_order = order_df.iloc[0]
# 提取字段
order_time = latest_order['business_time'] # 时间戳
order_price = latest_order['hq_px'] # 委托价格
order_vol = latest_order['business_amount'] # 委托数量
order_dir = latest_order['business_direction'] # 委托方向 (0-卖, 1-买, 2-借入, 3-出借)
order_kind = latest_order['trans_kind'] # 委托类别 (1-市价, 2-限价, 3-本方最优)
# 简单的逻辑示例:打印大额买单
if order_dir == 1 and order_vol > 10000: # 假设大于100手算大单
log.info("[逐笔委托] 监测到大额买单: 时间=%s, 价格=%.2f, 数量=%d" % (order_time, order_price, order_vol))
# ------------------------------------------------------
# 解析逐笔成交 (Transaction)
# ------------------------------------------------------
# 注意:API文档中该Key有时拼写为 'transcation',需根据实际返回字典键值获取
trans_df = stock_data.get('transcation')
if trans_df is not None and len(trans_df) > 0:
latest_trans = trans_df.iloc[0]
# 提取字段
trans_time = latest_trans['business_time'] # 时间戳
trans_price = latest_trans['hq_px'] # 成交价格
trans_vol = latest_trans['business_amount'] # 成交数量
trans_dir = latest_trans['business_direction'] # 成交方向 (0-卖, 1-买)
trans_idx = latest_trans['trade_index'] # 成交编号
# 简单的逻辑示例:打印主动买入成交
if trans_dir == 1:
# 限制日志打印频率
g.log_counter += 1
if g.log_counter % 10 == 0:
log.info("[逐笔成交] 主动买入: 时间=%s, 价格=%.2f, 数量=%d" % (trans_time, trans_price, trans_vol))
def handle_data(context, data):
# 分钟/日线级别的逻辑(如果需要)
# 也可以在这里使用主动查询接口获取当日累积的逐笔数据
# 示例:主动查询逐笔成交(获取最近50条)
# 注意:is_dict=True 可以提高返回速度,返回字典格式
if is_trade(): # 仅在交易模式下有效
transactions = get_individual_transaction(stocks=[g.security], data_count=10, is_dict=True)
if transactions:
# 处理主动查询到的数据
pass
tick_data 中的数据结构在 tick_data(context, data) 函数中,data 参数是一个字典。对于每一只股票,它包含三个主要键值:
tick: 当前的行情快照(盘口、最新价等)。order: 最近一条逐笔委托数据。transcation: 最近一条逐笔成交数据(请注意: PTrade文档及实际返回中,这个Key通常拼写为 transcation 而非 transaction,编写代码时需特别留意,或者先打印 data[security].keys() 确认)。order) 常用字段:
hq_px: 委托价格。business_amount: 委托数量。business_direction: 0-卖, 1-买。trans_kind: 1-市价, 2-限价, 3-本方最优。transcation) 常用字段:
hq_px: 成交价格。business_amount: 成交数量。business_direction: 0-卖(内盘/主动卖), 1-买(外盘/主动买)。buy_no / sell_no: 买方/卖方委托单号(可用于追踪大单拆单)。除了在 tick_data 中被动接收,你也可以在 handle_data 或其他地方主动调用:
get_individual_entrust(stocks=..., is_dict=True): 获取逐笔委托。get_individual_transaction(stocks=..., is_dict=True): 获取逐笔成交。is_dict=True,这样返回的是字典格式,解析速度比 DataFrame 快,更适合高频场景。Q1: 为什么我在回测中 tick_data 里取不到 order 和 transcation 数据?
A: 这通常有两个原因:
tick_data 函数才会被调用。Q2: tick_data 推送的数据是全量的吗?
A: 不一定。tick_data 的触发频率通常是每3秒一次(或根据券商配置)。在 data 参数中返回的 order 和 transcation 通常是最近一条或该切片时间内的数据。如果市场交易非常活跃,3秒内发生了成百上千笔交易,单纯依靠 tick_data 的推送可能会漏掉中间的明细。如果需要极其精确的全量逐笔分析,建议结合 get_individual_transaction 主动查询,或者确认券商端的推送机制是否支持全量推送。
Q3: 如何判断逐笔成交是主动买入还是主动卖出?
A: 查看 transcation 数据中的 business_direction 字段。
1: 代表买(Buy),即外盘,通常理解为主动买入(买方以卖一价或更高价格成交)。0: 代表卖(Sell),即内盘,通常理解为主动卖出(卖方以买一价或更低价格成交)。