3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
本策略是一个典型的短线超卖反弹(两日游)策略,适用于波动率较大、具有均值回归特性的 ETF 标的。为了提高信号的可靠性,策略引入了多指标共振机制:
以下是基于聚宽 API 实现的完整策略代码。策略开启了真实价格(动态复权)模式,并使用 attribute_history 获取历史数据进行指标计算。
import numpy as np
import pandas as pd
import talib
from jqdata import *
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉比error级别低的log
log.set_level('order', 'error')
# 设定交易税费:ETF买入免印花税,佣金万分之三
set_order_cost(OrderCost(close_tax=0.0, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='fund')
# 策略参数设置
g.etf_pool = [
'510300.XSHG', # 沪深300ETF
'510500.XSHG', # 中证500ETF
'159915.XSHE', # 创业板ETF
'518880.XSHG', # 黄金ETF
'513100.XSHG' # 纳指ETF
]
# 记录持仓天数
g.hold_days = {} # key: security, value: days_held
# 每天 09:30 运行
run_daily(market_open, time='09:30')
def market_open(context):
# 1. 出场逻辑:持有满2天,第3天开盘卖出
for security in list(context.portfolio.positions.keys()):
if security in g.hold_days:
g.hold_days[security] += 1
if g.hold_days[security] >= 2: # 持有满2个交易日
order_target(security, 0)
log.info(f"持有满2天,卖出平仓: {security}")
del g.hold_days[security]
# 2. 进场逻辑
# 过滤出当前未持仓的候选ETF
available_cash = context.portfolio.available_cash
if available_cash <= 0:
return
buy_list = []
for security in g.etf_pool:
if security in context.portfolio.positions:
continue
# 获取计算指标所需的数据
# 布林带需要20日,CCI需要14日,为了计算稳定获取40天数据
hist = attribute_history(security, 40, '1d', ['open', 'close', 'high', 'low', 'volume'])
if len(hist) < 40:
continue
closes = hist['close'].values
highs = hist['high'].values
lows = hist['low'].values
opens = hist['open'].values
volumes = hist['volume'].values
# 计算技术指标
# RSI (6)
rsi = talib.RSI(closes, timeperiod=6)[-1]
# CCI (14)
cci = talib.CCI(highs, lows, closes, timeperiod=14)[-1]
# WR (10)
wr = talib.WILLR(highs, lows, closes, timeperiod=10)[-1] # TALIB的WR范围是 -100 到 0
wr_val = abs(wr) # 转换为 0 到 100
# 布林带下轨 (20, 2)
upper, middle, lower = talib.BBANDS(closes, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
boll_down = lower[-1]
# 5日均量
ma_vol5 = volumes[-5:].mean()
# 信号判断
# 1. 超卖指标3选2
oversold_signals = 0
if rsi < 25: oversold_signals += 1
if cci < -150: oversold_signals += 1
if wr_val > 85: oversold_signals += 1
cond_oversold = (oversold_signals >= 2)
# 2. 价格跌破布林带下轨
cond_boll = (closes[-1] < boll_down)
# 3. 放量收阳
cond_volume_price = (closes[-1] > opens[-1]) and (volumes[-1] > ma_vol5)
# 共振触发
if cond_oversold and cond_boll and cond_volume_price:
buy_list.append(security)
# 执行买入(资金均分给触发信号的ETF)
if buy_list:
cash_per_share = available_cash / len(buy_list)
for security in buy_list:
order_value(security, cash_per_share)
g.hold_days[security] = 0
log.info(f"触发超卖共振,买入入场: {security}")
set_option('use_real_price', True):attribute_history 与 TALIB 库:TALIB 库计算 RSI、CCI、WILLR 和 BBANDS。注意,TALIB.WILLR 计算出的威廉指标区间为 [-100, 0],因此代码中使用了 abs(wr) 将其转换为常规的 [0, 100] 进行判断。g.hold_days:order_target(security, 0) 卖出,实现精准的“两日游”短线控制。