diff --git a/configs/trader_config.json.example b/configs/trader_config.json.example index d890933..eb0b8b3 100755 --- a/configs/trader_config.json.example +++ b/configs/trader_config.json.example @@ -12,7 +12,7 @@ "tp_mode": 3, #Take profit mode. (check strategy documentation for more details) "tp_table": [], #Profit percentage table. (check strategy documentation for more details) "is_short": true, #Signals the trader mode (true if short, false if long) - "autoswitch": true, #If short, switches to long mode if certain conditions are met. (check strategy documentation for more details) + "autoswitch": true, #If the trader is operating in short mode, switches to long mode if certain conditions are met. (check strategy documentation for more details) "attempt_restart": true, #Attempts to restart the trader if there is an error. "check_old_long_price": true, #Compares the current price with the old_long price. (check strategy documentation for more details) "dynamic_so_deviance": true, #Uses a non-linear safety order deviance algorithm. (check strategy documentation for more details) diff --git a/main.py b/main.py index a41edf4..d843807 100644 --- a/main.py +++ b/main.py @@ -40,6 +40,12 @@ white = "\033[0;37;40m" def seconds_to_time(total_seconds: float) -> str: ''' Takes an int or float as an input and it returns a D:HH:MM:SS formatted string. + + Parameters: + total_seconds (float): The number of seconds to convert + + Returns: + str: The formatted string ''' time_delta = datetime.timedelta(seconds=total_seconds) @@ -55,7 +61,16 @@ def seconds_to_time(total_seconds: float) -> str: def time_to_unix(year: str, month: str, day: str) -> int: ''' Takes three integer values as an input and returns the unix time corresponding to that input + + Parameters: + year (str): The year to convert + month (str): The month to convert + day (str): The day to convert + + Returns: + int: The unix time corresponding to the input ''' + try: return int(time.mktime(datetime.date(int(year), int(month), int(day)).timetuple())) except Exception as e: @@ -64,6 +79,15 @@ def time_to_unix(year: str, month: str, day: str) -> int: def import_instance(pair: str) -> int: + ''' + Imports an previously running trader instance from the status file. + + Parameters: + pair (str): The trading pair to import with the format BASEQUOTE (no slash). + + Returns: + int: 0 if successful + ''' broker.logger.log_this(f"Importing {pair}") #with open(f"status/{pair}.status", "r") as f: # status_file_contents = json.load(f) @@ -76,6 +100,17 @@ def import_instance(pair: str) -> int: def add_instance(base: str, quote: str) -> int: + ''' + Adds a new instance of the trader class to the running_instances list. + + Parameters: + base (str): The base currency of the pair. + quote (str): The quote currency of the pair. + + Returns: + int: 0 if the instance was successfully added, 1 if the pair is already running. + ''' + #Check if the pair is already running pair = f"{base}{quote}" for x in running_instances: @@ -104,7 +139,13 @@ def add_instance(base: str, quote: str) -> int: def initialize_instance(pair: str) -> int: ''' Loads the pair config file and initializes the trader object by adding it to the running instances list + + Parameters: + pair (str): The pair to initialize with the format BASEQUOTE (no slash) + Returns: + int: 0 if successful ''' + with open(f"configs/{pair}.json", "r") as y: config_details = json.load(y) broker.logger.log_this(f"Initializing {pair}") @@ -145,8 +186,15 @@ def generate_config_file(base: str, quote: str) -> dict: def set_exchange(config: dict): ''' - Takes the config dictionary as an input and returns the exchange object properly configured + Takes the config dictionary as an input and returns the exchange object + + Parameters + config (dict): The config dictionary + + Returns + exchange (ccxt.Exchange): The exchange object ''' + timeout = 10000 if config["exchange"]=="binance": exchange_class = getattr(ccxt, "binance") @@ -209,6 +257,17 @@ def set_exchange(config: dict): def restart_pair_no_json(base: str, quote: str) -> int: + ''' + Trader restart routine + + Parameters: + base (str): Base currency + quote (str): Quote currency + + Returns: + int: 0 if successful, 1 if not + ''' + try: order_list = broker.fetch_full_orders(tickers) for x in running_instances: @@ -388,8 +447,17 @@ def main_loop(): def load_keys_from_db(file_name: str) -> list: ''' Load valid API keys + + Parameters + ---------- + file_name : str + Name of the database file + + Returns + ------- + valid_keys : list + List of valid API keys ''' - #valid_keys = [] database_connection = sqlite3.connect(file_name) database_cursor = database_connection.cursor() @@ -398,8 +466,6 @@ def load_keys_from_db(file_name: str) -> list: database_connection.close() valid_keys = [line[1] for line in data] - #for line in data: - # valid_keys.append(line[1]) return valid_keys @@ -439,6 +505,7 @@ def return_global_status(): Parameters: None ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_global_status() return jsonify({'Error': 'API key invalid'}), 401 @@ -464,6 +531,7 @@ def return_worker_status(): base: str quote: str ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: base = request.args.get("base") @@ -484,6 +552,7 @@ def return_old_long(): quote: str from_file: bool ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: base = request.args.get("base") @@ -503,6 +572,7 @@ def return_all_worker_status(): Parameters: None ''' + 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 @@ -516,6 +586,7 @@ def add_pair(): 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: @@ -538,6 +609,7 @@ def remove_pair(): 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: @@ -560,6 +632,7 @@ def restart_pair(): 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: @@ -582,6 +655,7 @@ def import_pair(): 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: @@ -605,6 +679,7 @@ def switch_to_long(): quote: str calculate_profits: int ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -628,6 +703,7 @@ def switch_to_short(): 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: @@ -650,6 +726,7 @@ def load_old_long(): 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: @@ -673,6 +750,7 @@ def add_so(): quote: str amount: int ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -697,6 +775,7 @@ def mod_tp_level(): quote: str amount: float ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -719,6 +798,7 @@ def mod_global_tp_level(): Parameters: amount: float ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -740,6 +820,7 @@ def last_call(): 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: @@ -763,6 +844,7 @@ def deferred_last_call(): quote: str yyyymmdd: str ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -786,6 +868,7 @@ def toggle_pause(): 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: @@ -807,6 +890,7 @@ def global_last_call(): Parameters: None ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_global_last_call() return jsonify({'Error': 'API key invalid'}), 401 @@ -821,6 +905,7 @@ def add_quote(): quote: str amount: float ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -843,6 +928,7 @@ def missing_pairs(): Parameters: None ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_missing_pairs() return jsonify({'Error': 'API key invalid'}), 401 @@ -856,6 +942,7 @@ def toggle_cleanup(): 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: @@ -878,6 +965,7 @@ def toggle_autoswitch(): 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: @@ -900,6 +988,7 @@ def toggle_check_old_long_price(): 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: @@ -923,6 +1012,7 @@ def switch_quote_currency(): quote: str new_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: @@ -945,6 +1035,7 @@ def toggle_restart(): Parameters: None ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_toggle_restart() return jsonify({'Error': 'API key invalid'}), 401 @@ -957,6 +1048,7 @@ def toggle_telegram(): Parameters: None ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_toggle_telegram() return jsonify({'Error': 'API key invalid'}), 401 @@ -969,6 +1061,7 @@ def server_time(): Parameters: None ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_server_time() return jsonify({'Error': 'API key invalid'}), 401 @@ -981,6 +1074,7 @@ def trader_time(): Parameters: None ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_trader_time() return jsonify({'Error': 'API key invalid'}), 401 @@ -993,6 +1087,7 @@ def loop_wait_time(): Parameters: wait_time: float ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -1013,6 +1108,7 @@ def call_wait_time(): Parameters: wait_time: float ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: @@ -1034,6 +1130,7 @@ def reload_markets(): base: str quote: str ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: return unwrapped_reload_markets() @@ -1046,8 +1143,8 @@ def reload_safety_order(): Parameters: None - ''' + if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: try: if request.json is None: