🚀 AI 一键生成 qmt 策略代码

QMT 策略中 call_vba 在最新 K 线数值不变化的解决方案

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

问题描述

call_vba计算值 到当前时间后 不再变化

我的是 期货账号

周期: 1分钟
快速计算: 10
环境:模型研究【运行模式】

(1)序号10 之前, call_vba 每1分钟计算一次值 都是不同的。 这个是正常的
(2)序号10 之后, call_vba 到当前时间后 就维持 序号10 的值 不再变化了, 这个不正常


不知道这是为什么 call_vba计算值 到当前时间后 不再变化 , 有大佬知道的吗?

解决方案

在 QMT 平台中遇到 call_vba 在历史 K 线上计算正常,但在最新 K 线(当前时间)上数值不再变化的问题,通常与 QMT 的底层运行机制以及 VBA 指标的计算缓存有关。

为什么会出现这种情况?

根据 QMT 的运行机制(详见文档 1.2.3 Python 交易函数运行机制):

  1. 历史 K 线阶段:模型逐根 K 线运行,每根 K 线调用一次 handlebar,此时 call_vba 会根据确定的历史 K 线数据计算出准确的值。
  2. 实时行情阶段(最新 K 线):当运行到最后一根未走完的 K 线时,每来一个 tick 数据,handlebar 就会被触发一次。然而,部分通过 call_vba 调用的底层指标在设计上可能存在缓存机制,或者仅在 K 线闭合(走完)时才更新其内部状态,导致在盘中 tick 驱动时,返回的始终是该 K 线初始或上一次闭合时的值。

解决方案与建议

为了解决实时行情下指标不更新的问题,建议采用以下几种方法:

方法一:使用 Python 原生库替代 call_vba(强烈推荐)

QMT 平台内置了丰富的 Python 第三方库(如 PandasNumPyTA-Lib)。使用 Python 原生代码计算指标,不仅可以避免 call_vba 的黑盒缓存问题,还能确保在每个 tick 到来时都能基于最新价格实时计算。

示例:使用 TA-Lib 计算均线替代 VBA 的 MA

#coding:gbk
import talib
import numpy as np

def init(ContextInfo):
    ContextInfo.set_universe(['IF.IF']) # 设置期货主力合约

def handlebar(ContextInfo):
    # 获取包含最新 tick 价格的 K 线数据
    df = ContextInfo.get_market_data(['close'], stock_code=ContextInfo.get_universe(), period='1m', count=15)
    
    if df.empty or len(df) < 10:
        return
        
    # 提取收盘价序列
    close_prices = df['close'].values
    
    # 使用 TA-Lib 实时计算 10 周期均线
    ma10 = talib.SMA(close_prices, timeperiod=10)
    
    # 打印最新值,盘中每个 tick 都会实时更新
    print(f"当前 Bar 索引: {ContextInfo.barpos}, 最新 MA10: {ma10[-1]}")

方法二:检查是否被 is_last_bar() 限制

请检查您的代码中是否使用了 ContextInfo.is_last_bar()ContextInfo.is_new_bar()。如果在 call_vba 外层加了条件判断,可能会导致在盘中 tick 刷新时跳过了计算逻辑。

方法三:强制获取最新分笔数据辅助计算

如果您必须依赖某些特定的逻辑,可以在 handlebar 中使用 ContextInfo.get_full_tick() 获取最新的分笔数据,手动将最新价(lastPrice)拼接到历史序列中进行计算,以确保计算结果包含最新的市场变化。

总结call_vba 主要用于兼容旧版公式,在实时高频(Tick 级别)驱动下表现可能不如预期。在 Python API 环境下,直接使用 ContextInfo.get_market_data 获取数据并结合 TA-LibPandas 进行计算,是解决此类不刷新问题的最佳实践。