3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个关于在 QMT 平台进行可视化绘图和技术指标计算的需求。
在 QMT 的 Python API 中,我们无法直接修改主图原生 K 线(蜡烛图)的颜色属性(例如将某一根原本是红色的阳线强制改成黄色实体)。但是,我们可以通过以下方式达到视觉上的效果:
下面的代码将实现:
# -*- 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线导致显示混乱。
数据获取 (get_market_data_ex):
high, low, close 数据。count=100 确保有足够的数据来计算 EMA 和 MACD,使其数值准确。MACD 计算 (get_macd):
pandas 的 ewm 函数计算指数移动平均线,这是计算 MACD 的标准方法。金叉判断:
当前DIF > 当前DEA 且 前一根DIF <= 前一根DEA。绘图 (paint, draw_vertline, draw_icon):
paint 输出 DIF、DEA 和 MACD 柱子,方便您核对金叉位置。ContextInfo.draw_vertline(..., 'yellow'):在金叉当天的最高价和最低价之间画一条黄色直线。这在视觉上会把该 K 线的中间部分染黄。ContextInfo.draw_icon:在 K 线下方打一个标记,确保您不会错过信号。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) 即可。