问题描述
解决方案
KST(Know Sure Thing)确然指标是由马丁·普林(Martin Pring)发明的一种动量震荡指标。它本质上是四个不同周期的变化率(ROC)的加权移动平均值的总和。
以下是在 QMT 平台中实现 KST 指标的完整 Python 代码。该策略计算 KST 线及其信号线,并将其绘制在副图上。
QMT KST 指标策略代码
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
"""
初始化函数,设置KST指标的参数
"""
# KST 标准参数设置
# ROC 的四个周期
ContextInfo.roc_p1 = 10
ContextInfo.roc_p2 = 15
ContextInfo.roc_p3 = 20
ContextInfo.roc_p4 = 30
# ROC 移动平均的四个周期
ContextInfo.sma_p1 = 10
ContextInfo.sma_p2 = 10
ContextInfo.sma_p3 = 10
ContextInfo.sma_p4 = 15
# KST 信号线的周期
ContextInfo.sig_p = 9
# 权重设置 (通常为 1, 2, 3, 4)
ContextInfo.w1 = 1
ContextInfo.w2 = 2
ContextInfo.w3 = 3
ContextInfo.w4 = 4
def handlebar(ContextInfo):
"""
K线周期回调函数,计算并绘制KST
"""
# 获取当前主图的股票代码和市场
stock_code = ContextInfo.stockcode + '.' + ContextInfo.market
# 获取足够的历史数据以确保计算准确
# 需要的数据长度至少为:最大ROC周期 + 最大SMA周期 + 信号线周期 + 缓冲
# 30 + 15 + 9 = 54,这里取 150 根以确保稳定
count = 150
# 使用 get_market_data_ex 获取历史收盘价
# 注意:period 使用 ContextInfo.period 跟随主图周期
data_dict = ContextInfo.get_market_data_ex(
['close'],
[stock_code],
period=ContextInfo.period,
count=count,
dividend_type='follow',
fill_data=True
)
if stock_code not in data_dict:
return
df = data_dict[stock_code]
if df.empty or len(df) < count // 2:
return
# 提取收盘价序列
close = df['close']
# 1. 计算四个周期的 ROC (Rate of Change)
# ROC = (当前价格 - N天前价格) / N天前价格 * 100
roc1 = close.pct_change(periods=ContextInfo.roc_p1) * 100
roc2 = close.pct_change(periods=ContextInfo.roc_p2) * 100
roc3 = close.pct_change(periods=ContextInfo.roc_p3) * 100
roc4 = close.pct_change(periods=ContextInfo.roc_p4) * 100
# 2. 计算 ROC 的移动平均 (SMA)
rc1 = roc1.rolling(window=ContextInfo.sma_p1).mean()
rc2 = roc2.rolling(window=ContextInfo.sma_p2).mean()
rc3 = roc3.rolling(window=ContextInfo.sma_p3).mean()
rc4 = roc4.rolling(window=ContextInfo.sma_p4).mean()
# 3. 计算 KST 主线 (加权求和)
kst = (rc1 * ContextInfo.w1) + \
(rc2 * ContextInfo.w2) + \
(rc3 * ContextInfo.w3) + \
(rc4 * ContextInfo.w4)
# 4. 计算 KST 信号线 (KST 的 SMA)
signal = kst.rolling(window=ContextInfo.sig_p).mean()
# 获取当前 K 线的数值
current_kst = kst.iloc[-1]
current_signal = signal.iloc[-1]
# 5. 绘制指标
# 注意:index=-1 表示在当前最新的 K 线位置绘制
# limit='noaxis' 表示不影响主图坐标轴(即在副图显示,或者数值不干扰主图K线显示范围)
# 如果要在副图独立显示,请在 QMT 界面将模型位置设置为“副图”
# 绘制 KST 线 (黄色)
ContextInfo.paint("KST", current_kst, -1, 0, "yellow", "noaxis")
# 绘制 Signal 线 (白色)
ContextInfo.paint("Signal", current_signal, -1, 0, "white", "noaxis")
# 绘制零轴参考线 (可选)
ContextInfo.paint("Zero", 0, -1, 0, "gray", "noaxis")
# 简单的交易逻辑示例(金叉死叉提示)
# 获取上一根 K 线的数值用于判断交叉
if len(kst) > 1:
prev_kst = kst.iloc[-2]
prev_signal = signal.iloc[-2]
# 金叉:KST 上穿 Signal
if prev_kst < prev_signal and current_kst > current_signal:
ContextInfo.draw_text(True, current_kst, "金叉")
# 死叉:KST 下穿 Signal
if prev_kst > prev_signal and current_kst < current_signal:
ContextInfo.draw_text(True, current_kst, "死叉")
代码说明
-
参数设置 (
init):- KST 指标由四个 ROC 周期组成,默认为 10, 15, 20, 30。
- 每个 ROC 对应的平滑周期默认为 10, 10, 10, 15。
- 权重默认为 1, 2, 3, 4(周期越长,权重越大)。
- 信号线周期默认为 9。
-
数据获取 (
get_market_data_ex):- 使用
get_market_data_ex获取历史收盘价。 count=150:为了计算长周期的 ROC 和多次平滑,需要获取足够的历史数据。
- 使用
-
计算逻辑:
- 利用 Pandas 的
pct_change计算变化率(ROC)。 - 利用
rolling().mean()计算简单移动平均(SMA)。 - 按照公式
KST = RC1*1 + RC2*2 + RC3*3 + RC4*4进行加权求和。
- 利用 Pandas 的
-
绘图 (
paint):- 使用
ContextInfo.paint将 KST 线和 Signal 线绘制出来。 - 建议在 QMT 策略编辑器中,将该策略的**“位置”设置为“副图”**,以便更清晰地观察指标走势。
- 使用
Q&A
Q: 如何在 QMT 中将此指标显示在副图?
A: 在 QMT 的策略编辑器界面,点击右侧的“基本信息”,找到“位置”选项,将其从“主图”或“主图叠加”更改为**“副图”**。
Q: KST 指标的用法是什么?
A: KST 主要用于识别趋势的反转。
- 金叉:KST 线从下向上穿过 Signal 线,通常视为买入信号。
- 死叉:KST 线从上向下穿过 Signal 线,通常视为卖出信号。
- 零轴:KST 在零轴上方表示多头动能占优,下方表示空头动能占优。
Q: 为什么代码第一行要加 # -*- coding: gbk -*-?
A: QMT 的 Python 环境默认编码通常为 GBK。为了防止中文字符(如注释或 draw_text 中的文字)出现乱码或导致报错,必须在文件头部声明编码格式。