diff --git a/main.py b/main.py index 627279a..f9d0a3c 100644 --- a/main.py +++ b/main.py @@ -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,12 +301,11 @@ 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) + future = executor.submit(instance.check_status, open_orders) futures.append(future) online_pairs.append(f"{instance.base}{instance.quote}") pairs_to_fetch.append(instance.config.get_pair()) @@ -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] @@ -579,7 +575,7 @@ def return_all_worker_status(): None ''' - if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_return_all_worker_status() return jsonify({'Error': 'API key invalid'}), 401 @@ -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"}) @@ -1507,14 +1490,15 @@ def unwrapped_import_pair(base,quote,forced_tp_id = None, forced_so_id = None): jsonified dictionary detailing the outcome of the operation. ''' - try: + 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,