Customizing the trading strategy

In this post, we introduce other settings to customize the trading strategy as follows:

  1. Creating a tuple to easily alter static parameters in our trading strategy.
  2. Change the position size of each trade.

The code additions here are in the following cells:

  1. Strategy Class
  2. Backtest settings

Import modules

In [6]:
import datetime
import os.path
import sys
import backtrader as bt
import matplotlib.pyplot as plt

Data

In [7]:
homepath = os.getenv('HOME')
datapath = os.path.join(homepath, 'github/backtrader/datas/orcl-1995-2014.txt')

data = bt.feeds.YahooFinanceCSVData(
    dataname=datapath,
    fromdate=datetime.datetime(2000,1,1),
    todate = datetime.datetime(2000,12,31),
    reverse=False)

Strategy Class

We add a tuple of tuples called params at the top of the class so we can easily update these strategy variables. The exitbars is set to 10 instead of 5.

We also update the sell signal from (self.bar_executed+5) to (self.bar_executed+self.params.exitbars).

In [8]:
class Strat1_2BD_5BH(bt.Strategy):
    
    params = (
        ('exitbars',10), # Tuple of tuples containing any variable settings required by the strategy.
    )
    
    def __init__(self):
        self.dataclose= self.datas[0].close    # Keep a reference to the "close" line in the data[0] dataseries
        self.order = None # Property to keep track of pending orders.  There are no orders when the strategy is initialized.
        self.buyprice = None
        self.buycomm = None
    
    
    def log(self, txt, dt=None):
        # Logging function for the strategy.  'txt' is the statement and 'dt' can be used to specify a specific datetime
        dt = dt or self.datas[0].datetime.date(0)
        print('{0},{1}'.format(dt.isoformat(),txt))
    
    def notify_order(self, order):
        # 1. If order is submitted/accepted, do nothing 
        if order.status in [order.Submitted, order.Accepted]:
            return
        # 2. If order is buy/sell executed, report price executed
        if order.status in [order.Completed]: 
            if order.isbuy():
                self.log('BUY EXECUTED, Price: {0:8.2f}, Cost: {1:8.2f}, Comm: {2:8.2f}'.format(
                    order.executed.price,
                    order.executed.value,
                    order.executed.comm))
                
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:
                self.log('SELL EXECUTED, {0:8.2f}, Cost: {1:8.2f}, Comm{2:8.2f}'.format(
                    order.executed.price, 
                    order.executed.value,
                    order.executed.comm))
            
            self.bar_executed = len(self) #when was trade executed
        # 3. If order is canceled/margin/rejected, report order canceled
        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
        
        self.log('OPERATION PROFIT, GROSS {0:8.2f}, NET {1:8.2f}'.format(
            trade.pnl, trade.pnlcomm))
    
    def next(self):
        # Log the closing prices of the series from the reference
        self.log('Close, {0:8.2f}'.format(self.dataclose[0]))

        if self.order: # check if order is pending, if so, then break out
            return
                
        # since there is no order pending, are we in the market?    
        if not self.position: # not in the market
            if self.dataclose[0] < self.dataclose[-1]:
                if self.dataclose[-1] < self.dataclose[-2]:
                    self.log('BUY CREATE {0:8.2f}'.format(self.dataclose[0]))
                    self.order = self.buy()           
        else: # in the market
            if len(self) >= (self.bar_executed+self.params.exitbars):
                self.log('SELL CREATE, {0:8.2f}'.format(self.dataclose[0]))
                self.order = self.sell()

Backtest settings

Parameters that are defined in the trading strategy can also be modified in the cerebro.addstrategy() function and this will override the parameters set within the Strategy class. We see that we have set exitbars=10.

For the size of each trade, we have set a cerebro.addsizer that sets the number of units (e.g., futures contracts, share lots) to be purchased. In the below code, we have set the stake=10 such that 10 units of the asset is purchased each time there is a successful Buy signal.

In [9]:
cerebro = bt.Cerebro()  
cerebro.adddata(data) 
cerebro.addstrategy(Strat1_2BD_5BH, exitbars=10) 
cerebro.addsizer(bt.sizers.FixedSize,stake=10)
cerebro.broker.setcash(100000.0) 
cerebro.broker.setcommission(commission=0.001) 

Run backtest

We can see from below that the Buy signal is still the same as buy orders are created after the closing price is down twice in a row, except that Sell signal is triggered only after 10 trading days (i.e, Buy is on 2000-01-06, and Sell is on 2000-01-21). The trading strategy continues to be profitable with a Final value of $100155.

In [10]:
print('Starting Portfolio Value: {0:8.2f}'.format(cerebro.broker.getvalue()))
cerebro.run()
print('Final Portfolio Value: {0:8.2f}'.format(cerebro.broker.getvalue()))
Starting Portfolio Value: 100000.00
2000-01-03,Close,    26.27
2000-01-04,Close,    23.95
2000-01-05,Close,    22.68
2000-01-05,BUY CREATE    22.68
2000-01-06,BUY EXECUTED, Price:    22.27, Cost:   222.70, Comm:     0.22
2000-01-06,Close,    21.35
2000-01-07,Close,    22.99
2000-01-10,Close,    25.74
2000-01-11,Close,    24.99
2000-01-12,Close,    23.49
2000-01-13,Close,    23.36
2000-01-14,Close,    23.75
2000-01-18,Close,    24.74
2000-01-19,Close,    25.41
2000-01-20,Close,    26.35
2000-01-21,Close,    26.55
2000-01-21,SELL CREATE,    26.55
2000-01-24,SELL EXECUTED,    26.80, Cost:   222.70, Comm    0.27
2000-01-24,OPERATION PROFIT, GROSS    45.30, NET    44.81
2000-01-24,Close,    24.10
2000-01-25,Close,    25.10
2000-01-26,Close,    24.49
2000-01-27,Close,    23.04
2000-01-27,BUY CREATE    23.04
2000-01-28,BUY EXECUTED, Price:    22.90, Cost:   229.00, Comm:     0.23
2000-01-28,Close,    21.07
2000-01-31,Close,    22.22
2000-02-01,Close,    24.02
2000-02-02,Close,    24.16
2000-02-03,Close,    25.21
2000-02-04,Close,    25.71
2000-02-07,Close,    26.66
2000-02-08,Close,    26.49
2000-02-09,Close,    26.66
2000-02-10,Close,    27.71
2000-02-11,Close,    26.55
2000-02-11,SELL CREATE,    26.55
2000-02-14,SELL EXECUTED,    27.07, Cost:   229.00, Comm    0.27
2000-02-14,OPERATION PROFIT, GROSS    41.70, NET    41.20
2000-02-14,Close,    27.66
2000-02-15,Close,    27.30
2000-02-16,Close,    27.24
2000-02-16,BUY CREATE    27.24
2000-02-17,BUY EXECUTED, Price:    27.46, Cost:   274.60, Comm:     0.27
2000-02-17,Close,    27.41
2000-02-18,Close,    26.05
2000-02-22,Close,    26.38
2000-02-23,Close,    28.05
2000-02-24,Close,    27.55
2000-02-25,Close,    31.41
2000-02-28,Close,    30.52
2000-02-29,Close,    33.02
2000-03-01,Close,    31.80
2000-03-02,Close,    30.47
2000-03-03,Close,    33.36
2000-03-03,SELL CREATE,    33.36
2000-03-06,SELL EXECUTED,    33.27, Cost:   274.60, Comm    0.33
2000-03-06,OPERATION PROFIT, GROSS    58.10, NET    57.49
2000-03-06,Close,    33.69
2000-03-07,Close,    33.33
2000-03-08,Close,    36.97
2000-03-09,Close,    37.36
2000-03-10,Close,    36.30
2000-03-13,Close,    35.02
2000-03-13,BUY CREATE    35.02
2000-03-14,BUY EXECUTED, Price:    36.41, Cost:   364.10, Comm:     0.36
2000-03-14,Close,    34.25
2000-03-15,Close,    34.97
2000-03-16,Close,    36.44
2000-03-17,Close,    35.50
2000-03-20,Close,    34.75
2000-03-21,Close,    35.89
2000-03-22,Close,    37.39
2000-03-23,Close,    38.64
2000-03-24,Close,    38.69
2000-03-27,Close,    39.33
2000-03-28,Close,    38.50
2000-03-28,SELL CREATE,    38.50
2000-03-29,SELL EXECUTED,    38.28, Cost:   364.10, Comm    0.38
2000-03-29,OPERATION PROFIT, GROSS    18.70, NET    17.95
2000-03-29,Close,    36.69
2000-03-29,BUY CREATE    36.69
2000-03-30,BUY EXECUTED, Price:    34.91, Cost:   349.10, Comm:     0.35
2000-03-30,Close,    34.88
2000-03-31,Close,    34.72
2000-04-03,Close,    34.19
2000-04-04,Close,    33.77
2000-04-05,Close,    34.80
2000-04-06,Close,    36.55
2000-04-07,Close,    38.75
2000-04-10,Close,    36.69
2000-04-11,Close,    34.41
2000-04-12,Close,    32.52
2000-04-13,Close,    31.99
2000-04-13,SELL CREATE,    31.99
2000-04-14,SELL EXECUTED,    31.10, Cost:   349.10, Comm    0.31
2000-04-14,OPERATION PROFIT, GROSS   -38.10, NET   -38.76
2000-04-14,Close,    27.80
2000-04-14,BUY CREATE    27.80
2000-04-17,BUY EXECUTED, Price:    26.91, Cost:   269.10, Comm:     0.27
2000-04-17,Close,    33.27
2000-04-18,Close,    35.11
2000-04-19,Close,    33.16
2000-04-20,Close,    31.49
2000-04-24,Close,    32.22
2000-04-25,Close,    33.61
2000-04-26,Close,    32.11
2000-04-27,Close,    34.38
2000-04-28,Close,    35.55
2000-05-01,Close,    35.44
2000-05-02,Close,    34.61
2000-05-02,SELL CREATE,    34.61
2000-05-03,SELL EXECUTED,    34.19, Cost:   269.10, Comm    0.34
2000-05-03,OPERATION PROFIT, GROSS    72.80, NET    72.19
2000-05-03,Close,    33.72
2000-05-03,BUY CREATE    33.72
2000-05-04,BUY EXECUTED, Price:    33.49, Cost:   334.90, Comm:     0.33
2000-05-04,Close,    33.02
2000-05-05,Close,    34.16
2000-05-08,Close,    32.16
2000-05-09,Close,    32.02
2000-05-10,Close,    30.08
2000-05-11,Close,    32.19
2000-05-12,Close,    32.99
2000-05-15,Close,    34.25
2000-05-16,Close,    35.22
2000-05-17,Close,    34.77
2000-05-18,Close,    32.49
2000-05-18,SELL CREATE,    32.49
2000-05-19,SELL EXECUTED,    32.02, Cost:   334.90, Comm    0.32
2000-05-19,OPERATION PROFIT, GROSS   -14.70, NET   -15.36
2000-05-19,Close,    31.16
2000-05-19,BUY CREATE    31.16
2000-05-22,BUY EXECUTED, Price:    31.16, Cost:   311.60, Comm:     0.31
2000-05-22,Close,    30.16
2000-05-23,Close,    27.85
2000-05-24,Close,    28.57
2000-05-25,Close,    29.55
2000-05-26,Close,    29.80
2000-05-30,Close,    32.99
2000-05-31,Close,    31.97
2000-06-01,Close,    34.63
2000-06-02,Close,    35.66
2000-06-05,Close,    36.00
2000-06-06,Close,    34.27
2000-06-06,SELL CREATE,    34.27
2000-06-07,SELL EXECUTED,    34.13, Cost:   311.60, Comm    0.34
2000-06-07,OPERATION PROFIT, GROSS    29.70, NET    29.05
2000-06-07,Close,    35.58
2000-06-08,Close,    36.64
2000-06-09,Close,    36.77
2000-06-12,Close,    35.83
2000-06-13,Close,    36.33
2000-06-14,Close,    35.13
2000-06-15,Close,    36.69
2000-06-16,Close,    36.41
2000-06-19,Close,    38.25
2000-06-20,Close,    38.27
2000-06-21,Close,    38.33
2000-06-22,Close,    36.25
2000-06-23,Close,    35.36
2000-06-23,BUY CREATE    35.36
2000-06-26,BUY EXECUTED, Price:    35.69, Cost:   356.90, Comm:     0.36
2000-06-26,Close,    36.77
2000-06-27,Close,    36.58
2000-06-28,Close,    36.89
2000-06-29,Close,    35.97
2000-06-30,Close,    37.39
2000-07-03,Close,    35.66
2000-07-05,Close,    32.16
2000-07-06,Close,    33.63
2000-07-07,Close,    33.75
2000-07-10,Close,    32.97
2000-07-11,Close,    32.16
2000-07-11,SELL CREATE,    32.16
2000-07-12,SELL EXECUTED,    32.66, Cost:   356.90, Comm    0.33
2000-07-12,OPERATION PROFIT, GROSS   -30.30, NET   -30.98
2000-07-12,Close,    33.22
2000-07-13,Close,    33.69
2000-07-14,Close,    33.86
2000-07-17,Close,    33.86
2000-07-18,Close,    32.99
2000-07-19,Close,    32.80
2000-07-19,BUY CREATE    32.80
2000-07-20,BUY EXECUTED, Price:    33.27, Cost:   332.70, Comm:     0.33
2000-07-20,Close,    34.75
2000-07-21,Close,    33.55
2000-07-24,Close,    33.36
2000-07-25,Close,    33.80
2000-07-26,Close,    34.13
2000-07-27,Close,    33.38
2000-07-28,Close,    32.19
2000-07-31,Close,    33.44
2000-08-01,Close,    32.52
2000-08-02,Close,    32.52
2000-08-03,Close,    34.44
2000-08-03,SELL CREATE,    34.44
2000-08-04,SELL EXECUTED,    34.83, Cost:   332.70, Comm    0.35
2000-08-04,OPERATION PROFIT, GROSS    15.60, NET    14.92
2000-08-04,Close,    36.27
2000-08-07,Close,    36.41
2000-08-08,Close,    36.91
2000-08-09,Close,    36.19
2000-08-10,Close,    35.61
2000-08-10,BUY CREATE    35.61
2000-08-11,BUY EXECUTED, Price:    35.55, Cost:   355.50, Comm:     0.36
2000-08-11,Close,    36.08
2000-08-14,Close,    36.64
2000-08-15,Close,    36.14
2000-08-16,Close,    36.11
2000-08-17,Close,    37.33
2000-08-18,Close,    36.16
2000-08-21,Close,    37.00
2000-08-22,Close,    37.16
2000-08-23,Close,    36.86
2000-08-24,Close,    37.66
2000-08-25,Close,    37.64
2000-08-25,SELL CREATE,    37.64
2000-08-28,SELL EXECUTED,    37.80, Cost:   355.50, Comm    0.38
2000-08-28,OPERATION PROFIT, GROSS    22.50, NET    21.77
2000-08-28,Close,    38.58
2000-08-29,Close,    39.03
2000-08-30,Close,    39.25
2000-08-31,Close,    40.44
2000-09-01,Close,    41.19
2000-09-05,Close,    40.50
2000-09-06,Close,    39.69
2000-09-06,BUY CREATE    39.69
2000-09-07,BUY EXECUTED, Price:    40.08, Cost:   400.80, Comm:     0.40
2000-09-07,Close,    40.56
2000-09-08,Close,    38.50
2000-09-11,Close,    37.11
2000-09-12,Close,    35.30
2000-09-13,Close,    36.39
2000-09-14,Close,    37.78
2000-09-15,Close,    34.83
2000-09-18,Close,    34.01
2000-09-19,Close,    35.27
2000-09-20,Close,    35.55
2000-09-21,Close,    35.11
2000-09-21,SELL CREATE,    35.11
2000-09-22,SELL EXECUTED,    33.77, Cost:   400.80, Comm    0.34
2000-09-22,OPERATION PROFIT, GROSS   -63.10, NET   -63.84
2000-09-22,Close,    35.91
2000-09-25,Close,    35.02
2000-09-26,Close,    35.33
2000-09-27,Close,    35.52
2000-09-28,Close,    36.24
2000-09-29,Close,    35.02
2000-10-02,Close,    35.02
2000-10-03,Close,    30.91
2000-10-04,Close,    30.30
2000-10-04,BUY CREATE    30.30
2000-10-05,BUY EXECUTED, Price:    30.38, Cost:   303.80, Comm:     0.30
2000-10-05,Close,    30.38
2000-10-06,Close,    30.08
2000-10-09,Close,    29.69
2000-10-10,Close,    28.74
2000-10-11,Close,    27.69
2000-10-12,Close,    28.02
2000-10-13,Close,    31.69
2000-10-16,Close,    30.74
2000-10-17,Close,    29.96
2000-10-18,Close,    29.85
2000-10-19,Close,    32.36
2000-10-19,SELL CREATE,    32.36
2000-10-20,SELL EXECUTED,    32.13, Cost:   303.80, Comm    0.32
2000-10-20,OPERATION PROFIT, GROSS    17.50, NET    16.87
2000-10-20,Close,    31.35
2000-10-23,Close,    30.30
2000-10-23,BUY CREATE    30.30
2000-10-24,BUY EXECUTED, Price:    31.13, Cost:   311.30, Comm:     0.31
2000-10-24,Close,    31.85
2000-10-25,Close,    30.58
2000-10-26,Close,    30.30
2000-10-27,Close,    30.41
2000-10-30,Close,    28.13
2000-10-31,Close,    29.35
2000-11-01,Close,    27.91
2000-11-02,Close,    26.30
2000-11-03,Close,    26.96
2000-11-06,Close,    24.85
2000-11-07,Close,    23.63
2000-11-07,SELL CREATE,    23.63
2000-11-08,SELL EXECUTED,    24.35, Cost:   311.30, Comm    0.24
2000-11-08,OPERATION PROFIT, GROSS   -67.80, NET   -68.35
2000-11-08,Close,    22.07
2000-11-08,BUY CREATE    22.07
2000-11-09,BUY EXECUTED, Price:    21.96, Cost:   219.60, Comm:     0.22
2000-11-09,Close,    24.18
2000-11-10,Close,    22.63
2000-11-13,Close,    22.01
2000-11-14,Close,    25.24
2000-11-15,Close,    25.68
2000-11-16,Close,    24.35
2000-11-17,Close,    25.63
2000-11-20,Close,    22.01
2000-11-21,Close,    21.24
2000-11-22,Close,    19.85
2000-11-24,Close,    21.46
2000-11-24,SELL CREATE,    21.46
2000-11-27,SELL EXECUTED,    22.63, Cost:   219.60, Comm    0.23
2000-11-27,OPERATION PROFIT, GROSS     6.70, NET     6.25
2000-11-27,Close,    20.57
2000-11-28,Close,    20.15
2000-11-28,BUY CREATE    20.15
2000-11-29,BUY EXECUTED, Price:    20.63, Cost:   206.30, Comm:     0.21
2000-11-29,Close,    20.35
2000-11-30,Close,    23.57
2000-12-01,Close,    23.52
2000-12-04,Close,    25.07
2000-12-05,Close,    28.02
2000-12-06,Close,    26.85
2000-12-07,Close,    25.18
2000-12-08,Close,    26.74
2000-12-11,Close,    28.41
2000-12-12,Close,    27.35
2000-12-13,Close,    25.24
2000-12-13,SELL CREATE,    25.24
2000-12-14,SELL EXECUTED,    26.02, Cost:   206.30, Comm    0.26
2000-12-14,OPERATION PROFIT, GROSS    53.90, NET    53.43
2000-12-14,Close,    24.46
2000-12-14,BUY CREATE    24.46
2000-12-15,BUY EXECUTED, Price:    26.18, Cost:   261.80, Comm:     0.26
2000-12-15,Close,    25.41
2000-12-18,Close,    28.46
2000-12-19,Close,    27.24
2000-12-20,Close,    25.35
2000-12-21,Close,    26.24
2000-12-22,Close,    28.35
2000-12-26,Close,    27.52
2000-12-27,Close,    27.30
2000-12-28,Close,    27.63
2000-12-29,Close,    25.85
Final Portfolio Value: 100155.09

Plot backtest results

In [27]:
%matplotlib inline
cerebro.plot()
Out[27]:
[[<Figure size 432x288 with 4 Axes>]]

Conclusion

In this post, we learnt how to customize the trading strategy as follows:

  1. We learnt how to set static parameters using a tuple of tuples at the top of the strategy class. These parameters can also be modified in the cerebro.addstrategy().
  2. We also set the number of units/contracts for the trading strategy to enter.

In the next post, we will look at adding indicators.

The below code needs to be run to execute cerebro.plot() successfullly

In [26]:
import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randint(0,100,size=(100,4)),columns = list('ABCD'))
df.head()
df.plot()
Out[26]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2312b3a940>
In [ ]:
 

Comments

Comments powered by Disqus