Demo entry 6662191

final

   

Submitted by anonymous on Nov 25, 2017 at 04:57
Language: Python 3. Code size: 20.5 kB.

# -*- coding: utf-8 -*-
"""
Created on Sat Nov 18 22:31:30 2017

@author: Administrator
"""
import xlrd#导入表格读取包
import numpy as np
import matplotlib.dates as mdates
import matplotlib.pylab as pylab
import matplotlib.pyplot as plt
import pandas as pd
from hmmlearn import hmm
import scipy.stats as sc
plt.rcParams['font.sans-serif']=['SimHei']#设置绘图中文格式
plt.rcParams['axes.unicode_minus']=False#设置绘图的负半轴
##############################################################################
#定义移动平均函数
def ma(x, length):
        MA=np.zeros(len(x))
        MA[range(length-1)]=x[range(0,length-1)]
        for i in range(length-1,len(x)):
            MA[i]=sum(x[(i-length+1):i+1])/length
        return MA

#获取棕榈油数据
data_Pal = xlrd.open_workbook('棕榈油.xlsx')
table_Pal = data_Pal.sheets()[0]
rownum_Pal = table_Pal.row_values(0)
col1_Pal=table_Pal.col_values(0)
col2_Pal=table_Pal.col_values(4)
col3_Pal=table_Pal.col_values(7)
date_Pal=[]
price_Pal=[]
vol_Pal=[]
for i in range(0,len(col1_Pal)-1):
    ind1=col1_Pal[i]
    ind2=col2_Pal[i]
    ind3=col3_Pal[i]
    if (type(col1_Pal[i]) is float) == True:
        ind1=col1_Pal[i]+693594
        date_Pal.append(pylab.num2date(ind1))
        price_Pal.append(ind2)
        vol_Pal.append(ind3)

#获取B油数据
data_Soy= xlrd.open_workbook('豆油.xlsx')
table_Soy= data_Soy.sheets()[0]
rownum_Soy= table_Soy.row_values(0)
col1_Soy=table_Soy.col_values(0)
col2_Soy=table_Soy.col_values(4)
col3_Soy=table_Soy.col_values(7)
date_Soy=[]
price_Soy=[]
vol_Soy=[]
for i in range(0,len(col1_Soy)-1):
    ind1=col1_Soy[i]
    ind2=col2_Soy[i]
    ind3=col3_Soy[i]
    if (type(col1_Soy[i]) is float) == True:
        ind1=col1_Soy[i]+693594
        date_Soy.append(pylab.num2date(ind1))
        price_Soy.append(ind2)
        vol_Soy.append(ind3)
#清洗数据
Date=[]
Price_Pal=[]
Price_Soy=[]
Vol_Pal=[]
Vol_Soy=[]

if len(price_Pal)!=len(price_Soy): 
    for i in range(0,len(date_Pal)):
        if (date_Pal[i] in date_Soy):
            ind2=date_Soy.index(date_Pal[i])
            Date.append(date_Pal[i])
            Price_Pal.append(price_Pal[i])
            Vol_Pal.append(vol_Pal[i])
            Price_Soy.append(price_Soy[ind2])
            Vol_Soy.append(vol_Soy[ind2])
       
#画出清洗干净的数据
fig,ax=plt.subplots(figsize=(13,9)) 
ax.plot(Date,np.array(Price_Pal),label='棕榈油',color='yellow')
ax.plot(Date,np.array(Price_Soy),label='豆油',color='coral')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('日期',fontsize=25)
plt.setp(plt.gca().get_xticklabels(),rotation=30)
plt.ylabel('收盘价',fontsize=25)
plt.legend(loc='upper right',fontsize=20)
plt.title(u'棕榈油/豆油 主力合约收盘价',color='blue',fontsize=20)
plt.grid(True)
#画出成交量
fig,ax=plt.subplots(figsize=(13,9)) 
#ax.plot(Date,np.array(Vol_Rap),label='菜籽油期货',color='blue')
ax.plot(Date,np.array(Vol_Pal),label='棕榈油',color='yellow')
ax.plot(Date,np.array(Vol_Soy),label='豆油',color='coral')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('日期',fontsize=25)
plt.setp(plt.gca().get_xticklabels(),rotation=30)
plt.ylabel('成交量',fontsize=25)
plt.legend(loc='upper right',fontsize=20)
plt.title(u'棕榈油/豆油 主力合约成交量',color='blue',fontsize=20)
plt.grid(True)


#构造协整序列
constant=np.ones(len(Price_Pal))
x=np.vstack((np.mat(Price_Pal),np.mat(constant)))
y=np.mat(Price_Pal)
b=(((x*x.T).I)*x)*y.T
PS=np.mat(Price_Soy).T-np.mat(Price_Pal).T*b[0]-b[1]
#PS=np.array(Price_Rap)
ps=PS-min(PS)+3
#ps=np.array(PS)
vs=np.mat(Vol_Soy).T+np.mat(Vol_Pal).T*b[0]+3
#vs=np.array(Vol_Rap)
#plt.plot(PS)
#plt.plot(volumnseries)
fig,ax=plt.subplots(figsize=(13,9)) 
#ax.plot(Date,np.array(Vol_Rap),label='菜籽油期货',color='blue')
ax.plot(Date,PS,'-',label='价差序列',color='black')
ax.plot(Date,np.ones(len(PS))*(np.mean(PS)+0.75*np.std(PS)),'-',label='套利信号线',color='blue')
ax.plot(Date,np.ones(len(PS))*(np.mean(PS)-0.75*np.std(PS)),'-',color='blue')
ax.plot(Date,np.ones(len(PS))*(np.mean(PS)+2*np.std(PS)),'-',label='止损线',color='red')
ax.plot(Date,np.ones(len(PS))*(np.mean(PS)-2*np.std(PS)),'-',color='red')
ax.plot(Date,np.ones(len(PS))*(np.mean(PS)),'-',label='获利平仓线',color='gray')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('日期',fontsize=25)
plt.setp(plt.gca().get_xticklabels(),rotation=30)
plt.ylabel('元',fontsize=25)
plt.legend(loc='upper right',fontsize=20)
plt.title(u'棕榈油/豆油 价差协整序列',fontsize=25)
plt.grid(True)
#定义正态分布函数
def normfun(x,mu, sigma):
    pdf = np.exp(-((x - mu)**2) / (2* sigma**2)) / (sigma * np.sqrt(2*np.pi))
    return pdf
#绘制价差的分布图
ind=PS
x = np.arange(min(ind), max(ind),1)
y=normfun(x,np.mean(ind),np.std(ind))
fig,ax=plt.subplots(figsize=(13,9)) 
plt.plot(x,y, color='g',linewidth = 3)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
#数据,数组,颜色,颜色深浅,组宽,显示频率
plt.hist(ind, bins =100, color = 'r',alpha=0.5,rwidth= 0.9, normed=True)
plt.title('棕榈油/豆油 价差分布图',color='blue',fontsize=20)
plt.xlabel('价差',fontsize=25)
plt.ylabel('概率',fontsize=25)
plt.grid(True)
plt.show()

#绘制成交量组合序列
fig,ax=plt.subplots(figsize=(13,9)) 
ax.plot(Date,vs,label='成交量相加序列',color='blue')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('日期',fontsize=25)
plt.setp(plt.gca().get_xticklabels(),rotation=30)
plt.ylabel('成交量',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title(u'棕榈油/豆油 成交量相加序列',color='blue',fontsize=20)
plt.grid(True)
#平滑处理价差序列
ShortLen=5
locals()['MA%s'%ShortLen]=np.zeros(len(ps))
locals()['MA%s'%ShortLen]=ma(ps,ShortLen)
plt.plot(locals()['MA%s'%ShortLen])
ps=locals()['MA%s'%ShortLen]
#计算一日收益率和五日收益率
logRet_1=np.array(np.log(np.array(ps[1:]))-np.log(np.array(ps[:-1])))
logRet_1=logRet_1[4:]
logRet_5=np.log(np.array(ps[5:]))-np.log(np.array(ps[:-5]))
#计算每五日指数对数成交量变化率
logVol_1=np.array(np.log(np.array(vs[1:]))-np.log(np.array(vs[:-1])))
logVol_1=logVol_1[4:]
logVol_5=np.log(np.array(vs[5:]))-np.log(np.array(vs[:-5]))
    
###############################################################################

#观测序列
O=np.column_stack([logRet_5,logVol_5])
O=O[:-1]
date=pd.to_datetime(Date[5:])
date=date[:-1]
Close=PS[5:-1]
#状态序列
#计算无截距回归斜率
MA5=ps
Len=3
states=np.zeros(len(PS))
beta=np.zeros(len(states.T))
for i in range(len(beta)-Len+1):
    y=np.zeros(Len)
    for j in range(Len):
        y[j]=MA5[i+j]-MA5[i]
    DateN=Date[i:i+Len]
    x=np.zeros(len(y.T))
    for j in range(len(x)):
        x[j]=(DateN[j]-DateN[0]).days
    b0=np.ones(len(y.T))
    x=x[:,np.newaxis]
    beta[i], _, _, _ = np.linalg.lstsq(x, y.T)
#计算回撤率
MDn=np.zeros(Len)
MDN=np.zeros(len(states.T))
for i in range(len(beta)-Len+1):
    RetN=np.zeros(Len)
    for j in range(Len):
        RetN[j]=MA5[i+j]
    for t in range(len(RetN)):
        if beta[i]>0:
            C=max(RetN[range(t+1)])
            if C==RetN[t]:
                MDn[t]=0
            elif C!=RetN[t]:
                MDn[t]= (RetN[t]-C)/C
            MDn = abs(MDn)
        elif beta[i]<0:
            C=min(RetN[range(t+1)])
            if C==RetN[t]:
                MDn[t]=0
            elif C!=RetN[t]:
                MDn[t]= (RetN[t]-C)/C
            MDn = abs(MDn)
    MDN[i]=max(MDn)
Bot=np.unique(MDN)[np.floor(len(np.unique(MDN))*0.1)]
for i in range(len(MDN)):
    if MDN[i]<Bot:
        MDN[i]=Bot
#计算beta/Draw
bM=np.zeros(len(MDN))
for i in range(len(bM)):
    bM[i]=beta[i]/(MDN[i]*(max(beta)-min(beta)))
#绘制beta/Draw的分布情况
ind=bM
x = np.arange(min(ind), max(ind),1)
y=normfun(x,np.mean(ind),np.std(ind))
fig,ax=plt.subplots(figsize=(13,9)) 
plt.plot(x,y, color='g',linewidth = 3)
#数据,数组,颜色,颜色深浅,组宽,显示频率
plt.hist(ind, bins =100, color = 'r',alpha=0.5,rwidth= 0.9, normed=True)
plt.title('distribution')
plt.xlabel('beta/Draw')
plt.ylabel('Probability')
plt.show()  
#缩尾处理
sigma_bm=np.std(bM)
mu_bm=np.mean(bM)
for i in range(len(bM)):
    if bM[i]>mu_bm+3*sigma_bm:
        bM[i]=mu_bm+3*sigma_bm
    elif bM[i]<mu_bm-3*sigma_bm:
        bM[i]=mu_bm-3*sigma_bm
#划分状态对应的bM区间
n=3
sigma=np.std(bM)
mu=np.mean(bM)
Edge=np.zeros(n-1)
for i in range(7,9):
    Edge[i-7]=mu+sigma*sc.norm.ppf(i/(15))
#标注状态
states=np.zeros(len(ps))
statesN=np.zeros(n)
for i in range(len(beta)):
    if bM[i]<Edge[0]:
        states[i]=range(n)[0]
        statesN[0]+=1
    elif bM[i]>=Edge[-1]:
        states[i]=range(n)[-1]
        statesN[-1]+=1
    else:
        for j in range(len(Edge)-1):
            if bM[i]>=Edge[j] and bM[i]<Edge[j+1]:
                states[i]=j+1
                statesN[j+1]+=1
#状态序列
I=states[5:-1]
#训练集(样本内
len_train=int(np.floor(len(I)/6)*5)
O_train=O[0:len_train,:]
I_train=I[0:len_train]
Date_train=date[0:len_train]
Close_train=Close[0:len_train]
#测试集(样本外)
O_test=O[len_train:,:]
I_test=I[len_train:]
Date_test=date[len_train:]
Close_test=Close[len_train:]
#计算状态之间的转移概率
n=len(set(I_train))
A=np.zeros([n,n])#初始化转移概率矩阵
Countmat=np.zeros([n,n])#初始化统计矩阵
for i in range(len(I_train)-1):
    for j in range(n):
        for k in range(n):
            if I_train[i]==j:
                if I_train[i+1]==k:
                    Countmat[j,k]+=1
for i in range(n):
    for j in range(n):
        A[i,j]=Countmat[i,j]/(np.sum(Countmat[i]))#计算转移概率
n=3
#定义有监督学习的HMM
class CustomHMM:
  def __init__(self):
      def build_hmm():
          model = hmm.GMMHMM(n_components=n, n_mix=n, covariance_type="diag", init_params="t")
          model.transmat_ =A
          return model
      #构建n个状态的HMM模型
      for i in range(n):
          exec('self.hmm_'+str(i)+'=build_hmm()')

  def fit(self, X_train, y_train):
      # X_train shape(n_instances, n_samples)
      labels = set(y_train)
      if len(labels) != n:
          raise Exception("y_train 没有包含n个状态")
      for i in range(n):
          exec('X_'+str(i)+'=X_train[y_train==i,:]')
      #训练HMM模型
      for i in range(n):
          exec('self.hmm_'+str(i)+'.fit(X_'+str(i)+')')
  #预测观测数据
  def predict(self, X_test):
      res = []
      for x in X_test:
          order='self.hmm_0.score(x)'
          for i in range(n):
              if i>0:
                  order=order+',self.hmm_'+str(i)+'.score(x)'
          score=eval('['+order+']')
          #score得分最大的状态作为预测结果
          C=max(score)
          for i in range(n):
              if score[i]==C:
                  ind=i
          res.append(ind)
      return np.array(res)
##############################################################################
#开始训练模型
#建立一个空白的模型
clf = CustomHMM()
#设置训练用观测序列与状态序列之间的错开天数
Day=4
#训练模型
clf.fit(O_train[:-Day], I_train[Day:])

##在这切换样本内预测和样本外预测
#Sample='train'
Sample='test'
if Sample=='train':
    A_test=O_train
    close=Close_train
    date=Date_train
if Sample=='test':
    A_test=O_test
    close=Close_test
    date=Date_test
#预测
hidden_states=clf.predict(A_test)

#绘制预测结果
plt.figure(figsize=(13,9))
plt.plot(date,close)
for i in range(n):
    pos=(hidden_states==i)
    plt.plot_date(date[pos],close[pos],'.',label='隐含状态 %d'%i,lw=2)
    plt.legend(loc='left')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('时间',fontsize=25)
plt.legend(loc='upper right',fontsize=20)
plt.grid(True)

#Len是用于约束止损的移动平均的天数参数
#为了控制变量,规定用于移动平均所损失的Len天都不进行交易
Len=50
#第二天买入#
InitialE=50e4
RetN=np.zeros([len(close),n])
ReturnD=np.zeros(len(close))
scale=300
for i in range(n):
    #第一天收盘后收到交易信号
    pos=(hidden_states==i)
    #第二天买入
    pos=np.append(0,pos[:-1])
    for j in range(Len+1,len(pos)):
        if pos[j-1]==1:
            #第三天收盘价减去第二天收盘价,结算每日收益
            ReturnD[j]=(close[j]-close[j-1])*scale
        if pos[j-1]==0:
            ReturnD[j]=0
    for t in range(0,len(close)):
        RetN[t,i] = sum(ReturnD[range(0,t)])
RetN = RetN + InitialE
#涨状态多头,跌状态空头
RET=RetN[:,2]-RetN[:,0]+InitialE
#绘制不同状态下做多头的权益曲线
fig,ax=plt.subplots(figsize=(13,9)) 
for i in range(n):
    plt.plot(date,RetN[:,i],'-',label='隐含状态 %d'%i,lw=1)
plt.plot(date,RET,'-',label='状态_2-状态_0',lw=1)
plt.title('不同状态下做多头的权益曲线',fontsize=25,color='blue')
plt.legend(loc='upper left',fontsize=20)
plt.grid(True)
plt.xlabel('日期',fontsize=25)
plt.ylabel('价格',fontsize=25)

#绘制仿真交易的示意图
plt.figure(figsize=(13,9))
plt.plot(date,close,'-',color='gray',label='价差组合')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('日期',fontsize=25)
plt.ylabel('价格',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('回测过程',fontsize=25,color='blue')
plt.grid(True)
Pos=np.zeros(len(close))
InitialE=50e4
ReturnD=np.zeros(len(close))
scale=300
for t in range(Len+1,len(close)):
    #第一天收到交易信号
    #买入信号
    SignalBuy=(hidden_states[t-1]==2)         
    #卖出信号
    SignalSell=(hidden_states[t-1]==0) 
    #第二天执行交易
    if SignalBuy==1:
        Pos[t]=1
        pylab.text(date[t],close[t],'←多',fontsize=8)
    if SignalSell==1:
        Pos[t]=-1
        pylab.text(date[t],close[t],'←空',fontsize=8)
if Pos[-1]!=0:
    Pos[-1]=0
    pylab.text(date[t],close[t],'←平',fontsize=8)
##############################################################################
#第三天收盘价减去第二天收盘价结算每日收益
for t in range(1,len(close)):
    if Pos[t-1]==1:
        ReturnD[t]=(close[t]-close[t-1])*scale
    if Pos[t-1]==-1:
        ReturnD[t]=(close[t-1]-close[t])*scale
    if Pos[t-1]==0:
        ReturnD[t]=0
#计算累计收益
ReturnCum=np.zeros(len(close))
for t in range(1,len(close)):
    ReturnCum[t] = sum(ReturnD[range(0,t+1)])
ReturnCum = ReturnCum + InitialE
#计算最大回撤
MaxDrawD=np.zeros(len(close));
for t in range(1,len(close)):
    C=max(ReturnCum[range(0,t+1)])
    if C==ReturnCum[t]:
        MaxDrawD[t]=0
    elif C!=ReturnCum[t]:
        MaxDrawD[t]= (ReturnCum[t]-C)/C
MaxDrawD = abs(MaxDrawD)       
#绘制资产净值曲线               
fig,ax=plt.subplots(figsize=(13,3)) 
ax.plot(date,ReturnCum,label='ReturnCum',color='coral')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.ylabel('资产净值',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('收益曲线',color='blue')
plt.grid(True)
#绘制仓位曲线
plt.rcParams['axes.unicode_minus']=False
fig,ax=plt.subplots(figsize=(13,3)) 
ax.plot(date,Pos,label='Position',color='coral')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.ylabel('仓位',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('仓位曲线',color='blue')
plt.grid(True)
#绘制回撤曲线
fig,ax=plt.subplots(figsize=(13,3)) 
ax.plot(date,MaxDrawD,label='DrawD',color='coral')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.ylabel('回撤率',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('回撤曲线(初始资金50万)',color='blue')
plt.grid(True)
#计算交易结果
if Sample=='train':
    YR=((((ReturnCum[-1]-InitialE)/InitialE))/(2992))*365
    MD=max(MaxDrawD)
    R2D=(((((ReturnCum[-1]-InitialE)/InitialE))/(2992))*365)/max(MaxDrawD)
if Sample=='test':
    YR=((((ReturnCum[-1]-InitialE)/InitialE))/(602))*365
    MD=max(MaxDrawD)
    R2D=(((((ReturnCum[-1]-InitialE)/InitialE))/(602))*365)/max(MaxDrawD)
result_1=[YR,MD,R2D]

#Winsorize缩尾处理
#参考简单统计套利
#超出样本两倍Sigma的赋予mean±2*Sigma
close_ws=np.zeros(len(close))
for i in range(len(close)):
    if close[i]>2*np.std(Close_train):
        close_ws[i]=2*np.std(Close_train)
    elif close[i]<-2*np.std(Close_train):
        close_ws[i]=-2*np.std(Close_train) 
    else:
        close_ws[i]=close[i]
#计算新的均衡
MAlong=ma(close_ws,Len)    
DIST=np.zeros(len(close))
DIST=abs(close.T-MAlong)
Sigma_D=np.std(DIST)
#绘制新的均衡以及止损线以及示意图
plt.figure(figsize=(13,9))
plt.plot(date,close,'-',color='gray',label='价差组合')
plt.plot(date,MAlong ,'-',color='red',label='MA'+str(Len))
plt.plot(date,MAlong+2*Sigma_D,'-',color='blue',label='MA'+str(Len)+'+2*Sigma')
plt.plot(date,MAlong-2*Sigma_D,'-',color='blue',label='MA'+str(Len)+'-2*Sigma')
plt.title('定义新的均衡以及止损线',fontsize=25,color='blue')
plt.legend(loc='upper left',fontsize=15)
plt.xlabel('日期',fontsize=25)
plt.ylabel('价格',fontsize=25)
#第二天买入#
InitialE=50e4
RetN=np.zeros([len(close),n])
ReturnD=np.zeros(len(close))
scale=300
n=3
for i in range(n):
    pos=(hidden_states==i)
    pos=np.append(0,pos[:-1])
    for j in range(Len+1,len(pos)):
        if pos[j-1]==1:
            if DIST[:,j-1]<2*Sigma_D:
                ReturnD[j]=(close[j]-close[j-1])*scale
            else:
                ReturnD[j]=0
        if pos[j-1]==0:
            ReturnD[j]=0
    for t in range(0,len(close)):
        RetN[t,i] = sum(ReturnD[range(0,t+1)])
RetN = RetN + InitialE
RET=RetN[:,2]-RetN[:,0]+InitialE
fig,ax=plt.subplots(figsize=(13,9)) 
for i in range(n):
    plt.plot(date,RetN[:,i],'-',label='隐含状态 %d'%i,lw=1)
plt.plot(date,RET,'-',label='状态_2-状态_0',lw=1)
plt.title('不同状态下做多头的权益曲线',fontsize=25,color='blue')
plt.legend(loc='upper left',fontsize=20)
plt.grid(True)
plt.xlabel('日期',fontsize=25)
plt.ylabel('价格',fontsize=25)

plt.figure(figsize=(13,9))
plt.plot(date,close,'-',color='gray',label='价差组合')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.xlabel('日期',fontsize=25)
plt.ylabel('价格',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('回测过程',fontsize=25,color='blue')
plt.grid(True)
Pos=np.zeros(len(close))#初始化仓位
InitialE=50e4#初始权益五十万
ReturnD=np.zeros(len(close))#初始化每日收益
scale=300#每次交易3手
for t in range(Len+1,len(close)):
    #接收买信号
    SignalBuy=(hidden_states[t-1]==2 and DIST[:,t-1]<2*Sigma_D)     
    #接收卖信号
    SignalSell=(hidden_states[t-1]==0 and DIST[:,t-1]<2*Sigma_D)
    #执行交易
    if SignalBuy==1:

        Pos[t]=1
        pylab.text(date[t],close[t],'←多',fontsize=8)
    if SignalSell==1:
        Pos[t]=-1
        pylab.text(date[t],close[t],'←空',fontsize=8)
if Pos[-1]!=0:
    Pos[-1]=0
    pylab.text(date[t],close[t],'←平',fontsize=8)
##############################################################################
for t in range(1,len(close)):
    if Pos[t-1]==1:
        ReturnD[t]=(close[t]-close[t-1])*scale
    if Pos[t-1]==-1:
        ReturnD[t]=(close[t-1]-close[t])*scale
    if Pos[t-1]==0:
        ReturnD[t]=0
#计算累计收益
ReturnCum=np.zeros(len(close))
for t in range(1,len(close)):
    ReturnCum[t] = sum(ReturnD[range(0,t+1)])
ReturnCum = ReturnCum + InitialE
#计算最大回撤
MaxDrawD=np.zeros(len(close));
for t in range(1,len(close)):
    C=max(ReturnCum[range(0,t+1)])
    if C==ReturnCum[t]:
        MaxDrawD[t]=0
    elif C!=ReturnCum[t]:
        MaxDrawD[t]= (ReturnCum[t]-C)/C
MaxDrawD = abs(MaxDrawD)       
               
fig,ax=plt.subplots(figsize=(13,3)) 
ax.plot(date,ReturnCum,label='ReturnCum',color='coral')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.ylabel('资产净值',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('收益曲线',color='blue')
plt.grid(True)

plt.rcParams['axes.unicode_minus']=False
fig,ax=plt.subplots(figsize=(13,3)) 
ax.plot(date,Pos,label='Position',color='coral')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.ylabel('仓位',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('仓位曲线',color='blue')
plt.grid(True)

fig,ax=plt.subplots(figsize=(13,3)) 
ax.plot(date,MaxDrawD,label='DrawD',color='coral')
plt.xticks(fontsize=10)
plt.yticks(fontsize=20)
plt.rcParams['font.sans-serif']=['SimHei']
plt.ylabel('回撤率',fontsize=25)
plt.legend(loc='upper left',fontsize=20)
plt.title('回撤曲线(初始资金50万)',color='blue')
plt.grid(True)

if Sample=='train':
    YR=((((ReturnCum[-1]-InitialE)/InitialE))/(2992))*365
    MD=max(MaxDrawD)
    R2D=(((((ReturnCum[-1]-InitialE)/InitialE))/(2992))*365)/max(MaxDrawD)
if Sample=='test':
    YR=((((ReturnCum[-1]-InitialE)/InitialE))/(602))*365
    MD=max(MaxDrawD)
    R2D=(((((ReturnCum[-1]-InitialE)/InitialE))/(602))*365)/max(MaxDrawD)
result_2=[YR,MD,R2D]

This snippet took 0.05 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).