🚀 AI 一键生成 qmt 策略代码

如何在 QMT 平台用 Python 实现双均线金叉死叉策略?

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

问题描述

请帮我写一个双均线交叉策略,当短期均线上穿长期均线时买入,下穿时卖出。

解决方案

这是一个基于 QMT 平台的双均线交叉(金叉买入,死叉卖出)策略。

策略逻辑

  1. 短期均线(Short MA):例如 5 日均线。
  2. 长期均线(Long MA):例如 20 日均线。
  3. 买入信号(金叉):当短期均线上穿长期均线时,全仓买入。
  4. 卖出信号(死叉):当短期均线下穿长期均线时,清仓卖出。

代码实现

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

def init(ContextInfo):
    """
    初始化函数,设定策略参数和变量
    """
    # 策略参数设置
    ContextInfo.short_period = 5   # 短期均线周期
    ContextInfo.long_period = 20   # 长期均线周期
    ContextInfo.account_id = 'YOUR_ACCOUNT_ID' # 【重要】请在此处替换您的资金账号
    ContextInfo.account_type = 'STOCK' # 账号类型:'STOCK'股票, 'FUTURE'期货
    
    # 设定股票池(这里以浦发银行为例,实际使用时可在界面设置或此处修改)
    ContextInfo.set_universe(['600000.SH']) 
    
    # 费率设置(回测用,实盘无效)
    ContextInfo.set_commission(0.0003) # 手续费万三
    ContextInfo.set_slippage(1, 0.002) # 滑点 0.002元

def handlebar(ContextInfo):
    """
    K线周期运行函数,每根K线执行一次
    """
    # 获取当前正在运行的股票代码
    stock_code = ContextInfo.stockcode 
    
    # 获取当前K线的索引位置
    index = ContextInfo.barpos
    
    # 如果当前K线数量不足以计算长期均线,则直接返回
    if index < ContextInfo.long_period:
        return

    # 获取历史行情数据
    # 取过去 long_period + 2 根K线的数据,保证有足够数据计算均线和判断交叉
    # dividend_type='front' 表示使用前复权数据,防止分红除权影响均线形态
    data = ContextInfo.get_market_data(
        ['close'], 
        stock_code=[stock_code], 
        count=ContextInfo.long_period + 5, 
        dividend_type='front'
    )
    
    # 如果数据获取失败或为空,直接返回
    if data is None or data.empty:
        return

    # 提取收盘价序列 (Series格式)
    close_prices = data['close']

    # 计算均线
    ma_short = close_prices.rolling(window=ContextInfo.short_period).mean()
    ma_long = close_prices.rolling(window=ContextInfo.long_period).mean()
    
    # 获取最近两个时间点的均线值
    # -1 代表当前K线的值,-2 代表上一根K线的值
    # 注意:在回测中,-1是当前回测到的时间点;在实盘中,-1是最新的一根K线
    ma_short_curr = ma_short.iloc[-1]
    ma_short_prev = ma_short.iloc[-2]
    ma_long_curr = ma_long.iloc[-1]
    ma_long_prev = ma_long.iloc[-2]

    # 检查是否产生信号
    # 金叉:上根K线短均线 < 长均线,且 当前K线短均线 > 长均线
    golden_cross = (ma_short_prev < ma_long_prev) and (ma_short_curr > ma_long_curr)
    
    # 死叉:上根K线短均线 > 长均线,且 当前K线短均线 < 长均线
    death_cross = (ma_short_prev > ma_long_prev) and (ma_short_curr < ma_long_curr)

    # 执行交易逻辑
    # 使用 order_target_percent 接口,它会自动计算需要买卖的数量
    # 1.0 代表调整仓位到 100%(全仓),0.0 代表调整仓位到 0%(清仓)
    
    if golden_cross:
        print(f"时间: {ContextInfo.get_bar_timetag(index)} | 信号: 金叉买入 | {stock_code}")
        # 全仓买入
        order_target_percent(stock_code, 1.0, ContextInfo, ContextInfo.account_id)
        
    elif death_cross:
        print(f"时间: {ContextInfo.get_bar_timetag(index)} | 信号: 死叉卖出 | {stock_code}")
        # 清仓卖出
        order_target_percent(stock_code, 0.0, ContextInfo, ContextInfo.account_id)

代码说明与注意事项

  1. 编码格式

    • 第一行 # -*- coding: gbk -*- 是必须的,QMT 的 Python 编辑器默认使用 GBK 编码,否则中文注释会乱码或报错。
  2. 账号设置

    • init 函数中,ContextInfo.account_id = 'YOUR_ACCOUNT_ID' 这一行必须修改为你实际的资金账号。
  3. 数据获取

    • 使用了 ContextInfo.get_market_data 获取历史收盘价。
    • 参数 dividend_type='front' 设置为前复权。在均线策略中,复权非常重要,否则分红派息导致的股价缺口会产生错误的死叉信号。
  4. 交易函数

    • 使用了 order_target_percent。这是一个非常方便的高级函数:
      • 当信号为买入时,传入 1.0,系统会自动计算当前可用资金能买多少股,并下单买入。
      • 当信号为卖出时,传入 0.0,系统会自动检查当前持仓,如果有持仓则全部卖出。
    • 如果你需要固定手数交易(例如每次买100股),可以使用 order_shares(stock_code, 100, ...)
  5. 回测与实盘

    • 此代码既可用于回测,也可用于实盘(需在界面选择“运行”模式)。
    • 在实盘模式下,handlebar 会随行情刷新。如果运行在日线周期,通常在收盘前或收盘后确认信号;如果运行在分钟线,则每根分钟线结束时确认信号。