🚀 AI 一键生成 joinquant 策略代码

如何用 JoinQuant 编写双均线金叉死叉交易策略?(附完整代码)

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

问题描述

帮我写一个双均线金叉买入,死叉卖出的策略。

解决方案

这是一个经典的趋势跟踪策略。策略逻辑如下:

  1. 核心逻辑
    • 金叉(买入信号):当短期均线(如5日均线)由下向上穿过长期均线(如20日均线)时,视为上涨趋势确立,全仓买入。
    • 死叉(卖出信号):当短期均线由上向下穿过长期均线时,视为下跌趋势确立,清仓卖出。
  2. 标的:以平安银行(000001.XSHE)为例。
  3. 频率:按日回测。

以下是基于聚宽(JoinQuant)API 实现的完整策略代码:

# -*- coding: utf-8 -*-
# 导入聚宽函数库
import jqdata

def initialize(context):
    """
    初始化函数,设定基准、股票池、参数等
    """
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level('order', 'error')
    
    # 设定要操作的股票:平安银行
    g.security = '000001.XSHE'
    
    # 设定均线窗口
    g.short_window = 5   # 短期均线窗口
    g.long_window = 20   # 长期均线窗口
    
    # 设定交易费率:买入万分之三,卖出万分之三加千分之一印花税,最低5元
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 每天开盘时运行策略
    run_daily(trade_func, time='9:30')

def trade_func(context):
    """
    交易逻辑函数
    """
    security = g.security
    
    # 获取过去 g.long_window 天的收盘价数据
    # 注意:为了计算长期均线,我们需要获取足够长的数据
    # include_now=True 表示包含当前bar的数据(回测中如果是日频,开盘时取不到当日收盘价,通常取前一日数据计算信号)
    # 这里我们使用 attribute_history 获取过去的数据(不包含今天,避免未来函数)
    hist_data = attribute_history(security, g.long_window, '1d', ['close'])
    
    # 如果数据长度不足(例如刚上市的股票),则跳过
    if len(hist_data) < g.long_window:
        return
    
    # 计算短期均线 (MA5)
    # 取最后 short_window 天的数据求平均
    ma_short = hist_data['close'][-g.short_window:].mean()
    
    # 计算长期均线 (MA20)
    # 取所有 long_window 天的数据求平均
    ma_long = hist_data['close'].mean()
    
    # 获取当前持仓数量
    current_position = context.portfolio.positions[security].total_amount
    # 获取当前可用资金
    available_cash = context.portfolio.available_cash
    
    # 交易信号判断
    
    # 1. 金叉买入:短期均线 > 长期均线 且 当前无持仓
    if ma_short > ma_long and current_position == 0:
        # 全仓买入
        order_value(security, available_cash)
        log.info("金叉出现 (MA5:%.2f > MA20:%.2f),买入 %s" % (ma_short, ma_long, security))
        
    # 2. 死叉卖出:短期均线 < 长期均线 且 当前有持仓
    elif ma_short < ma_long and current_position > 0:
        # 清仓卖出
        order_target(security, 0)
        log.info("死叉出现 (MA5:%.2f < MA20:%.2f),卖出 %s" % (ma_short, ma_long, security))

    # 记录均线值,方便在回测图表中查看
    record(MA_Short=ma_short, MA_Long=ma_long)

代码要点解析:

  1. initialize 函数

    • 设置了 use_real_priceTrue,这是聚宽回测的推荐设置,确保使用真实复权价格。
    • 定义了全局变量 g.short_windowg.long_window,方便后续调整参数(例如改为 10日和60日)。
    • 使用 run_daily 指定每天 9:30 开盘时执行交易逻辑。
  2. 数据获取 (attribute_history)

    • 使用 attribute_history 获取过去 g.long_window 天的历史收盘价。
    • 注意:在日级回测中,9:30 调用的 attribute_history 获取的是截止到昨天收盘的数据。这意味着我们是利用昨天的均线形态来决定今天的开盘操作,这是一种常见的避免“未来函数”的做法。
  3. 均线计算

    • 利用 Pandas 的切片功能 [-g.short_window:] 截取最近的数据来计算短期均值。
    • 利用 .mean() 方法快速计算平均值。
  4. 交易执行

    • order_value(security, cash):按金额下单,这里传入 available_cash 实现全仓买入。
    • order_target(security, 0):调整持仓到目标数量,传入 0 即为清仓卖出。
  5. record 函数

    • 将计算出的 MA 值记录下来,回测结束后,你可以在收益曲线图中看到这两条均线的走势,方便验证策略逻辑。