🚀 AI 一键生成 qmt 策略代码

QMT 策略图表:使用 `draw_icon` 标记买卖信号图标

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

问题描述

怎么在图表上画出买卖信号的图标?

解决方案

在 QMT 中,要在图表上绘制买卖信号的图标,主要使用 ContextInfo.draw_icon() 函数。为了使信号更加直观,通常还会配合 ContextInfo.draw_text() 函数来标记文字(如“买”、“卖”)。

核心函数说明

  1. ContextInfo.draw_icon(cond, height, type)

    • cond: 布尔值 (True/False)。当条件为 True 时绘制图标。
    • height: 图标绘制在图表上的 Y 轴位置(通常是价格,如最高价、最低价或收盘价)。
    • type: 图标的类型索引。根据文档,0 代表矩形,1 代表椭圆。
  2. ContextInfo.draw_text(condition, position, text)

    • condition: 布尔值。当条件为 True 时绘制文字。
    • position: 文字绘制的 Y 轴位置。
    • text: 要显示的字符串内容(如 "Buy", "Sell")。

完整代码示例

以下是一个完整的策略代码示例。该策略基于 双均线交叉(金叉买入,死叉卖出) 的逻辑,在产生信号的 K 线位置画出图标和文字。

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

def init(ContextInfo):
    # 设置均线周期
    ContextInfo.short_len = 5
    ContextInfo.long_len = 10
    
    # 设置图表上显示的指标线(可选,方便肉眼观察交叉)
    # 注意:paint函数在handlebar中调用,这里仅做逻辑说明

def handlebar(ContextInfo):
    # 获取当前主图的股票代码
    stock_code = ContextInfo.stockcode
    
    # 获取足够的历史数据来计算均线
    # 我们需要获取收盘价、最高价(High)和最低价(Low)
    # High和Low用于决定图标画在K线的上方还是下方,避免遮挡K线
    count = ContextInfo.long_len + 5
    data_map = ContextInfo.get_market_data_ex(
        ['close', 'high', 'low'], 
        [stock_code], 
        period=ContextInfo.period, 
        count=count,
        subscribe=True
    )
    
    if stock_code not in data_map:
        return
        
    df = data_map[stock_code]
    
    # 数据长度不足时不计算
    if len(df) < ContextInfo.long_len + 1:
        return
        
    # 提取价格序列
    close_prices = df['close']
    high_prices = df['high']
    low_prices = df['low']
    
    # 计算短期和长期均线
    ma_short = close_prices.rolling(window=ContextInfo.short_len).mean()
    ma_long = close_prices.rolling(window=ContextInfo.long_len).mean()
    
    # 获取当前K线和上一根K线的均线值(用于判断交叉)
    # iloc[-1] 代表当前最新的一根K线
    curr_short = ma_short.iloc[-1]
    curr_long = ma_long.iloc[-1]
    prev_short = ma_short.iloc[-2]
    prev_long = ma_long.iloc[-2]
    
    # 获取当前K线的最高价和最低价,用于定位图标
    curr_high = high_prices.iloc[-1]
    curr_low = low_prices.iloc[-1]
    
    # --- 定义信号逻辑 ---
    
    # 金叉(买入信号):短期均线上穿长期均线
    buy_condition = (prev_short < prev_long) and (curr_short > curr_long)
    
    # 死叉(卖出信号):短期均线下穿长期均线
    sell_condition = (prev_short > prev_long) and (curr_short < curr_long)
    
    # --- 绘图部分 ---
    
    # 1. 绘制买入信号
    # 位置:画在最低价下方一点,避免重叠
    buy_pos = curr_low * 0.99 
    # draw_icon: 参数分别为 条件, 高度, 图标类型(1为椭圆)
    ContextInfo.draw_icon(buy_condition, buy_pos, 1)
    # draw_text: 配合文字更清晰
    if buy_condition:
        ContextInfo.draw_text(True, buy_pos, '买入')
    
    # 2. 绘制卖出信号
    # 位置:画在最高价上方一点
    sell_pos = curr_high * 1.01
    # draw_icon: 参数分别为 条件, 高度, 图标类型(0为矩形)
    ContextInfo.draw_icon(sell_condition, sell_pos, 0)
    if sell_condition:
        ContextInfo.draw_text(True, sell_pos, '卖出')
        
    # 3. (可选) 在图表上画出均线,方便核对
    ContextInfo.paint('MA_Short', curr_short, -1, 0, 'yellow')
    ContextInfo.paint('MA_Long', curr_long, -1, 0, 'blue')

代码详解

  1. 数据获取:使用 get_market_data_ex 获取 close, high, low 数据。highlow 用于计算图标绘制的最佳位置(买入画在 K 线下方,卖出画在 K 线 上方),这样视觉效果更好。
  2. 信号判断:通过比较当前 K 线和上一根 K 线的均线位置关系,判断是否发生“金叉”或“死叉”。
  3. draw_icon
    • buy_condition 为 True 时,在 buy_pos 位置画一个椭圆(类型 1)。
    • sell_condition 为 True 时,在 sell_pos 位置画一个矩形(类型 0)。
  4. draw_text:仅画图标可能不够直观,因此在相同位置添加了“买入”或“卖出”的文字标记。

如何运行

  1. 打开 QMT 客户端,进入【模型研究】或【策略编辑器】。
  2. 新建一个 Python 策略。
  3. 将上述代码复制粘贴进去。
  4. 点击【运行】或将策略加载到图表上,你将在均线交叉的位置看到对应的图标和文字。

Q&A

Q: draw_icontype 参数除了 0 和 1 还有其他选择吗?
A: 根据官方文档,目前明确列出的只有 0(矩形)和 1(椭圆)。如果需要更丰富的视觉效果(如箭头),建议主要依赖 draw_text 使用文字符号(如 "↑", "↓")或者直接写明 "Buy"/"Sell"。

Q: 为什么图标有时候会遮挡 K 线?
A: 如果将 height 参数直接设置为 close(收盘价),图标就会画在 K 线中间。为了避免遮挡,建议买入信号画在 low * 0.99(最低价下方),卖出信号画在 high * 1.01(最高价上方)。

Q: 这个绘图函数在回测中能看到吗?
A: 可以。在回测模式下,QMT 会在回测结束后生成的图表上展示这些图标。在实盘/模拟盘的主图叠加模式下,也会实时刷新显示。