🚀 AI 一键生成 qmt 策略代码

在 QMT Python 策略中集成并调用 TA-Lib 计算技术指标

qmt | 发布时间: 2025/11/24
以下内容由 EasyQuant 生成。

问题描述

如何在我的代码里使用 TA-Lib 库来计算移动平均线(MA)?

解决方案

在 QMT 平台中使用 TA-Lib 库计算移动平均线(MA)非常直接,因为 QMT 的内置 Python 环境通常已经预装了 talibnumpy 库。

要在代码中实现这一功能,主要步骤如下:

  1. 获取数据:使用 ContextInfo.get_market_data 获取历史行情数据(通常是 pandas DataFrame 格式)。
  2. 数据转换:TA-Lib 的函数通常需要 numpy.ndarray 类型的输入,因此需要将 pandas 数据转换为 numpy 数组。
  3. 调用函数:使用 talib.MA 或具体的 talib.SMAtalib.EMA 等函数进行计算。

以下是一个完整的策略示例代码,展示了如何在 handlebar 函数中计算 5日简单移动平均线(SMA)和 10日指数移动平均线(EMA)。

# -*- coding: gbk -*-
import pandas as pd
import numpy as np
import talib

def init(ContextInfo):
    # 设置股票池,这里以平安银行为例
    ContextInfo.set_universe(['000001.SZ'])
    # 设置基准
    ContextInfo.benchmark = '000300.SH'

def handlebar(ContextInfo):
    # 获取当前图表的股票代码
    stock_code = ContextInfo.get_universe()[0]
    
    # 1. 获取历史行情数据
    # 我们需要获取足够的历史数据来计算 MA。例如计算 MA10,至少需要 10 根 K 线
    # 这里获取过去 100 根日线数据的收盘价
    # 注意:dividend_type='front' 表示使用前复权数据,这在计算指标时很重要
    data = ContextInfo.get_market_data(
        ['close'], 
        stock_code=[stock_code], 
        count=100, 
        period='1d', 
        dividend_type='front'
    )
    
    # 检查数据是否获取成功
    if data is None or data.empty:
        return

    # 2. 数据转换
    # get_market_data 返回的是 pandas DataFrame
    # 我们需要提取 'close' 列并转换为 numpy 数组,因为 TA-Lib 需要 numpy 数组作为输入
    # 注意:TA-Lib 要求输入数据类型通常为 float
    close_prices = data['close'].values.astype(float)
    
    # 3. 使用 TA-Lib 计算移动平均线
    
    # 计算 5日 简单移动平均线 (SMA)
    # timeperiod: 周期
    # matype: 移动平均类型 (0=SMA, 1=EMA, 2=WMA, 3=DEMA, 4=TEMA, etc.)
    ma5 = talib.MA(close_prices, timeperiod=5, matype=0)
    
    # 计算 10日 指数移动平均线 (EMA)
    ma10 = talib.MA(close_prices, timeperiod=10, matype=1)
    
    # 或者直接使用具体函数
    # ma10_ema = talib.EMA(close_prices, timeperiod=10) 
    
    # 4. 获取最新的指标值
    # 数组的最后一个元素 [-1] 是最新的计算结果
    current_ma5 = ma5[-1]
    current_ma10 = ma10[-1]
    
    # 打印结果
    # 注意:如果数据不足(例如刚上市的股票),计算结果可能是 nan
    if not np.isnan(current_ma5) and not np.isnan(current_ma10):
        print(f"代码: {stock_code}")
        print(f"当前时间: {ContextInfo.get_bar_timetag(ContextInfo.barpos)}")
        print(f"最新收盘价: {close_prices[-1]}")
        print(f"MA5: {current_ma5:.2f}")
        print(f"MA10 (EMA): {current_ma10:.2f}")
        print("-" * 30)

    # 简单的策略逻辑示例:金叉(MA5 上穿 MA10)
    if len(ma5) >= 2 and len(ma10) >= 2:
        prev_ma5 = ma5[-2]
        prev_ma10 = ma10[-2]
        
        # 排除 nan 值
        if not np.isnan(prev_ma5) and not np.isnan(prev_ma10):
            if prev_ma5 < prev_ma10 and current_ma5 > current_ma10:
                print(f"信号触发: {stock_code} 形成金叉 (MA5 上穿 MA10)")

代码关键点说明:

  1. # -*- coding: gbk -*-: 必须添加在文件首行,以确保中文字符和 QMT 环境兼容。
  2. import talib: 引入库。
  3. get_market_data: 获取数据时,count 参数必须大于你要计算的 MA 周期。例如计算 MA60,count 至少要设为 60,通常建议设得更大(如 100 或 200),以确保计算稳定。
  4. .values.astype(float): TA-Lib 对输入数据的类型比较敏感,确保传入的是 float 类型的 numpy 数组是最稳妥的做法。
  5. talib.MA 参数:
    • 第一个参数是输入数组(收盘价)。
    • timeperiod: 计算周期(如 5, 10, 20)。
    • matype: 移动平均线的类型。0 代表 SMA (Simple),1 代表 EMA (Exponential)。你也可以直接调用 talib.SMA(...)talib.EMA(...)
  6. 处理 NaN: 移动平均线计算的前 N-1 个数据通常是 NaN(无效值),在使用结果前最好进行非空判断。