问题描述
解决方案
在 QMT 平台的 Python 策略中,要在图表上根据条件显示文字或图标,主要使用 ContextInfo 对象提供的绘图函数。
以下是两个核心函数的说明及完整的代码示例。
核心函数说明
1. 显示文字:ContextInfo.draw_text
该函数用于在满足特定条件时,在图表的指定价格位置显示一段文本。
- 语法:
ContextInfo.draw_text(condition, position, text) - 参数:
condition(bool):布尔值条件。只有当为True时才显示文字。position(number):显示文字的纵坐标位置(通常使用当根 K 线的最高价high或最低价low)。text(string):要显示的字符串内容(如 "买入"、"卖出")。
2. 显示图标:ContextInfo.draw_icon
该函数用于在满足特定条件时,在图表的指定位置绘制一个小图标。
- 语法:
ContextInfo.draw_icon(cond, height, type) - 参数:
cond(bool):布尔值条件。只有当为True时才绘制图标。height(number):显示图标的纵坐标位置。type(number):图标的类型编号(例如 0 代表矩形,1 代表椭圆,具体样式取决于客户端版本)。
完整策略代码示例
以下代码展示了一个简单的双均线策略(5日均线上穿10日均线买入,下穿卖出)。代码会在产生买入信号时在 K 线最低价下方显示“买入”文字和图标,在产生卖出信号时在最高价上方显示“卖出”文字和图标。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
# 设置股票池,这里以浦发银行为例
ContextInfo.set_universe(['600000.SH'])
# 设置策略运行周期
ContextInfo.period = '1d'
def handlebar(ContextInfo):
# 获取当前主图的品种代码
code = ContextInfo.stockcode
# 获取历史行情数据 (取最近20根K线以计算均线)
# 注意:get_market_data 返回的数据类型取决于参数,这里获取单个股票数据返回 DataFrame
data = ContextInfo.get_market_data(
['close', 'high', 'low'],
stock_code=[code],
count=20,
period=ContextInfo.period,
dividend_type='follow'
)
# 如果数据不足,直接返回
if data is None or len(data) < 15:
return
# 提取收盘价、最高价、最低价序列
close_series = data['close']
high_series = data['high']
low_series = data['low']
# 计算 5日 和 10日 简单移动平均线
ma5 = close_series.rolling(5).mean()
ma10 = close_series.rolling(10).mean()
# 获取当前 K 线(最新一根)和上一根 K 线的数据
# iloc[-1] 代表当前最新值,iloc[-2] 代表上一根 K 线的值
curr_ma5 = ma5.iloc[-1]
last_ma5 = ma5.iloc[-2]
curr_ma10 = ma10.iloc[-1]
last_ma10 = ma10.iloc[-2]
# 获取当前 K 线的高低价,用于定位文字和图标的显示高度
curr_high = high_series.iloc[-1]
curr_low = low_series.iloc[-1]
# --- 定义交易信号条件 ---
# 金叉条件:上一根 MA5 < MA10 且 当前 MA5 > MA10
buy_condition = (last_ma5 < last_ma10) and (curr_ma5 > curr_ma10)
# 死叉条件:上一根 MA5 > MA10 且 当前 MA5 < MA10
sell_condition = (last_ma5 > last_ma10) and (curr_ma5 < curr_ma10)
# --- 绘图操作 ---
# 1. 绘制文字
# 如果满足买入条件,在最低价位置显示 "买入"
ContextInfo.draw_text(buy_condition, curr_low, '买入')
# 如果满足卖出条件,在最高价位置显示 "卖出"
ContextInfo.draw_text(sell_condition, curr_high, '卖出')
# 2. 绘制图标
# 如果满足买入条件,在最低价位置画一个图标 (type=1 通常为椭圆或圆点)
ContextInfo.draw_icon(buy_condition, curr_low, 1)
# 如果满足卖出条件,在最高价位置画一个图标
ContextInfo.draw_icon(sell_condition, curr_high, 1)
# 3. 调试输出 (可选)
if buy_condition:
print(f"{ContextInfo.barpos} - 触发买入信号")
if sell_condition:
print(f"{ContextInfo.barpos} - 触发卖出信号")
注意事项
- 运行模式:绘图函数在“回测模式”和“模型运行(界面主图叠加)”模式下均有效。如果是在后台纯交易模式下运行,绘图函数不会产生视觉效果。
- 坐标位置:
position参数决定了文字/图标在 Y 轴(价格轴)上的高度。为了避免文字遮挡 K 线,买入信号通常设置在low(最低价)或low * 0.99处,卖出信号通常设置在high(最高价)或high * 1.01处。 - 条件判断:
draw_text和draw_icon是逐 K 线执行的。condition参数必须是一个布尔值(True/False),代表当前这根 K 线是否满足显示条件。
Q&A
Q: draw_text 显示的文字颜色可以修改吗?
A: draw_text 函数本身没有直接的颜色参数。它通常跟随系统默认设置或指标线的颜色设置。如果需要更复杂的绘图(如指定颜色的线条或柱状图),可以使用 ContextInfo.paint() 函数,该函数支持 color 参数(如 'red', 'green', 'yellow' 等)。
Q: 为什么我的图标显示在 K 线实体的中间,挡住了 K 线?
A: 这是因为传入的 position 或 height 参数使用了收盘价 (close) 或开盘价 (open)。建议在买入信号时使用最低价 (low),在卖出信号时使用最高价 (high),或者在此基础上稍微加减一点数值(例如 low - 0.05),使图标与 K 线保持距离。
Q: draw_icon 的 type 参数除了 0 和 1 还有哪些?
A: 根据 QMT 基础文档,主要支持 0(矩形)和 1(椭圆)。部分券商定制版 QMT 可能支持更多图标索引(如箭头),但这取决于具体的客户端版本实现。建议优先使用 draw_text 直接显示文字,表意更清晰。