3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 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}")
获取数据 (get_market_data_ex):
ContextInfo.get_market_data_ex,因为它直接返回 {stock_code: DataFrame} 的字典结构,非常适合 Pandas 处理。count: 获取的数据长度必须大于你要计算的均线周期。例如计算 MA20,count 至少要设为 20,通常建议设得更大(如 100),以确保均线数据的连续性。计算均线 (rolling().mean()):
df['close']: 提取收盘价列(Series)。.rolling(window=N): Pandas 的核心函数,用于创建一个大小为 N 的滚动窗口。.mean(): 对窗口内的数据求平均值。df['MA5'])。数据访问:
df['MA5'].iloc[-1] 获取最新一根 K 线的均线值,或者 df['MA5'].iloc[-2] 获取上一根 K 线的值(常用于判断金叉死叉)。Q: 为什么计算出来的均线前几行是 NaN (Not a Number)?
A: 这是正常的。例如计算 5 日均线,前 4 天的数据不足以凑齐 5 个数据点来计算平均值,因此 Pandas 会填充为 NaN。如果需要处理,可以使用 df.dropna() 删除这些行,或者在逻辑判断时忽略它们。
Q: 如何计算加权移动平均线 (WMA) 或指数移动平均线 (EMA)?
A:
df['close'].ewm(span=N, adjust=False).mean()。apply 配合权重计算,或者直接调用 talib 库(QMT 内置了 TA_Lib)来计算,例如 talib.WMA。Q: get_market_data_ex 返回的数据包含哪些列?
A: 返回的 DataFrame 的列名取决于你在 fields 参数中传入的列表。通常包括 'open', 'high', 'low', 'close', 'volume', 'amount' 等。在计算均线时,通常只使用 'close' 列。