For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Trailing



  • Hi,

    It's the first time when I write here and I'm new to Backtrader, first of all congratulations on the idea, brilliant! I think with the right strategy this is like a money printing machine.

    I've tested over the last days Backtrader and it's great, my only problem... can't figure out how to setup the trailing stop for profits and losses...

    I'm trying to add a trailing stop to the oandav20test.py project, but it seems that is not working. Every time an order goes in the API it goes without S/L T/P or T/S

    So I'm not sure what I'm missing, if you can help me please...

    class TestStrategy(bt.Strategy):
        params = dict(
            smaperiod=5,
            trade=False,
            stake=10,
            exectype=bt.Order.Market,
            stopafter=0,
            valid=None,
            cancel=0,
            donotcounter=False,
            sell=False,
            usebracket=False,
        )
    
        def __init__(self):
            # To control operation entries
            self.orderid = list()
            self.order = None
    
            self.counttostop = 0
            self.datastatus = 0
    
            # Create SMA on 2nd data
            self.sma = bt.indicators.MovAv.SMA(self.data, period=self.p.smaperiod)
    
            print('--------------------------------------------------')
            print('Strategy Created')
            print('--------------------------------------------------')
    
        def notify_data(self, data, status, *args, **kwargs):
            print('*' * 5, 'DATA NOTIF:', data._getstatusname(status), *args)
            if status == data.LIVE:
                self.counttostop = self.p.stopafter
                self.datastatus = 1
    
        def notify_store(self, msg, *args, **kwargs):
            print('*' * 5, 'STORE NOTIF:', msg)
    
        def notify_order(self, order):
            if order.status in [order.Completed, order.Cancelled, order.Rejected]:
                self.order = None
    
            print('-' * 50, 'ORDER BEGIN', datetime.datetime.now())
            print(order)
            print('-' * 50, 'ORDER END')
    
        def notify_trade(self, trade):
            print('-' * 50, 'TRADE BEGIN', datetime.datetime.now())
            print(trade)
            print('-' * 50, 'TRADE END')
    
        def prenext(self):
            self.next(frompre=True)
    
        def next(self, frompre=False):
            txt = list()
            txt.append('Data0')
            txt.append('%04d' % len(self.data0))
            dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
            txt.append('{:f}'.format(self.data.datetime[0]))
            txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt))
            txt.append('{:f}'.format(self.data.open[0]))
            txt.append('{:f}'.format(self.data.high[0]))
            txt.append('{:f}'.format(self.data.low[0]))
            txt.append('{:f}'.format(self.data.close[0]))
            txt.append('{:6d}'.format(int(self.data.volume[0])))
            txt.append('{:d}'.format(int(self.data.openinterest[0])))
            txt.append('{:f}'.format(self.sma[0]))
            print(', '.join(txt))
    
            if len(self.datas) > 1 and len(self.data1):
                txt = list()
                txt.append('Data1')
                txt.append('%04d' % len(self.data1))
                dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
                txt.append('{}'.format(self.data1.datetime[0]))
                txt.append('%s' % self.data1.datetime.datetime(0).strftime(dtfmt))
                txt.append('{}'.format(self.data1.open[0]))
                txt.append('{}'.format(self.data1.high[0]))
                txt.append('{}'.format(self.data1.low[0]))
                txt.append('{}'.format(self.data1.close[0]))
                txt.append('{}'.format(self.data1.volume[0]))
                txt.append('{}'.format(self.data1.openinterest[0]))
                txt.append('{}'.format(float('NaN')))
                print(', '.join(txt))
    
            if self.counttostop:  # stop after x live lines
                self.counttostop -= 1
                if not self.counttostop:
                    self.env.runstop()
                    return
    
            if not self.p.trade:
                return
    
            if self.datastatus and not self.position and len(self.orderid) < 1:
                if not self.p.usebracket:
                    if not self.p.sell:
                        # price = round(self.data0.close[0] * 0.90, 2)
                        price = self.data0.close[0] - 0.005
                        self.order = self.buy(size=self.p.stake,
                                              exectype=self.p.exectype,
                                              price=price,
                                              valid=self.p.valid)
                    else:
                        # price = round(self.data0.close[0] * 1.10, 4)
                        price = self.data0.close[0] - 0.05
                        self.order = self.sell(size=self.p.stake,
                                               exectype=self.p.exectype,
                                               price=price,
                                               valid=self.p.valid)
    
                else:
                    print('USING BRACKET')
                    price = self.data0.close[0] - 0.05
                    self.order, _, _ = self.buy_bracket(size=self.p.stake,
                                                        price=price,
                                                        exectype=bt.Order.StopTrail, 
                                                        trailpercent=0.02,
                                                        valid=self.p.valid)
    
                self.orderid.append(self.order)
            elif self.position and not self.p.donotcounter:
                if self.order is None:
                    if not self.p.sell:
                        self.order = self.sell(size=self.p.stake // 2,
                                               exectype=bt.Order.Market,
                                               price=self.data0.close[0])
                    else:
                        self.order = self.buy(size=self.p.stake // 2,
                                              exectype=bt.Order.Market,
                                              price=self.data0.close[0])
    
                self.orderid.append(self.order)
    
            elif self.order is not None and self.p.cancel:
                if self.datastatus > self.p.cancel:
                    self.cancel(self.order)
    
            if self.datastatus:
                self.datastatus += 1
    
        def start(self):
            if self.data0.contractdetails is not None:
                print('-- Contract Details:')
                print(self.data0.contractdetails)
    
            header = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume',
                      'OpenInterest', 'SMA']
            print(', '.join(header))
    
            self.done = False
    

    I need this to be applied for when I place the order first time, but as well when the strategy triggers it, in neither cases is not working or at least I didn't configure it well (most likely)

    As a trigger in my terminal I use this:

    @xxxx: python oandav20test.py --account '101-004-XXXXXXXX' --token 'e8f4f3daabffXXXXXXXXX' --data0 GBP_JPY --resample --timeframe Minutes --compression 1 --no-backfill_start --stake 1000 --trade --broker
    

    Thank you very much again for this great tool and all the support.



  • For example on GBP_JPY there is an opening price for 143.277, I should have a stop loss at let's say -0.2%, and a trailing stop which will follow the current price in case the strategy is right, with let's say -0.05% new stop loss; they should work in both directions either for sell or buy... I think this makes it a bit more clear what I'm after... thank you again


Log in to reply
 

});