🚀 AI 一键生成 joinquant 策略代码

JoinQuant 量化策略实战:如何编写一个布林带通道突破交易策略?

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

问题描述

请帮我写一个价格突破布林带上轨就买入,跌破下轨就卖出的策略

解决方案

这是一个基于布林带(Bollinger Bands)的经典突破策略。

策略逻辑

  1. 计算布林带
    • 中轨:过去 N 天(通常为20天)的收盘价移动平均线。
    • 上轨:中轨 + K 倍(通常为2)标准差。
    • 下轨:中轨 - K 倍(通常为2)标准差。
  2. 买入信号:当当前价格突破上轨,且当前无持仓时,全仓买入。
  3. 卖出信号:当当前价格跌破下轨,且当前有持仓时,清仓卖出。

以下是可以在聚宽(JoinQuant)平台上直接运行的策略代码:

# -*- coding: utf-8 -*-
import numpy as np

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'
    # 布林带的时间窗口 N
    g.n = 20
    # 标准差倍数 K
    g.k = 2
    
    # 设置交易运行频率,这里设置为每天运行一次
    run_daily(trade_func, time='every_bar')

def trade_func(context):
    """
    交易函数,计算指标并执行交易
    """
    security = g.security
    
    # 获取过去 g.n 天的收盘价数据
    # 注意:在日级回测中,'1d'获取的是不包含当天的过去数据
    hist_data = attribute_history(security, g.n, '1d', ['close'], skip_paused=True)
    
    # 如果数据不足 N 天,无法计算均线,直接返回
    if len(hist_data) < g.n:
        return

    # 提取收盘价数组
    close_prices = hist_data['close'].values
    
    # --- 计算布林带 ---
    # 1. 计算中轨(均线)
    mid_line = np.mean(close_prices)
    # 2. 计算标准差 (ddof=1 表示样本标准差)
    std = np.std(close_prices, ddof=1)
    # 3. 计算上轨
    upper_band = mid_line + g.k * std
    # 4. 计算下轨
    lower_band = mid_line - g.k * std
    
    # --- 获取当前数据 ---
    current_data = get_current_data()
    # 如果停牌则跳过
    if current_data[security].paused:
        return
        
    # 获取当前最新价格
    current_price = current_data[security].last_price
    
    # 获取当前可用资金
    cash = context.portfolio.available_cash
    # 获取当前持仓数量
    position = context.portfolio.positions[security].closeable_amount
    
    # --- 交易逻辑 ---
    
    # 信号1:价格突破上轨 -> 买入
    if current_price > upper_band and position == 0:
        # 全仓买入
        order_value(security, cash)
        log.info(f"价格({current_price})突破上轨({upper_band:.2f}),买入 {security}")
        
    # 信号2:价格跌破下轨 -> 卖出
    elif current_price < lower_band and position > 0:
        # 清仓卖出
        order_target(security, 0)
        log.info(f"价格({current_price})跌破下轨({lower_band:.2f}),卖出 {security}")
        
    # (可选) 打印日志方便调试
    # log.info(f"当前价:{current_price}, 上轨:{upper_band:.2f}, 下轨:{lower_band:.2f}")

代码说明

  1. initialize:
    • 设置了基准和复权模式。
    • 定义了全局变量 g.security(标的股票)、g.n(周期20)、g.k(2倍标准差)。
  2. trade_func:
    • 使用 attribute_history 获取过去20天的收盘价。
    • 使用 numpy 计算均值(中轨)和标准差,进而算出上轨和下轨。
    • 使用 get_current_data 获取当前的实时价格。
    • 买入逻辑current_price > upper_band 且当前空仓。
    • 卖出逻辑current_price < lower_band 且当前持有股票。

如何使用

  1. 登录聚宽官网,进入“我的策略”。
  2. 新建一个策略,将上述代码复制粘贴到代码编辑区。
  3. 点击“编译运行”或“运行回测”即可看到效果。
  4. 你可以修改 g.security 来更换想要回测的股票代码。

Q&A

Q: 如何修改布林带的参数,比如改成25天周期?
A: 在 initialize 函数中,修改 g.n = 20g.n = 25 即可。同样,修改 g.k 可以调整标准差的倍数(例如改为1.5或3)。

Q: 这个策略可以用于多只股票吗?
A: 当前代码是针对单只股票设计的。如果要用于多只股票,需要将 g.security 改为一个列表(例如 g.stocks = ['000001.XSHE', '600519.XSHG']),然后在 trade_func 中使用 for 循环遍历这个列表,对每一只股票分别计算布林带和执行交易逻辑。

Q: 为什么使用 attribute_history 而不是 get_bars
A: 在聚宽的回测环境中,attribute_history 是获取历史数据最常用的便捷函数,它返回的是 DataFrame 格式,非常适合直接进行数学计算。get_bars 也可以使用,但在处理简单的历史切片数据时,attribute_history 代码更简洁。