Navigation

    Backtrader Community

    • Register
    • 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/

    CCXTbt make market order if limit order is not filled in X minutes

    General Code/Help
    2
    3
    121
    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.
    • D
      Dimasik007 last edited by

      Hi, I am using ccxtbt to trade on Binance. I use limit orders and trade on 1, 2 and 4 hour candles. Occasionally, limit orders might not get filled and I want to add a condition to the ccxtbroker "next" method to send market orders if the limit order is not filled within 2-3 minutes.

      Buy/sell methods take owner, data, size and exectype parameters, so I was wondering how would I specify them within the next() of the CCXTBroker class?

      My code goes in the next function after this comment: # execute order with market if limit is not filled after X amount of time

      Can anyone suggest how would I properly cancel existing limit order and create a new market buy/sell order?

      self.buy(self, owner, data, size, exectype)
      
          def next(self):
              if self.debug:
                  print('Broker next() called')
      
              for o_order in list(self.open_orders):
                  oID = o_order.ccxt_order['id']
      
                  # Print debug before fetching so we know which order is giving an
                  # issue if it crashes
                  if self.debug:
                      print('Fetching Order ID: {}'.format(oID))
      
                  # Get the order
                  ccxt_order = self.store.fetch_order(oID, o_order.data.p.dataname,
                                                      params={'type': 'future'})  # ADDED PARAMS HERE
                  # Check for new fills
                  if self.debug:
                      print(f'checking for trades in ccxt_order - ccxt_order is {ccxt_order}')
      
                  if ccxt_order['trades'] is not None:  # added explicit check for None otherwise it was proceeding
      
                      if self.debug:
                          print('reading trades in ccxt_order')
      
                      for fill in ccxt_order['trades']:
                          if fill not in o_order.executed_fills:
                              o_order.execute(fill['datetime'], fill['amount'], fill['price'],
                                              0, 0.0, 0.0,
                                              0, 0.0, 0.0,
                                              0.0, 0.0,
                                              0, 0.0)
                              o_order.executed_fills.append(fill['id'])
      
                  # execute order with market if limit is not filled after X amount of time
                  if float(ccxt_order['info']['executedQty']) < abs(float(ccxt_order['info']['origQty'])):
                      now = datetime.utcnow()
                      time_created = datetime.strptime(ccxt_order['datetime'][:-5], '%Y-%m-%dT%H:%M:%S')
                      timedelta_diff = now - time_created
                      
                      diff_s = timedelta_diff.total_seconds() / 60
                      print(f'time now: {now}, order time {time_created} and diff: {diff_s}')
                      
                      if diff_s > 0.1:
                          print(f'difference is greater than {diff_s} seconds - make market order')
                          
                          # cancel the limit order here
                          self.cancel(ccxt_order, params={'type': 'future'})
                          self.open_orders.remove(o_order)
                          o_order.cancel()
                          self.notify(o_order)
                          
                          if ccxt_order['side'] == 'buy':
                              print('send market buy order')
                              # market_order = self.buy(size=o_order.size, exectype='market')
                          elif ccxt_order['side'] == 'sell':
                              print('send market sell order')
                              # market_order = self.sell(size=o_order.size, exectype='market')
      
                  if self.debug:
                      print(json.dumps(ccxt_order, indent=self.indent))
      
                  # Check if the order is closed
                  if ccxt_order[self.mappings['closed_order']['key']] == self.mappings['closed_order']['value']:
                      # https://github.com/Dave-Vallance/bt-ccxt-store/compare/master...robobit:master
                      # check if order is closed and add commission info
                      if self.debug:
                          print('checking for closed status to notify of trade')
                      pos = self.getposition(o_order.data, clone=False)
                      pos.update(o_order.size, o_order.price)
                      o_order.completed()
                      self.notify(o_order)
                      self.open_orders.remove(o_order)
                      self.get_balance()
      
                  # Manage case when an order is being Canceled from the Exchange
                  #  from https://github.com/juancols/bt-ccxt-store/
                  if ccxt_order[self.mappings['canceled_order']['key']] == self.mappings['canceled_order']['value']:
                      self.open_orders.remove(o_order)
                      o_order.cancel()
                      self.notify(o_order)
      

      Thanks a lot!

      1 Reply Last reply Reply Quote 0
      • B
        balibou last edited by

        Hello @Dimasik007 ! Maybe you should use the valid parameter for creating your orders (https://www.backtrader.com/docu/order/#order-creation)

        for example when the buy order is filled, on notify_trade function you can create a sell order with a valid in datetime (+ 2/3 minutes)

        1 Reply Last reply Reply Quote 1
        • D
          Dimasik007 last edited by

          Hi @balibou ! thanks for your reply and suggestion. valid unfortunately doesn't work because it's not implemented in the ccxtbt. But thanks to your suggestion I decided to create limit orders in the next and add a variable valid which I am using to check how long the order was on the order book and if it wasn't filled in the required time, I am creating a new market order from the notify_order.

          The problem now is that when I am using a market order, it's executing immediately and I can't get back into the notify order until the next candle. I am using around 10 orders to scale into position when the signal is generated, so I am still stuck. If there are any other suggestions on how to solve this or that question, I would really appreciate anyones help.

          1 Reply Last reply Reply Quote 0
          • 1 / 1
          • First post
            Last post
          Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
          $(document).ready(function () { app.coldLoad(); }); }