CCXTbt make market order if limit order is not filled in X minutes
-
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!
-
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 avalid
in datetime (+ 2/3 minutes) -
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 variablevalid
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 thenotify_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.