问题描述
解决方案
在 QMT (Quantitative Trading Platform) 的 Python API 中,无法直接修改原生 K 线(蜡烛图)的填充颜色。原生的 K 线颜色通常由客户端的系统设置决定(如红涨绿跌)。
但是,你可以通过 ContextInfo.paint() 函数在主图上绘制自定义颜色的线条或柱状线,从而达到“视觉上改变颜色”或“高亮特定 K 线”的效果。
实现原理
- 计算指标或条件:在
handlebar函数中判断当前 K 线是否满足特定条件(例如:收盘价大于均线)。 - 使用
paint绘图:- 如果满足条件,使用
ContextInfo.paint绘制一种颜色的数值。 - 如果不满足,绘制另一种颜色。
- 如果满足条件,使用
- 设置叠加位置:在策略编辑器中,必须将策略的**“位置”设置为“主图叠加”**,这样绘制的内容才会显示在 K 线图上。
代码示例
以下代码演示了如何根据条件改变显示的颜色:
- 条件:当收盘价 > 10日均线时,在收盘价位置绘制红色圆点/线;当收盘价 <= 10日均线时,绘制绿色圆点/线。
- 同时绘制黄色的 10 日均线作为参考。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
# 策略初始化,设置需要的股票池等(此处仅为演示绘图,不做具体交易设置)
pass
def handlebar(ContextInfo):
# 获取当前 K 线的位置索引
index = ContextInfo.barpos
# 获取当前主图的品种代码
stock_code = ContextInfo.stockcode + '.' + ContextInfo.market
# 获取足够计算 MA10 的历史数据 (取最近 11 条数据以确保计算)
# 使用 get_market_data_ex 获取数据,这是官方推荐的接口
# 注意:period 使用 'follow' 跟随主图周期,dividend_type 使用 'follow' 跟随主图复权
df = ContextInfo.get_market_data_ex(
fields=['close'],
stock_code=[stock_code],
period='follow',
count=20,
dividend_type='follow'
)
# 检查数据是否获取成功
if stock_code not in df or df[stock_code].empty:
return
# 获取收盘价序列
close_series = df[stock_code]['close']
# 确保数据量足够计算 MA10
if len(close_series) < 10:
return
# 计算 MA10 (10日移动平均线)
ma10 = close_series.rolling(window=10).mean().iloc[-1]
# 获取当前的收盘价
current_close = close_series.iloc[-1]
# --- 绘图逻辑 ---
# 1. 绘制 MA10 均线 (黄色,线型 0 代表曲线)
ContextInfo.paint('MA10', ma10, -1, 0, 'yellow')
# 2. 根据条件改变颜色
# 条件:如果收盘价 > MA10,显示红色;否则显示绿色
# 注意:这里我们绘制的是收盘价的位置
if current_close > ma10:
# 参数说明: paint(指标名称, 数值, 索引(-1为当前), 线型, 颜色)
# 线型 0: 曲线 (连接起来就是线)
# 线型 42: 柱状线 (看起来像一根立柱)
# 这里演示使用线型 0,但在视觉上会根据条件分段变色
ContextInfo.paint('ConditionColor', current_close, -1, 0, 'red')
else:
ContextInfo.paint('ConditionColor', current_close, -1, 0, 'green')
# 3. (可选) 另一种高亮方式:使用 draw_vertline 绘制垂直线背景
# 如果收盘价上穿 MA10 (当前大于,上一个小于),画一条垂直线提示
if len(close_series) >= 2:
prev_close = close_series.iloc[-2]
prev_ma10 = close_series.rolling(window=10).mean().iloc[-2]
# 金叉条件
is_gold_cross = (prev_close <= prev_ma10) and (current_close > ma10)
if is_gold_cross:
# 在当前位置画一条白色的垂直线,limit='noaxis' 表示不影响坐标轴缩放
ContextInfo.draw_vertline(True, 0, 0, 'white', 'noaxis')
关键函数说明
-
ContextInfo.paint(name, value, index, line_style, color, limit)- name: 指标名称,鼠标悬停在图表上时会显示。
- value: 要绘制的数值(通常是价格)。
- index:
-1表示在当前 K 线位置绘制。 - line_style:
0: 曲线(默认)。42: 柱状线(如果你想画类似成交量的柱子,可以用这个)。
- color: 颜色字符串,支持
'red','green','blue','yellow','white','cyan','magenta','brown'。
-
ContextInfo.draw_vertline(cond, number1, number2, color, limit)- 这是一个辅助函数,用于在满足条件时绘制贯穿上下的垂直线,非常适合用来标记买卖信号或状态改变的时刻。
如何查看效果
- 将上述代码复制到 QMT 的策略编辑器中。
- 在策略编辑器的右侧或基本信息设置中,找到 “位置” 选项。
- 将其设置为 “主图叠加” (Main Chart Overlay)。
- 点击 “运行” 或 “回测”。
- 你会看到主图上出现了一条黄色的均线,以及一条跟随收盘价变色的线(高于均线为红,低于均线为绿)。
常见问题
Q: 我可以直接把 K 线实体的填充颜色变了吗?
A: QMT Python API 目前不支持直接修改底层 K 线对象的属性(如 Bar.Color)。上述方法是通过在 K 线位置绘制新的图形元素来覆盖或陪衬,从而达到视觉提示的效果。
Q: 为什么我看不到画的线?
A: 请检查策略的“位置”设置是否为“主图叠加”。如果是“副图”,画的线会显示在 K 线图下方的独立窗口中,且数值坐标可能与股价不一致导致看起来是一条直线。