3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 QMT 平台中遇到 call_vba 在历史 K 线上计算正常,但在最新 K 线(当前时间)上数值不再变化的问题,通常与 QMT 的底层运行机制以及 VBA 指标的计算缓存有关。
根据 QMT 的运行机制(详见文档 1.2.3 Python 交易函数运行机制):
handlebar,此时 call_vba 会根据确定的历史 K 线数据计算出准确的值。handlebar 就会被触发一次。然而,部分通过 call_vba 调用的底层指标在设计上可能存在缓存机制,或者仅在 K 线闭合(走完)时才更新其内部状态,导致在盘中 tick 驱动时,返回的始终是该 K 线初始或上一次闭合时的值。为了解决实时行情下指标不更新的问题,建议采用以下几种方法:
call_vba(强烈推荐)QMT 平台内置了丰富的 Python 第三方库(如 Pandas、NumPy 和 TA-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-Lib 或 Pandas 进行计算,是解决此类不刷新问题的最佳实践。