🚀 AI 一键生成 qmt 策略代码

如何在 QMT 策略中根据自定义条件改变 K 线颜色?

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

问题描述

我想在上涨时把K线画成红色,下跌时画成绿色,并且在 MACD 金叉时画成黄色,该怎么实现?

解决方案

这是一个关于在 QMT 平台进行可视化绘图技术指标计算的需求。

实现思路

在 QMT 的 Python API 中,我们无法直接修改主图原生 K 线(蜡烛图)的颜色属性(例如将某一根原本是红色的阳线强制改成黄色实体)。但是,我们可以通过以下方式达到视觉上的效果:

  1. 上涨/下跌颜色:QMT 主图默认就是“红涨绿跌”(国内习惯),这部分无需额外代码,平台自带。
  2. MACD 金叉变黄:由于无法直接变色 K 线实体,我们可以采用以下两种替代方案之一来“高亮”显示金叉当天的 K 线:
    • 方案 A(推荐):在金叉当天的 K 线位置绘制一个黄色图标(如箭头或圆点)或者写上文字。
    • 方案 B:在金叉当天,沿着该 K 线的最高价和最低价画一条黄色的垂直线,覆盖在原 K 线上。

下面的代码将实现:

  1. 自动计算 MACD 指标(DIF, DEA)。
  2. 判断金叉条件(DIF 上穿 DEA)。
  3. 视觉实现
    • 在金叉位置绘制黄色垂直线(覆盖原 K 线高低点)。
    • 在金叉位置下方绘制黄色图标(增强提示)。
    • 在副图绘制 MACD 指标线供参考。

策略代码

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

def init(ContextInfo):
    # 设置默认测试标的(如果未在界面选择)
    ContextInfo.set_universe(['600000.SH'])
    
    # 定义MACD参数
    ContextInfo.short_len = 12
    ContextInfo.long_len = 26
    ContextInfo.mid_len = 9

def get_macd(close_series, short_len, long_len, mid_len):
    """
    计算MACD指标的辅助函数
    """
    # 计算短周期EMA
    ema_short = close_series.ewm(span=short_len, adjust=False).mean()
    # 计算长周期EMA
    ema_long = close_series.ewm(span=long_len, adjust=False).mean()
    
    # 计算DIF
    dif = ema_short - ema_long
    # 计算DEA
    dea = dif.ewm(span=mid_len, adjust=False).mean()
    # 计算MACD柱
    macd = (dif - dea) * 2
    
    return dif, dea, macd

def handlebar(ContextInfo):
    # 获取当前主图的品种代码
    stock_code = ContextInfo.stockcode + '.' + ContextInfo.market
    
    # 获取足够的历史数据用于计算MACD (取最近100根即可,保证计算稳定)
    # 注意:get_market_data_ex 返回的数据格式需要处理
    data_df = ContextInfo.get_market_data_ex(
        ['high', 'low', 'close'], 
        [stock_code], 
        period=ContextInfo.period, 
        count=100, 
        dividend_type=ContextInfo.dividend_type
    )
    
    # 数据校验,防止数据不足报错
    if stock_code not in data_df or data_df[stock_code].empty:
        return
        
    df = data_df[stock_code]
    
    # 计算 MACD
    dif, dea, macd = get_macd(df['close'], ContextInfo.short_len, ContextInfo.long_len, ContextInfo.mid_len)
    
    # 获取当前K线和上一根K线的索引位置
    # 在handlebar中,iloc[-1]是当前正在运行的K线,iloc[-2]是前一根
    if len(dif) < 2:
        return

    current_dif = dif.iloc[-1]
    current_dea = dea.iloc[-1]
    last_dif = dif.iloc[-2]
    last_dea = dea.iloc[-2]
    
    # --- 逻辑判断 ---
    
    # 1. 判断金叉:DIF 上穿 DEA (当前DIF>DEA 且 上一根DIF<=DEA)
    golden_cross = (current_dif > current_dea) and (last_dif <= last_dea)
    
    # 2. 获取当前K线的高低价,用于画线
    current_high = df['high'].iloc[-1]
    current_low = df['low'].iloc[-1]
    
    # --- 绘图部分 ---
    
    # 1. 在副图画出 MACD 指标 (方便对比)
    # limit='noaxis' 表示在主图画,不填或填其他值通常在副图
    # 这里我们不加 'noaxis',让它显示在副图区域
    ContextInfo.paint('DIF', current_dif, -1, 0, 'white')
    ContextInfo.paint('DEA', current_dea, -1, 0, 'yellow')
    # 画MACD柱状图,style=42为柱状线
    color_macd = 'red' if macd.iloc[-1] > 0 else 'green'
    ContextInfo.paint('MACD', macd.iloc[-1], -1, 42, color_macd)

    # 2. 实现 "金叉时画成黄色" 的视觉效果
    # 由于无法直接改变K线实体颜色,我们在主图(noaxis)绘制黄色标记
    
    if golden_cross:
        # 方法A: 在主图 K 线位置画一条黄色的垂直线,覆盖高低点,模拟黄色K线芯
        # draw_vertline(条件, 价格1, 价格2, 颜色)
        ContextInfo.draw_vertline(True, current_high, current_low, 'yellow')
        
        # 方法B: 在最低价下方画一个黄色图标 (图标类型1通常为圆点或箭头,视版本而定)
        # draw_icon(条件, 位置, 图标类型)
        ContextInfo.draw_icon(True, current_low * 0.99, 1)
        
        # 方法C: 在主图写字提示
        ContextInfo.draw_text(True, current_high * 1.01, '金叉')

    # 3. 上涨画红、下跌画绿
    # 说明:QMT主图默认就是红涨绿跌,无需额外代码。
    # 如果需要强制画线强调,可以使用 draw_vertline 配合 close > open 判断,
    # 但通常不需要这样做,因为会覆盖原生K线导致显示混乱。

代码说明

  1. 数据获取 (get_market_data_ex)

    • 我们获取了 high, low, close 数据。
    • count=100 确保有足够的数据来计算 EMA 和 MACD,使其数值准确。
  2. MACD 计算 (get_macd)

    • 使用了 pandasewm 函数计算指数移动平均线,这是计算 MACD 的标准方法。
  3. 金叉判断

    • 逻辑是:当前DIF > 当前DEA前一根DIF <= 前一根DEA
  4. 绘图 (paint, draw_vertline, draw_icon)

    • 副图:代码默认使用 paint 输出 DIF、DEA 和 MACD 柱子,方便您核对金叉位置。
    • 主图金叉高亮
      • ContextInfo.draw_vertline(..., 'yellow'):在金叉当天的最高价和最低价之间画一条黄色直线。这在视觉上会把该 K 线的中间部分染黄。
      • ContextInfo.draw_icon:在 K 线下方打一个标记,确保您不会错过信号。

如何使用

  1. 打开 QMT 客户端,进入【模型研究】或【策略编辑器】。
  2. 新建一个 Python 策略。
  3. 将上述代码完整复制进去。
  4. 点击【运行】或将策略加载到行情图上。
  5. 您会看到主图上发生金叉的位置出现了黄色标记和线条,副图显示了 MACD 指标。

Q&A

Q: 为什么不能直接把 K 线实体变成黄色?
A: QMT 的 Python API 主要用于量化计算和画辅助线(指标)。它没有提供类似 plot_candle(color=...) 这样直接重绘原生 K 线实体的函数。使用 draw_vertline(画垂直线)是实现“变色”效果最接近的替代方案。

Q: 代码中的 limit='noaxis' 是什么意思?
A: 在 paint 函数中,如果加上 limit='noaxis',指标线会画在主图(和 K 线在一起)。如果不加,指标线会画在副图(K 线图下方的区域)。本策略中,MACD 数据画在副图,而金叉的黄色标记画在主图。

Q: 如何调整 MACD 的参数?
A: 修改 init 函数中的 ContextInfo.short_len (默认12), ContextInfo.long_len (默认26), ContextInfo.mid_len (默认9) 即可。