how to change backtrader default buy & sell signal strategy into our own strategy



  • Hi,

    I am new to Backtrader , im slowly getting everything now. I want to change default backtrader buy sell signal strategy into my own strategy. Can you help me to fix this?. I want to know following things.

    • what kind of strategy it is using to generate?
    • can we change?

    here is my code.

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    import os.path
    import argparse
    import datetime
    import collections
    
    import backtrader as bt
    import backtrader.feeds as btfeeds
    import backtrader.plot as plt
    import backtrader.indicators as btinds
    
    MAINSIGNALS = collections.OrderedDict(
        (('longonly', bt.SIGNAL_LONG),
         ('shortonly', bt.SIGNAL_SHORT),
         ))
    
    
    class Plotter(plt.Plot):
        def __init__(self):
            super().__init__(volup='#60cc73')  # custom color for volume up bars
    
        def show(self):
            mng = self.mpyplot.get_current_fig_manager()
            mng.window.state('zoomed')
            self.mpyplot.show()
    
    
    class St(bt.Strategy):
        def log(self, txt, dt=None):
            ''' Logging function fot this strategy'''
            dt = dt or self.data.datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
            self.signal = 0
    
    
        def notify_order(self, order):
    
    
    
            if order.status in [order.Submitted, order.Accepted]:
                return
    
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.signal += 1
                    self.log(
                        'BUY EXECUTED, Price: %.5f, Cost: %.5f, Position : %d' %
                        (order.executed.price,
                         order.executed.value, self.signal))
                    self.buyprice = order.executed.price
    
                else:  # Sell
                    self.signal -= 1
                    self.log('SELL EXECUTED, Price: %.5f, Cost: %.5f,Position : %d' %
                             (order.executed.price,
                              order.executed.value, self.signal))
    
                    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
    
            self.log('OPERATION PROFIT, GROSS %.5f, NET %.5f' %
                     (trade.pnl, trade.pnlcomm))
    
    
        def next(self):
            txt = ','.join(
                ['%04d' % len(self.data),
                 self.data.datetime.date(0).isoformat(),
                 'Open : %.5f' % self.data.open[0],
                 'High : %.5f' % self.data.high[0],
                 'Low : %.5f' % self.data.low[0],
                 'Close : %.5f' % self.data.close[0],
                 'Position : %d' % self.signal])
            print(txt)
    
            if self.signal == 0:
                if self.data.open[0] > self.data.close[0]:
    
    
                    o1 = self.buy(exectype=bt.Order.Market,
                                  transmit=False)
    
                    print('{}: Oref {} / Buy at {}'.format(
                        self.datetime.date(), o1.ref, self.data.open[1]))
    
                    o2 = self.sell(exectype=bt.Order.Stop,
                                   price=0.99 * self.data.open[1],
                                   parent=o1,
                                   transmit=False)
    
                    print('{}: Oref {} / Sell Stop at {}'.format(
                        self.datetime.date(), o2.ref, 0.99 * self.data.open[1]))
    
                    o3 = self.sell(exectype=bt.Order.Limit,
                                   price=1.01 * self.data.open[1],
                                   parent=o1,
                                   transmit=True)
    
                    print('{}: Oref {} / Sell Limit at {}'.format(
                        self.datetime.date(), o3.ref, 1.01 * self.data.open[1]))
    
                    self.orefs = [o1.ref, o2.ref, o3.ref]
    
                elif self.data.open[0] < self.data.close[0]:
    
                    o1 = self.sell(exectype=bt.Order.Market,
                                   transmit=False)
    
                    print('{}: Oref {} / Sell at {}'.format(
                        self.datetime.date(), o1.ref, self.data.open[1]))
    
                    o2 = self.buy(exectype=bt.Order.Stop,
                                  price=1.01 * self.data.open[1],
                                  parent=o1,
                                  transmit=False)
    
                    print('{}: Oref {} / Buy Stop at {}'.format(
                        self.datetime.date(), o2.ref, 1.01 * self.data.open[1]))
    
                    o3 = self.buy(exectype=bt.Order.Limit,
                                  price=0.99 * self.data.open[1],
                                  parent=o1,
                                  transmit=True)
    
                    print('{}: Oref {} / Buy Limit at {}'.format(
                        self.datetime.date(), o3.ref, 0.99 * self.data.open[1]))
    
                    self.orefs = [o1.ref, o2.ref, o3.ref]
    
            elif self.signal == 1:
                if self.data.open[0] > self.data.close[0]:
                    return
    
                elif self.data.open[0] < self.data.close[0]:
                    o1 = self.sell(exectype=bt.Order.Market,
                                   transmit=False, size=2)
    
                    print('{}: Oref {} / Sell at {}'.format(
                        self.datetime.date(), o1.ref, self.data.open[1]))
    
                    o2 = self.buy(exectype=bt.Order.Stop,
                                  price=1.01 * self.data.open[1],
                                  parent=o1,
                                  transmit=False)
    
                    print('{}: Oref {} / Buy Stop at {}'.format(
                        self.datetime.date(), o2.ref, 1.01 * self.data.open[1]))
    
                    o3 = self.buy(exectype=bt.Order.Limit,
                                  price=0.99 * self.data.open[1],
                                  parent=o1,
                                  transmit=True)
    
                    print('{}: Oref {} / Buy Limit at {}'.format(
                        self.datetime.date(), o3.ref, 0.99 * self.data.open[1]))
    
                    self.orefs = [o1.ref, o2.ref, o3.ref]
    
            elif self.signal == -1:
                if self.data.open[0] < self.data.close[0]:
                    return
    
                elif self.data.open[0] > self.data.close[0]:
    
                    o1 = self.sell(exectype=bt.Order.Market, size=2,
                                   transmit=False)
    
                    print('{}: Oref {} / Sell at {}'.format(
                        self.datetime.date(), o1.ref, self.data.open[1]))
    
                    o2 = self.buy(exectype=bt.Order.Stop,
                                  price=1.01 * self.data.open[1],
                                  parent=o1,
                                  transmit=False)
    
                    print('{}: Oref {} / Buy Stop at {}'.format(
                        self.datetime.date(), o2.ref, 1.01 * self.data.open[1]))
    
                    o3 = self.buy(exectype=bt.Order.Limit,
                                  price=0.99 * self.data.open[1],
                                  parent=o1,
                                  transmit=True)
    
                    print('{}: Oref {} / Buy Limit at {}'.format(
                        self.datetime.date(), o3.ref, 0.99 * self.data.open[1]))
    
                    self.orefs = [o1.ref, o2.ref, o3.ref]
    
    
    class Plotter(plt.Plot):
        def __init__(self):
            super().__init__(volup='#60cc73')  # custom color for volume up bars
    
        def show(self):
            mng = self.mpyplot.get_current_fig_manager()
            mng.window.state('zoomed')
            self.mpyplot.show()
    
    
    def runstrat():
        args = parse_args()
    
        cerebro = bt.Cerebro()
        # modpath = 'd:\\I - TradersGPS\\'
        # datapath = os.path.join(modpath, 'GBPUSD_D1_UTC+2_00.csv')
        data = btfeeds.GenericCSVData(  dataname='E:\\SARATH\\Project\\IQfeed\\data-1510663056754.csv',
                                        fromdate=datetime.datetime(2017, 6, 1),
                                        todate=datetime.datetime(2017, 11, 3),
                                        timeframe=bt.TimeFrame.Minutes,
                                        compression=1,
                                        nullvalue=0.0,
                                        dtformat=('%Y-%m-%d %H:%M:%S'),
                                        datetime=0,
                                        time=-1,
                                        open=2,
                                        high=3,
                                        low=4,
                                        close=1,
                                        volume=5,
                                        openinterest=6 )
    
        cerebro.adddata(data)
    
        cerebro.addstrategy(St)
        cerebro.broker.setcash(100000.0)
        print('Starting Portfolio Value: %.5f' % cerebro.broker.getvalue())
        cerebro.run(stdstats=False)
        print('Final Portfolio Value: %.5f' % cerebro.broker.getvalue())
        plotter = Plotter()
        cerebro.plot(plotter=plotter,subplot=False)
    
    
    def parse_args():
        parser = argparse.ArgumentParser(
            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
            description='Sample for pivot point and cross plotting')
    
        parser.add_argument('--data0',
                            default='d:\\I - TradersGPS\\GBPUSD_D1_UTC+2_00.csv',
                            required=False, help='Data0 to read in')
    
        parser.add_argument('--data1',
                            default='d:\\I - TradersGPS\\GBPUSD_H1_UTC+2_00.csv',
                            required=False, help='Data1 to read in')
    
        parser.add_argument('--fromdate', required=False, default='2001-01-01',
                            help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')
    
        parser.add_argument('--todate', required=False, default='2007-01-01',
                            help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')
    
        parser.add_argument('--plot', required=False, action='store_true',
                            help=('Plot the result'))
    
        return parser.parse_args()
    
    
    if __name__ == '__main__':
        runstrat()
    

    This code itself i have got one of the users from this community. Can anyone help me?

    Thanks in advance



  • @sarathmj_7 said in how to change backtrader default buy & sell signal strategy into our own strategy:

    default backtrader buy sell signal strategy

    I don't think there is any default buy/sell signal strategy. You have to implement the logic.

    The logic is there as in

    if self.signal == 0:
        if self.data.open[0] > self.data.close[0]: 
    

    which is used to enter the market. Change it to something else and you will have a different logic (signal)



  • @Paska-Houso , in this code

    def __init__(self):
            self.signal = 0
    
    
        def notify_order(self, order):
    
    
    
            if order.status in [order.Submitted, order.Accepted]:
                return
    
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.signal += 1
                    self.log(
                        'BUY EXECUTED, Price: %.5f, Cost: %.5f, Position : %d' %
                        (order.executed.price,
                         order.executed.value, self.signal))
                    self.buyprice = order.executed.price
    
                else:  # Sell
                    self.signal -= 1
                    self.log('SELL EXECUTED, Price: %.5f, Cost: %.5f,Position : %d' %
                             (order.executed.price,
                              order.executed.value, self.signal))
    
                    self.bar_executed = len(self)
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Canceled/Margin/Rejected')
    
            self.order = None
    

    here initially
    self.signal = 0

    when this function called inside for loop

    if order.isbuy():
    signal is changing like -1 or 1, but order is happened before this signal changes..

    I have a strategy i want apply my signal here, According to that it should buy or sell if i want to do this where to change and what to change? pls help.



  • @sarathmj_7

    self.signal in the strategy above is used only for position tracking, not to generate actual order. Actual trading logic is sitting in the next().

    Anyway if you have questions like where to change and what to change?, then better to read thru the documentation or read Quickstart at least.



  • @ab_trader Thanks , i got and fixed it. I am using intraday data, but when i plot buy and sell signals are not coming in chart(red and green symbol). can you help me?!
    0_1510832651059_Figure_0.png

    here BUY and SELL symbol indication and profit loss are also missing..





  • @sarathmj_7 as @Paska-Houso stated use just

    cerebro.run(stdstats=True)
    

    or

    cerebro.run()
    

    to show such basic observers as broker value and cash and buy/sell arrows.


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.