From a26dbf41b5446310bb02b9cb4f4946e488ace2c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20S=C3=A1nchez?= Date: Wed, 30 Oct 2024 18:19:58 -0300 Subject: [PATCH] Bug hunting --- changelog.txt | 4 ++++ exchange_wrapper.py | 28 +++++++++++++--------------- main.py | 2 +- trader.py | 19 ++++++++++++++----- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/changelog.txt b/changelog.txt index 2c72e30..150a773 100755 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,7 @@ +2024.10.30: +. Changes trying to catch the wrong base amount bug. +. Simplified new_market_order code. + 2024.10.29: . New functions to get top ask and top bid prices. . Improvements when dealing with shallow orderbooks. diff --git a/exchange_wrapper.py b/exchange_wrapper.py index 2ac9127..bda6db4 100755 --- a/exchange_wrapper.py +++ b/exchange_wrapper.py @@ -39,7 +39,6 @@ class broker: self.exchange.load_markets() - def all_markets(self,no_retries=False): retries = self.retries while retries>0: @@ -674,22 +673,21 @@ class broker: if side=="buy": to_buy = float(size) if not amount_in_base: - order_book = self.get_order_book(symbol) - if order_book=={}: - self.logger.log_this(f"new_market_order - Orderbook request returned an empty dictionary - Not using orderbook. Switching to a less precise method.",1,symbol) - price = self.get_ticker_price(symbol) - else: - price = self.average_price_depth(order_book,size,side) - if price is None: - #Something failed, back to the basics - self.logger.log_this(f"new_market_order - average_price_depth returned None. Switching to a less precise method.",1,symbol) - price = self.get_ticker_price(symbol) - to_buy = float(size)/price + #order_book = self.get_order_book(symbol) + #if order_book=={}: + # self.logger.log_this(f"new_market_order - Orderbook request returned an empty dictionary - Not using orderbook. Switching to a less precise method.",1,symbol) + # price = self.get_ticker_price(symbol) + #else: + # price = self.average_price_depth(order_book,size,side) + # if price is None: + # #Something failed, back to the basics + # self.logger.log_this(f"new_market_order - average_price_depth returned None. Switching to a less precise method.",1,symbol) + # price = self.get_ticker_price(symbol) + to_buy = float(size)/self.get_top_ask_price(pair) amount = self.amount_to_precision(pair,to_buy) else: - amount = self.amount_to_precision(pair,size) #Market sell orders are ALWAYS nominated in baseexchange.create_order(pair,"market",side,amount) - - #self.logger.log_this(f"Order to be sent: {side} {amount}",1,pair) + amount = self.amount_to_precision(pair,size) #Market sell orders are always nominated in base currency + order_to_send = self.exchange.create_order(pair,"market",side,amount) time.sleep(self.wait_time) return self.get_order(order_to_send["id"],pair) diff --git a/main.py b/main.py index 1340094..624fcf2 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ In case the permissions of the certificate changes, reset them this way: # ll /etc/letsencrypt/ ''' -version = "2024.10.29" +version = "2024.10.30" ''' Color definitions. If you want to change them, check the reference at https://en.wikipedia.org/wiki/ANSI_escape_code#Colors diff --git a/trader.py b/trader.py index f9be7c3..adbaad9 100755 --- a/trader.py +++ b/trader.py @@ -120,6 +120,8 @@ class trader: #Reset some variables self.safety_order_index = 0 self.status_dict["deal_order_history"].clear() + self.tp_order = self.broker.get_empty_order() + self.so = self.broker.get_empty_order() #Reloads the market new_market_data = self.broker.fetch_market(self.pair) @@ -214,13 +216,19 @@ class trader: #Wait until the first order gets filled self.status_dict["pause_reason"] = "start_bot - waiting for the first order to get filled" while True: - time.sleep(self.broker.get_wait_time()) + #Wait a bit longer, to catch a bug: + #Sometimes the amount of base taken into account by the trader is lower than the amount bought, + # which ends up misrepresenting the trade cost per unit of base, which causes the take profit price to skyrocket. + # Maybe is the first market order getting "closed" before is fully filled? + # Or is there an error later in the trader? + #UPDATE: A rogue order appeared selling half of the last filled safety order. + # Is Gate.io pulling shady stuff? + time.sleep(self.broker.get_wait_time()*self.broker.get_cooldown_multiplier()) returned_order = self.broker.get_order(first_order["id"],self.pair) if returned_order==self.broker.get_empty_order(): self.broker.logger.log_this("Problems with the initial order",1,self.pair) return 1 elif returned_order["status"]=="closed": - self.tp_order = returned_order #Why???? break elif returned_order["status"]=="expired": self.broker.logger.log_this(f"First order expired. Id: {returned_order['id']}",1,self.pair) @@ -250,7 +258,8 @@ class trader: if returned_order["filled"]!=None: self.total_amount_of_base = returned_order["filled"] if not self.is_short: - self.total_amount_of_base -= self.parse_fees(returned_order)[0] #The substraction is because some exchanges charges some fees in base + #self.total_amount_of_base -= self.parse_fees(returned_order)[0] #The substraction is because some exchanges charges some fees in base + self.total_amount_of_base -= self.fees_paid_in_base self.total_amount_of_quote = returned_order["cost"] else: self.broker.logger.log_this("Error starting bot. Aborting.",1,self.pair) @@ -900,8 +909,8 @@ class trader: self.status_dict["pause_reason"] = "take_profit_routine - var cleanup" self.fees_paid_in_quote = 0 self.fees_paid_in_base = 0 - self.tp_order = self.broker.get_empty_order() - self.so = self.broker.get_empty_order() + #self.tp_order = self.broker.get_empty_order() + #self.so = self.broker.get_empty_order() self.safety_price_table.clear() #self.safety_order_index = 0 self.config_dict = self.reload_config_dict()