2025.05.16

This commit is contained in:
Nicolás Sánchez 2025-05-16 17:06:25 -03:00
parent 68892d2d47
commit 1a62e483ae
4 changed files with 45 additions and 44 deletions

View File

@ -1,5 +1,13 @@
2025.05.16:
. Added exception handling when removing a trader.
. Minor variable renaming.
2025.05.12:
. Improved config file handling when switching to long or short.
. If the config file does not exist, it creates it.
2025.05.05: 2025.05.05:
. Forced Telegram message when a quit flag is raised. . Forced Telegram message when quit flag is raised.
2025.05.04: 2025.05.04:
. Simplified unwrapped_add_pair. . Simplified unwrapped_add_pair.

View File

@ -37,13 +37,18 @@ class ConfigHandler:
self.config_dictionary = self.default_config_dictionary.copy() self.config_dictionary = self.default_config_dictionary.copy()
#Loads from disk the config file (if it exists) #Loads from disk the config file (if it exists)
self.load_from_file() if self.load_from_file()==1:
#If the config file does not exist, write a new one with the default values
self.save_to_file()
if config_dict is not None: if config_dict is not None:
self.config_dictionary = {**self.config_dictionary, **config_dict} self.config_dictionary = {**self.config_dictionary, **config_dict}
self.save_to_file() self.save_to_file()
def reset_to_default(self):
self.config_dictionary = self.default_config_dictionary.copy()
return 0
def get_pair(self): def get_pair(self):
return self.config_dictionary["pair"] return self.config_dictionary["pair"]

12
main.py
View File

@ -16,7 +16,7 @@ import exchange_wrapper
import trader import trader
version = "2025.05.05" version = "2025.05.16"
''' '''
Color definitions. If you want to change them, check the reference at https://en.wikipedia.org/wiki/ANSI_escape_code#Colors Color definitions. If you want to change them, check the reference at https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
@ -244,7 +244,10 @@ def restart_pair_no_json(base: str, quote: str) -> int:
elif order["symbol"]==f"{base}/{quote}" and not x.config.get_is_short() and order["side"]=="buy": elif order["symbol"]==f"{base}/{quote}" and not x.config.get_is_short() and order["side"]=="buy":
broker.logger.log_this(f"Cancelling old buy orders",2,f"{base}/{quote}") broker.logger.log_this(f"Cancelling old buy orders",2,f"{base}/{quote}")
broker.cancel_order(order["id"],order["symbol"]) broker.cancel_order(order["id"],order["symbol"])
running_instances.remove(x) try:
running_instances.remove(x)
except ValueError:
broker.logger.log_this(f"Instance {x.config.get_pair()} not found in running_instances.",1,x.config.get_pair())
add_instance(base,quote) add_instance(base,quote)
return 0 return 0
return 1 return 1
@ -274,7 +277,10 @@ def main_loop():
broker.rewrite_config_file() broker.rewrite_config_file()
if x.config.get_pair() in worker_status: if x.config.get_pair() in worker_status:
del(worker_status[x.config.get_pair()]) del(worker_status[x.config.get_pair()])
running_instances.remove(x) try:
running_instances.remove(x)
except ValueError:
broker.logger.log_this(f"Instance {x.config.get_pair()} not found in running_instances.",1,x.config.get_pair())
#Adds pending traders #Adds pending traders
if bool(instances_to_add): if bool(instances_to_add):

View File

@ -496,19 +496,6 @@ class trader:
self.pause = True self.pause = True
self.status.set_pause_reason("switch_to_short") self.status.set_pause_reason("switch_to_short")
#Read the config file
self.broker.logger.log_this("Reading config file",2,self.config.get_pair())
try:
with open(f"configs/{self.base}{self.quote}.json","r") as f:
old_config = json.load(f)
except Exception as e:
self.broker.logger.log_this(f"Error. Can't read the config file. Can't switch mode. Exception: {e}",1,self.config.get_pair())
self.pause = False
self.status.set_pause_reason("")
return 1
#Calculate if there is enough base and, if so, calculate the optimal order size
#Fetch the real amount of available base #Fetch the real amount of available base
self.broker.logger.log_this(f"Fetching available {self.base}",2,self.config.get_pair()) self.broker.logger.log_this(f"Fetching available {self.base}",2,self.config.get_pair())
free_base = self.fetch_free_base() free_base = self.fetch_free_base()
@ -566,21 +553,16 @@ class trader:
#Modify config file accordingly #Modify config file accordingly
self.broker.logger.log_this("Modifying config file and saving a backup",2,self.config.get_pair()) self.broker.logger.log_this("Modifying config file and saving a backup",2,self.config.get_pair())
try: try:
with open(f"configs/{self.base}{self.quote}.bak","w") as c: self.config.save_to_file(f"configs/{self.base}{self.quote}.bak")
c.write(json.dumps(old_config, indent=4)) self.config.set_is_short(True)
old_config["is_short"] = True self.config.save_to_file()
#old_config["order_size"] = optimal_order_size #Now calculated on-the-fly at the start of every deal
#old_config["no_of_safety_orders"] = amount_of_so
#4. Write the config file
with open(f"configs/{self.base}{self.quote}.json","w") as c:
c.write(json.dumps(old_config, indent=4))
self.broker.logger.log_this("Config file updated",2,self.config.get_pair()) self.broker.logger.log_this("Config file updated",2,self.config.get_pair())
except Exception as e: except Exception as e:
self.broker.logger.log_this(f"Error. Can't write the config file. Exception: {e}",1,self.config.get_pair()) self.broker.logger.log_this(f"Error. Can't write the config file. Exception: {e}",1,self.config.get_pair())
#self.pause = False #self.pause = False
return 1 return 1
self.status.set_stop_when_profit(False) self.status.set_stop_when_profit(False)
self.config.set_is_short(True) #self.config.set_is_short(True)
self.broker.logger.log_this("Done configuring. Starting bot...",2,self.config.get_pair()) self.broker.logger.log_this("Done configuring. Starting bot...",2,self.config.get_pair())
return 0 return 0
@ -590,13 +572,13 @@ class trader:
Takes a short bot and changes the mode to long. Takes a short bot and changes the mode to long.
Only does it if the current bot was previously a long one. Only does it if the current bot was previously a long one.
''' '''
#Check if it's not already long
if not self.config.get_is_short():
self.broker.logger.log_this("Can't switch a long trader to long, there's nothing to do",1,self.config.get_pair())
return 1
if not self.config.get_is_short():
self.broker.logger.log_this("Trader already in long mode, nothing to do",1,self.config.get_pair())
return 1
self.broker.logger.log_this("Attempting to switch to long bot",0,self.config.get_pair()) self.broker.logger.log_this("Attempting to switch to long bot",0,self.config.get_pair())
#Check old_long data
if not ignore_old_long and self.status.get_old_long()=={}: if not ignore_old_long and self.status.get_old_long()=={}:
self.broker.logger.log_this("Can't find old long info on status_dict, searching for oldlong file",1,self.config.get_pair()) self.broker.logger.log_this("Can't find old long info on status_dict, searching for oldlong file",1,self.config.get_pair())
try: try:
@ -624,21 +606,21 @@ class trader:
except Exception as e: except Exception as e:
self.broker.logger.log_this(f"Error in cancel_order while cancelling take profit order. Exception: {e}",1,self.config.get_pair()) self.broker.logger.log_this(f"Error in cancel_order while cancelling take profit order. Exception: {e}",1,self.config.get_pair())
#Liquidate base #Sell all base currency
self.liquidate_base(ignore_profits=ignore_old_long, already_received_quote=already_received_quote) self.liquidate_base(ignore_profits=ignore_old_long, already_received_quote=already_received_quote)
#switch config files and set self.config.get_is_short() to False #Rewrite config file (if it exists)
try: if os.path.isfile(f"configs/{self.base}{self.quote}.bak") and os.path.isfile(f"configs/{self.base}{self.quote}.json"):
with open(f"configs/{self.base}{self.quote}.bak") as c: with open(f"configs/{self.base}{self.quote}.bak") as c:
old_config = json.load(c) old_config = json.load(c)
with open(f"configs/{self.base}{self.quote}.json","w") as c: with open(f"configs/{self.base}{self.quote}.json","w") as c:
c.write(json.dumps(old_config, indent=4)) c.write(json.dumps(old_config, indent=4))
self.config.load_from_file() if self.config.load_from_file()==1:
self.config.set_is_short(False) #This probably is not needed self.config.reset_to_default()
except Exception as e: else:
self.broker.logger.log_this(f"Exception in switch_to_long while switching config files: {e}",1,self.config.get_pair()) self.broker.logger.log_this("Config/backup file does not exist",1,self.config.get_pair())
self.quit = True self.config.reset_to_default()
return 1 self.config.save_to_file()
#Remove old_long file (if it exists) #Remove old_long file (if it exists)
if os.path.isfile(f"status/{self.base}{self.quote}.oldlong"): if os.path.isfile(f"status/{self.base}{self.quote}.oldlong"):
@ -958,13 +940,13 @@ class trader:
amount = (order_size/mid_price)*2 #Extra margin to avoid surprises. amount = (order_size/mid_price)*2 #Extra margin to avoid surprises.
else: else:
amount = order_size*2 amount = order_size*2
first_price = order_book["asks"][0][0] top_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:
last_price = x[0] last_price = x[0]
break break
if last_price-first_price>first_price*threshold: if last_price-top_price>top_price*threshold:
#Threshold exceeded #Threshold exceeded
return True return True
return False return False