Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Implementing Bracket Orders for binance API

    Indicators/Strategies/Analyzers
    3
    6
    949
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      godseye last edited by

      From my research online, I understand that binance doesn't provide an option to place bracket orders directly, so, inspite of being able to use backet orders while backtesting using backtrader, it's difficult to deploy the same backtrader code into the live markets. Luckily, binance supports OCO(One cancels the other) orders which I could use to place a target and stoploss once I enter into a position. So, I am looking for some thoughts on how I could manually create bracket orders in the strategy class.

      class Strategy(bt.Strategy):
           def __init__(self):
                self.close = self.datas[0].close
                .. ..... ....
      
           def next(self):
      
                if not self.order and not self.position:
                     Print("Case 1 - Place order if strategy conditions are met")
                if not self.order and self.position:
                     Print("Case 2 - Send the stoploss and target orders")
                if self.order and not self.position:
                     Print("Case 3 - Check if the order is still valid based on the strategy being applied on fresh data, if not, cancel the existing entry order")
                if self.order and self.position: - 
                     Print("Case 4 - Sit back and relax!")
      
      

      So, all the print statements are for reference and I want to implement the idea of the respective comments. When I have a position and no orders, that means I need to quickly send a target and stoploss order using the OCO order type(case 2) but the issue is my stoploss/target values are already decided when I place an entry order(case 1) and I just can't figure out where to store these stoploss/target values before the backtrader enters the case 2(to create an OCO order) in the next iteration after the order is filled into a position. Is there a way I could store these value somewhere?

      Also, I would appreciate if there are any alternative strategies that I could to create the bracket order behaviour?

      And, lastly, a fundamental question wrt live markets, let's say, I am working on 15 min candles, I believe the backtrader will only work once in 15 mins and remains quiet the rest of the time, basically whenever new data is available it triggers the next function right? If yes, I believe my approach to create the bracket order is doomed because if I wait for 15 mins to place the OCO order(stoploss and target orders) after my entry order turns into a position, I might have a naked position in the market for 15 mins in a worst case scenario and that's not an outcome I could take a risk on!

      I hope someone could throw some thoughts on my issues, I want to deploy the backtrader algo on binance real-time if that info matters. Thank you!

      run-out Kisko Apeles 2 Replies Last reply Reply Quote 1
      • run-out
        run-out @godseye last edited by

        @godseye You should use the notify_order method. When your order gets filled, you will get a call to notify_order. From here you check if the order is complete and then issue your new orders.

         def notify_order(self, order):
                """ Triggered upon changes to orders. """
                # Suppress notification if it is just a submitted order.
                if order.status == order.Submitted:
                    return
        
                if order.status == order.Margin:
                    return
        
                # Check if an order has been completed
                if order.status in [order.Completed]:
                    ####### ISSUE BRACKET ORDERS HERE #######
                    self.log(
                        f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
                        # f"EXECUTED for: {dn} "
                        f"Price: {order.executed.price:6.2f} "
                        f"Value: {order.executed.value:6.2f} "
                        f"Comm: {order.executed.comm:4.2f} "
                        f"Size: {order.created.size:9.4f} "
                    )
        

        RunBacktest.com

        G 1 Reply Last reply Reply Quote 2
        • G
          godseye @run-out last edited by

          @run-out really appreciate the response, that makes a lot of sense to me now, one last question is how to handle partial fills? I believe even if my entry trade is partially filled it appears in the order.Submitted I understand. so let's say I placed an order for entry with quantity 10, and only 5 got filled initial(which is a partial fill) and then my backtrader enters the notify_trade() block, so I place an order for tp/sl (OCO) with 5 lots. but then when the rest of it is filled, now backtrader enters the notify_order() block again this time will it show the quantity filled in the order as 10 or 5? if it's 10 I will be in a situation that it places 10 lots of oco order rather than 5. How should I overcome this situation?

          Also, when the OCO order is filled, even then it enters the order.completed in the notify_order right? is there a way I could find the difference between simple buy/sell order(that I place to enter the trader - so, want to use the details in order.completed) and my oco orders(placed for stoploss/target, - so don't want to use it in order.completed)?

          run-out 1 Reply Last reply Reply Quote 0
          • run-out
            run-out @godseye last edited by

            @godseye

            @godseye said in Implementing Bracket Orders for binance API:

            Submitted I understand. so let's say I placed an order for entry with quantity 10, and only 5 got filled initial(which is a partial fill) and then my backtrader enters the notify_trade() block, so I place an order for tp/sl (OCO) with 5 lots. but then when the rest of it is filled, now backtrader enters the notify_order() block again this time will it show the quantity filled in the order as 10 or 5? if it's 10 I will be in a situation that it places 10 lots of oco order rather than 5. How should I overcome this situation?

            I"m not 100% on this but I can get you the right direction. Orders have events as follows:

            ['Created', 'Submitted', 'Accepted', 'Partial', 'Completed', 'Canceled', 'Expired', 'Margin', 'Rejected']
            

            You can specify the event you are looking for in the notify_order method:

            if order.status == order.Submitted:
                return
            

            If you wish to do stuff for partial orders, then

            if order.status == order.Partial:
                return
            

            For details on partial orders, check the docs :

            Notifications may happen even several times for the same status in the case of Order.Partial. This status will not be seen in the backtesting broker (which doesn’t consider volume when matching) but it will for sure be set by real brokers.
            
            Real brokers may issue one or more executions before updating a position, and this group of executions will make up for an Order.Partial notification.
            
            Actual execution data is in the attribute: order.executed which is an object of type OrderData (see below for the reference), with usual fields as size and price
            

            @godseye said in Implementing Bracket Orders for binance API:

            Also, when the OCO order is filled, even then it enters the order.completed in the notify_order right? is there a way I could find the difference between simple buy/sell order(that I place to enter the trader - so, want to use the details in order.completed) and my oco orders(placed for stoploss/target, - so don't want to use it in order.completed)?

            The non-completed leg of an OCO is 'cancelled` status, not complete.

            RunBacktest.com

            run-out 1 Reply Last reply Reply Quote 0
            • run-out
              run-out @run-out last edited by

              @run-out said in Implementing Bracket Orders for binance API:

              if order.status == order.Partial:
              return

              Should read:

              if order.status == order.Partial:
                  do stuff here
              

              RunBacktest.com

              1 Reply Last reply Reply Quote 0
              • Kisko Apeles
                Kisko Apeles @godseye last edited by

                @godseye said in Implementing Bracket Orders for binance API:

                I might have a naked position in the market for 15 mins in a worst case scenario and that's not an outcome I could take a risk on!

                Have you solved the naked position problem?

                1 Reply Last reply Reply Quote 0
                • 1 / 1
                • First post
                  Last post
                Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors