问题描述
/
解决方案
在 ptrade 量化交易平台中,调用 get_snapshot 获取实时行情快照时,如果发现均价字段(如 avg_px 或 wavg_px)返回为 0,通常是由以下几个原因导致的:
1. 在盘前阶段(before_trading_start)调用
根据 ptrade API 文档的特别提示:在盘前阶段(before_trading_start)使用该函数 get_snapshot,返回数据里大部分数据是 0,比如成交量、当前价格、换手率等。
因为此时集合竞价尚未产生实际的连续成交,系统无法计算出有效的均价,因此返回 0。
2. 当日尚未产生任何成交
如果股票在盘中处于停牌状态(trade_status 为 HALT 或 SUSP),或者开盘后极其冷门、一笔成交都没有发生(business_amount 为 0),那么均价自然为 0。
3. 字段名称混淆(avg_px 与 wavg_px)
请注意检查您获取的字段名。在 ptrade 的 get_snapshot 返回字典中,官方文档标注的加权平均价字段名为 wavg_px,而不是 avg_px(avg_px 通常出现在 tick_data 的 tick DataFrame 中)。如果您强行获取一个不存在或未赋值的字段,可能会得到 0 或 None。
解决办法与代码示例
为了避免均价为 0 导致策略计算异常(如除以 0 报错),建议在策略中加入状态判断和容错处理:
1. 确保在盘中(handle_data 或 tick_data)调用
不要在 before_trading_start 中依赖快照的均价数据。如果必须在盘前获取昨天的均价,请使用 get_history 或 get_price 获取昨日的 K 线数据进行计算。
2. 增加容错与状态过滤代码
在获取均价时,先判断交易状态是否为连续撮合(TRADE),并判断成交量是否大于 0。
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
snapshot = get_snapshot(g.security)
if not snapshot or g.security not in snapshot:
return
stock_snap = snapshot[g.security]
# 1. 检查交易状态是否为正常交易
trade_status = stock_snap.get('trade_status')
if trade_status not in ['TRADE', 'OCALL']:
log.info(f"{g.security} 当前状态为 {trade_status},非连续交易时段")
return
# 2. 获取加权平均价 wavg_px
wavg_px = stock_snap.get('wavg_px', 0)
# 3. 容错处理:如果 wavg_px 依然为 0,可以通过总成交额 / 总成交量 手动估算
if wavg_px == 0:
business_balance = stock_snap.get('business_balance', 0)
business_amount = stock_snap.get('business_amount', 0)
if business_amount > 0:
# 注意:不同品种的乘数不同,股票通常直接相除即可(注意单位)
wavg_px = business_balance / business_amount
if wavg_px > 0:
log.info(f"{g.security} 当前有效均价为: {wavg_px}")
# 在此处编写基于均价的交易逻辑
else:
log.info(f"{g.security} 当前无有效均价数据")
总结:遇到均价为 0 时,首先检查调用时机(是否在盘前),其次检查字段名(快照中应为 wavg_px),最后在代码中做好容错判断(wavg_px > 0)以保证策略的健壮性。