问题描述
解决方案
这是一个基于布林带(Bollinger Bands)的经典突破策略。
策略逻辑
- 计算布林带:
- 中轨:过去 N 天(通常为20天)的收盘价移动平均线。
- 上轨:中轨 + K 倍(通常为2)标准差。
- 下轨:中轨 - K 倍(通常为2)标准差。
- 买入信号:当当前价格突破上轨,且当前无持仓时,全仓买入。
- 卖出信号:当当前价格跌破下轨,且当前有持仓时,清仓卖出。
以下是可以在聚宽(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}")
代码说明
initialize:- 设置了基准和复权模式。
- 定义了全局变量
g.security(标的股票)、g.n(周期20)、g.k(2倍标准差)。
trade_func:- 使用
attribute_history获取过去20天的收盘价。 - 使用
numpy计算均值(中轨)和标准差,进而算出上轨和下轨。 - 使用
get_current_data获取当前的实时价格。 - 买入逻辑:
current_price > upper_band且当前空仓。 - 卖出逻辑:
current_price < lower_band且当前持有股票。
- 使用
如何使用
- 登录聚宽官网,进入“我的策略”。
- 新建一个策略,将上述代码复制粘贴到代码编辑区。
- 点击“编译运行”或“运行回测”即可看到效果。
- 你可以修改
g.security来更换想要回测的股票代码。
Q&A
Q: 如何修改布林带的参数,比如改成25天周期?
A: 在 initialize 函数中,修改 g.n = 20 为 g.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 代码更简洁。