用Dual-Thrust策略回测CTA

以下是小哥用Dual-Thrust策略回测CTA的代码和结果,错误的地方还请大家提出来。

标的是螺纹钢的主力连续合约

#%% Dual Thrust策略
# 导入包
import pandas as pd
import matplotlib.pyplot as plt

#%% 导入和清洗数据
RBL=pd.read_excel('H:/RBL8.xlsx')
RBL.index=pd.to_datetime(RBL.iloc[:,0])
RBL=RBL['2016':'2017']
RBL=RBL.iloc[:,1:5]
RBL.columns=('Open','High','Low','Close')

#%% Dual_Thrust策略
#输入时间序列
#输出买卖信号、持仓情况
def dt(tso,tsh,tsl,tsc,N,k1,k2):
    #输入
    #开盘价df:tso,最高价df:tsh,最低价df:tsl,收盘价df:tsc
    #参数int:N,k1,k2
    
    #初始化
    HH=pd.Series(index=tso.index[N-1:])
    LC=pd.Series(index=tso.index[N-1:])
    HC=pd.Series(index=tso.index[N-1:])
    LL=pd.Series(index=tso.index[N-1:])
    
    Range=pd.Series(index=tso.index[N-1:])
    BuyLine=pd.Series(index=tso.index[N-1:])
    SellLine=pd.Series(index=tso.index[N-1:])
    
    Open=tso.iloc[N-1:]
    Close=tsc.iloc[N-1:]
    Signal=pd.Series(0,index=tso.index[N-1:]) #交易信号
    Case=pd.Series(0,index=tso.index[N-1:]) #仓位情况
    
    #计算N日内最高价HH,Close的最低价LC,Close的最高价HC,最低价LL
    for i in range(len(tso.index)-N+1):
        HH.iloc[i]=max(tsh.iloc[i:i+N])
        LC.iloc[i]=min(tsc.iloc[i:i+N])
        HC.iloc[i]=max(tsc.iloc[i:i+N])
        LL.iloc[i]=min(tsl.iloc[i:i+N])
        Range.iloc[i]=max(HH.iloc[i]-LC.iloc[i],HC.iloc[i]-LL.iloc[i])
    
    #生成Range,买入线BuyLine,买出线,SellLine
    BuyLine=Open+k1*Range
    SellLine=Open-k2*Range
    
    #画出区间
    plt.figure('BuyLine和SellLine')    
    plt.plot(BuyLine)
    plt.plot(SellLine)
    
    #构建交易信号
    #当日收盘价低于或高于区间时生成交易信号Signal
    for i in range(len(Range)-1):
        Signal.iloc[i]=0
        Case.iloc[i+1]=Case.iloc[i]
        if Close.iloc[i]>=BuyLine.iloc[i] and Case.iloc[i]<1:
            Signal.iloc[i]=1
            Case.iloc[i+1]=1
        elif Close.iloc[i]<=SellLine.iloc[i] and Case.iloc[i]>-1:
            Signal.iloc[i]=-1
            Case.iloc[i+1]=-1
    
    return Signal,Case 

#%% 进行回测
[sig,ca]=dt(RBL['Open'],RBL['High'],RBL['Low'],RBL['Close'],20,0.1,0.1)

#%% 输出收盘价、交易信号、持仓情况
plt.figure('输出收盘价、交易信号、持仓情况')
plt.subplot(3,1,1)
plt.plot(RBL['Close'])
plt.title('收盘价')
plt.subplot(3,1,2)
plt.plot(sig)
plt.title('交易信号')
plt.subplot(3,1,3)
plt.plot(ca)
plt.title('持仓情况')

#%% 指标评价
# 累计收益、年化收益率、标的收益率、胜率、持仓时间、交易次数、最大回撤
#累计收益率
def all_re(tsc,Case):
    re=tsc.diff().dropna() #以收盘价衡量的每日收益
    day_profit=pd.Series(index=Case.index) #持仓后每日的收益
    for i in range(len(Case)):
        day_profit[i]=Case.iloc[i]*re[Case.index[i]]
    
    #累计收益
    acc_profit=day_profit.cumsum()
    #保证金,以持仓初始日的保证金为本金买入一手
    insur=tsc[Case.index[0]]*0.05+10000
    
    #年化收益:日收益率的平均值做成年化
    day_rate=acc_profit[-1]/(insur*len(acc_profit))
    anual_rate=day_rate*250
    
    #标的收益率
    bid_re=tsc[-1]/(insur*len(tsc))
    
    return acc_profit+insur,anual_rate,bid_re

#%% 交易次数、多头次数、空头次数
def trade_num(sig):
    return len(sig[sig!=0]),len(sig[sig==1]),len(sig[sig==-1])

#%% 持仓时间
def in_case(case):
    return len(case[case!=0])

#%% 回撤、最大回撤
def tradeback(tsc,Case):
    tb=pd.Series(0,index=Case.index)
    re=tsc.diff().dropna() #以收盘价衡量的每日收益
    day_profit=pd.Series(index=Case.index) #持仓后每日的收益
    for i in range(len(Case)):
        day_profit[i]=Case.iloc[i]*re[Case.index[i]]
        
    insur=tsc[Case.index[0]]*0.05+10000
    #累计收益
    acc_profit=day_profit.cumsum()+insur
    
    #回撤率
    for i in range(10,len(tb)-1):
        if acc_profit[i]>0:
            tb.iloc[i]=abs((max(acc_profit[:i+1])-acc_profit[i+1])/max(acc_profit[:i+1]))
           
    #返回回撤率、最大回撤率    
    return tb,max(tb)

#%%计算胜率
def victor(tsc,Case):
    ca_re=pd.Series(0,index=Case.index)
    re=tsc.diff().dropna()
    for i in range(len(Case)):
        ca_re.iloc[i]=Case.iloc[i]*re[Case.index[i]]
    
    vi=len(ca_re[ca_re>0])/len(Case) 
    return vi
    
#%% 输出累计收益率,回撤
plt.figure('累计收益、回撤')
plt.subplot(2,1,1)
plt.plot(all_re(RBL['Close'],ca)[0])
plt.title('累计收益')
plt.subplot(2,1,2)
plt.plot(tradeback(RBL['Close'],ca)[0]*100)
plt.title('回撤')

#%% 各项指标
print('年化收益率:',all_re(RBL['Close'],ca)[1]*100,'%')
print('\n标的收益率:',all_re(RBL['Close'],ca)[2]*100,'%')
print('\n交易次数:',trade_num(sig)[0],'\n多头次数:',trade_num(sig)[1],\
      '\n空头次数:',trade_num(sig)[2])
print('\n胜率:',victor(RBL['Close'],ca))
print('\n持仓时间:',in_case(ca))
print('\n最大回撤:',tradeback(RBL['Close'],ca)[1]*100,'%')   

结果为

年化收益率: 13.68464099 %
标的收益率: 0.0772052921481 %
交易次数: 93 
多头次数: 47 
空头次数: 46
胜率: 0.5256410256410257
持仓时间: 463
最大回撤: 5.36926264923 %

你可能感兴趣的:(Python量化)