🚀 AI 一键生成 qmt 策略代码

如何在 QMT 策略中利用 Pandas 进行高效的数据分析?

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

问题描述

获取到行情数据后,如何用 Pandas 计算移动平均线?

解决方案

在 QMT 中获取行情数据后,利用 Pandas 计算移动平均线(Moving Average, MA)是非常常见的操作。主要步骤包括:使用 ContextInfo.get_market_data_ex 获取 DataFrame 格式的数据,然后调用 Pandas 的 rolling().mean() 方法进行计算。

以下是完整的策略代码示例及详细说明。

策略代码示例

# -*- coding: gbk -*-
import pandas as pd

def init(ContextInfo):
    # 1. 设置股票池,这里以浦发银行为例
    ContextInfo.set_universe(['600000.SH'])
    
    # 2. 定义需要计算的均线周期,例如 5日均线 和 20日均线
    ContextInfo.ma_short = 5
    ContextInfo.ma_long = 20

def handlebar(ContextInfo):
    # 仅在最后一根K线处理,避免历史回测时重复打印大量日志(视需求而定)
    if not ContextInfo.is_last_bar():
        return

    # 获取当前主图周期
    period = ContextInfo.period
    stock_list = ContextInfo.get_universe()
    
    # 3. 获取历史行情数据
    # 注意:count 必须大于最大的均线周期,否则数据不足以计算
    # 这里取 100 根 K 线以确保有足够的数据计算 MA20
    data_dict = ContextInfo.get_market_data_ex(
        fields=['close'],      # 只需要收盘价
        stock_code=stock_list, 
        period=period, 
        count=100,             # 数据长度
        dividend_type='follow' # 复权方式跟随主图
    )

    for stock in stock_list:
        if stock in data_dict:
            # 获取该股票的 DataFrame
            df = data_dict[stock]
            
            # 4. 使用 Pandas 计算移动平均线
            # rolling(window=N): 创建一个 N 周期的滑动窗口
            # mean(): 计算窗口内的平均值
            df['MA5'] = df['close'].rolling(window=ContextInfo.ma_short).mean()
            df['MA20'] = df['close'].rolling(window=ContextInfo.ma_long).mean()
            
            # 5. 处理 NaN 值(可选)
            # 刚开始的 N-1 个数据因为窗口未满会产生 NaN,可以使用 dropna() 去除或 fillna() 填充
            # df.dropna(inplace=True) 

            # 打印结果验证
            print(f"====== {stock} 均线计算结果 (最后5行) ======")
            print(df.tail())
            
            # 获取最新的均线值
            last_ma5 = df['MA5'].iloc[-1]
            last_ma20 = df['MA20'].iloc[-1]
            print(f"最新 MA5: {last_ma5}, 最新 MA20: {last_ma20}")

关键步骤解析

  1. 获取数据 (get_market_data_ex):

    • 推荐使用 ContextInfo.get_market_data_ex,因为它直接返回 {stock_code: DataFrame} 的字典结构,非常适合 Pandas 处理。
    • 重要参数 count: 获取的数据长度必须大于你要计算的均线周期。例如计算 MA20,count 至少要设为 20,通常建议设得更大(如 100),以确保均线数据的连续性。
  2. 计算均线 (rolling().mean()):

    • df['close']: 提取收盘价列(Series)。
    • .rolling(window=N): Pandas 的核心函数,用于创建一个大小为 N 的滚动窗口。
    • .mean(): 对窗口内的数据求平均值。
    • 结果会自动对齐索引,赋值回 DataFrame 的新列(如 df['MA5'])。
  3. 数据访问:

    • 计算完成后,可以通过 df['MA5'].iloc[-1] 获取最新一根 K 线的均线值,或者 df['MA5'].iloc[-2] 获取上一根 K 线的值(常用于判断金叉死叉)。

常见问题 (Q&A)

Q: 为什么计算出来的均线前几行是 NaN (Not a Number)?
A: 这是正常的。例如计算 5 日均线,前 4 天的数据不足以凑齐 5 个数据点来计算平均值,因此 Pandas 会填充为 NaN。如果需要处理,可以使用 df.dropna() 删除这些行,或者在逻辑判断时忽略它们。

Q: 如何计算加权移动平均线 (WMA) 或指数移动平均线 (EMA)?
A:

  • EMA: Pandas 提供了直接的方法 df['close'].ewm(span=N, adjust=False).mean()
  • WMA: Pandas 没有直接的 WMA 函数,通常需要自定义函数或使用 apply 配合权重计算,或者直接调用 talib 库(QMT 内置了 TA_Lib)来计算,例如 talib.WMA

Q: get_market_data_ex 返回的数据包含哪些列?
A: 返回的 DataFrame 的列名取决于你在 fields 参数中传入的列表。通常包括 'open', 'high', 'low', 'close', 'volume', 'amount' 等。在计算均线时,通常只使用 'close' 列。