diff --git a/changelog.txt b/changelog.txt index 4598c27..2c72e30 100755 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,7 @@ 2024.10.29: . New functions to get top ask and top bid prices. +. Improvements when dealing with shallow orderbooks. +. Removed unnecessary status file writes to disk. 2024.10.28: . Docstrings and comments improvements. diff --git a/main.py b/main.py index a8367fd..1340094 100644 --- a/main.py +++ b/main.py @@ -2024,7 +2024,7 @@ if __name__=="__main__": read_config = json.load(f) except Exception as e: print(e) - print("Wrong syntax. Correct syntax is 'python3 dcaruntime.py xxxxx.json', xxxxx.json being the config file.") + print("Wrong syntax. Correct syntax is 'python3 main.py xxxxx.json (--first_start)', xxxxx.json being the config file.") os._exit(1) #Check for import or load diff --git a/utils/todo.txt b/todo.txt similarity index 96% rename from utils/todo.txt rename to todo.txt index 6912677..e549abc 100755 --- a/utils/todo.txt +++ b/todo.txt @@ -4,6 +4,7 @@ Mandatory: 1. Stats webpage. 2. Instead of giving a list of order_ids to each trader, give a list of the open orders and that's it (for easier future development, partial order fills for example) 3. Deploying script, both for testnet and for mainnet. +4. Maintain local orderbooks for each trading pair. Would be nice to have: diff --git a/trader.py b/trader.py index 066c5f2..f9be7c3 100755 --- a/trader.py +++ b/trader.py @@ -192,7 +192,7 @@ class trader: #check slippage self.broker.logger.log_this("Checking slippage...",2,self.pair) self.status_dict["pause_reason"] = "start_bot - checking slippage" - if self.check_slippage(self.broker.get_slippage_default_threshold(),self.config_dict["order_size"]): + if self.check_orderbook_depth(self.broker.get_slippage_default_threshold(),self.config_dict["order_size"]): #Slippage threshold exceeded self.broker.logger.log_this("Slippage threshold exceeded",1,self.pair) return 3 @@ -916,6 +916,12 @@ class trader: self.pause = False self.restart = True return 1 + elif self.check_orderbook_depth(self.broker.get_slippage_default_threshold(),self.config_dict["order_size"],filled_order["price"]): + self.broker.logger.log_this(f"Orderbook depth not sufficient, waiting for cooldown and restarting pair",1,self.pair) + time.sleep(self.broker.get_wait_time()*self.broker.get_cooldown_multiplier()) + self.pause = False + self.restart = True + return 1 #Restarting the trader self.status_dict["pause_reason"] = "take_profit_routine - restart_bot call" @@ -926,25 +932,25 @@ class trader: return 0 elif restart_bot==1: self.pause = False - self.write_status_file(True) + #self.write_status_file(True) self.restart = True self.broker.logger.log_this("Error in trader, start_bot returned 1. Trader will be restarted",1,self.pair) return 1 elif restart_bot==2: self.pause = False - self.write_status_file(True) + #self.write_status_file(True) self.restart = True self.broker.logger.log_this("Error in trader, start_bot returned 2 (Initial order never got filled). Trader will be restarted",1,self.pair) return 2 elif restart_bot==3: self.pause = False - self.write_status_file(True) + #self.write_status_file(True) self.restart = True self.broker.logger.log_this("Error in trader, start_bot returned 3 (Slippage exceeded). Trader will be restarted",1,self.pair) return 3 else: self.broker.logger.log_this(f"Error restarting trader, trader will be removed. Error code {restart_bot}",0,self.pair) - self.write_status_file(True) + #self.write_status_file(True) self.quit = True return 1 @@ -1076,10 +1082,23 @@ class trader: return 0 - def check_slippage(self, threshold: float, order_size: float, old_price: float = 0) -> bool: + def check_orderbook_depth(self, threshold: float, order_size: float, old_price: float = 0, size_in_quote = True) -> bool: ''' - Checks that the slippage is between range. Returns True if threshold is exceeded, False otherwise. + Checks if the orderbook depth exceed the slippage threshold. Returns True if threshold is exceeded, False otherwise. + + Parameters: + threshold (float): The threshold for the orderbook depth. + order_size (float): The size of the order to check.. + old_price (float): The old price of the order. + size_in_quote (bool): If True, the order size is in quote currency. If False, the order size is in base currency. + + Returns: + bool: True if the orderbook depth exceeds the threshold, False otherwise. ''' + + if self.is_short: #Do not check for slippage in short traders (Pending to be implemented) + return False + order_book = self.broker.get_order_book(self.pair,no_retries=True) if order_book=={}: self.broker.logger.log_this("Can't fetch orderbook",1,self.pair) @@ -1087,8 +1106,11 @@ class trader: suma = 0 try: mid_price = old_price if old_price!=0 else (order_book["asks"][0][0]+order_book["bids"][0][0])/2 - amount = (order_size/mid_price)*2 #Extra margin to avoid surprises. - first_price = order_book["asks"][0][0] #This could be first_price = old_price if old_price!=0 else order_book["asks"][0][0] + if size_in_quote: + amount = (order_size/mid_price)*2 #Extra margin to avoid surprises. + else: + amount = order_size*2 + first_price = order_book["asks"][0][0] for x in order_book["asks"]: suma += x[1] if suma>=amount: @@ -1099,7 +1121,7 @@ class trader: return True return False except Exception as e: - self.broker.logger.log_this(f"Exception in check_slippage: {e}",1,self.pair) + self.broker.logger.log_this(f"Exception in check_orderbook_depth: {e}",1,self.pair) return False