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

Notify_trade profit and loss not working properly in bracket orders?



  • I am relatively new to backtrader and I am trying to place a bracket order which I will later be using for Live trading in interactive broker. Even though the bracket order is working properly their are issues during calculation of profit and loss. Can you please look into it as their might be a chance I have done something wrong. Although I have researched a lot and have not found any solution to this. Below is my code.

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    import backtrader as bt
    import pandas as pd
    # from report import Cerebro
    import datetime  # For datetime objects
    import os.path  # To manage paths
    import sys  # To find out the script name (in argv[0])
    #
    
    
    class TestStrategy(bt.Strategy):
        params = dict(
            stop_loss=0.005,  # price is 2% less than the entry point
            trail=False,
            profitper = 0.015,
            stake = 15
        )
        def log(self, txt, dt=None):
            if  True:
                dt = dt or self.datas[0].datetime.datetime(0)
                print('%s - %s' % (dt.isoformat(), txt))
     
        def __init__(self):
            self.ema1 = bt.indicators.ExponentialMovingAverage(self.datas[0].close, period = 6)
            self.ema3 = bt.indicators.ExponentialMovingAverage(self.datas[0].close, period = 24)       
            self.dclose = self.datas[0].close
            self.cross_ema = bt.ind.CrossOver(self.ema1, self.ema3)
        def notify(self, order):
            print('{}: Order ref: {} / Type {} / Status {}'.format(
                self.data.datetime.date(0),
                order.ref, 'Buy' * order.isbuy() or 'Sell',
                order.getstatusname()))
    
            if order.status == order.Completed:
                self.holdstart = len(self)
    
            if not order.alive() and order.ref in self.orefs:
                self.orefs.remove(order.ref)
               
                    
        def notify_trade(self, trade):
            date = self.data.datetime.datetime()
            if trade.isclosed:
                print('-'*32,' NOTIFY TRADE ','-'*32)
                print('{}, Close Price: {}, Profit, Gross {}, Net {}'.format(
                                                    date,
                                                    trade.price,
                                                    round(trade.pnl,2),
                                                    round(trade.pnlcomm,2)))
                print('-'*80)
                    
    
        def next(self):
    #         self.log('close : %.2f   ema6 : %.2f   ema24 : %.2f' % (self.dclose[0], self.ema1[0], self.ema3[0]))
            pos = self.getposition(self.data)
            dpos = pos.size
    #         self.log(dpos)
            if not self.position and self.cross_ema == 1:
                    stop_price = self.data.close[0] * (1.0 - self.p.stop_loss)
                    tk_profit = self.data.close[0] * (1.0 + self.p.profitper)
                    self.log('FORMING BRACKER ORDER :;: mAIN PRICE %.2f :;: STOP LOSS %.2f  :;: TAKE PROFIT %.2f' % (self.data.close[0],stop_price,tk_profit))
    #                 self.buy_order = self.buy(limitprice=tk_profit, price=self.dclose, stopprice=stop_price,size=15)
    #                 mainside = self.buy(transmit=False, size = self.p.stake)
    #                 lowside  = self.sell(price=stop_price, size=mainside.size, exectype=bt.Order.Stop,transmit=False, parent=mainside)
    #                 highside = self.sell(price=tk_profit, size=mainside.size, exectype=bt.Order.Limit,transmit=True, parent=mainside)
    #                 self.orefs = [mainside.ref,lowside.ref,highside.ref]
                    os = self.buy_bracket(limitprice=tk_profit, stopprice=stop_price, size = 15)
                    self.orefs = [o.ref for o in os]
                #             if self.dclose >= tk_profit:
    #                 self.sell_order = self.sell(execType = bt.Order.Limit, size=15, price= tk_profit,parent=self.buy_order)
    #                 cancel = order.cancel(oco='self.sl_order')
    
                
    class FixedCommisionScheme(bt.CommInfoBase):
        '''
        This is a simple fixed commission scheme
        '''
        params = (
            ('commission', 6),
            ('stocklike', True),
            ('commtype', bt.CommInfoBase.COMM_FIXED),
            )
    
        def _getcommission(self, size, price, pseudoexec):
            return self.p.commission
    
        
    if __name__ == '__main__':
        # Create a cerebro entity
        cerebro = bt.Cerebro()
    
        # Add a strategy
        cerebro.addstrategy(TestStrategy)
    
        # Datas are in a subfolder of the samples. Need to find where the script is
        # because it could have been called from anywhere
        modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
        datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt')
    
        # Pass it to the backtrader datafeed and add it to the cerebro
        data = bt.feeds.PandasData(dataname=INFY)
    
        
    #     weeklydata = cerebro.resampledata(data,timeframe=bt.TimeFrame.Months, compression = 0.5)
        # Add the Data Feed to Cerebro
        cerebro.adddata(data)
    
        # Set our desired cash start
        cerebro.broker.setcash(100000.0)
        
    #     cerebro.broker.set_coc(True)
        # Add a FixedSize sizer according to the stake
        cerebro.addsizer(bt.sizers.FixedSize, stake=1)
        #Set commissions
        comminfo = FixedCommisionScheme()
        cerebro.broker.addcommissioninfo(comminfo)
        
        # Print out the starting conditions
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        cerebro.broker.set_coc(True)
        # Run over everything
        cerebro.run()
    
        # Print out the final result
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
        # Plot the result
        cerebro.plot()
        
    #     print('____________________________________________________________')
    #     print('order history %.2f' % cerebro.broker.getposition())
        
    

    Below is the output:

    Starting Portfolio Value: 100000.00
    2019-02-06T14:15:00 - FORMING BRACKER ORDER :;: mAIN PRICE 298.90 :;: STOP LOSS 297.41  :;: TAKE PROFIT 303.38
    2019-02-06: Order ref: 4489 / Type Buy / Status Submitted
    2019-02-06: Order ref: 4490 / Type Sell / Status Submitted
    2019-02-06: Order ref: 4491 / Type Sell / Status Submitted
    2019-02-06: Order ref: 4489 / Type Buy / Status Accepted
    2019-02-06: Order ref: 4490 / Type Sell / Status Accepted
    2019-02-06: Order ref: 4491 / Type Sell / Status Accepted
    2019-02-06: Order ref: 4489 / Type Buy / Status Completed
    2019-02-07: Order ref: 4491 / Type Sell / Status Completed
    2019-02-07: Order ref: 4490 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-07 10:00:00, Close Price: 298.9, Profit, Gross 69.75, Net 57.75
    --------------------------------------------------------------------------------
    2019-02-11T15:15:00 - FORMING BRACKER ORDER :;: mAIN PRICE 294.00 :;: STOP LOSS 292.53  :;: TAKE PROFIT 298.41
    2019-02-12: Order ref: 4492 / Type Buy / Status Submitted
    2019-02-12: Order ref: 4493 / Type Sell / Status Submitted
    2019-02-12: Order ref: 4494 / Type Sell / Status Submitted
    2019-02-12: Order ref: 4492 / Type Buy / Status Accepted
    2019-02-12: Order ref: 4493 / Type Sell / Status Accepted
    2019-02-12: Order ref: 4494 / Type Sell / Status Accepted
    2019-02-12: Order ref: 4492 / Type Buy / Status Completed
    2019-02-12: Order ref: 4493 / Type Sell / Status Completed
    2019-02-12: Order ref: 4494 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-12 12:00:00, Close Price: 290.0, Profit, Gross 37.5, Net 25.5
    --------------------------------------------------------------------------------
    2019-02-12T14:30:00 - FORMING BRACKER ORDER :;: mAIN PRICE 294.75 :;: STOP LOSS 293.28  :;: TAKE PROFIT 299.17
    2019-02-12: Order ref: 4495 / Type Buy / Status Submitted
    2019-02-12: Order ref: 4496 / Type Sell / Status Submitted
    2019-02-12: Order ref: 4497 / Type Sell / Status Submitted
    2019-02-12: Order ref: 4495 / Type Buy / Status Accepted
    2019-02-12: Order ref: 4496 / Type Sell / Status Accepted
    2019-02-12: Order ref: 4497 / Type Sell / Status Accepted
    2019-02-12: Order ref: 4495 / Type Buy / Status Completed
    2019-02-13: Order ref: 4496 / Type Sell / Status Completed
    2019-02-13: Order ref: 4497 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-13 09:15:00, Close Price: 294.75, Profit, Gross -48.0, Net -60.0
    --------------------------------------------------------------------------------
    2019-02-13T13:30:00 - FORMING BRACKER ORDER :;: mAIN PRICE 292.55 :;: STOP LOSS 291.09  :;: TAKE PROFIT 296.94
    2019-02-13: Order ref: 4498 / Type Buy / Status Submitted
    2019-02-13: Order ref: 4499 / Type Sell / Status Submitted
    2019-02-13: Order ref: 4500 / Type Sell / Status Submitted
    2019-02-13: Order ref: 4498 / Type Buy / Status Accepted
    2019-02-13: Order ref: 4499 / Type Sell / Status Accepted
    2019-02-13: Order ref: 4500 / Type Sell / Status Accepted
    2019-02-13: Order ref: 4498 / Type Buy / Status Completed
    2019-02-13: Order ref: 4499 / Type Sell / Status Completed
    2019-02-13: Order ref: 4500 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-13 14:15:00, Close Price: 291.3, Profit, Gross -3.19, Net -15.19
    --------------------------------------------------------------------------------
    2019-02-14T14:30:00 - FORMING BRACKER ORDER :;: mAIN PRICE 290.25 :;: STOP LOSS 288.80  :;: TAKE PROFIT 294.60
    2019-02-14: Order ref: 4501 / Type Buy / Status Submitted
    2019-02-14: Order ref: 4502 / Type Sell / Status Submitted
    2019-02-14: Order ref: 4503 / Type Sell / Status Submitted
    2019-02-14: Order ref: 4501 / Type Buy / Status Accepted
    2019-02-14: Order ref: 4502 / Type Sell / Status Accepted
    2019-02-14: Order ref: 4503 / Type Sell / Status Accepted
    2019-02-14: Order ref: 4501 / Type Buy / Status Completed
    2019-02-18: Order ref: 4503 / Type Sell / Status Completed
    2019-02-18: Order ref: 4502 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-18 09:45:00, Close Price: 290.25, Profit, Gross 65.31, Net 53.31
    --------------------------------------------------------------------------------
    2019-02-19T09:45:00 - FORMING BRACKER ORDER :;: mAIN PRICE 293.25 :;: STOP LOSS 291.78  :;: TAKE PROFIT 297.65
    2019-02-19: Order ref: 4504 / Type Buy / Status Submitted
    2019-02-19: Order ref: 4505 / Type Sell / Status Submitted
    2019-02-19: Order ref: 4506 / Type Sell / Status Submitted
    2019-02-19: Order ref: 4504 / Type Buy / Status Accepted
    2019-02-19: Order ref: 4505 / Type Sell / Status Accepted
    2019-02-19: Order ref: 4506 / Type Sell / Status Accepted
    2019-02-19: Order ref: 4504 / Type Buy / Status Completed
    2019-02-19: Order ref: 4505 / Type Sell / Status Completed
    2019-02-19: Order ref: 4506 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-19 15:15:00, Close Price: 293.0, Profit, Gross -28.5, Net -40.5
    --------------------------------------------------------------------------------
    2019-02-20T10:00:00 - FORMING BRACKER ORDER :;: mAIN PRICE 296.00 :;: STOP LOSS 294.52  :;: TAKE PROFIT 300.44
    2019-02-20: Order ref: 4507 / Type Buy / Status Submitted
    2019-02-20: Order ref: 4508 / Type Sell / Status Submitted
    2019-02-20: Order ref: 4509 / Type Sell / Status Submitted
    2019-02-20: Order ref: 4507 / Type Buy / Status Accepted
    2019-02-20: Order ref: 4508 / Type Sell / Status Accepted
    2019-02-20: Order ref: 4509 / Type Sell / Status Accepted
    2019-02-20: Order ref: 4507 / Type Buy / Status Completed
    2019-02-20: Order ref: 4508 / Type Sell / Status Completed
    2019-02-20: Order ref: 4509 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-20 10:30:00, Close Price: 296.0, Profit, Gross -98.25, Net -110.25
    --------------------------------------------------------------------------------
    2019-02-21T12:15:00 - FORMING BRACKER ORDER :;: mAIN PRICE 297.00 :;: STOP LOSS 295.51  :;: TAKE PROFIT 301.45
    2019-02-21: Order ref: 4510 / Type Buy / Status Submitted
    2019-02-21: Order ref: 4511 / Type Sell / Status Submitted
    2019-02-21: Order ref: 4512 / Type Sell / Status Submitted
    2019-02-21: Order ref: 4510 / Type Buy / Status Accepted
    2019-02-21: Order ref: 4511 / Type Sell / Status Accepted
    2019-02-21: Order ref: 4512 / Type Sell / Status Accepted
    2019-02-21: Order ref: 4510 / Type Buy / Status Completed
    2019-02-25: Order ref: 4511 / Type Sell / Status Completed
    2019-02-25: Order ref: 4512 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-25 09:15:00, Close Price: 297.0, Profit, Gross -22.28, Net -34.28
    --------------------------------------------------------------------------------
    2019-02-25T11:30:00 - FORMING BRACKER ORDER :;: mAIN PRICE 298.35 :;: STOP LOSS 296.86  :;: TAKE PROFIT 302.83
    2019-02-25: Order ref: 4513 / Type Buy / Status Submitted
    2019-02-25: Order ref: 4514 / Type Sell / Status Submitted
    2019-02-25: Order ref: 4515 / Type Sell / Status Submitted
    2019-02-25: Order ref: 4513 / Type Buy / Status Accepted
    2019-02-25: Order ref: 4514 / Type Sell / Status Accepted
    2019-02-25: Order ref: 4515 / Type Sell / Status Accepted
    2019-02-25: Order ref: 4513 / Type Buy / Status Completed
    2019-02-25: Order ref: 4514 / Type Sell / Status Completed
    2019-02-25: Order ref: 4515 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-25 12:30:00, Close Price: 298.35, Profit, Gross -22.38, Net -34.38
    --------------------------------------------------------------------------------
    2019-02-25T13:00:00 - FORMING BRACKER ORDER :;: mAIN PRICE 298.00 :;: STOP LOSS 296.51  :;: TAKE PROFIT 302.47
    2019-02-25: Order ref: 4516 / Type Buy / Status Submitted
    2019-02-25: Order ref: 4517 / Type Sell / Status Submitted
    2019-02-25: Order ref: 4518 / Type Sell / Status Submitted
    2019-02-25: Order ref: 4516 / Type Buy / Status Accepted
    2019-02-25: Order ref: 4517 / Type Sell / Status Accepted
    2019-02-25: Order ref: 4518 / Type Sell / Status Accepted
    2019-02-25: Order ref: 4516 / Type Buy / Status Completed
    2019-02-25: Order ref: 4517 / Type Sell / Status Completed
    2019-02-25: Order ref: 4518 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-25 15:15:00, Close Price: 298.0, Profit, Gross -26.25, Net -38.25
    --------------------------------------------------------------------------------
    2019-02-26T13:00:00 - FORMING BRACKER ORDER :;: mAIN PRICE 296.70 :;: STOP LOSS 295.22  :;: TAKE PROFIT 301.15
    2019-02-26: Order ref: 4519 / Type Buy / Status Submitted
    2019-02-26: Order ref: 4520 / Type Sell / Status Submitted
    2019-02-26: Order ref: 4521 / Type Sell / Status Submitted
    2019-02-26: Order ref: 4519 / Type Buy / Status Accepted
    2019-02-26: Order ref: 4520 / Type Sell / Status Accepted
    2019-02-26: Order ref: 4521 / Type Sell / Status Accepted
    2019-02-26: Order ref: 4519 / Type Buy / Status Completed
    2019-02-27: Order ref: 4521 / Type Sell / Status Completed
    2019-02-27: Order ref: 4520 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-27 10:45:00, Close Price: 296.7, Profit, Gross 66.76, Net 54.76
    --------------------------------------------------------------------------------
    2019-02-27T14:30:00 - FORMING BRACKER ORDER :;: mAIN PRICE 299.15 :;: STOP LOSS 297.65  :;: TAKE PROFIT 303.64
    2019-02-27: Order ref: 4522 / Type Buy / Status Submitted
    2019-02-27: Order ref: 4523 / Type Sell / Status Submitted
    2019-02-27: Order ref: 4524 / Type Sell / Status Submitted
    2019-02-27: Order ref: 4522 / Type Buy / Status Accepted
    2019-02-27: Order ref: 4523 / Type Sell / Status Accepted
    2019-02-27: Order ref: 4524 / Type Sell / Status Accepted
    2019-02-27: Order ref: 4522 / Type Buy / Status Completed
    2019-02-28: Order ref: 4523 / Type Sell / Status Completed
    2019-02-28: Order ref: 4524 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-28 09:45:00, Close Price: 299.15, Profit, Gross -45.75, Net -57.75
    --------------------------------------------------------------------------------
    2019-02-28T13:15:00 - FORMING BRACKER ORDER :;: mAIN PRICE 298.70 :;: STOP LOSS 297.21  :;: TAKE PROFIT 303.18
    2019-02-28: Order ref: 4525 / Type Buy / Status Submitted
    2019-02-28: Order ref: 4526 / Type Sell / Status Submitted
    2019-02-28: Order ref: 4527 / Type Sell / Status Submitted
    2019-02-28: Order ref: 4525 / Type Buy / Status Accepted
    2019-02-28: Order ref: 4526 / Type Sell / Status Accepted
    2019-02-28: Order ref: 4527 / Type Sell / Status Accepted
    2019-02-28: Order ref: 4525 / Type Buy / Status Completed
    2019-03-01: Order ref: 4527 / Type Sell / Status Completed
    2019-03-01: Order ref: 4526 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-03-01 14:30:00, Close Price: 298.7, Profit, Gross 67.21, Net 55.21
    --------------------------------------------------------------------------------
    Final Portfolio Value: 99855.93
    

    For example if we look at this small part of the output buy price is 294.75 and sell price is 294.75 though gross profit is -48 and net is -60.

    2019-02-12T14:30:00 - FORMING BRACKER ORDER :;: mAIN PRICE 294.75 :;: STOP LOSS 293.28  :;: TAKE PROFIT 299.17
    2019-02-12: Order ref: 3937 / Type Buy / Status Submitted
    2019-02-12: Order ref: 3938 / Type Sell / Status Submitted
    2019-02-12: Order ref: 3939 / Type Sell / Status Submitted
    2019-02-12: Order ref: 3937 / Type Buy / Status Accepted
    2019-02-12: Order ref: 3938 / Type Sell / Status Accepted
    2019-02-12: Order ref: 3939 / Type Sell / Status Accepted
    2019-02-12: Order ref: 3937 / Type Buy / Status Completed
    2019-02-13: Order ref: 3938 / Type Sell / Status Completed
    2019-02-13: Order ref: 3939 / Type Sell / Status Canceled
    --------------------------------  NOTIFY TRADE  --------------------------------
    2019-02-13 09:15:00, Close Price: 294.75, Profit, Gross -48.0, Net -60.0
    

    There is a chance I might be doing something wrong. Can someone please help me with this?


  • administrators

    @Suraj-Thorat said in Notify_trade profit and loss not working properly in bracket orders?:

    Notify_trade profit and loss not working properly in bracket orders?

    It is working properly.

    @Suraj-Thorat said in Notify_trade profit and loss not working properly in bracket orders?:

    Even though the bracket order is working properly their are issues during calculation of profit and loss.

    No, there are no issues.

    @Suraj-Thorat said in Notify_trade profit and loss not working properly in bracket orders?:

    For example if we look at this small part of the output buy price is 294.75

    No. That's a print statement you have issued and not the price.



  • My buy price is 294.7 got from next() by logging data.close[0].
    My sell price is 294.7 by printing trade.price in notify_trade. Shouldn't the gross profit be 0 and net profit -12?


  • administrators

    @Suraj-Thorat said in Notify_trade profit and loss not working properly in bracket orders?:

    My buy price is 294.7 got from next() by logging data.close[0].

    You print the close price and that is the execution price, ... because you printed it?

    Sorry, but I think there is some misunderstanding on your side as to how an order is executed and what the prices you see in next mean.

    • What you see in next are PAST prices. When you see something it HAS ALREADY HAPPENED
    • You then submit an order and it goes to the broker which will execute it (depending on order type, price, and ... and ...) when it can and the best it can, which it can be much worse than you expect.

    Read:



  • @backtrader Thank you for the help and I truly appreciate it. I got that part fixed.
    For people who have done such a simple mistake which I doubt anyone will, here is a fix.
    Add the below code to notify:

            if order.status == order.Completed:
                        
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.executed.price,
                         order.executed.value,
                         order.executed.comm))
    
                    self.buyprice = order.executed.price
                    self.buycomm = order.executed.comm
                else:  # Sell
                    self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                             (order.executed.price,
                              order.executed.value,
                              order.executed.comm))
    
    
    
    

Log in to reply
 

});