问题描述
解决方案
在 PTrade 量化交易平台中,获取实时的总委买量和总委卖量主要通过 get_snapshot 函数来实现。该函数可以获取指定标的的实时行情快照,其中包含了买卖盘口的详细数据。
核心逻辑说明
- 调用接口:使用
get_snapshot(security)获取标的的实时快照。 - 获取字段:
total_bidqty:总委买量(所有买盘委托数量之和)。total_offerqty:总委卖量(所有卖盘委托数量之和)。
- 计算盘口压力(委比):
- 通常使用 委比 (Entrust Rate) 来衡量盘口压力。
- 公式:
(总委买量 - 总委卖量) / (总委买量 + 总委卖量) * 100%。 - 正值(>0):表示委买量大于委卖量,买盘强劲,价格有上涨支撑。
- 负值(<0):表示委卖量大于委买量,抛压较重,价格有下跌压力。
注意事项
- 适用环境:
get_snapshot函数仅在交易模式(实盘/模拟盘)下可用,回测模式下不支持该函数(回测中通常使用data[security]['volume']或get_history获取历史成交量,无法获取历史盘口挂单总量)。 - 数据精度:返回的数据通常为整型(int),单位为“股”或“张”。
策略代码示例
以下是一个完整的 PTrade 策略示例,展示了如何在盘中实时获取总委买和总委卖量,并计算委比来判断盘口压力。
def initialize(context):
"""
初始化函数
"""
# 设置要监控的股票,例如:恒生电子
g.security = '600570.SS'
# 设置股票池
set_universe(g.security)
# 设置一个标志位,用于控制日志打印频率(可选)
g.last_log_time = 0
def handle_data(context, data):
"""
盘中运行函数,根据频率(分钟/日线)运行
"""
# 仅在交易模式下运行此逻辑,因为回测不支持 get_snapshot
if not is_trade():
log.info("当前为回测模式,get_snapshot 函数不可用,跳过执行。")
return
# 获取实时行情快照
snapshot = get_snapshot(g.security)
# 检查是否成功获取数据
if snapshot and g.security in snapshot:
tick_info = snapshot[g.security]
# 获取总委买量 (total_bidqty) 和 总委卖量 (total_offerqty)
# 注意:使用 .get() 方法防止字段缺失报错,默认值为 0
total_bid_qty = tick_info.get('total_bidqty', 0)
total_offer_qty = tick_info.get('total_offerqty', 0)
# 获取最新价,用于辅助判断
current_price = tick_info.get('last_px', 0.0)
# 计算委比 (Entrust Rate)
# 公式:(委买 - 委卖) / (委买 + 委卖)
total_qty = total_bid_qty + total_offer_qty
if total_qty > 0:
entrust_rate = (total_bid_qty - total_offer_qty) / total_qty
else:
entrust_rate = 0
# 打印日志信息
log.info("=" * 30)
log.info("标的: %s, 最新价: %.2f" % (g.security, current_price))
log.info("总委买量: %d" % total_bid_qty)
log.info("总委卖量: %d" % total_offer_qty)
log.info("当前委比: %.2f%%" % (entrust_rate * 100))
# 简单的盘口压力判断逻辑
if entrust_rate > 0.5:
log.info("【盘口信号】买盘强势:委买量远大于委卖量,支撑较强。")
# 在此处可以添加买入逻辑,例如:
# order_target(g.security, 1000)
elif entrust_rate < -0.5:
log.info("【盘口信号】抛压沉重:委卖量远大于委买量,阻力较大。")
# 在此处可以添加卖出逻辑,例如:
# order_target(g.security, 0)
else:
log.info("【盘口信号】多空平衡:委买委卖数量差距不大。")
else:
log.warning("未能获取到 %s 的快照数据" % g.security)
代码解析
-
is_trade()判断:
代码中加入了if not is_trade():的判断。这是因为get_snapshot是交易专用接口,如果在回测中直接调用会返回空值或报错,加上此判断可以保证代码的健壮性。 -
数据获取:
通过snapshot[g.security].get('total_bidqty', 0)安全地获取数据。如果该标的停牌或数据流中断,.get()方法会返回默认值 0,避免程序崩溃。 -
委比计算:
代码实现了标准的委比计算公式。委比值范围在 -1 到 1 之间(即 -100% 到 100%)。- +100%:涨停板通常会出现这种情况(只有买单,没有卖单)。
- -100%:跌停板通常会出现这种情况(只有卖单,没有买单)。
-
Python 版本兼容性:
代码使用了%格式化字符串(如"%.2f" % val),完全兼容 Python 3.5 及以上版本,符合 PTrade 的运行环境要求。
Q&A
Q1: get_snapshot 和 tick_data 中的 data 有什么区别?
A: get_snapshot 是主动查询接口,可以在 handle_data 或 run_interval 中随时调用,返回的是调用时刻的最新快照。而 tick_data(context, data) 是一个事件驱动函数,每当有新的 Tick 数据推送时自动触发,其中的 data 参数直接包含了当前的 Tick 信息。如果你需要高频处理(如每3秒一次),建议使用 tick_data 函数或配合 run_interval 使用 get_snapshot。
Q2: 为什么我在回测中获取到的总委买量是 0?
A: PTrade 的回测机制基于历史 K 线数据(分钟或日线),历史数据中通常不包含盘口挂单总量的详细快照(Level-2 数据量过大,通常不用于标准回测)。因此,get_snapshot 仅在实盘或模拟交易环境中有效。
Q3: 除了总委买/卖量,还有哪些字段可以判断压力?
A: 你还可以利用 bid_grp(买盘档位)和 offer_grp(卖盘档位)来分析具体的压单位置。例如,如果 offer_grp 的卖一到卖五档中有某一档挂单量巨大,那个价格就是短期的直接压力位。