问题描述
帮我编写一个RSI交易策略,当RSI指标进入超卖区时买入,进入超买区时卖出。
解决方案
这是一个基于QMT平台的RSI(相对强弱指标)交易策略。
策略逻辑
- 指标计算:使用
talib库计算14周期RSI。 - 买入条件:当 RSI 值小于 30(超卖区)时,全仓买入。
- 卖出条件:当 RSI 值大于 70(超买区)时,清仓卖出。
- 资金管理:使用
order_target_percent函数,买入时调整仓位至 100%,卖出时调整仓位至 0%。
策略代码
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
import talib
def init(ContextInfo):
"""
初始化函数,设定策略参数和账户
"""
# 1. 设置策略参数
ContextInfo.rsi_period = 14 # RSI计算周期
ContextInfo.buy_threshold = 30 # 超卖阈值(买入)
ContextInfo.sell_threshold = 70 # 超买阈值(卖出)
# 2. 设置交易标的 (此处以浦发银行为例,实际运行时可由界面选择或在此修改)
# 如果在界面选择了标的,这里可以注释掉
ContextInfo.stock_code = '600000.SH'
ContextInfo.set_universe([ContextInfo.stock_code])
# 3. 设置资金账号 (请替换为您自己的资金账号)
ContextInfo.account_id = 'YOUR_ACCOUNT_ID'
ContextInfo.set_account(ContextInfo.account_id)
print("RSI策略初始化完成")
def handlebar(ContextInfo):
"""
K线周期运行函数
"""
# 获取当前K线位置
index = ContextInfo.barpos
# 获取当前图表的周期
period = ContextInfo.period
# 获取当前主图的股票代码 (如果init中未固定,则取主图代码)
stock = ContextInfo.stock_code
# 1. 获取历史行情数据
# 获取过去 50 根K线的数据,确保足够计算 RSI
# count=-1 表示取所有数据,这里为了效率取最近50根即可
data = ContextInfo.get_market_data(
['close'],
stock_code=[stock],
period=period,
count=50,
dividend_type='front' # 前复权
)
# 数据校验
if data is None or data.empty:
return
# 提取收盘价序列
# get_market_data 单只股票返回 DataFrame,列名为字段名
close_prices = data['close'].values
# 如果数据长度不足以计算RSI,直接返回
if len(close_prices) <= ContextInfo.rsi_period:
return
# 2. 计算 RSI 指标
# talib.RSI 需要传入 numpy 数组
rsi_values = talib.RSI(close_prices, timeperiod=ContextInfo.rsi_period)
# 获取最新的 RSI 值 (当前K线的值)
current_rsi = rsi_values[-1]
# 获取上一根K线的 RSI 值 (用于判断是否刚刚穿越)
prev_rsi = rsi_values[-2]
# 打印当前 RSI 值方便调试
# print(f"时间: {ContextInfo.get_bar_timetag(index)}, RSI: {current_rsi:.2f}")
# 3. 交易逻辑
# 情况一:RSI 进入超卖区 (小于30) -> 买入
if current_rsi < ContextInfo.buy_threshold:
# 这里使用 order_target_percent,目标仓位设为 1.0 (100%)
# 该函数会自动计算需要买入多少股
print(f"触发买入信号: RSI={current_rsi:.2f} < {ContextInfo.buy_threshold}")
order_target_percent(stock, 1.0, ContextInfo, ContextInfo.account_id)
# 情况二:RSI 进入超买区 (大于70) -> 卖出
elif current_rsi > ContextInfo.sell_threshold:
# 目标仓位设为 0.0 (0%),即清仓
print(f"触发卖出信号: RSI={current_rsi:.2f} > {ContextInfo.sell_threshold}")
order_target_percent(stock, 0.0, ContextInfo, ContextInfo.account_id)
使用说明
- 账号设置:
- 请务必将代码中的
'YOUR_ACCOUNT_ID'替换为您实际的资金账号(字符串格式)。
- 请务必将代码中的
- 标的设置:
- 代码中默认设置了
600000.SH。如果您在QMT界面的左侧行情栏选择了其他股票运行策略,代码会自动对当前主图股票生效(前提是您注释掉init函数中强制设置stock_code的那一行,或者将stock_code变量指向ContextInfo.stockcode)。
- 代码中默认设置了
- 回测与实盘:
- 回测:请在“模型回测”界面设置好初始资金、费率和起止时间。
- 实盘:请确保QMT客户端已登录交易账号,并且策略运行模式选择为“实盘”。
- 库依赖:
- QMT内置了
talib库,无需额外安装。
- QMT内置了
代码关键点解释
get_market_data:用于获取历史行情数据,这里设置count=50是为了保证有足够的数据计算14周期的RSI,同时避免获取过多数据影响速度。talib.RSI:调用专业的金融技术指标库计算RSI,比手动编写公式更准确且效率更高。order_target_percent:这是一个非常方便的交易函数。- 设置为
1.0时,系统会自动计算当前可用资金,买入直到持仓达到总资产的100%。 - 设置为
0.0时,系统会自动卖出该股票的所有持仓。 - 这样避免了手动判断“当前是否有持仓”或“可用资金能买多少股”的繁琐逻辑。
- 设置为