Slippage detection optimization

This commit is contained in:
Nicolás Sánchez 2024-10-30 10:39:55 -03:00
parent 452bddbe3e
commit 8981353230
4 changed files with 36 additions and 11 deletions

View File

@ -1,5 +1,7 @@
2024.10.29: 2024.10.29:
. New functions to get top ask and top bid prices. . 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: 2024.10.28:
. Docstrings and comments improvements. . Docstrings and comments improvements.

View File

@ -2024,7 +2024,7 @@ if __name__=="__main__":
read_config = json.load(f) read_config = json.load(f)
except Exception as e: except Exception as e:
print(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) os._exit(1)
#Check for import or load #Check for import or load

View File

@ -4,6 +4,7 @@ Mandatory:
1. Stats webpage. 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) 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. 3. Deploying script, both for testnet and for mainnet.
4. Maintain local orderbooks for each trading pair.
Would be nice to have: Would be nice to have:

View File

@ -192,7 +192,7 @@ class trader:
#check slippage #check slippage
self.broker.logger.log_this("Checking slippage...",2,self.pair) self.broker.logger.log_this("Checking slippage...",2,self.pair)
self.status_dict["pause_reason"] = "start_bot - checking slippage" 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 #Slippage threshold exceeded
self.broker.logger.log_this("Slippage threshold exceeded",1,self.pair) self.broker.logger.log_this("Slippage threshold exceeded",1,self.pair)
return 3 return 3
@ -916,6 +916,12 @@ class trader:
self.pause = False self.pause = False
self.restart = True self.restart = True
return 1 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 #Restarting the trader
self.status_dict["pause_reason"] = "take_profit_routine - restart_bot call" self.status_dict["pause_reason"] = "take_profit_routine - restart_bot call"
@ -926,25 +932,25 @@ class trader:
return 0 return 0
elif restart_bot==1: elif restart_bot==1:
self.pause = False self.pause = False
self.write_status_file(True) #self.write_status_file(True)
self.restart = True self.restart = True
self.broker.logger.log_this("Error in trader, start_bot returned 1. Trader will be restarted",1,self.pair) self.broker.logger.log_this("Error in trader, start_bot returned 1. Trader will be restarted",1,self.pair)
return 1 return 1
elif restart_bot==2: elif restart_bot==2:
self.pause = False self.pause = False
self.write_status_file(True) #self.write_status_file(True)
self.restart = 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) 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 return 2
elif restart_bot==3: elif restart_bot==3:
self.pause = False self.pause = False
self.write_status_file(True) #self.write_status_file(True)
self.restart = 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) self.broker.logger.log_this("Error in trader, start_bot returned 3 (Slippage exceeded). Trader will be restarted",1,self.pair)
return 3 return 3
else: else:
self.broker.logger.log_this(f"Error restarting trader, trader will be removed. Error code {restart_bot}",0,self.pair) 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 self.quit = True
return 1 return 1
@ -1076,10 +1082,23 @@ class trader:
return 0 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) order_book = self.broker.get_order_book(self.pair,no_retries=True)
if order_book=={}: if order_book=={}:
self.broker.logger.log_this("Can't fetch orderbook",1,self.pair) self.broker.logger.log_this("Can't fetch orderbook",1,self.pair)
@ -1087,8 +1106,11 @@ class trader:
suma = 0 suma = 0
try: try:
mid_price = old_price if old_price!=0 else (order_book["asks"][0][0]+order_book["bids"][0][0])/2 mid_price = old_price if old_price!=0 else (order_book["asks"][0][0]+order_book["bids"][0][0])/2
if size_in_quote:
amount = (order_size/mid_price)*2 #Extra margin to avoid surprises. 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] else:
amount = order_size*2
first_price = order_book["asks"][0][0]
for x in order_book["asks"]: for x in order_book["asks"]:
suma += x[1] suma += x[1]
if suma>=amount: if suma>=amount:
@ -1099,7 +1121,7 @@ class trader:
return True return True
return False return False
except Exception as e: 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 return False