自己做量化交易软件(6)通通量化历史交易回测设计1

前面我们介绍的通通量化软件的一些程序设计。
自己做量化交易软件(1)通通量化分析环境安装使用
https://blog.csdn.net/hepu8/article/details/81866694
自己做量化交易软件(2) 通通量化python跨版本环境设置和使用
https://blog.csdn.net/hepu8/article/details/82712669
自己做量化交易软件(3)通通量化分析框架构成1
https://blog.csdn.net/hepu8/article/details/82718220
自己做量化交易软件(4)通通量化分析框架构成2
https://blog.csdn.net/hepu8/article/details/82718592
自己做量化交易软件(5)通通量化中创作的布林指标BOLL线
https://blog.csdn.net/hepu8/article/details/82719010

下面开始介绍回测功能的设计。我们前面软件主要用的python函数设计,从现在开始使用python的类设计。
首先设计类class hpQuant(object)。初始化函数中存放一些交易变量。其中一些变量可以外部设置,例如总资金,交易手续费等等,我们按照A股交易规则,买卖有佣金,卖出需要印花税。
所以关于交易回测的代码,我们存放到HP_sys.py文件中。下面直接给出全部源代码。读者可复制到前面下载的通通项目目录中。

import sys,os
import numpy as np
import pandas as pd

from HP_global import *
from HP_set import *


class hpQuant(object):
    def __init__(self):
        self.order_df=None   #下单流水
        self.trade_df=None   #交易流水
        self.security_df=None   #持仓清单
        self.money2=1000000.00  #总资金
        self.money=1000000.00  #资金
        self.priceBuy=0.00    #最后一次买入价格
        self.priceSell=999999.00  #最后一次卖出价格
        self.amount=0.00   #证券数量
        self.code=""   #证券代码
        self.stamp_duty=0.001   #印花税 0.1%
        self.trading_Commission=0.0005    #交易佣金0.05%
        self.priceStopLoss=0.00   #止损价
        self.position=False   #持仓状态
        self.stop_loss_on=True #允许止损
        self.stop_loss_num=0   #止损次数
        self.stop_loss_max=50 #止损3次,就停止交易
        self.stop_loss_range=0.05   #止损幅度
        self.trade=True   #允许交易
        self.Init()

    def Init(self):
        self.order_df = pd.DataFrame(columns = ['date', 'time','mode','code','amount','price']) 
        self.order_df =self.order_df.reset_index(level=None, drop=True ,col_level=0, col_fill='')  
        self.trade_df = pd.DataFrame(columns = ['date', 'time','mode','code','amount','price','money']) 
        self.trade_df =self.trade_df.reset_index(level=None, drop=True ,col_level=0, col_fill='')  
        self.security_df = pd.DataFrame(columns = ['code','amount','price','money']) 
        self.security_df =self.security_df.reset_index(level=None, drop=True ,col_level=0, col_fill='')  

    def PrintOrder(self):
        print(self.order_df)

    def PrintTrade(self):
        print(self.trade_df)

    def PrintSecurity(self):
        print(self.security_df)

    def Order(self,date,time,mode,code,amount,price):
        ln=len(self.order_df)
        df_new = pd.DataFrame({'date':date,'time':time,'mode':mode,'code':code,'amount':amount,'price':price},index=[ln])
        self.order_df=self.order_df.append( df_new,ignore_index=True)

        ln=len(self.trade_df)
        if mode==1:   #买入
            se=amount*price*(1+self.trading_Commission)
            self.money=self.money-se
            df_new = pd.DataFrame({'date':date,'time':time,'mode':mode,'code':code,'amount':amount,'price':price,'money':self.money},index=[ln])
            self.trade_df=self.trade_df.append( df_new,ignore_index=True)
            if len(self.security_df[self.security_df.code==code])==0 :
                df_new = pd.DataFrame({'code':code,'amount':amount,'price':se/amount,'money':se},index=[ln])
                self.security_df=self.security_df.append( df_new,ignore_index=True)
            else:
                self.security_df.index=self.security_df['code']
                self.security_df.loc[code,'amount']=self.security_df.loc[code,'amount']+amount
                self.security_df=self.security_df.reset_index(level=None, drop=True ,col_level=0, col_fill='')  
        
        ln=len(self.security_df[self.security_df.code==code])
        if mode==2 and ln>0:  #卖出
            self.security_df.index=self.security_df['code']
            am=self.security_df.loc[code,'amount']
            if am<amount :
                amount=am
               
            se=amount*price*(1-self.trading_Commission-self.stamp_duty)
            self.money=self.money+se
            df_new = pd.DataFrame({'date':date,'time':time,'mode':mode,'code':code,'amount':amount,'price':price,'money':self.money},index=[ln])
            self.trade_df=self.trade_df.append( df_new,ignore_index=True)
            am2=self.security_df.loc[code,'amount']-amount
            self.security_df.loc[code,'amount']=am2
            if am2==0:
                self.security_df=self.security_df.drop(code, axis = 0) # 在行的维度上删除行
            self.security_df=self.security_df.reset_index(level=None, drop=True ,col_level=0, col_fill='')  


#####################回测功能#########################
    def Trade_testing(self,df,tp1,tp2,al=''):
        self.Init()
        self.trade=True   #允许交易
        myMoney=self.money2
        if (al.strip()==''):
            na='property'
        else:
            na=al 
        self.text='    ----开始回测-----\n'
        i = 0  
        ZB_l = []
        while i < len(df):  
            close=df.get_value(i, 'close')
            if (df.get_value(i, tp1) >0 and self.position==False and self.trade==True) :  #买点
                self.priceBuy=df.get_value(i, 'close')
                x=int(myMoney/(self.priceBuy*(1+self.trading_Commission))/100)
                self.amount=x*100.00
                self.Order(df.get_value(i, 'date'),'14:45:01',1,self.code,self.amount,close)
                myMoney=myMoney-self.amount*self.priceBuy*(1.00+self.trading_Commission)
                self.position=True
                self.priceStopLoss=self.priceBuy*(1-self.stop_loss_range)
                self.text=self.text+'日期:'+df.get_value(i, 'date').strftime('%Y-%m-%d')+' 买入:'+str(round(self.amount,0))+'股, 价格:'+str(round(self.priceBuy,2))+'\n'
            
            if (df.get_value(i, tp2) >0 and self.position==True and self.trade==True) : #卖点
                self.priceSell=df.get_value(i, 'close')
                myMoney=myMoney+self.amount*self.priceSell*(1.00-self.trading_Commission-self.stamp_duty)
                self.position=False
                self.Order(df.get_value(i, 'date'),'14:45:02',2,self.code,self.amount,df.get_value(i, 'close'))
                self.text=self.text+'日期:'+df.get_value(i, 'date').strftime('%Y-%m-%d')+' 卖出:'+str(round(self.amount,0))+'股, 价格:'+str(round(self.priceSell,2))+'获利:'+str(round((myMoney-self.money2)/self.money2*100,2))+'%\n'
                self.amount=0.00
            
            if (close<=self.priceStopLoss and self.position==True and self.trade  and self.stop_loss_on):  #止损
                self.priceSell=self.priceStopLoss-0.01
                myMoney=myMoney+self.amount*self.priceSell*(1.00-self.trading_Commission-self.stamp_duty)
                self.position=False
                self.stop_loss_num=self.stop_loss_num+1
                self.Order(df.get_value(i, 'date'),'14:45:02',2,self.code,self.amount,df.get_value(i, 'close'))
                self.text=self.text+'日期:'+df.get_value(i, 'date').strftime('%Y-%m-%d')+' 止损:'+str(round(self.amount,0))+'股, 价格:'+str(round(self.priceSell,2))+'获利:'+str(round((myMoney-self.money2)/self.money2*100,2))+'%\n'
                self.amount=0.00
                if (self.stop_loss_num>=self.stop_loss_max):
                    self.trade=False
                

            y= (myMoney+self.amount*close-self.money2)/self.money2 *100 
            ZB_l.append(y)  
            i = i + 1          
            
        ZB_s = pd.Series(ZB_l)  
        ZB = pd.Series(ZB_s, name = na)  
        df = df.join(ZB)  
        y= (myMoney+self.amount*close-self.money2)/self.money2  *100
        self.text=self.text+'总投入:1000000.00,最终获利幅度'+str(round(y,0))+'%\n'
            
        return df

使用方法:

import HP_lib as mylib
from HP_sys import *

##回测
tt=hpQuant()   ##初始化类

#下面是用户可设置信息。
#        self.money2=1000000.00  #总资金
#        self.code=""   #证券代码
#        self.stamp_duty=0.001   #印花税 0.1%
#        self.trading_Commission=0.0005    #交易佣金0.05%
#        self.stop_loss_on=True #允许止损
#        self.stop_loss_max=50 #止损3次,就停止交易
#        self.stop_loss_range=0.05   #止损幅度

tt.code=code   #证券代码,必须输入
tt.stop_loss_on=False    #关闭自动止损
df3=tt.Trade_testing(df2,'B1','S1','HL')   #开始回测
print('\n打印交易过程')
tt.PrintTrade()    #打印交易过程
print('\n打印持仓信息')
tt.PrintSecurity()   #打印持仓信息
print('\n 打印内部交易记录信息')
print(tt.text)     #打印交易信息

具体使用,我在下一篇介绍一个简单的回测例子。

猜你喜欢

转载自blog.csdn.net/hepu8/article/details/82821534