一种基于RSI和K线的择时策略
程序员文章站
2022-07-13 17:15:48
...
该策略为择时策略,是小哥用来练习写量化程序用的
策略:
入场逻辑
多头:当 12 周期 RSI>50 并且当前K线收盘价为 40 周期内的最高点,在下一
K 线的开盘价买入。
ii. 空头:当 12 周期 RSI<50 并且当前K线收盘价为 40 周期内的最低点,在下一
K 线的开盘价卖出
平台:Python
标的:沪深300指数主力连续合约
标的数量:一手
回测时间:2010至今
代码如下:
#%% 导入包
import pandas as pd
import rsi
import matplotlib.pyplot as plt
import numpy as np
#%% 导入数据
IFL8=pd.read_excel('H:/Python/Paper/IFL8.xlsx')
IFL8.dropna()
IFL8=IFL8.iloc[1:,0:5]
IFL8.columns=IFL8.iloc[0,:]
IFL8=IFL8.iloc[2:-1,:]
IFL8.index=IFL8.iloc[:,0]
IFL8=IFL8.iloc[:,1:]
IFL8.columns=['开盘价','最高价','最低价','收盘价']
IFL8.index=pd.to_datetime(IFL8.index)
print(IFL8.head())
#%% 计算收盘价和开盘价
Close=IFL8['收盘价']
Open=IFL8['开盘价']
#%% 计算RSI(12期)
RSI12=rsi.rsi(Close,12)
#%% 画图
Close=Close[RSI12.index]
Open=Open[RSI12.index]
Close.name='Close'
Open.name='Open'
RSI12.name='RSI12'
#第一张图
plt.figure('开盘价、收盘价和RSI')
plt.subplot(211)
plt.plot(Close)
plt.plot(Open)
plt.legend()
#第二张图
plt.subplot(212)
plt.plot(RSI12)
plt.legend()
#%% 构建策略信号
signal=pd.Series(0,index=Close.index) #信号初始化
signal.name='策略信号'
for i in range(39,len(Close)):
if all([RSI12[i]>50,Close[i]==max(Close[i-39:i+1])]): #多头条件
signal[i]=1 #条件触发则买入多头
elif all([RSI12[i]<50,Close[i]==min(Close[i-39:i+1])]): #空头条件
signal[i]=-1 #条件出发则买入空头
#%% 构建交易信号和仓位变化
tradeSig=pd.Series(0,index=signal.index) # 交易信号
tradeSig.name='交易信号'
cage=pd.Series(0,index=signal.index) #持仓情况
cage.name='仓位情况'
for i in range(0,len(signal)-1):
if all([signal[i]==1,cage[i]<1]): #当策略信号触发且仓位为空头时,触发多头信号
tradeSig[i+1]=1
cage[i+1]=1
elif all([signal[i]==-1,cage[i]>-1]): #当策略信号触发且多头时,触发空头信号
tradeSig[i+1]=-1
cage[i+1]=-1
else:
cage[i+1]=cage[i] #仓位的保持
cage[-1]=0 #期末平仓
#%% 绘制策略信号、交易信号和仓位情况图像
plt.figure('策略信号、交易信号和仓位情况')
plt.subplot(311)
plt.plot(signal)
plt.subplot(312)
plt.plot(tradeSig)
plt.subplot(313)
plt.plot(cage)
#%% 计算累计收益率,最大回撤,年化收益率,胜率,持仓时间,
# 计算累计收益率
Return=((Close-Close.shift(1))/Close.shift(1)).dropna() # 日收益率
cumReturn_capital=np.cumprod(1+Return).dropna() # 标的累计收益率
cumReturn_capital.name='标的累积收益率'
cumReturn_strategy=np.cumprod(1+cage*Return).dropna() # 策略累计收益率
cumReturn_strategy.name='策略累积收益率'
plt.figure('累积收益率和回撤率')
plt.subplot(221)
plt.plot(cumReturn_capital)
plt.legend()
plt.subplot(222)
plt.plot(cumReturn_strategy)
plt.legend()
#%% 计算最大回撤
def traceback(Close):
traceback=pd.Series(0,index=Close.index) #回撤
for i in range(len(traceback)):
traceback[i]=(max(Close[0:i+1])-Close[i])/max(Close[0:i+1])*100
maxtraceback=max(traceback) # 最大回撤
return maxtraceback,traceback
traceback_capital=traceback(cumReturn_capital)[1]
traceback_capital.name='标的回撤率'
traceback_strategy=traceback(cumReturn_strategy)[1]
traceback_strategy.name='策略回撤率'
plt.subplot(223)
plt.plot(traceback_capital)
plt.legend()
plt.subplot(224)
plt.plot(traceback_strategy)
plt.legend()
print('标的最大回撤率:',traceback(cumReturn_capital)[0],'%\n')
print('策略最大回撤率:',traceback(cumReturn_strategy)[0],'%\n')
#%% 年化收益率
yearReturn_capital=(cumReturn_capital[-1]**(212/len(cumReturn_capital))-1)*100
yearReturn_strategy=(cumReturn_strategy[-1]**(212/len(cumReturn_strategy))-1)*100
print('标的年化收益率:',yearReturn_capital,'%\n')
print('策略年化收益率:',yearReturn_strategy,'%\n')
#%% 计算胜率
returnD_strategy=(cage*Return).dropna() # 策略的日收益率
victor=len(returnD_strategy[returnD_strategy>0])/len(returnD_strategy) # 胜率
print('策略的胜率:',victor)
#%% 持仓时间
print('持仓时间:',len(cage[cage!=0]),'天')
计算RSI的函数
#%% 计算RSI
# input:收盘价和期数
# output: RSI
def rsi(price,period=6):
import numpy as np
import pandas as pd
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的时间序列
接着得到策略信号、交易信号和仓位情况的序列
之后计算最重要的累计收益率和回撤率
策略的结果参数为
标的最大回撤率: 48 %
策略最大回撤率: 58 %
标的年化收益率: 2.7500531042845555 %
策略年化收益率: -1.5597819693758175 %
策略的胜率: 0.4923425978445831
持仓时间: 1723 天
结论:可见这个策略连标的都没有跑过,而且回撤是如此之大,以至于这样操作会大亏,所以这个策略并不好。权当小哥写回测程序练手罢了。
上一篇: 使用git遇到的问题汇总
推荐阅读