🚀 AI 一键生成 joinquant 策略代码

如何在 JoinQuant 中对一篮子股票同时应用双均线金叉死叉策略?

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

问题描述

请编写一个对多只股票同时执行双均线金叉买入、死叉卖出策略的程序。

解决方案

这是一个基于聚宽(JoinQuant)平台的双均线(Dual Moving Average)策略代码。

策略逻辑说明

  1. 标的:选取了一组具有代表性的股票(如平安银行、万科A、贵州茅台、招商银行)作为股票池。
  2. 指标
    • 短期均线:5日均线(MA5)
    • 长期均线:20日均线(MA20)
  3. 交易信号
    • 金叉买入:当短期均线大于长期均线,且当前无持仓时,买入。
    • 死叉卖出:当短期均线小于长期均线,且当前有持仓时,卖出。
  4. 资金管理:采用等权重分配资金,即总资产除以股票池数量作为每只股票的目标持仓金额。

策略代码

# -*- 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')
    
    # 设定股票类每笔交易时的手续费
    # 买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # --- 策略参数设置 ---
    # 设定短期均线窗口
    g.short_window = 5
    # 设定长期均线窗口
    g.long_window = 20
    
    # 设定要操作的股票池 (这里示例选取了几个不同行业的龙头股)
    g.security_list = [
        '000001.XSHE', # 平安银行
        '000002.XSHE', # 万科A
        '600519.XSHG', # 贵州茅台
        '600036.XSHG'  # 招商银行
    ]
    
    # 每天开盘时运行策略
    run_daily(market_open, time='open')

def market_open(context):
    """
    每日交易逻辑
    """
    # 获取当前持仓的股票列表
    current_positions = context.portfolio.positions
    
    # 计算每只股票应该分配的资金 (总资产 / 股票池数量)
    # 这种方式是简单的等权重分配
    target_value_per_stock = context.portfolio.total_value / len(g.security_list)
    
    for security in g.security_list:
        # 获取股票过去 g.long_window 天的收盘价数据
        # 注意:在按天回测中,time='open'时获取的是昨天及以前的数据,避免未来函数
        hist_data = attribute_history(security, g.long_window, '1d', ['close'])
        
        # 如果数据长度不足(例如新股上市时间太短),则跳过
        if len(hist_data) < g.long_window:
            continue
            
        # 获取当前标的的信息(用于判断是否停牌)
        current_data = get_current_data()[security]
        if current_data.paused:
            continue
            
        # --- 计算均线 ---
        # 收盘价序列
        close_prices = hist_data['close']
        
        # 计算短期均线 (取最后 short_window 天的平均值)
        ma_short = close_prices[-g.short_window:].mean()
        
        # 计算长期均线 (取所有 long_window 天的平均值)
        ma_long = close_prices.mean()
        
        # --- 交易逻辑 ---
        
        # 获取该股票当前的持仓数量
        current_amount = context.portfolio.positions[security].total_amount
        
        # 1. 金叉:短期均线 > 长期均线
        if ma_short > ma_long:
            # 如果当前没有持仓,或者持仓价值远低于目标价值,则买入/加仓
            # 这里使用 order_target_value 自动调整仓位到目标金额
            if current_amount == 0:
                log.info("金叉买入: %s (MA5:%.2f, MA20:%.2f)" % (security, ma_short, ma_long))
                order_target_value(security, target_value_per_stock)
        
        # 2. 死叉:短期均线 < 长期均线
        elif ma_short < ma_long:
            # 如果当前有持仓,则清仓卖出
            if current_amount > 0:
                log.info("死叉卖出: %s (MA5:%.2f, MA20:%.2f)" % (security, ma_short, ma_long))
                order_target(security, 0)

代码关键点解析

  1. attribute_history: 这是获取历史数据的核心函数。在 run_daily(..., time='open') 模式下,它获取的是截止到昨天收盘的数据。这是为了在今天开盘时根据昨天的指标进行决策,避免使用今天的收盘价(未来数据)来决定今天的开盘交易。
  2. order_target_value: 这是一个非常实用的下单函数。它会根据当前股价自动计算需要买入或卖出多少股,使该股票的持仓市值达到你设定的 target_value_per_stock
  3. get_current_data: 用于检查股票是否停牌(paused),避免对停牌股票下单导致报错或无效订单。
  4. 资金管理: 代码中使用了 context.portfolio.total_value / len(g.security_list) 来计算每只股票的仓位。这意味着策略会尽量保持每只股票占用相同的资金比例。

如何使用

  1. 登录聚宽官网。
  2. 进入“我的策略” -> “新建策略”。
  3. 将上述代码复制粘贴到代码编辑区。
  4. 点击“编译运行”进行回测。

Q&A

Q: 如何修改均线的天数?
A: 修改 initialize 函数中的 g.short_window (短期) 和 g.long_window (长期) 变量的值即可。例如改为 10日和 60日均线。

Q: 如何更换股票池?
A: 修改 g.security_list 列表。你可以手动输入股票代码,也可以使用 get_index_stocks('000300.XSHG') 来获取沪深300的所有成分股(注意:如果股票池很大,回测速度会变慢)。

Q: 为什么使用 order_target_value 而不是 order
A: order 是按股数下单,而 order_target_value 是按目标市值下单。在多股票策略中,按市值分配资金(例如每只股票买1万元)比按股数分配(例如每只股票买100股)更能平衡风险,因为不同股票的单价差异很大。

Q: 策略是在盘中实时成交吗?
A: 本代码设置的是 run_daily(market_open, time='open'),意味着回测引擎会在每天开盘时(09:30)根据昨天的收盘数据计算信号,并以开盘价撮合成交。这是日线级别策略最常用的回测方式。