🚀 AI 一键生成 qmt 策略代码

QMT实时Tick行情中成交额(amount)字段精度丢失怎么办?

qmt | 发布时间: 2026/5/27
以下内容由 EasyQuant 生成。

问题描述

tick行情amount字段精度有问题

如图,513050,qmt全推行情返回的tick显示成交额数据是966171400.0,盘后拿历史数据拿到的正确数据是966171356,实时推送的数据精度明显被**了

解决方案

问题原因分析

在 QMT 平台中,实时 Tick 行情与盘后历史数据在 amount(成交额)字段上出现精度差异,主要由以下几个原因导致:

  1. 底层数据类型与浮点数精度限制
    实时行情为了追求极低的延迟和高并发传输,底层在处理或序列化 amount 字段时,可能采用了单精度浮点数(float32)。单精度浮点数的有效十进制数字大约为 7位。当成交额达到上亿级别(例如 966,171,356,共9位数字)时,超出的部分会发生精度截断或四舍五入,从而变成类似 966171400.0 的数值。

  2. 实时推送与盘后清洗的机制差异

    • 实时全推行情:直接对接交易所的实时快照,经过网关快速分发,数据结构偏向轻量化。
    • 盘后历史数据:收盘后,数据中心会对全天的行情进行清洗、校对,并以更高精度的数据类型(如 doubleint64)落盘存储。因此,通过 get_local_dataget_market_data_ex 获取的历史数据是绝对精确的。

解决方案与处理建议

针对这种精度丢失现象,建议在编写量化策略时采取以下应对措施:

1. 评估策略对精度的实际需求

对于绝大多数基于成交额的量化策略(如计算资金净流入、放量突破、量价背离等),上亿成交额中几十元的精度误差(误差率不到千万分之一)对策略信号的触发没有任何实质性影响。在实时交易中,可以直接忽略这一微小的尾数差异。

2. 估算单笔/区间成交额

如果您需要计算两个 Tick 之间的区间成交额,直接相减可能会放大浮点数误差。可以通过成交量差值 × 最新价来进行估算:

def on_quote(datas):
    for code, data in datas.items():
        # 假设记录了上一个tick的 volume
        current_volume = data['volume'].iloc[-1]
        last_volume = get_last_volume(code) # 自定义函数获取上一个tick的volume
        
        current_price = data['close'].iloc[-1]
        
        # 估算当前Tick的真实成交额
        tick_amount_est = (current_volume - last_volume) * current_price
        print(f"{code} 当前Tick估算成交额: {tick_amount_est}")

3. 升级至 Level2 行情

如果您的策略是高频的微观结构策略,对盘口和逐笔成交的金额要求绝对精确,建议开通并订阅 Level2 行情。Level2 提供的逐笔成交明细(Tick-by-Tick)在数据结构上通常保留了完整的精度,能够满足高频交易的需求。

4. 盘后复盘务必使用历史接口

在进行盘后回测、财务对账或统计分析时,不要依赖盘中收集的实时 Tick 数据进行累加。请使用 QMT 提供的历史数据接口获取清洗后的高精度数据:

def handlebar(ContextInfo):
    if not ContextInfo.is_last_bar():
        return
    
    # 获取盘后高精度日线/Tick数据
    data = ContextInfo.get_market_data_ex(
        ['amount', 'volume', 'close'], 
        ['513050.SH'], 
        period='1d',
        subscribe=False
    )
    print("盘后精确成交额:", data['513050.SH']['amount'].iloc[-1])

总结:实时 Tick 行情 amount 字段的尾数归零是底层浮点数精度限制所致。在实盘策略中可忽略此误差或用量价推算,盘后统计则应统一使用历史数据接口。