RSI 策略
上一节
下一节
1. 资源
2. RSI策略
(1)相对强弱指标概述(RSI)
相对强弱指数RSI是根据一定时期内上涨点数和下跌点数之和的比率制作出的一种技术曲线。能够反映出市场在一定时期内的景气程度。由威尔斯.威尔德(Welles Wilder)最早应用于期货买卖,后来人们发现在众多的图表技术分析中,强弱指标的理论和实践极其适合于股票市场的短线投资,于是被用于股票升跌的测量和分析中。该分析指标的设计是以三条线来反映价格走势的强弱,这种图形可以为投资者提供操作依据,非常适合做短线差价操作。
(2)RSI指标原理
RSI值于0-100之间呈常态分配,当6日RSI值为80‰以上时,股市呈超买现象,若出现M头,市场风险较大;当6日RSI值在20‰以下时,股市呈超卖现象,若出现W头,市场机会增大。
RSI一般选用6日、12日、24日作为参考基期,基期越长越有趋势性(慢速RSI),基期越短越有敏感性,(快速RSI)。当快速RSI由下往上突破慢速RSI时,机会增大;当快速RSI由上而下跌破慢速RSI时,风险增大。
(3)RSI指标计算公式
RS = (X天的平均上涨点数)/(X天的平均下跌点数)
RSI = [RS/(1+RS)]* 100
(4)RSI指标交易策略

(5)RSI策略之Python实战
--------------------------------------准备工作(导入包)---------------------------------------------------------------------------------------------------------------
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
import matplotlib
matplotlib.rcParams['axes.unicode_minus'] = False
--------------------------------------读取数据(交通银行)---------------------------
# 获取交通银行股票交易数据
JTYH = pd.read_csv('jtyh_data.csv',index_col='Date')
# 设置时间格式
JTYH.index = pd.to_datetime(JTYH.index, format='%Y-%m-%d')
# 提取交通银行收盘价(jtyhclp)
jtyhclp = JTYH.Close
-----------------------------------------计算RSI值---------------------------------
# 计算交通银行收盘价变化(clprcChange)
clprcChange = jtyhclp - jtyhclp.shift(1)
# 利用dropn()删除NaN值
clprcChange = clprcChange.dropna()
#统一收盘价与价格变化索引
indexprc = clprcChange.index
#建立价格上升量(upPrc)的Series
upPrc = pd.Series(0,index=indexprc)
#寻找上升(up)值,即clprcChange>0
upPrc[clprcChange > 0] = clprcChange[clprcChange > 0]
#建立价格下降量(downPrc)的Series
downPrc = pd.Series(0,index=indexprc)
#寻找下升(down)值,即clprcChange<0,并改为相反数值
downPrc[clprcChange < 0] = -clprcChange[clprcChange < 0]
# 构造由上述四个Series合并而成的数据框rsidata
rsidata = pd.concat([jtyhclp,clprcChange,upPrc,downPrc],axis=1)
rsidata.columns = ['Close','PrcChange','upPrc','downPrc']
rsidata = rsidata.dropna() #利用dropn()删除NaN值(即第一行)
# 利用简单平均数计算交通银行收盘价6日上涨力度SMUP和下跌力度SMDOWN,然后计算6日RSI的值!
SMUP = [] #初始值
SMDOWN = [] #初始值
# 第一个6日应该是2014-01-10
for i in range(6,len(upPrc)+1):
SMUP.append(np.mean(upPrc.values[(i-6):i],dtype=np.float64))
SMDOWN.append(np.mean(downPrc.values[(i-6):i],dtype=np.float64))
# 计算rsi6(列表解析)
rsi6 = [100*SMUP[i]/(SMUP[i]+SMDOWN[i]) for i in range(0,len(SMUP))]
indexRsi = indexprc[5:] #确定index
Rsi6 = pd.Series(rsi6,index=indexRsi) #确定Rsi6
--------------------------------------绘制RSI序列值曲线图--------------------------
UP = pd.Series(SMUP,index=indexRsi)
DOWN = pd.Series(SMDOWN,index=indexRsi)
plt.figure(figsize=(12,8))
plt.subplot(411) #多个子图绘制:41代表子图排列为4X1型,最后一个1代表第一个子图
plt.plot(jtyhclp,color='k') #做曲线图,且颜色为'k'(表示黑色)
#plt.xlabel('date') #设定坐标轴标签
plt.ylabel('Close')
plt.title('RSI的相关指标',loc='center') #图的标题
plt.subplot(412)
plt.plot(UP,'b')
plt.ylabel('UP')
plt.subplot(413)
plt.plot(DOWN,'y')
plt.ylabel('DOWN')
plt.subplot(414)
plt.plot(DOWN,'g')
plt.xlabel('date')
plt.ylabel('Rsi6')
plt.subplots_adjust(left=None, bottom=None, right=None, top=None,wspace=None,
hspace=1) #调整图的距离
plt.show()

------------------------------------编写RSI函数(封装代码)--------------------------
# 定义rsi()函数
def rsi(price,period=6):
clprcChange = price-price.shift(1)
clprcChange = clprcChange.dropna()
indexprc = clprcChange.index
upPrc = pd.Series(0,index=indexprc)
upPrc[clprcChange>0] = clprcChange[clprcChange>0]
downPrc = pd.Series(0,index=indexprc)
downPrc[clprcChange<0] = -clprcChange[clprcChange<0]
rsidata = pd.concat([price,clprcChange,upPrc,downPrc],axis=1)
rsidata.columns = ['price','PrcChange','upPrc','downPrc']
rsidata = rsidata.dropna()
SMUP = []
SMDOWN = []
for i in range(period,len(upPrc)+1):
SMUP.append(np.mean(upPrc.values[(i-period):i],dtype=np.float32))
SMDOWN.append(np.mean(downPrc.values[(i-period):i],dtype=np.float32))
rsi = [100*SMUP[i]/(SMUP[i]+SMDOWN[i]) for i in range(0,len(SMUP))]
indexRsi = indexprc[(period-1):]
rsi = pd.Series(rsi,index=indexRsi)
return(rsi)------------------------------------编写RSI函数(封装代码)--------------------------
# 定义rsi()函数
def rsi(price,period=6): # 默认周期为6
clprcChange = price-price.shift(1)
clprcChange = clprcChange.dropna()
indexprc = clprcChange.index
upPrc = pd.Series(0,index=indexprc)
upPrc[clprcChange>0] = clprcChange[clprcChange>0]
downPrc = pd.Series(0,index=indexprc)
downPrc[clprcChange<0] = -clprcChange[clprcChange<0]
rsidata = pd.concat([price,clprcChange,upPrc,downPrc],axis=1)
rsidata.columns = ['price','PrcChange','upPrc','downPrc']
rsidata = rsidata.dropna()
SMUP = []
SMDOWN = []
for i in range(period,len(upPrc)+1):
SMUP.append(np.mean(upPrc.values[(i-period):i],dtype=np.float32))
SMDOWN.append(np.mean(downPrc.values[(i-period):i],dtype=np.float32))
rsi = [100*SMUP[i]/(SMUP[i]+SMDOWN[i]) for i in range(0,len(SMUP))]
indexRsi = indexprc[(period-1):]
rsi = pd.Series(rsi,index=indexRsi)
return(rsi)
------------------------------------计算RSI12和RSI24---------------------------
Rsi12 = rsi(jtyhclp,12) #计算交通银行的12日RSI值
Rsi24 = rsi(jtyhclp,24) #计算交通银行的24日RSI值
--------------------------------RSI指标判断股票超买和超卖状态-----------------------
# 绘制RSI6的超买超卖曲线
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
plt.plot(Rsi6)
plt.title('RSI6指标超买和超卖',loc='center')
plt.ylim(-10,110)
plt.axhline(y=80,color='red') #在y=80处添加水平线(红色)
plt.axhline(y=20,color='red')
plt.show()

--------------------------------RSI的“黄金交叉”与“死亡交叉”-------------------------
----------------------------------------------------------------------------------
--------------------------------RSI捕捉交通银行股票买卖点---------------------------
#rsi6捕捉买卖点
Sig1 = []
for i in rsi6:
if i > 80:
Sig1.append(-1)
elif i < 20:
Sig1.append(1)
else:
Sig1.append(0)
date1 = rsi6.index
Signal1 = pd.Series(Sig1,index=date1)
Signal2 = pd.Series(0,index=rsi24.index)
lagrsi6 = rsi6.shift(1)
lagrsi24 = rsi24.shift(1)
for i in rsi24.index:
if (rsi6[i]>rsi24[i]) & (lagrsi6[i]<lagrsi24[i]):
Signal2[i] = 1
elif (rsi6[i]<rsi24[i]) & (lagrsi6[i]>lagrsi24[i]):
Signal2[i] = -1
signal = Signal1 + Signal2
signal[signal>=1] = 1
signal[signal<=-1] = -1
signal = signal.dropna()
---------------------------------RSI交易策略执行及回测------------------------------
tradSig = signal.shift(1)
#求交通银行股票收益率
ret = jtyhclp/jtyhclp.shift(1)-1
#求买入交易收益率
ret = ret[tradSig.index]
buy = tradSig[tradSig==1]
buyRet = ret[tradSig==1] * buy
#求卖出交易收益率
sell = tradSig[tradSig == -1]
sellRet = ret[tradSig == -1] * sell
#求买卖交易合并的收益率
tradeRet = ret * tradSig
----------------------绘制三种交易的时序图,展现收益分布情况-------------------------
plt.figure(figsize=(10,6))
plt.subplot(211)
plt.plot(buyRet,label="buyRet",color='g') #一图多线
plt.plot(sellRet,label="sellRet",color='r',linestyle='dashed')
plt.title('RSI指标交易策略',loc='center')
plt.ylabel('strategy return')
plt.legend(loc=2)
plt.subplot(212)
plt.plot(ret,'b')
plt.ylabel('stock return')
plt.show()

#计算信号点预测准确率情况,求预测正确时的平均收益率与预测失败时的平均收益率
def strat(tradeSignal,ret):
indexDate = tradeSignal.index
ret = ret[indexDate]
tradeRet = ret * tradeSignal
tradeRet[tradeRet==(-0)] = 0
winRate = len(tradeRet[tradeRet>0]) / len(tradeRet[tradeRet!=0])
meanWin = sum(tradeRet[tradeRet>0]) / len(tradeRet[tradeRet>0])
meanLoss = sum(tradeRet[tradeRet<0]) / len(tradeRet[tradeRet<0])
perform = {'winRate':winRate, 'meanWin':meanWin, 'meanLoss':meanLoss}
return(perform)
# 计算买入点、卖出点和整个交易的预测获胜率、平均获胜收益率与平均损失率
BuyOnly = strat(buy,ret)
SellOnly = strat(sell,ret)
Trade = strat(tradSig,ret)
Test = pd.DataFrame({'BuyOnly':BuyOnly, 'SellOnly':SellOnly, 'Trade':Trade})
#比较RSI指标交易策略的累计收益率(与股票本身累计收益率作比较)
cumStock = np.cumprod(1+ret)-1
cumTrade = np.cumprod(1+tradeRet)-1
----------------绘制累计收益率曲线图(RSI策略与股票自身累计收益率)--------------------
import matplotlib.pyplot as plt
plt.figure(figsize=(10,8))
plt.subplot(211)
plt.plot(cumStock)
plt.ylabel('cumStock')
plt.title('股票本身累计收益率',loc='center')
plt.subplot(212)
plt.plot(cumTrade)
plt.ylabel('cumTrade')
plt.title('RSI策略累计收益率',loc='center')
plt.subplots_adjust(left=None, bottom=None, right=None, top=None,wspace=None, hspace=0.3) #调整图的距离
plt.show()


