From c65848658ea3e9281ee87a453f10d171e440e911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20S=C3=A1nchez?= Date: Sat, 31 May 2025 17:28:35 -0300 Subject: [PATCH] liquidate_after_switch --- changelog.txt | 3 +++ config_handler.py | 11 ++++++++++ main.py | 52 +++++++++++++++++++++++++++++++++++++++++++++- trader.py | 12 ++++++++--- utils/commander.py | 19 +++++++++++++++-- 5 files changed, 91 insertions(+), 6 deletions(-) diff --git a/changelog.txt b/changelog.txt index ee43525..b4f9b08 100755 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +2025.05.31: +. Added "liquidate after switch": Once the short trader is ready to switch to long, it liquidates the base currency and shuts down the trader. + 2025.05.27: . Commented out parameter validation in config and status handlers. diff --git a/config_handler.py b/config_handler.py index 233f03b..88d038a 100644 --- a/config_handler.py +++ b/config_handler.py @@ -21,6 +21,7 @@ class ConfigHandler: "dsd_range": 1, "cleanup": True, "autoswitch": False, + "liquidate_after_switch": False, "attempt_restart": True, "tp_mode": 3, "tp_level": 1.025, @@ -87,6 +88,9 @@ class ConfigHandler: def get_autoswitch(self): return self.config_dictionary["autoswitch"] + def get_liquidate_after_switch(self): + return self.config_dictionary["liquidate_after_switch"] + def get_attempt_restart(self): return self.config_dictionary["attempt_restart"] @@ -217,6 +221,13 @@ class ConfigHandler: self.config_dictionary["autoswitch"] = autoswitch return 0 + def set_liquidate_after_switch(self, liquidate_after_switch: bool): + # if not isinstance(liquidate_after_switch, bool): + # self.broker.logger.log_this(f"liquidate_after_switch must be a boolean",1,self.get_pair()) + # return 1 + self.config_dictionary["liquidate_after_switch"] = liquidate_after_switch + return 0 + def set_tp_mode(self, tp_mode: int): # if not isinstance(tp_mode, int): # self.broker.logger.log_this(f"tp_mode must be an integer",1,self.get_pair()) diff --git a/main.py b/main.py index c06552b..f01031a 100644 --- a/main.py +++ b/main.py @@ -16,7 +16,7 @@ import exchange_wrapper import trader -version = "2025.05.27" +version = "2025.05.31" ''' Color definitions. If you want to change them, check the reference at https://en.wikipedia.org/wiki/ANSI_escape_code#Colors @@ -979,6 +979,29 @@ def toggle_autoswitch(): return jsonify({'Error': 'Halp'}) return jsonify({'Error': 'API key invalid'}), 401 +@base_api.route("/toggle_liquidate_after_switch", methods=['POST']) #type:ignore +def toggle_liquidate_after_switch(): #type:ignore + ''' + POST request + + Parameters: + base: str + quote: str + ''' + + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: + try: + if request.json is None: + return jsonify({'Error': 'request.json is None'}) + data = request.json + base = data["base"] + quote = data["quote"] + return unwrapped_toggle_liquidate_after_switch(base,quote) + except Exception as e: + print(e) + return jsonify({'Error': 'Halp'}) + return jsonify({'Error': 'API key invalid'}), 401 + @base_api.route("/toggle_check_old_long_price", methods=['POST'])#type:ignore def toggle_check_old_long_price(): ''' @@ -1928,6 +1951,33 @@ def unwrapped_toggle_autoswitch(base,quote): broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,f"{base}{quote}") return jsonify({"Error": "Halp"}) +def unwrapped_toggle_liquidate_after_switch(base,quote): + ''' + Signals a trader to enable or disable quitting after switching from short to long. + + Parameters: + base (str): The base currency of the trading pair. + quote (str): The quote currency of the trading pair. + + Returns: + A jsonified dictionary detailing the outcome of the operation. + ''' + + try: + pair_to_toggle = f"{base}/{quote}" + for x in running_instances: + if pair_to_toggle==x.config.get_pair(): + if x.config.get_liquidate_after_switch(): + broker.logger.log_this("Liquidate after switch turned OFF",1,f"{base}/{quote}") + x.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}") + x.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}") + return jsonify({"Error": "Halp"}) def unwrapped_toggle_check_old_long_price(base,quote): ''' diff --git a/trader.py b/trader.py index 0e19545..85d63e9 100755 --- a/trader.py +++ b/trader.py @@ -980,7 +980,10 @@ class trader: #Sell all base (market), report the profits and restart the trader self.status.set_pause_reason("automatic_switch") self.switch_to_long(already_received_quote=self.status.get_quote_spent()) - self.restart = True + if self.config.get_liquidate_after_switch(): + self.quit = True + else: + self.restart = True return 1 #Extract ids from order list @@ -1542,10 +1545,13 @@ class trader: if self.status.get_is_boosted(): line1 = f"{line1} | BOOSTED" if self.config.get_autoswitch(): - line1 = f"{line1} | AUTO" + auto_color = white + if self.config.get_liquidate_after_switch(): + auto_color = red + line1 = f"{line1} | {auto_color}AUTO{white}" if multiplier>1: #Only displays the multiplier if autoswitch is enabled. - line1 = f"{line1}x{multiplier}" + line1 = f"{line1}{auto_color}x{multiplier}{white}" if self.config.get_programmed_stop() and time.time()<=self.config.get_programmed_stop_time(): line1 = f"{line1} | PROGRAMMED LAST DEAL" if self.status.get_stop_when_profit(): diff --git a/utils/commander.py b/utils/commander.py index 7a2415f..0edf72b 100644 --- a/utils/commander.py +++ b/utils/commander.py @@ -56,7 +56,7 @@ TRADERS 65) toggle_pause 66) toggle_cleanup 67) toggle_autoswitch 68) toggle_check_old_long_price 69) switch_quote_currency 70) reload_safety_order 71) view_old_long 72) switch_price -73) reload_trader_config +73) reload_trader_config 74) toggle_liquidate_after_switch 98) Change broker 99) Exit ''' @@ -802,4 +802,19 @@ if __name__=="__main__": parameters = {"base": base, "quote": quote} print(json.loads(requests.post(url, headers=headers, json=parameters).content)) - input("Press ENTER to continue ") \ No newline at end of file + input("Press ENTER to continue ") + + elif command==74: + print("toggle_liquidate_after_switch enables or disables the liquidation after an automatic switch to long of a short trader") + print("This is only valid in a short trader, of course.") + trading_pair = input("Input trader in the format BASE/QUOTE: ").upper() + if not validate_pair(trading_pair): + print("The input is invalid") + break + if input("Proceed? (Y/n) ") in ["Y","y",""]: + url = f"{base_url}{port}/toggle_liquidate_after_switch" + base,quote = trading_pair.split("/") + parameters = {"base": base, + "quote": quote} + print(json.loads(requests.post(url, headers=headers, json=parameters).content)) + input("Press ENTER to continue ") \ No newline at end of file