🚀 AI 一键生成 qmt 策略代码

如何在 K 线图上用图标或文字清晰标记买卖信号?(QMT 绘图函数进阶)

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

问题描述

请教一下,怎样才能在K线图上出现买卖信号的时候,自动画一个向上的箭头或者写一个“买”字?

解决方案

在 QMT (Quantitative Trading Platform) 中,要在 K 线图上绘制文字或标记,主要使用 ContextInfo.draw_text 函数。

核心函数说明

ContextInfo.draw_text(condition, position, text)

  • condition (bool): 绘图条件。当该值为 True 时,才会在当前 K 线位置绘制。
  • position (number): 绘制在 Y 轴(价格轴)上的位置。通常买入信号画在最低价下方,卖出信号画在最高价上方。
  • text (string): 要显示的文本内容。可以使用中文(如“买”),也可以使用符号(如“↑”)。

实现思路

  1. 获取数据:使用 get_market_data_ex 获取当前主图品种的历史 K 线数据。
  2. 计算指标:计算均线或其他指标(本例使用 MA5 上穿 MA10 作为金叉买入信号)。
  3. 判断信号:判断当前 K 线是否满足买卖条件。
  4. 执行绘图
    • 如果是买入信号,在 low * 0.99(最低价下方一点)的位置画“↑买”。
    • 如果是卖出信号,在 high * 1.01(最高价上方一点)的位置画“↓卖”。
  5. 辅助绘图:使用 paint 函数画出均线,以便直观验证信号。

完整策略代码

以下代码实现了一个双均线策略(MA5 和 MA10),当金叉时在 K 线下方标记“↑买”,死叉时在 K 线上方标记“↓卖”。

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

def init(ContextInfo):
    # 设置当前图表的股票池(这里仅作演示,实际运行时会跟随主图代码)
    ContextInfo.set_universe([ContextInfo.stockcode + '.' + ContextInfo.market])

def handlebar(ContextInfo):
    # 获取当前主图的品种代码
    stock_code = ContextInfo.stockcode + '.' + ContextInfo.market
    
    # 获取当前 K 线的位置索引
    index = ContextInfo.barpos
    
    # 获取历史行情数据,用于计算均线
    # 获取过去 20 根 K 线的数据足以计算 MA10
    # 注意:get_market_data_ex 返回的是字典 {code: dataframe}
    data_map = ContextInfo.get_market_data_ex(
        ['close', 'high', 'low'], 
        [stock_code], 
        period=ContextInfo.period, 
        count=20, 
        dividend_type=ContextInfo.dividend_type,
        subscribe=True
    )
    
    if stock_code not in data_map:
        return

    df = data_map[stock_code]
    
    # 如果数据不足以计算 MA10,则退出
    if len(df) < 11:
        return

    # 提取价格序列
    close_prices = df['close'].values
    high_prices = df['high'].values
    low_prices = df['low'].values
    
    # 计算 MA5 和 MA10
    # 使用 pandas 的 rolling 函数计算移动平均
    ma5_series = pd.Series(close_prices).rolling(window=5).mean().values
    ma10_series = pd.Series(close_prices).rolling(window=10).mean().values
    
    # 获取当前 K 线(最新)的均线值和上一根 K 线的均线值
    # -1 代表当前最新值,-2 代表上一根 K 线的值
    curr_ma5 = ma5_series[-1]
    curr_ma10 = ma10_series[-1]
    prev_ma5 = ma5_series[-2]
    prev_ma10 = ma10_series[-2]
    
    # 检查数据有效性(避免 NaN)
    if np.isnan(curr_ma5) or np.isnan(curr_ma10) or np.isnan(prev_ma5) or np.isnan(prev_ma10):
        return

    # --- 信号判断逻辑 ---
    
    # 金叉:上一根 MA5 < MA10,且当前 MA5 > MA10
    buy_condition = (prev_ma5 < prev_ma10) and (curr_ma5 > curr_ma10)
    
    # 死叉:上一根 MA5 > MA10,且当前 MA5 < MA10
    sell_condition = (prev_ma5 > prev_ma10) and (curr_ma5 < curr_ma10)
    
    # --- 绘图逻辑 ---
    
    # 1. 绘制均线 (方便观察)
    # paint(name, value, index, line_style, color)
    ContextInfo.paint('MA5', curr_ma5, -1, 0, 'red')
    ContextInfo.paint('MA10', curr_ma10, -1, 0, 'green')
    
    # 2. 绘制买卖信号文字
    # draw_text(condition, position, text)
    
    if buy_condition:
        # 在最低价下方 1% 的位置写 "↑买"
        draw_pos = low_prices[-1] * 0.99
        ContextInfo.draw_text(True, draw_pos, '↑买')
        
    if sell_condition:
        # 在最高价上方 1% 的位置写 "↓卖"
        draw_pos = high_prices[-1] * 1.01
        ContextInfo.draw_text(True, draw_pos, '↓卖')

常见问题解答 (Q&A)

Q: 为什么我运行后图上没有显示文字?
A: 请检查以下几点:

  1. 确保策略已经点击“编译”并保存。
  2. 确保策略是运行在“主图”或“主图叠加”模式,而不是副图。如果是副图,文字可能会因为坐标轴范围不同而显示在视野外。
  3. 确保当前 K 线确实触发了金叉或死叉逻辑。

Q: 可以改变文字的颜色吗?
A: ContextInfo.draw_text 函数本身在标准文档中不支持直接设置颜色参数,它通常跟随系统默认文本颜色或指标颜色设置。如果需要不同颜色的线条,可以使用 ContextInfo.paint 并指定颜色参数(如 'red', 'green')。

Q: 如何调整文字与 K 线的距离?
A: 代码中的 0.991.01 是距离系数。

  • 如果想让文字离 K 线更远,可以将买入系数调小(如 0.98),卖出系数调大(如 1.02)。
  • 如果想让文字离 K 线更近,可以将买入系数调大(如 0.995),卖出系数调小(如 1.005)。