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?
-
@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? -
@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:
- What you see in
-
@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))