3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于**布林带(Bollinger Bands)**的日内均值回归策略。
# -*- coding: utf-8 -*-
from jqdata import *
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')
# 设定操作标的:沪深300股指期货主力合约
# 注意:日内回测建议使用期货,因为股票是T+1,无法日内回转
g.security = 'IF9999.CCFX'
# 策略参数
g.n = 20 # 均线窗口长度(20分钟)
g.k = 2.0 # 标准差倍数
g.open_num = 1 # 每次开仓手数
# 设定账户类型为期货账户,并给予初始资金
set_subportfolios([SubPortfolioConfig(cash=context.portfolio.starting_cash, type='futures')])
# 设定期货保证金比例(根据实际情况调整,这里设为15%)
set_option('futures_margin_rate', 0.15)
# 运行频率:每分钟运行一次
run_daily(trade_func, time='every_bar')
# 每日收盘前强制平仓,确保日内策略不留隔夜仓
run_daily(close_all, time='14:55')
def trade_func(context):
"""
交易主逻辑,每分钟执行一次
"""
# 获取当前时间
current_time = context.current_dt.time()
# 避免在刚开盘数据不足时或收盘前最后几分钟交易
if str(current_time) < '09:30:00' or str(current_time) > '14:50:00':
return
security = g.security
# 获取过去 g.n 分钟的收盘价数据
# include_now=True 表示包含当前这一分钟的实时bar(回测中)
# 如果是实盘,建议根据需求调整,通常使用过去N个已完成的bar
data = get_bars(security, count=g.n, unit='1m', fields=['close'], include_now=False)
if data is None or len(data) < g.n:
return
close_prices = data['close']
# 计算布林带
mid_line = close_prices.mean() # 中轨:均线
std = close_prices.std() # 标准差
up_line = mid_line + g.k * std # 上轨
low_line = mid_line - g.k * std # 下轨
# 获取当前最新价格
current_data = get_current_data()
current_price = current_data[security].last_price
# 获取当前持仓情况
# long_positions: 多单仓位
# short_positions: 空单仓位
long_pos = context.portfolio.long_positions[security]
short_pos = context.portfolio.short_positions[security]
# ---------------------------------------------------
# 交易逻辑
# ---------------------------------------------------
# 1. 平仓逻辑 (回归均值即平仓)
# 如果持有多单,且价格回归到中轨上方,平多
if long_pos.total_amount > 0 and current_price >= mid_line:
order_target(security, 0, side='long')
log.info("价格回归中轨,平多单。当前价: %.2f, 中轨: %.2f" % (current_price, mid_line))
# 如果持有空单,且价格回归到中轨下方,平空
if short_pos.total_amount > 0 and current_price <= mid_line:
order_target(security, 0, side='short')
log.info("价格回归中轨,平空单。当前价: %.2f, 中轨: %.2f" % (current_price, mid_line))
# 2. 开仓逻辑 (突破轨道即逆势开仓)
# 如果没有持仓
if long_pos.total_amount == 0 and short_pos.total_amount == 0:
# 价格跌破下轨,看多(均值回归),开多单
if current_price < low_line:
order(security, g.open_num, side='long')
log.info("价格跌破下轨,开多单。当前价: %.2f, 下轨: %.2f" % (current_price, low_line))
# 价格突破上轨,看空(均值回归),开空单
elif current_price > up_line:
order(security, g.open_num, side='short')
log.info("价格突破上轨,开空单。当前价: %.2f, 上轨: %.2f" % (current_price, up_line))
def close_all(context):
"""
收盘前强制平仓函数
"""
security = g.security
long_pos = context.portfolio.long_positions[security]
short_pos = context.portfolio.short_positions[security]
if long_pos.total_amount > 0:
order_target(security, 0, side='long')
log.info("收盘强制平多单")
if short_pos.total_amount > 0:
order_target(security, 0, side='short')
log.info("收盘强制平空单")
标的选择 (IF9999.CCFX):
数据获取 (get_bars):
get_bars 获取过去20分钟的K线数据。include_now=False 表示我们使用过去20个已完成的分钟Bar来计算指标,避免当前分钟价格波动导致信号闪烁。布林带计算:
numpy 和 pandas 的特性,直接对获取的数组进行 .mean() 和 .std() 计算,效率较高。交易指令 (order / order_target):
side 参数。side='long' 操作多单,side='short' 操作空单。order_target(security, 0, side='...') 用于将仓位调整为0,即平仓。强制平仓 (close_all):
14:55 触发强制平仓,防止因忘记平仓而持有隔夜风险。Q: 为什么不用股票做这个策略?
A: 股票是T+1交易,如果你上午买入,下午即使触发了卖出信号也无法卖出。除非你使用“底仓做T”的逻辑(即持有老股,买入新股,卖出老股),但这会使代码逻辑复杂很多。
Q: 为什么回测没有交易?
A: 可能是资金不足。股指期货一手合约价值较高(例如IF合约价值约100万,保证金15%约需15万)。如果初始资金设置太少(如1万),会导致下单失败。请检查日志中的 Order Rejected 信息。
Q: 如何调整策略的敏感度?
A: 修改 g.n(周期)和 g.k(标准差倍数)。
g.k(如改为1.5):交易更频繁,但假信号可能增加。g.k(如改为2.5):交易更少,信号更可靠,但可能错过机会。