易经量化交易系统2

在本篇博文中,我们要向回测系统中加入佣金、印花税、过户费等交易成本项目,使我们的回测系统更加真实。
根据当前A股市场税费的规定,主要有以下三项:

  • 佣金:交易额的0.3%,起征点5元,双向收取;
  • 过户费:交易额的0.02%,双向收取;
  • 印花税:交易额的0.1%,卖出方收取;

在原始的BackTrader中,只允许收取固定比例佣金,所以我们需要扩展其功能。我们首先扩展CommInfoBase类:

# A股手续类,主要包括三项:
# 1. 佣金:交易额的0.3%,起征点5元,双向收取;
# 2. 过户费:交易额的0.02%,双向收取;
# 3. 印花税:交易额的0.1%,卖出方收取;
# 其他如经手费和证管费通常都包含在佣金中收取
import backtrader as bt

class AshareCommInfo(bt.CommInfoBase):
    def __init__(self, comm_rate=0.003, trans_rate=0.0002, stamp_duty_tax=0.001):
        super(AshareCommInfo, self).__init__()
        self.comm_rate = comm_rate # 佣金
        self.trans_rate = trans_rate # 过户费
        self.stamp_duty_tax_rate = stamp_duty_tax # 印花税

    def _getcommission(self, size, price, pseudoexec):
        amount = abs(size) * price
        comm_fee = amount * self.comm_rate
        if comm_fee < 5.0:
            comm_fee = 5.0
        trans_fee = amount * self.trans_rate
        stamp_duty_tax_fee = 0.0
        if size < 0:
            #卖出
            stamp_duty_tax_fee = amount * self.stamp_duty_tax_rate        
        return comm_fee + trans_fee + stamp_duty_tax_fee

    def getcommission(self, size, price):
        '''
        计算交易费用方法
        '''
        return self._getcommission(size, price, pseudoexec=True)

我们需要修改backtrader/broker.py中的BrokerBase类,添加如下方法:

class BrokerBase(with_metaclass(MetaBroker, object)):
     def set_commission_obj(self, comm_obj, name=None):
        self.comminfo[name] = comm_obj

我们在程序启动时,加入这个手续费类即可,如下所示:

class BtApp(object):
    def startup(self, code='sh601318', start_cash=100000.0):
        print('回测系统示例程序 v0.0.2')
        cerebro = bt.Cerebro()
        cerebro.addstrategy(TestStrategy)
        stock_zh_a_daily_df = ak.stock_zh_a_daily(
            symbol=code, adjust="hfq"
        )  # 通过 AkShare 获取需要的数据
        data = bt.feeds.PandasData(dataname=stock_zh_a_daily_df)  # 规范化数据格式
        cerebro.adddata(data)  # 将数据加载至回测系统
        cerebro.broker.setcash(start_cash) # 设置初始资金
        cerebro.broker.set_commission_obj(AshareCommInfo())
        print(cerebro.broker)
        print('期初净值: {0:.2f}'.format(cerebro.broker.getvalue()))
        cerebro.run()
        print('期末净值: {0:.2f}'.format(cerebro.broker.getvalue()))

到此为止,我们就有了一个基本的A股市场回测系统了。但是运行这个程序,大家会发现,我们从原来的略有盈利,由于有手续费的存在,变为亏损3000元了,所以我们需要改进我们的策略。

你可能感兴趣的:(量化交易,量化交易,python)