Backtrader 量化回测实践(4)—— 投资组合股票回测同一策略

Backtrader 量化回测实践(4)—— 投资组合股票回测同一策略

需要将一组股票作为一个投资组合,验证一个策略。观察操作是否具有一致性。比如在某一段时间,组合中的买卖操作,有一定的相似度。
对所有股票依次做单独的策略回测,不好对比,不好直观验证策略的优劣。
基于backtrader,编写多股票同时回测程序。
以MACD简单策略演示。
需要关注理解策略中的四个关键点 :

  • init 初始化参数
  • next 交易实施
  • notice 过程监控
  • datafeed 数据加载

1. init

    def __init__(self):  
        # 创建MACD指标
        # 组合股票信号使用dict存储
        self.macds = dict()
        
        # 枚举数据的序号和数据,d就是一个股票的数据lines
        for i, d in enumerate(self.datas):
            # 每一个数据指标一个dict
            self.macds[d] = dict()
            self.macds[d]['macd'] = bt.indicators.MACD(d.close,period_me1=self.p.short_period,
                        period_me2=self.p.long_period,period_signal=self.p.signal_period)
            self.macds[d]['signal'] = self.macds[d]['macd'].lines.signal 
        
        # 初始化订单  
        self.order = None  

说明:
(1)用dict保存多个股票指标信息

        # 组合股票信号使用dict存储
        self.macds = dict()

(2)每个股票是一个dict,保存对应的股票macd信息

            # 每一个数据指标一个dict
            self.macds[d] = dict()

2. next

next方法中,循环遍历所有待测的股票,对每只股票,获取时间及股票名称,打印输出、日志留存或者调试。
先判断当前股票position的size,判断是否已经买入该股票,如果没有买入,判断macd指标成立,即可买入。如果已经持有了该股票,判断macd指标失败,平仓卖出。

    def next(self):  
        # 检查是否有未完成的订单  
        if self.order:  
            return  
        
        # 枚举数据的序号和数据,d就是一个股票的数据lines
        for i, d in enumerate(self.datas):
            # 获取时间及股票代码
            dt, dn = self.datetime.date(), d._name      
            # 获取对应代码的仓位
            pos = self.getposition(d).size
            
            # 无仓位,则可以买入
            if not pos:   
                # MACD买入信号  ,可以多次买入
                if self.macds[d]['macd'] > self.macds[d]['signal']:
                    # data = d指定buy的代码
                    self.buy(data = d, size = self.p.pstake) 
            
            # 平仓 ,一次卖出
            elif self.macds[d]['macd'] < self.macds[d]['signal']:                  
                # data = d指定sell的代码
                self.close(data = d)   

说明:
(1)还是使用枚举的方式,循环组合股票列表,按股票获取仓位:

            pos = self.getposition(d).size

(2)触发指标判断,通过dict的股票指标逐一判断

                if self.macds[d]['macd'] > self.macds[d]['signal']:

(3)买卖要指定股票

self.buy(data = d, size = self.p.pstake) 

3. notice

以notify_trade 为例,notify_order的概念一样。

    def notify_trade(self, trade):
        if not trade.isclosed:
            return
        
        #可以按trade.data取触发notify_trade的日期
        dt = trade.data.datetime.date()
        
        # trade是一次处理一个数据,不存在trader.datas!!!    
        if trade.isclosed:
            self.log('%s :Closed, PnL Gross %.2f, Net %.2f,Net worth: %.2f' %
                (trade.data._name, round(trade.pnl, 2), round(trade.pnlcomm, 2),self.broker.getvalue()))
    

说明:
(1)trade和order 都没有trade.datas或order.datas !!! 每一个触发都是独立的一个notice对象。
(2)区分不同股票的方法,trade.data._name或order.data._name 。

4.datafeed

# 添加策略  
codes=['000858.SZ','000859.SZ','000860.SZ','000861.SZ','000862.SZ','000863.SZ','000868.SZ']

for code in codes:
    stock_df = get_code(code)
    data = btfeeds.PandasData(dataname=stock_df, fromdate=start_date, todate=end_date)  # 加载数据
    cerebro.adddata(data,name=code)
    print(code)

说明:
(1)逐一加载数据,需要注明代码名称

    cerebro.adddata(data,name=code)

5.代码示例

%matplotlib inline 
# 创建MACD策略  
class MACDStrategy(bt.Strategy):  
    params = (  
        ("short_period", 12),  
        ("long_period", 26),  
        ("signal_period", 9),  
        ("bprint", True), 
        ("pstake", 10), 
        ("pfast", 5), 
        ("pslow", 20), 
    )  
  
    def __init__(self):  
        # 创建MACD指标
        # 组合股票信号使用dict存储
        self.macds = dict()
        
        # 枚举数据的序号和数据,d就是一个股票的数据lines
        for i, d in enumerate(self.datas):
            # 每一个数据指标一个dict
            self.macds[d] = dict()
            self.macds[d]['macd'] = bt.indicators.MACD(d.close,period_me1=self.p.short_period,
                        period_me2=self.p.long_period,period_signal=self.p.signal_period)
            self.macds[d]['signal'] = self.macds[d]['macd'].lines.signal 
        
        # 初始化订单  
        self.order = None  

    def log(self, txt, dt=None):
        if self.params.bprint:
            dt = dt or self.data.datetime.date()
            print('%s, %s' % (dt.isoformat(), txt))
            
    def next(self):  
        # 检查是否有未完成的订单  
        if self.order:  
            return  
        
        # 枚举数据的序号和数据,d就是一个股票的数据lines
        for i, d in enumerate(self.datas):
            # 获取时间及股票代码
            dt, dn = self.datetime.date(), d._name      
            # 获取对应代码的仓位
            pos = self.getposition(d).size
            
            # 无仓位,则可以买入
            if not pos:   
                # MACD买入信号  ,可以多次买入
                if self.macds[d]['macd'] > self.macds[d]['signal']:
                    # data = d指定buy的代码
                    self.buy(data = d, size = self.p.pstake) 
            
            # 平仓 ,一次卖出
            elif self.macds[d]['macd'] < self.macds[d]['signal']:                  
                # data = d指定sell的代码
                self.close(data = d)                         
            
    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            # 提交给代理或者由代理接收的买/卖订单 - 不做操作
            return
        # 检查订单是否执行完毕
        
        # order是一次处理一个数据,不存在order.datas!!!    
        # order.data._name 区分order是哪个数据
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(
                    '%s :BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                    (order.data._name,
                     order.executed.price,
                     order.executed.value,
                     order.executed.comm))
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else: # 卖
                self.log('%s :SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                         (order.data._name,
                          order.executed.price,
                          order.executed.value,
                          order.executed.comm))
            
            self.bar_executed = len(self)

        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')
        # 无等待处理订单
        self.order = None
        
    def notify_trade(self, trade):
        if not trade.isclosed:
            return
        
        #可以按trade.data取触发notify_trade的日期
        dt = trade.data.datetime.date()
        
        # trade是一次处理一个数据,不存在trader.datas!!!    
        if trade.isclosed:
            self.log('%s :Closed, PnL Gross %.2f, Net %.2f,Net worth: %.2f' %
                (trade.data._name, round(trade.pnl, 2), round(trade.pnlcomm, 2),self.broker.getvalue()))
        
                
# 创建Cerebro引擎  
cerebro = bt.Cerebro()  
  
# 添加策略  
codes=['000858.SZ','000859.SZ','000860.SZ','000861.SZ','000862.SZ','000863.SZ','000868.SZ']

for code in codes:
    stock_df = get_code(code)
    data = btfeeds.PandasData(dataname=stock_df, fromdate=start_date, todate=end_date)  # 加载数据
    cerebro.adddata(data,name=code)
    print(code)

    
cerebro.addstrategy(MACDStrategy)  
  
# 设置初始资本  
cerebro.broker.set_cash(100000.0)  
  
# 运行Cerebro引擎  
    
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
# 遍历所有数据
cerebro.run()
# 打印最后结果
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())                   

  
# 输出策略结果  
#cerebro.plot(iplot=False)

6.输出结果

可以看到多个股票在一个策略下,在一个时间段同时交易。

000858.SZ
000859.SZ
000860.SZ
000861.SZ
000862.SZ
000863.SZ
000868.SZ
Starting Portfolio Value: 100000.00
2016-02-26, 000858.SZ :BUY EXECUTED, Price: 23.18, Cost: 231.80, Comm 0.00
2016-02-26, 000859.SZ :BUY EXECUTED, Price: 4.50, Cost: 45.00, Comm 0.00
2016-02-26, 000860.SZ :BUY EXECUTED, Price: 19.40, Cost: 194.00, Comm 0.00
2016-02-26, 000861.SZ :BUY EXECUTED, Price: 5.16, Cost: 51.60, Comm 0.00
2016-02-26, 000862.SZ :BUY EXECUTED, Price: 5.99, Cost: 59.90, Comm 0.00
2016-02-26, 000863.SZ :BUY EXECUTED, Price: 7.75, Cost: 77.50, Comm 0.00
2016-02-26, 000868.SZ :BUY EXECUTED, Price: 6.85, Cost: 68.50, Comm 0.00
2016-02-29, 000860.SZ :SELL EXECUTED, Price: 18.90, Cost: 194.00, Comm 0.00
2016-02-29, 000860.SZ :Closed, PnL Gross -5.00, Net -5.00,Net worth: 99965.10
2016-03-01, 000858.SZ :SELL EXECUTED, Price: 22.55, Cost: 231.80, Comm 0.00
2016-03-01, 000863.SZ :SELL EXECUTED, Price: 7.30, Cost: 77.50, Comm 0.00
2016-03-01, 000858.SZ :Closed, PnL Gross -6.30, Net -6.30,Net worth: 99974.80
2016-03-01, 000863.SZ :Closed, PnL Gross -4.50, Net -4.50,Net worth: 99974.80
2016-03-03, 000858.SZ :BUY EXECUTED, Price: 23.92, Cost: 239.20, Comm 0.00
2016-03-03, 000863.SZ :BUY EXECUTED, Price: 8.19, Cost: 81.90, Comm 0.00
2016-03-18, 000860.SZ :BUY EXECUTED, Price: 19.26, Cost: 192.60, Comm 0.00
2016-04-11, 000858.SZ :SELL EXECUTED, Price: 27.48, Cost: 239.20, Comm 0.00
2016-04-11, 000868.SZ :SELL EXECUTED, Price: 7.31, Cost: 68.50, Comm 0.00
2016-04-11, 000858.SZ :Closed, PnL Gross 35.60, Net 35.60,Net worth: 100091.10
2016-04-11, 000868.SZ :Closed, PnL Gross 4.60, Net 4.60,Net worth: 100091.10
2016-04-12, 000860.SZ :SELL EXECUTED, Price: 20.80, Cost: 192.60, Comm 0.00
2016-04-12, 000860.SZ :Closed, PnL Gross 15.40, Net 15.40,Net worth: 100090.00
2016-04-15, 000868.SZ :BUY EXECUTED, Price: 7.60, Cost: 76.00, Comm 0.00
2016-04-20, 000863.SZ :SELL EXECUTED, Price: 9.93, Cost: 81.90, Comm 0.00
2016-04-20, 000863.SZ :Closed, PnL Gross 17.40, Net 17.40,Net worth: 100075.50
2016-04-21, 000861.SZ :SELL EXECUTED, Price: 5.64, Cost: 51.60, Comm 0.00
2016-04-21, 000868.SZ :SELL EXECUTED, Price: 7.06, Cost: 76.00, Comm 0.00
2016-04-21, 000861.SZ :Closed, PnL Gross 4.80, Net 4.80,Net worth: 100075.30
2016-04-21, 000868.SZ :Closed, PnL Gross -5.40, Net -5.40,Net worth: 100075.30
2016-04-25, 000859.SZ :SELL EXECUTED, Price: 5.62, Cost: 45.00, Comm 0.00
2016-04-25, 000859.SZ :Closed, PnL Gross 11.20, Net 11.20,Net worth: 100074.70
2016-04-26, 000862.SZ :SELL EXECUTED, Price: 6.64, Cost: 59.90, Comm 0.00
2016-04-26, 000862.SZ :Closed, PnL Gross 6.50, Net 6.50,Net worth: 100074.30
2016-04-28, 000862.SZ :BUY EXECUTED, Price: 6.91, Cost: 69.10, Comm 0.00
2016-04-29, 000862.SZ :SELL EXECUTED, Price: 6.75, Cost: 69.10, Comm 0.00
2016-04-29, 000862.SZ :Closed, PnL Gross -1.60, Net -1.60,Net worth: 100072.70
2016-05-03, 000858.SZ :BUY EXECUTED, Price: 28.68, Cost: 286.80, Comm 0.00
2016-05-04, 000860.SZ :BUY EXECUTED, Price: 23.09, Cost: 230.90, Comm 0.00
2016-05-05, 000862.SZ :BUY EXECUTED, Price: 7.02, Cost: 70.20, Comm 0.00
2016-05-06, 000863.SZ :BUY EXECUTED, Price: 10.07, Cost: 100.70, Comm 0.00
2016-05-09, 000862.SZ :SELL EXECUTED, Price: 6.67, Cost: 70.20, Comm 0.00
2016-05-09, 000863.SZ :SELL EXECUTED, Price: 9.49, Cost: 100.70, Comm 0.00
2016-05-09, 000862.SZ :Closed, PnL Gross -3.50, Net -3.50,Net worth: 100055.80
2016-05-09, 000863.SZ :Closed, PnL Gross -5.80, Net -5.80,Net worth: 100055.80
2016-05-18, 000858.SZ :SELL EXECUTED, Price: 29.10, Cost: 286.80, Comm 0.00
2016-05-18, 000858.SZ :Closed, PnL Gross 4.20, Net 4.20,Net worth: 100055.20
2016-05-23, 000860.SZ :SELL EXECUTED, Price: 21.97, Cost: 230.90, Comm 0.00
2016-05-23, 000860.SZ :Closed, PnL Gross -11.20, Net -11.20,Net worth: 100056.40
2016-05-25, 000862.SZ :BUY EXECUTED, Price: 6.69, Cost: 66.90, Comm 0.00
2016-05-25, 000863.SZ :BUY EXECUTED, Price: 9.68, Cost: 96.80, Comm 0.00
2016-05-25, 000868.SZ :BUY EXECUTED, Price: 6.52, Cost: 65.20, Comm 0.00
2016-05-30, 000861.SZ :BUY EXECUTED, Price: 4.99, Cost: 49.90, Comm 0.00
2016-05-30, 000863.SZ :SELL EXECUTED, Price: 9.35, Cost: 96.80, Comm 0.00
2016-05-30, 000863.SZ :Closed, PnL Gross -3.30, Net -3.30,Net worth: 100052.80
2016-05-31, 000859.SZ :BUY EXECUTED, Price: 4.86, Cost: 48.60, Comm 0.00
2016-06-01, 000863.SZ :BUY EXECUTED, Price: 9.80, Cost: 98.00, Comm 0.00
2016-06-06, 000858.SZ :BUY EXECUTED, Price: 31.33, Cost: 313.30, Comm 0.00
2016-06-06, 000860.SZ :BUY EXECUTED, Price: 23.26, Cost: 232.60, Comm 0.00
2016-06-15, 000862.SZ :SELL EXECUTED, Price: 6.83, Cost: 66.90, Comm 0.00
2016-06-15, 000863.SZ :SELL EXECUTED, Price: 9.43, Cost: 98.00, Comm 0.00
2016-06-15, 000862.SZ :Closed, PnL Gross 1.40, Net 1.40,Net worth: 100070.60
2016-06-15, 000863.SZ :Closed, PnL Gross -3.70, Net -3.70,Net worth: 100070.60
2016-06-16, 000862.SZ :BUY EXECUTED, Price: 7.14, Cost: 71.40, Comm 0.00
2016-06-24, 000860.SZ :SELL EXECUTED, Price: 23.15, Cost: 232.60, Comm 0.00
2016-06-24, 000860.SZ :Closed, PnL Gross -1.10, Net -1.10,Net worth: 100057.10
2016-06-27, 000862.SZ :SELL EXECUTED, Price: 6.82, Cost: 71.40, Comm 0.00
2016-06-27, 000862.SZ :Closed, PnL Gross -3.20, Net -3.20,Net worth: 100069.20
2016-06-28, 000859.SZ :SELL EXECUTED, Price: 5.18, Cost: 48.60, Comm 0.00
2016-06-28, 000861.SZ :SELL EXECUTED, Price: 4.89, Cost: 49.90, Comm 0.00
2016-06-28, 000859.SZ :Closed, PnL Gross 3.20, Net 3.20,Net worth: 100070.60
2016-06-28, 000861.SZ :Closed, PnL Gross -1.00, Net -1.00,Net worth: 100070.60
2016-06-29, 000861.SZ :BUY EXECUTED, Price: 4.93, Cost: 49.30, Comm 0.00
2016-07-05, 000858.SZ :SELL EXECUTED, Price: 32.62, Cost: 313.30, Comm 0.00
2016-07-05, 000858.SZ :Closed, PnL Gross 12.90, Net 12.90,Net worth: 100074.90
2016-07-06, 000858.SZ :BUY EXECUTED, Price: 32.94, Cost: 329.40, Comm 0.00
2016-07-06, 000859.SZ :BUY EXECUTED, Price: 5.39, Cost: 53.90, Comm 0.00
2016-07-07, 000860.SZ :BUY EXECUTED, Price: 24.70, Cost: 247.00, Comm 0.00
2016-07-08, 000863.SZ :BUY EXECUTED, Price: 9.44, Cost: 94.40, Comm 0.00
2016-07-11, 000868.SZ :SELL EXECUTED, Price: 7.59, Cost: 65.20, Comm 0.00
2016-07-11, 000868.SZ :Closed, PnL Gross 10.70, Net 10.70,Net worth: 100116.90
2016-07-12, 000859.SZ :SELL EXECUTED, Price: 5.34, Cost: 53.90, Comm 0.00
2016-07-12, 000859.SZ :Closed, PnL Gross -0.50, Net -0.50,Net worth: 100123.50
2016-07-19, 000860.SZ :SELL EXECUTED, Price: 24.14, Cost: 247.00, Comm 0.00
2016-07-19, 000860.SZ :Closed, PnL Gross -5.60, Net -5.60,Net worth: 100096.00
2016-07-20, 000859.SZ :BUY EXECUTED, Price: 5.52, Cost: 55.20, Comm 0.00
2016-07-21, 000858.SZ :SELL EXECUTED, Price: 35.31, Cost: 329.40, Comm 0.00
2016-07-21, 000858.SZ :Closed, PnL Gross 23.70, Net 23.70,Net worth: 100092.40
2016-07-22, 000859.SZ :SELL EXECUTED, Price: 5.40, Cost: 55.20, Comm 0.00
2016-07-22, 000862.SZ :BUY EXECUTED, Price: 7.32, Cost: 73.20, Comm 0.00
2016-07-22, 000859.SZ :Closed, PnL Gross -1.20, Net -1.20,Net worth: 100089.80
2016-07-28, 000861.SZ :SELL EXECUTED, Price: 4.82, Cost: 49.30, Comm 0.00
2016-07-28, 000863.SZ :SELL EXECUTED, Price: 9.33, Cost: 94.40, Comm 0.00
2016-07-28, 000861.SZ :Closed, PnL Gross -1.10, Net -1.10,Net worth: 100090.30
2016-07-28, 000863.SZ :Closed, PnL Gross -1.10, Net -1.10,Net worth: 100090.30
2016-08-03, 000862.SZ :SELL EXECUTED, Price: 7.24, Cost: 73.20, Comm 0.00
2016-08-03, 000863.SZ :BUY EXECUTED, Price: 9.70, Cost: 97.00, Comm 0.00
2016-08-03, 000862.SZ :Closed, PnL Gross -0.80, Net -0.80,Net worth: 100086.40
2016-08-10, 000862.SZ :BUY EXECUTED, Price: 7.50, Cost: 75.00, Comm 0.00
2016-08-15, 000859.SZ :BUY EXECUTED, Price: 5.26, Cost: 52.60, Comm 0.00
2016-08-16, 000860.SZ :BUY EXECUTED, Price: 23.16, Cost: 231.60, Comm 0.00
2016-08-16, 000861.SZ :BUY EXECUTED, Price: 5.06, Cost: 50.60, Comm 0.00
2016-08-16, 000868.SZ :BUY EXECUTED, Price: 7.09, Cost: 70.90, Comm 0.00
2016-08-17, 000858.SZ :BUY EXECUTED, Price: 36.30, Cost: 363.00, Comm 0.00
2016-08-22, 000858.SZ :SELL EXECUTED, Price: 35.59, Cost: 363.00, Comm 0.00
2016-08-22, 000858.SZ :Closed, PnL Gross -7.10, Net -7.10,Net worth: 100087.80
2016-08-23, 000860.SZ :SELL EXECUTED, Price: 21.82, Cost: 231.60, Comm 0.00
2016-08-23, 000860.SZ :Closed, PnL Gross -13.40, Net -13.40,Net worth: 100089.10
2016-08-31, 000863.SZ :SELL EXECUTED, Price: 10.03, Cost: 97.00, Comm 0.00
2016-08-31, 000863.SZ :Closed, PnL Gross 3.30, Net 3.30,Net worth: 100078.80
2016-09-01, 000861.SZ :SELL EXECUTED, Price: 5.28, Cost: 50.60, Comm 0.00
2016-09-01, 000861.SZ :Closed, PnL Gross 2.20, Net 2.20,Net worth: 100075.20
2016-09-02, 000862.SZ :SELL EXECUTED, Price: 8.01, Cost: 75.00, Comm 0.00
2016-09-02, 000862.SZ :Closed, PnL Gross 5.10, Net 5.10,Net worth: 100077.20
2016-09-09, 000861.SZ :BUY EXECUTED, Price: 5.40, Cost: 54.00, Comm 0.00
2016-09-09, 000862.SZ :BUY EXECUTED, Price: 8.50, Cost: 85.00, Comm 0.00
2016-09-13, 000861.SZ :SELL EXECUTED, Price: 5.20, Cost: 54.00, Comm 0.00
2016-09-13, 000861.SZ :Closed, PnL Gross -2.00, Net -2.00,Net worth: 100077.80
2016-09-19, 000859.SZ :SELL EXECUTED, Price: 5.48, Cost: 52.60, Comm 0.00
2016-09-19, 000868.SZ :SELL EXECUTED, Price: 6.87, Cost: 70.90, Comm 0.00
2016-09-19, 000859.SZ :Closed, PnL Gross 2.20, Net 2.20,Net worth: 100077.70
2016-09-19, 000868.SZ :Closed, PnL Gross -2.20, Net -2.20,Net worth: 100077.70
2016-09-23, 000860.SZ :BUY EXECUTED, Price: 20.63, Cost: 206.30, Comm 0.00
2016-09-26, 000858.SZ :BUY EXECUTED, Price: 33.20, Cost: 332.00, Comm 0.00
2016-09-27, 000858.SZ :SELL EXECUTED, Price: 32.25, Cost: 332.00, Comm 0.00
2016-09-27, 000860.SZ :SELL EXECUTED, Price: 19.80, Cost: 206.30, Comm 0.00
2016-09-27, 000858.SZ :Closed, PnL Gross -9.50, Net -9.50,Net worth: 100059.40
2016-09-27, 000860.SZ :Closed, PnL Gross -8.30, Net -8.30,Net worth: 100059.40
2016-09-28, 000862.SZ :SELL EXECUTED, Price: 8.78, Cost: 85.00, Comm 0.00
2016-09-28, 000862.SZ :Closed, PnL Gross 2.80, Net 2.80,Net worth: 100058.80
2016-09-30, 000858.SZ :BUY EXECUTED, Price: 32.62, Cost: 326.20, Comm 0.00
2016-09-30, 000860.SZ :BUY EXECUTED, Price: 20.01, Cost: 200.10, Comm 0.00
2016-10-11, 000863.SZ :BUY EXECUTED, Price: 9.64, Cost: 96.40, Comm 0.00
2016-10-12, 000859.SZ :BUY EXECUTED, Price: 5.59, Cost: 55.90, Comm 0.00
2016-10-12, 000868.SZ :BUY EXECUTED, Price: 6.90, Cost: 69.00, Comm 0.00
2016-10-14, 000861.SZ :BUY EXECUTED, Price: 5.37, Cost: 53.70, Comm 0.00
2016-10-24, 000861.SZ :SELL EXECUTED, Price: 5.14, Cost: 53.70, Comm 0.00
2016-10-24, 000861.SZ :Closed, PnL Gross -2.30, Net -2.30,Net worth: 100074.40
2016-10-25, 000863.SZ :SELL EXECUTED, Price: 9.59, Cost: 96.40, Comm 0.00
2016-10-25, 000863.SZ :Closed, PnL Gross -0.50, Net -0.50,Net worth: 100083.80
2016-10-27, 000863.SZ :BUY EXECUTED, Price: 9.68, Cost: 96.80, Comm 0.00
2016-11-01, 000863.SZ :SELL EXECUTED, Price: 9.51, Cost: 96.80, Comm 0.00
2016-11-01, 000863.SZ :Closed, PnL Gross -1.70, Net -1.70,Net worth: 100088.40
2016-11-04, 000860.SZ :SELL EXECUTED, Price: 20.38, Cost: 200.10, Comm 0.00
2016-11-04, 000860.SZ :Closed, PnL Gross 3.70, Net 3.70,Net worth: 100080.30
2016-11-08, 000862.SZ :BUY EXECUTED, Price: 9.17, Cost: 91.70, Comm 0.00
2016-11-15, 000858.SZ :SELL EXECUTED, Price: 34.34, Cost: 326.20, Comm 0.00
2016-11-15, 000860.SZ :BUY EXECUTED, Price: 20.84, Cost: 208.40, Comm 0.00
2016-11-15, 000861.SZ :BUY EXECUTED, Price: 5.13, Cost: 51.30, Comm 0.00
2016-11-15, 000858.SZ :Closed, PnL Gross 17.20, Net 17.20,Net worth: 100086.70
2016-11-16, 000863.SZ :BUY EXECUTED, Price: 9.36, Cost: 93.60, Comm 0.00
2016-11-18, 000863.SZ :SELL EXECUTED, Price: 9.30, Cost: 93.60, Comm 0.00
2016-11-18, 000863.SZ :Closed, PnL Gross -0.60, Net -0.60,Net worth: 100082.00
2016-11-25, 000862.SZ :SELL EXECUTED, Price: 9.13, Cost: 91.70, Comm 0.00
2016-11-25, 000862.SZ :Closed, PnL Gross -0.40, Net -0.40,Net worth: 100086.30
2016-11-28, 000858.SZ :BUY EXECUTED, Price: 35.60, Cost: 356.00, Comm 0.00
2016-11-28, 000868.SZ :SELL EXECUTED, Price: 7.10, Cost: 69.00, Comm 0.00
2016-11-28, 000868.SZ :Closed, PnL Gross 2.00, Net 2.00,Net worth: 100084.80
2016-12-01, 000859.SZ :SELL EXECUTED, Price: 5.80, Cost: 55.90, Comm 0.00
2016-12-01, 000861.SZ :SELL EXECUTED, Price: 5.06, Cost: 51.30, Comm 0.00
2016-12-01, 000859.SZ :Closed, PnL Gross 2.10, Net 2.10,Net worth: 100081.80
2016-12-01, 000861.SZ :Closed, PnL Gross -0.70, Net -0.70,Net worth: 100081.80
2016-12-05, 000860.SZ :SELL EXECUTED, Price: 20.20, Cost: 208.40, Comm 0.00
2016-12-05, 000860.SZ :Closed, PnL Gross -6.40, Net -6.40,Net worth: 100070.60
2016-12-09, 000861.SZ :BUY EXECUTED, Price: 5.10, Cost: 51.00, Comm 0.00
2016-12-13, 000861.SZ :SELL EXECUTED, Price: 4.85, Cost: 51.00, Comm 0.00
2016-12-13, 000861.SZ :Closed, PnL Gross -2.50, Net -2.50,Net worth: 100075.30
2016-12-15, 000858.SZ :SELL EXECUTED, Price: 35.70, Cost: 356.00, Comm 0.00
2016-12-15, 000860.SZ :BUY EXECUTED, Price: 20.79, Cost: 207.90, Comm 0.00
2016-12-15, 000858.SZ :Closed, PnL Gross 1.00, Net 1.00,Net worth: 100072.60
2016-12-22, 000862.SZ :BUY EXECUTED, Price: 8.52, Cost: 85.20, Comm 0.00
2016-12-26, 000859.SZ :BUY EXECUTED, Price: 5.71, Cost: 57.10, Comm 0.00
2016-12-27, 000860.SZ :SELL EXECUTED, Price: 20.56, Cost: 207.90, Comm 0.00
2016-12-27, 000860.SZ :Closed, PnL Gross -2.30, Net -2.30,Net worth: 100070.80
2016-12-29, 000863.SZ :BUY EXECUTED, Price: 8.40, Cost: 84.00, Comm 0.00
Final Portfolio Value: 100068.70

7. plot

如果股票数量太多,绘图都汇集到一起,没有意义。
volume不绘图
组合用三个股票演示一下:

# 输出策略结果  
#cerebro.plot(style = "candlestick", iplot=False)
cerebro.plot(style = "candlestick",iplot=False,volume=False)

在这里插入图片描述

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
backtrader是一个功能强大的量化回测框架,可以用于多股票回测。文献提到了如何加载多只股票数据并构建交易组合进行量化回测。通过backtrader,你可以将多只股票的数据加载到回测系统中,并使用自定义的交易策略对这些股票进行回测。在回测过程中,你可以根据自己的需求设置参数阈值、优化策略,以及评估交易的业绩指标。同时,backtrader也可以进行股票组合的优化和回测,通过合理的选股范围和交易周期等参数设置,可以对股票组合的回报率、回撤、夏普比率等指标进行评估。然而,文献指出,回测实例的结果只是供参考,并不构成任何交易建议。因此,在使用backtrader进行多股票回测时,需要根据具体的情况进行参数设置和策略优化,以达到更好的回测效果。另外,文献也提到了一些建议,如如何正确实现滚动回测的算法和处理多股场景的问题等。总之,backtrader是一款非常强大的量化回测框架,可以满足多股票回测的需求,但在使用过程中需要根据具体情况进行参数设置和策略优化,才能得到更好的回测结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [如何用backtrader股票组合进行量化回测?](https://blog.csdn.net/ndhtou222/article/details/106416802)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [backtrader高级walk forward多股滚动回测](https://blog.csdn.net/qtbgo/article/details/125225612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值