minor refactorings

This commit is contained in:
Nicolás Sánchez 2025-08-16 17:27:07 -03:00
parent 8ef31c4bab
commit 3353a09db1
1 changed files with 95 additions and 102 deletions

191
main.py
View File

@ -240,19 +240,20 @@ def restart_pair_no_json(base: str, quote: str) -> int:
'''
try:
symbol = f"{base}/{quote}"
order_list = broker.fetch_full_orders(tickers)
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.pause = True
#Backing up old status file
instance.status.save_to_file(is_backup=True)
#Here, we could open a duster (if needed)
for order in order_list:
if order["symbol"]==f"{base}/{quote}" and instance.config.get_is_short() and order["side"]=="sell":
broker.logger.log_this(f"Cancelling old sell orders",2,f"{base}/{quote}")
if order["symbol"]==symbol and instance.config.get_is_short() and order["side"]=="sell":
broker.logger.log_this(f"Cancelling old sell orders",2,symbol)
broker.cancel_order(order["id"],order["symbol"])
elif order["symbol"]==f"{base}/{quote}" and not instance.config.get_is_short() and order["side"]=="buy":
broker.logger.log_this(f"Cancelling old buy orders",2,f"{base}/{quote}")
elif order["symbol"]==symbol and not instance.config.get_is_short() and order["side"]=="buy":
broker.logger.log_this(f"Cancelling old buy orders",2,symbol)
broker.cancel_order(order["id"],order["symbol"])
try:
running_traders.remove(instance)
@ -262,7 +263,7 @@ def restart_pair_no_json(base: str, quote: str) -> int:
return 0
return 1
except Exception as e:
broker.logger.log_this(f"Exception in restart_pair_no_json: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception in restart_pair_no_json: {e}",1,symbol)
return 1
@ -287,8 +288,6 @@ def main_loop():
tickers.remove(f"{instance.base}{instance.quote}")
broker.remove_pair_from_config(f"{instance.base}{instance.quote}")
broker.rewrite_config_file()
if instance.config.get_pair() in worker_status:
del(worker_status[instance.config.get_pair()])
try:
running_traders.remove(instance)
except ValueError:
@ -302,11 +301,10 @@ def main_loop():
#Prepares the trader threads
futures = []
open_orders = broker.fetch_open_orders(tickers)
pairs_to_fetch = []
online_pairs = []
open_orders = broker.fetch_open_orders(tickers)
for instance in running_traders:
#threads.append(Thread(target=instance.check_status,args=(open_orders,)))
future = executor.submit(instance.check_status, open_orders)
futures.append(future)
online_pairs.append(f"{instance.base}{instance.quote}")
@ -335,7 +333,6 @@ def main_loop():
instance.get_status_dict()["price"] = price_list[instance.config.get_pair()]
except Exception as e:
broker.logger.log_this(f"Exception while querying for pair price, key not present on price_list dictionary: {e}",1,instance.config.get_pair())
worker_status[instance.config.get_pair()] = instance.get_status_dict()
#Clear the screen buffer
screen_buffer.clear()
@ -349,7 +346,6 @@ def main_loop():
screen_buffer.append(str(instance))
#Updates some global status variables prior to deletion of those
#global_status["online_workers"] = online_pairs.copy()
if len(running_traders)!=len(global_status["online_workers"]):
global_status["online_workers"] = [instance.config.get_pair() for instance in running_traders]
@ -1385,9 +1381,10 @@ def unwrapped_return_worker_status(base,quote):
Returns:
dict: The status dictionary of the trader.
'''
if f"{base}/{quote}" in worker_status:
return jsonify(worker_status[f"{base}/{quote}"])
symbol = f"{base}/{quote}"
for instance in running_traders:
if instance.status.get_pair() == symbol:
return jsonify(instance.status.get_status())
return jsonify({"Error": "Worker does not exist"})
@ -1399,7 +1396,7 @@ def unwrapped_return_all_worker_status():
dict: The status dictionary of all traders.
'''
return jsonify(worker_status)
return {instance.status.get_pair(): instance.status.get_status() for instance in running_traders}
def unwrapped_add_pair(base,quote):
@ -1415,42 +1412,27 @@ def unwrapped_add_pair(base,quote):
'''
try:
symbol = f"{base}/{quote}"
#Check if the trader is already running
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
broker.logger.log_this(f"Pair already running",1,f"{base}/{quote}")
if symbol==instance.config.get_pair():
broker.logger.log_this(f"Pair already running",1,symbol)
return jsonify({"Error": "Pair already running"})
#Check if the market exists and it's open
if not broker.validate_market(f"{base}/{quote}"):
if not broker.validate_market(symbol):
return jsonify({"Error": "Market error. Check logs for more info."})
broker.logger.log_this(f"Initializing trader",2,f"{base}/{quote}")
broker.logger.log_this(f"Initializing trader",2,symbol)
add_instance(base,quote)
broker.add_pair_to_config(f"{base}{quote}")
broker.rewrite_config_file(backup=True)
# #Adding the pair to the config file (if it's not there yet)
# #1. Read the config file
# with open(sys.argv[1],"r") as f:
# temp_details = json.load(f)
# if base+quote not in temp_details["pairs"]:
# #2. Save the current config file as .bak
# with open(f"{sys.argv[1]}.bak","w") as c:
# c.write(json.dumps(temp_details, indent=4))
# #3. Add the pair to the right list
# temp_details["pairs"].append(f"{base}{quote}")
# #4. Write the config file
# with open(sys.argv[1],"w") as c:
# c.write(json.dumps(temp_details, indent=4))
# broker.logger.log_this(f"Broker's config file updated",2,f"{base}/{quote}")
# else:
# broker.logger.log_this(f"Pair already included in the config file",2,f"{base}/{quote}")
return jsonify({"Success": "Pair added"})
except Exception as e:
broker.logger.log_this(f"Exception while initializing new instance: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception while initializing new instance: {e}",1,symbol)
return jsonify({"Error": "Error initializing new instance."})
@ -1467,12 +1449,13 @@ def unwrapped_remove_pair(base,quote):
'''
try:
symbol = f"{base}/{quote}"
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.quit = True
return jsonify({"Success": "Pair to be removed"})
except Exception as e:
broker.logger.log_this(f"Exception while removing instance: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception while removing instance: {e}",1,symbol)
return jsonify({"Error": "Halp"})
@ -1508,13 +1491,14 @@ def unwrapped_import_pair(base,quote,forced_tp_id = None, forced_so_id = None):
'''
try:
symbol = f"{base}/{quote}"
import_instance(base,quote,forced_tp_id,forced_so_id)
broker.add_pair_to_config(f"{base}{quote}")
broker.rewrite_config_file()
broker.logger.log_this(f"Done",2,f"{base}/{quote}")
broker.logger.log_this(f"Done",2,symbol)
return jsonify({"Success": "Pair imported successfully"})
except Exception as e:
broker.logger.log_this(f"Exception while importing instance: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception while importing instance: {e}",1,symbol)
return jsonify({"Error": "Error importing instance"})
@ -1560,17 +1544,18 @@ def unwrapped_switch_to_short(base,quote):
'''
#Close trader and orders and pull info our of the orders
symbol = f"{base}/{quote}"
if f"{base}{quote}" not in broker.get_pairs():
return jsonify({"Error": "Pair not running"})
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair() and instance.switch_to_short()==1:
if symbol==instance.config.get_pair() and instance.switch_to_short()==1:
return jsonify({"Error": "Error in switch_to_short()"})
#Restart instance
try:
broker.logger.log_this(f"Reinitializing trader",2,f"{base}/{quote}")
broker.logger.log_this(f"Reinitializing trader",2,symbol)
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.status.set_take_profit_order(instance.broker.empty_order)
instance.so = instance.broker.empty_order
@ -1584,7 +1569,7 @@ def unwrapped_switch_to_short(base,quote):
return jsonify({"Error": "Error switching to short mode (wAPI)"})
return jsonify({"Success": "Pair switched to short mode"})
except Exception as e:
broker.logger.log_this(f"Exception while reinitializing instance: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception while reinitializing instance: {e}",1,symbol)
return jsonify({"Error": "Can't initialize trader"})
return jsonify({"Error": "Halp"})
@ -1603,22 +1588,23 @@ def unwrapped_load_old_long(base,quote):
#Load the file
try:
symbol = f"{base}/{quote}"
with open(f"{base}{quote}.oldlong") as ol:
old_long = load(ol)
except Exception as e:
broker.logger.log_this(f"Exception while loading old_long file: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception while loading old_long file: {e}",1,symbol)
return jsonify({"Error": "old_long file of that pair does not exist."})
#Check that the file has the proper keys
if not any(["tp_price" in old_long, "tp_amount" in old_long, "quote_spent" in old_long, "datetime" in old_long]):
broker.logger.log_this(f"old_long file invalid: keys missing.",1,f"{base}/{quote}")
broker.logger.log_this(f"old_long file invalid: keys missing.",1,symbol)
return jsonify({"Error": "File is invalid or missing keys"})
#Maybe here we could also check that the keys have the proper values
#Creates (or modifies) a key in the status dictionary and assigns the contents of the file to that same key.
for instance in running_traders:
if instance.config.get_pair()==f"{base}/{quote}":
if instance.config.get_pair()==symbol:
instance.get_status_dict()["old_long"]=old_long
instance.update_status(True)
return jsonify({"Success": "old_long file loaded to status_dict"})
@ -1639,18 +1625,19 @@ def unwrapped_view_old_long(base,quote,from_file):
'''
try:
symbol = f"{base}/{quote}"
if int(from_file)==1:
with open(f"{base}{quote}.oldlong") as ol:
old_long = load(ol)
return jsonify(old_long)
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
if "old_long" in instance.get_status_dict():
return jsonify(instance.get_status_dict()["old_long"])
return jsonify({"Error": "No old_long info found"})
return jsonify({"Error": "Pair not found"})
except Exception as e:
broker.logger.log_this(f"Exception while viewing old_long info: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception while viewing old_long info: {e}",1,symbol)
return jsonify({"Error": f"{e}"})
@ -1668,8 +1655,9 @@ def unwrapped_switch_to_long_price(base,quote):
'''
try:
symbol = f"{base}/{quote}"
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
if "old_long" in instance.get_status_dict():
#minimum_switch_price = (old_target - quote_already_in)/base_left
old_target = instance.get_status_dict()["old_long"]["tp_price"]*instance.get_status_dict()["old_long"]["tp_amount"]
@ -1679,7 +1667,7 @@ def unwrapped_switch_to_long_price(base,quote):
return jsonify({"Error": "No old_long info found"})
return jsonify({"Error": "Pair not found"})
except Exception as e:
broker.logger.log_this(f"Exception while viewing old_long info: {e}",1,f"{base}/{quote}")
broker.logger.log_this(f"Exception while viewing old_long info: {e}",1,symbol)
return jsonify({"Error": f"{e}"})
@ -1698,20 +1686,21 @@ def unwrapped_add_safety_orders(base,quote,amount):
'''
try:
symbol = f"{base}/{quote}"
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.pause = True
#x.no_of_safety_orders += int(amount)
instance.config.set_no_of_safety_orders(instance.config.get_no_of_safety_orders()+int(amount))
broker.logger.log_this("Recalculating safety price table...",1,f"{base}/{quote}")
broker.logger.log_this("Recalculating safety price table...",1,symbol)
instance.status.set_safety_price_table(instance.calculate_safety_prices(instance.status.get_start_price(),instance.config.get_no_of_safety_orders(),instance.config.get_safety_order_deviance()))
broker.logger.log_this(f"Done. Added {amount} safety orders",1,f"{base}/{quote}")
broker.logger.log_this(f"Done. Added {amount} safety orders",1,symbol)
instance.update_status(True)
instance.pause = False
return jsonify({"Success": f"Done. Added {amount} safety orders"})
return jsonify({"Error": "Pair not found"})
except Exception as e:
broker.logger.log_this(f"{e}",2,f"{base}/{quote}")
broker.logger.log_this(f"{e}",2,symbol)
return jsonify({"Error": "Error adding safety orders"})
@ -1728,8 +1717,9 @@ def unwrapped_base_add_so_calculation(base,quote):
'''
try:
symbol = f"{base}/{quote}"
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
free_base = instance.fetch_free_base()
if free_base is None:
return jsonify({"Error": "Can't fetch amount of free base on the exchange"})
@ -1737,7 +1727,7 @@ def unwrapped_base_add_so_calculation(base,quote):
return jsonify({"Amount": amount_of_orders, "Free base on exchange": free_base})
return jsonify({"Error": "Can't find the pair in the running instances"})
except Exception as e:
broker.logger.log_this(f"{e}",2,f"{base}/{quote}")
broker.logger.log_this(f"{e}",2,symbol)
return jsonify({"Error": "Error in unwrapped_base_add_so_calculation"})
@ -1755,13 +1745,14 @@ def unwrapped_mod_tp_level(base,quote,amount):
'''
try:
symbol = f"{base}/{quote}"
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.config.set_tp_level(float(amount))
broker.logger.log_this("Done. The change will take effect when the next take profit order is placed",2,f"{base}/{quote}")
broker.logger.log_this("Done. The change will take effect when the next take profit order is placed",2,symbol)
return jsonify({"Success": "Success. The change will take effect when the next TP order is placed"})
except Exception:
broker.logger.log_this("Error changing percentage. Ignoring...",2,f"{base}/{quote}")
broker.logger.log_this("Error changing percentage. Ignoring...",2,symbol)
return jsonify({"Error": "Error changing percentage"})
@ -1779,13 +1770,14 @@ def unwrapped_mod_order_size(base,quote,amount):
'''
try:
symbol = f"{base}/{quote}"
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.config.set_order_size(float(amount))
broker.logger.log_this("Done. The change will take effect when the next deal is started",2,f"{base}/{quote}")
broker.logger.log_this("Done. The change will take effect when the next deal is started",2,symbol)
return jsonify({"Success": "Success. The change will take effect when the next deal is started"})
except Exception:
broker.logger.log_this("Error changing order size. Ignoring...",2,f"{base}/{quote}")
broker.logger.log_this("Error changing order size. Ignoring...",2,symbol)
return jsonify({"Error": "Error changing order size"})
@ -1842,9 +1834,10 @@ def unwrapped_last_call(base,quote):
'''
try:
if f"{base}{quote}" in broker.get_pairs():
symbol = f"{base}/{quote}"
if symbol in broker.get_pairs(): #Why was this?
for instance in running_traders:
if f"{base}/{quote}"==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.status.set_stop_when_profit(not instance.status.get_stop_when_profit())
instance.update_status(True)
if instance.status.get_stop_when_profit():
@ -1902,9 +1895,10 @@ def unwrapped_toggle_pause(base,quote):
'''
try:
toggle_pauses.append(f"{base}/{quote}")
symbol = f"{base}/{quote}"
toggle_pauses.append(symbol)
for instance in running_traders:
if instance.config.get_pair()==f"{base}/{quote}":
if instance.config.get_pair()==symbol:
if instance.pause:
instance.status.set_pause_reason("")
return jsonify({"Success": "Trader will be resumed"})
@ -2053,15 +2047,15 @@ def unwrapped_toggle_cleanup(base,quote):
'''
try:
pair_to_toggle = f"{base}/{quote}"
symbol = f"{base}/{quote}"
for instance in running_traders:
if pair_to_toggle==instance.config.get_pair():
if symbol==instance.config.get_pair():
instance.config.set_cleanup(not instance.config.get_cleanup())
if instance.config.get_cleanup():
return jsonify({"Success": "Cleanup turned ON"})
return jsonify({"Success": "Cleanup turned OFF"})
except Exception as e:
broker.logger.log_this(f"Exception while toggling cleanup: {e}",1,f"{base}{quote}")
broker.logger.log_this(f"Exception while toggling cleanup: {e}",1,symbol)
return jsonify({"Error": "Halp"})
return jsonify({"Error": "Task failed successfully"})
@ -2079,19 +2073,19 @@ def unwrapped_toggle_autoswitch(base,quote):
'''
try:
pair_to_toggle = f"{base}/{quote}"
symbol = f"{base}/{quote}"
for instance in running_traders:
if pair_to_toggle==instance.config.get_pair():
if symbol==instance.config.get_pair():
if instance.config.get_autoswitch():
broker.logger.log_this("Autoswitch turned OFF",1,f"{base}/{quote}")
broker.logger.log_this("Autoswitch turned OFF",1,symbol)
instance.config.set_autoswitch(False)
return jsonify({"Success": "Autoswitch is now OFF"})
else:
broker.logger.log_this("Autoswitch turned ON",1,f"{base}/{quote}")
broker.logger.log_this("Autoswitch turned ON",1,symbol)
instance.config.set_autoswitch(True)
return jsonify({"Success": "Autoswitch is now ON"})
except Exception as e:
broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,f"{base}{quote}")
broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,symbol)
return jsonify({"Error": "Halp"})
def unwrapped_toggle_liquidate_after_switch(base,quote):
@ -2107,19 +2101,19 @@ def unwrapped_toggle_liquidate_after_switch(base,quote):
'''
try:
pair_to_toggle = f"{base}/{quote}"
symbol = f"{base}/{quote}"
for instance in running_traders:
if pair_to_toggle==instance.config.get_pair():
if symbol==instance.config.get_pair():
if instance.config.get_liquidate_after_switch():
broker.logger.log_this("Liquidate after switch turned OFF",1,f"{base}/{quote}")
broker.logger.log_this("Liquidate after switch turned OFF",1,symbol)
instance.config.set_liquidate_after_switch(False)
return jsonify({"Success": "Liquidate after switch is now OFF"})
else:
broker.logger.log_this("Liquidate after switch turned ON",1,f"{base}/{quote}")
broker.logger.log_this("Liquidate after switch turned ON",1,symbol)
instance.config.set_liquidate_after_switch(True)
return jsonify({"Success": "Liquidate after switch is now ON"})
except Exception as e:
broker.logger.log_this(f"Exception while toggling liquidate after switch: {e}",1,f"{base}{quote}")
broker.logger.log_this(f"Exception while toggling liquidate after switch: {e}",1,symbol)
return jsonify({"Error": "Halp"})
def unwrapped_toggle_check_old_long_price(base,quote):
@ -2135,19 +2129,19 @@ def unwrapped_toggle_check_old_long_price(base,quote):
'''
try:
pair_to_toggle = f"{base}/{quote}"
symbol = f"{base}/{quote}"
for instance in running_traders:
if pair_to_toggle==instance.config.get_pair():
if symbol==instance.config.get_pair():
if instance.config.get_check_old_long_price():
broker.logger.log_this("Check OFF",1,f"{base}/{quote}")
broker.logger.log_this("Check OFF",1,symbol)
instance.config.set_check_old_long_price(False)
return jsonify({"Success": "Old long price check turned OFF"})
else:
broker.logger.log_this("Check ON",1,f"{base}/{quote}")
broker.logger.log_this("Check ON",1,symbol)
instance.config.set_check_old_long_price(True)
return jsonify({"Success": "Old long price check turned ON"})
except Exception as e:
broker.logger.log_this(f"Exception while toggling check_old_long_price: {e}",1,f"{base}{quote}")
broker.logger.log_this(f"Exception while toggling check_old_long_price: {e}",1,symbol)
return jsonify({"Error": "Halp"})
@ -2165,9 +2159,9 @@ def unwrapped_switch_quote_currency(base,quote,new_quote):
'''
try:
pair_to_switch = f"{base}/{quote}"
symbol = f"{base}/{quote}"
for trader in running_traders:
if pair_to_switch==trader.config.get_pair():
if symbol==trader.config.get_pair():
#Pause the trader
trader.pause = True
@ -2175,14 +2169,12 @@ def unwrapped_switch_quote_currency(base,quote,new_quote):
if trader.switch_quote_currency(new_quote)==1:
return jsonify({"Error": "Swap failed. Check log files for details."})
del(worker_status[f"{base}/{quote}"])
#Resume the trader
trader.pause = False
return jsonify({"Success": "Mission successful"})
return jsonify({"Error": "Trader not found"})
except Exception as e:
broker.logger.log_this(f"Exception while switching quote currency: {e}",1,f"{base}{quote}")
broker.logger.log_this(f"Exception while switching quote currency: {e}",1,symbol)
return jsonify({"Error": "Halp"})
@ -2347,13 +2339,14 @@ def unwrapped_reload_safety_order(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation.
'''
try:
symbol = f"{base}/{quote}"
for trader in running_traders:
if trader.config.get_pair()==f"{base}/{quote}":
if trader.config.get_pair()==symbol:
trader.config.load_from_file()
return jsonify({"Success": "Safety order reloaded successfully"})
return jsonify({"Error": "Trader not found"})
except Exception as e:
broker.logger.log_this(f"Exception while reloading safety order: {e}",1)
broker.logger.log_this(f"Exception while reloading safety order: {e}",1,symbol)
return jsonify({"Error": "Safety order couldn't be reloaded"})
@ -2389,9 +2382,12 @@ def unwrapped_reload_trader_config(base,quote):
Returns:
jsonify: A jsonified dictionary detailing the outcome of the operation.
'''
symbol = f"{base}/{quote}"
for trader in running_traders:
if trader.config.get_pair() == f"{base}/{quote}":
return jsonify(worker_status[f"{base}/{quote}"])
if trader.config.get_pair() == symbol:
if trader.config.load_from_file()==0:
return jsonify({"Success": "Config file reloaded"})
return jsonify({"Error": "Error reloading config file"})
return jsonify({"Error": "Worker does not exist"})
@ -2436,14 +2432,11 @@ if __name__=="__main__":
#Declaring some variables
running_traders = []
open_orders = []
instances_to_add = []
online_pairs = []
toggle_pauses = []
tickers = []
threads = []
screen_buffer = []
worker_status = {}
global_status = {
"name": broker.get_config()["exchange"].upper(),
"instance_uptime": 0,