2025.03.03
This commit is contained in:
parent
ba86c76ad6
commit
7d90b7d833
|
|
@ -1,3 +1,8 @@
|
||||||
|
2025.03.03:
|
||||||
|
. Replaced more variables with their respective config handlers.
|
||||||
|
. Added a new API endpoint: reload_trader_config.
|
||||||
|
. Removed the config reloading when a trader closes a deal.
|
||||||
|
|
||||||
2025.03.02:
|
2025.03.02:
|
||||||
. Fixed an error in restart_pair_no_json()
|
. Fixed an error in restart_pair_no_json()
|
||||||
|
|
||||||
|
|
|
||||||
117
main.py
117
main.py
|
|
@ -24,7 +24,7 @@ In case the permissions of the certificate changes, reset them this way:
|
||||||
# ll /etc/letsencrypt/
|
# ll /etc/letsencrypt/
|
||||||
'''
|
'''
|
||||||
|
|
||||||
version = "2025.03.02"
|
version = "2025.03.03"
|
||||||
|
|
||||||
'''
|
'''
|
||||||
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
|
||||||
|
|
@ -240,7 +240,7 @@ def restart_pair_no_json(base: str, quote: str) -> int:
|
||||||
try:
|
try:
|
||||||
order_list = broker.fetch_full_orders(tickers)
|
order_list = broker.fetch_full_orders(tickers)
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
x.pause = True
|
x.pause = True
|
||||||
#Backing up old status file
|
#Backing up old status file
|
||||||
x.status.save_to_file(is_backup=True)
|
x.status.save_to_file(is_backup=True)
|
||||||
|
|
@ -270,17 +270,17 @@ def main_loop():
|
||||||
#Restart traders that have the restart flag raised and remove traders that have the quit flag raised
|
#Restart traders that have the restart flag raised and remove traders that have the quit flag raised
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if x.restart and x.config.get_attempt_restart():
|
if x.restart and x.config.get_attempt_restart():
|
||||||
broker.logger.log_this(f"Restarting trader",1,x.pair)
|
broker.logger.log_this(f"Restarting trader",1,x.config.get_pair())
|
||||||
restart_pair_no_json(x.base,x.quote)
|
restart_pair_no_json(x.base,x.quote)
|
||||||
if x.quit:
|
if x.quit:
|
||||||
#Here, check if a duster is needed
|
#Here, check if a duster is needed
|
||||||
broker.logger.log_this(f"Quit flag raised, removing pair.",0,x.pair)
|
broker.logger.log_this(f"Quit flag raised, removing pair.",0,x.config.get_pair())
|
||||||
if f"{x.base}{x.quote}" in tickers:
|
if f"{x.base}{x.quote}" in tickers:
|
||||||
tickers.remove(f"{x.base}{x.quote}")
|
tickers.remove(f"{x.base}{x.quote}")
|
||||||
broker.remove_pair_from_config(f"{x.base}{x.quote}")
|
broker.remove_pair_from_config(f"{x.base}{x.quote}")
|
||||||
broker.rewrite_config_file()
|
broker.rewrite_config_file()
|
||||||
if x.pair in worker_status:
|
if x.config.get_pair() in worker_status:
|
||||||
del(worker_status[x.pair])
|
del(worker_status[x.config.get_pair()])
|
||||||
running_instances.remove(x)
|
running_instances.remove(x)
|
||||||
|
|
||||||
#Adds pending traders
|
#Adds pending traders
|
||||||
|
|
@ -296,7 +296,7 @@ def main_loop():
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
threads.append(Thread(target=x.check_status,args=(open_orders,)))
|
threads.append(Thread(target=x.check_status,args=(open_orders,)))
|
||||||
online_pairs.append(f"{x.base}{x.quote}")
|
online_pairs.append(f"{x.base}{x.quote}")
|
||||||
pairs_to_fetch.append(x.pair)
|
pairs_to_fetch.append(x.config.get_pair())
|
||||||
|
|
||||||
#Here, append the dusters' pairs to pairs_to_fetch, if missing.
|
#Here, append the dusters' pairs to pairs_to_fetch, if missing.
|
||||||
#
|
#
|
||||||
|
|
@ -333,11 +333,11 @@ def main_loop():
|
||||||
top += int(x.config.get_no_of_safety_orders()) # It shows the percentage of safety orders not filled
|
top += int(x.config.get_no_of_safety_orders()) # It shows the percentage of safety orders not filled
|
||||||
if not x.quit: #Why? Maybe to protect return_status() from weird errors if the trader errored out?
|
if not x.quit: #Why? Maybe to protect return_status() from weird errors if the trader errored out?
|
||||||
try:
|
try:
|
||||||
if x.pair in price_list and price_list[x.pair] is not None:
|
if x.config.get_pair() in price_list and price_list[x.config.get_pair()] is not None:
|
||||||
x.get_status_dict()["price"] = price_list[x.pair]
|
x.get_status_dict()["price"] = price_list[x.config.get_pair()]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
broker.logger.log_this(f"Exception while querying for pair price, key not present on price_list dictionary: {e}",1,x.pair)
|
broker.logger.log_this(f"Exception while querying for pair price, key not present on price_list dictionary: {e}",1,x.config.get_pair())
|
||||||
worker_status[x.pair] = x.get_status_dict()
|
worker_status[x.config.get_pair()] = x.get_status_dict()
|
||||||
|
|
||||||
#Clear the screen buffer
|
#Clear the screen buffer
|
||||||
screen_buffer.clear()
|
screen_buffer.clear()
|
||||||
|
|
@ -354,14 +354,14 @@ def main_loop():
|
||||||
global_status["online_workers"] = online_pairs.copy()
|
global_status["online_workers"] = online_pairs.copy()
|
||||||
|
|
||||||
#Check for paused pairs
|
#Check for paused pairs
|
||||||
global_status["paused_traders"] = [x.pair for x in running_instances if x.pause]
|
global_status["paused_traders"] = [x.config.get_pair() for x in running_instances if x.pause]
|
||||||
if global_status["paused_traders"]:
|
if global_status["paused_traders"]:
|
||||||
screen_buffer.append(f"{cyan}Paused pairs: {list(global_status['paused_traders'])}{white}")
|
screen_buffer.append(f"{cyan}Paused pairs: {list(global_status['paused_traders'])}{white}")
|
||||||
|
|
||||||
#Check for paused pairs
|
#Check for paused pairs
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if x.pause:
|
if x.pause:
|
||||||
screen_buffer.append(f"{x.pair} paused: {x.get_status_dict()['pause_reason']}")
|
screen_buffer.append(f"{x.config.get_pair()} paused: {x.get_status_dict()['pause_reason']}")
|
||||||
|
|
||||||
#Prints general info
|
#Prints general info
|
||||||
instance_uptime = int(time.time()) - instance_start_time
|
instance_uptime = int(time.time()) - instance_start_time
|
||||||
|
|
@ -395,7 +395,7 @@ def main_loop():
|
||||||
#Toggle pauses
|
#Toggle pauses
|
||||||
if toggle_pauses:
|
if toggle_pauses:
|
||||||
for instance in running_instances:
|
for instance in running_instances:
|
||||||
if instance.pair in toggle_pauses:
|
if instance.config.get_pair() in toggle_pauses:
|
||||||
instance.pause = not instance.pause
|
instance.pause = not instance.pause
|
||||||
toggle_pauses.clear()
|
toggle_pauses.clear()
|
||||||
|
|
||||||
|
|
@ -1226,6 +1226,30 @@ def reload_safety_order():
|
||||||
return jsonify({'Error': 'API key invalid'}), 401
|
return jsonify({'Error': 'API key invalid'}), 401
|
||||||
|
|
||||||
|
|
||||||
|
@base_api.route("/reload_trader_config", methods=['POST'])#type:ignore
|
||||||
|
def reload_trader_config():
|
||||||
|
'''
|
||||||
|
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_reload_trader_config(base,quote)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return jsonify({'Error': 'Halp'})
|
||||||
|
return jsonify({'Error': 'API key invalid'}), 401
|
||||||
|
|
||||||
|
|
||||||
def run_API():
|
def run_API():
|
||||||
serve(base_api, host="0.0.0.0", port=broker.get_config()["port"], threads=16)
|
serve(base_api, host="0.0.0.0", port=broker.get_config()["port"], threads=16)
|
||||||
#base_api.run(host="0.0.0.0", port=broker.get_config()["port"])
|
#base_api.run(host="0.0.0.0", port=broker.get_config()["port"])
|
||||||
|
|
@ -1294,7 +1318,7 @@ def unwrapped_add_pair(base,quote):
|
||||||
try:
|
try:
|
||||||
#Check if the trader is already running
|
#Check if the trader is already running
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
broker.logger.log_this(f"Pair already running",1,f"{base}/{quote}")
|
broker.logger.log_this(f"Pair already running",1,f"{base}/{quote}")
|
||||||
return jsonify({"Error": "Pair already running"})
|
return jsonify({"Error": "Pair already running"})
|
||||||
|
|
||||||
|
|
@ -1348,7 +1372,7 @@ def unwrapped_remove_pair(base,quote):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
x.quit = True
|
x.quit = True
|
||||||
return jsonify({"Success": "Pair to be removed"})
|
return jsonify({"Success": "Pair to be removed"})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -1414,7 +1438,7 @@ def unwrapped_switch_to_long(base,quote,calculate_profits):
|
||||||
if f"{base}{quote}" not in broker.get_pairs():
|
if f"{base}{quote}" not in broker.get_pairs():
|
||||||
return jsonify({"Error": "Pair not running"})
|
return jsonify({"Error": "Pair not running"})
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
x.pause = True
|
x.pause = True
|
||||||
if x.switch_to_long(ignore_old_long=ignore_old_long)==1:
|
if x.switch_to_long(ignore_old_long=ignore_old_long)==1:
|
||||||
return jsonify({"Error": "Error in switch_to_long()"})
|
return jsonify({"Error": "Error in switch_to_long()"})
|
||||||
|
|
@ -1441,14 +1465,14 @@ def unwrapped_switch_to_short(base,quote):
|
||||||
if f"{base}{quote}" not in broker.get_pairs():
|
if f"{base}{quote}" not in broker.get_pairs():
|
||||||
return jsonify({"Error": "Pair not running"})
|
return jsonify({"Error": "Pair not running"})
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair and x.switch_to_short()==1:
|
if f"{base}/{quote}"==x.config.get_pair() and x.switch_to_short()==1:
|
||||||
return jsonify({"Error": "Error in switch_to_short()"})
|
return jsonify({"Error": "Error in switch_to_short()"})
|
||||||
|
|
||||||
#Restart instance
|
#Restart instance
|
||||||
try:
|
try:
|
||||||
broker.logger.log_this(f"Reinitializing trader",2,f"{base}/{quote}")
|
broker.logger.log_this(f"Reinitializing trader",2,f"{base}/{quote}")
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
x.status.set_take_profit_order(x.broker.empty_order)
|
x.status.set_take_profit_order(x.broker.empty_order)
|
||||||
x.so = x.broker.empty_order
|
x.so = x.broker.empty_order
|
||||||
|
|
||||||
|
|
@ -1496,7 +1520,7 @@ def unwrapped_load_old_long(base,quote):
|
||||||
|
|
||||||
#Creates (or modifies) a key in the status dictionary and assigns the contents of the file to that same key.
|
#Creates (or modifies) a key in the status dictionary and assigns the contents of the file to that same key.
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if x.pair==f"{base}/{quote}":
|
if x.config.get_pair()==f"{base}/{quote}":
|
||||||
x.get_status_dict()["old_long"]=old_long
|
x.get_status_dict()["old_long"]=old_long
|
||||||
x.update_status(True)
|
x.update_status(True)
|
||||||
return jsonify({"Success": "old_long file loaded to status_dict"})
|
return jsonify({"Success": "old_long file loaded to status_dict"})
|
||||||
|
|
@ -1522,7 +1546,7 @@ def unwrapped_view_old_long(base,quote,from_file):
|
||||||
old_long = json.load(ol)
|
old_long = json.load(ol)
|
||||||
return jsonify(old_long)
|
return jsonify(old_long)
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
if "old_long" in x.get_status_dict():
|
if "old_long" in x.get_status_dict():
|
||||||
return jsonify(x.get_status_dict()["old_long"])
|
return jsonify(x.get_status_dict()["old_long"])
|
||||||
return jsonify({"Error": "No old_long info found"})
|
return jsonify({"Error": "No old_long info found"})
|
||||||
|
|
@ -1547,7 +1571,7 @@ def unwrapped_switch_to_long_price(base,quote):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
if "old_long" in x.get_status_dict():
|
if "old_long" in x.get_status_dict():
|
||||||
#minimum_switch_price = (old_target - quote_already_in)/base_left
|
#minimum_switch_price = (old_target - quote_already_in)/base_left
|
||||||
old_target = x.get_status_dict()["old_long"]["tp_price"]*x.get_status_dict()["old_long"]["tp_amount"]
|
old_target = x.get_status_dict()["old_long"]["tp_price"]*x.get_status_dict()["old_long"]["tp_amount"]
|
||||||
|
|
@ -1577,7 +1601,7 @@ def unwrapped_add_safety_orders(base,quote,amount):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
x.pause = True
|
x.pause = True
|
||||||
#x.no_of_safety_orders += int(amount)
|
#x.no_of_safety_orders += int(amount)
|
||||||
x.config.set_no_of_safety_orders(x.config.get_no_of_safety_orders()+int(amount))
|
x.config.set_no_of_safety_orders(x.config.get_no_of_safety_orders()+int(amount))
|
||||||
|
|
@ -1608,7 +1632,7 @@ def unwrapped_mod_tp_level(base,quote,amount):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
x.config.set_tp_level(float(amount))
|
x.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,f"{base}/{quote}")
|
||||||
return jsonify({"Success": "Success. The change will take effect when the next TP order is placed"})
|
return jsonify({"Success": "Success. The change will take effect when the next TP order is placed"})
|
||||||
|
|
@ -1652,7 +1676,7 @@ def unwrapped_last_call(base,quote):
|
||||||
try:
|
try:
|
||||||
if f"{base}{quote}" in broker.get_pairs():
|
if f"{base}{quote}" in broker.get_pairs():
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
x.stop_when_profit = not x.stop_when_profit
|
x.stop_when_profit = not x.stop_when_profit
|
||||||
x.update_status(True)
|
x.update_status(True)
|
||||||
if x.stop_when_profit:
|
if x.stop_when_profit:
|
||||||
|
|
@ -1684,7 +1708,7 @@ def unwrapped_deferred_last_call(base,quote,yyyymmdd):
|
||||||
if limit==0:
|
if limit==0:
|
||||||
return jsonify({"Error": "Can't convert date to unix"})
|
return jsonify({"Error": "Can't convert date to unix"})
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}{quote}"==x.pair:
|
if f"{base}{quote}"==x.config.get_pair():
|
||||||
x.config.set_programmed_stop_time(limit)
|
x.config.set_programmed_stop_time(limit)
|
||||||
x.config.set_programmed_stop(True)
|
x.config.set_programmed_stop(True)
|
||||||
#save config file to disk
|
#save config file to disk
|
||||||
|
|
@ -1710,7 +1734,7 @@ def unwrapped_toggle_pause(base,quote):
|
||||||
try:
|
try:
|
||||||
toggle_pauses.append(f"{base}/{quote}")
|
toggle_pauses.append(f"{base}/{quote}")
|
||||||
for instance in running_instances:
|
for instance in running_instances:
|
||||||
if instance.pair==f"{base}/{quote}":
|
if instance.config.get_pair()==f"{base}/{quote}":
|
||||||
if instance.pause:
|
if instance.pause:
|
||||||
return jsonify({"Success": "Trader will be resumed"})
|
return jsonify({"Success": "Trader will be resumed"})
|
||||||
return jsonify({"Success": "Trader will be paused"})
|
return jsonify({"Success": "Trader will be paused"})
|
||||||
|
|
@ -1772,21 +1796,21 @@ def unwrapped_add_quote(base,quote,amount):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.config.get_pair():
|
||||||
if x.config.get_is_short():
|
if x.config.get_is_short():
|
||||||
return jsonify({"Error": "Quote can't be added to short bots"})
|
return jsonify({"Error": "Quote can't be added to short bots"})
|
||||||
x.pause = True
|
x.pause = True
|
||||||
new_average_price = (x.status.get_quote_spent()+float(amount))/(x.status.get_base_bought()+(float(amount)/x.get_status_dict()["price"]))
|
new_average_price = (x.status.get_quote_spent()+float(amount))/(x.status.get_base_bought()+(float(amount)/x.get_status_dict()["price"]))
|
||||||
broker.logger.log_this(f"Your new average buy price will be {new_average_price} {x.quote}",2,f"{base}/{quote}")
|
broker.logger.log_this(f"Your new average buy price will be {new_average_price} {x.quote}",2,f"{base}/{quote}")
|
||||||
broker.logger.log_this(f"Your new take profit price price will be {new_average_price*x.get_tp_level()} {x.quote}",2,f"{base}/{quote}")
|
broker.logger.log_this(f"Your new take profit price price will be {new_average_price*x.get_tp_level()} {x.quote}",2,f"{base}/{quote}")
|
||||||
new_order = broker.new_market_order(x.pair,float(amount),"buy")
|
new_order = broker.new_market_order(x.config.get_pair(),float(amount),"buy")
|
||||||
if new_order is None:
|
if new_order is None:
|
||||||
broker.logger.log_this("Error: Market order returned None",2,f"{base}/{quote}")
|
broker.logger.log_this("Error: Market order returned None",2,f"{base}/{quote}")
|
||||||
x.pause = False
|
x.pause = False
|
||||||
return jsonify({"Error": "Market order returned None"})
|
return jsonify({"Error": "Market order returned None"})
|
||||||
while True:
|
while True:
|
||||||
time.sleep(broker.get_wait_time())
|
time.sleep(broker.get_wait_time())
|
||||||
returned_order = broker.get_order(new_order["id"],x.pair)
|
returned_order = broker.get_order(new_order["id"],x.config.get_pair())
|
||||||
if returned_order==broker.empty_order:
|
if returned_order==broker.empty_order:
|
||||||
broker.logger.log_this("Problems sending the order",2,f"{base}/{quote}")
|
broker.logger.log_this("Problems sending the order",2,f"{base}/{quote}")
|
||||||
x.pause = False
|
x.pause = False
|
||||||
|
|
@ -1803,7 +1827,7 @@ def unwrapped_add_quote(base,quote,amount):
|
||||||
x.status.set_quote_spent(x.status.get_quote_spent()+returned_order["cost"])
|
x.status.set_quote_spent(x.status.get_quote_spent()+returned_order["cost"])
|
||||||
broker.logger.log_this("Cancelling old take profit order and sending a new one",2,f"{base}/{quote}")
|
broker.logger.log_this("Cancelling old take profit order and sending a new one",2,f"{base}/{quote}")
|
||||||
attempts = 5
|
attempts = 5
|
||||||
while broker.cancel_order(x.status.get_tp_order_id(),x.pair)==1:
|
while broker.cancel_order(x.status.get_tp_order_id(),x.config.get_pair())==1:
|
||||||
broker.logger.log_this("Can't cancel old take profit order, retrying...",2,f"{base}/{quote}")
|
broker.logger.log_this("Can't cancel old take profit order, retrying...",2,f"{base}/{quote}")
|
||||||
time.sleep(broker.get_wait_time())
|
time.sleep(broker.get_wait_time())
|
||||||
attempts-=1
|
attempts-=1
|
||||||
|
|
@ -1812,7 +1836,7 @@ def unwrapped_add_quote(base,quote,amount):
|
||||||
x.pause = False
|
x.pause = False
|
||||||
return jsonify({"Error": "Can't cancel old take profit order."})
|
return jsonify({"Error": "Can't cancel old take profit order."})
|
||||||
x.status.set_take_profit_price(x.status.get_quote_spent()/x.status.get_base_bought()*x.get_tp_level())
|
x.status.set_take_profit_price(x.status.get_quote_spent()/x.status.get_base_bought()*x.get_tp_level())
|
||||||
x.status.set_take_profit_order(broker.new_limit_order(x.pair,x.status.get_base_bought(),"sell",x.status.get_take_profit_price()))
|
x.status.set_take_profit_order(broker.new_limit_order(x.config.get_pair(),x.status.get_base_bought(),"sell",x.status.get_take_profit_price()))
|
||||||
x.update_status(True)
|
x.update_status(True)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
@ -1858,7 +1882,7 @@ def unwrapped_toggle_cleanup(base,quote):
|
||||||
try:
|
try:
|
||||||
pair_to_toggle = f"{base}/{quote}"
|
pair_to_toggle = f"{base}/{quote}"
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if pair_to_toggle==x.pair:
|
if pair_to_toggle==x.config.get_pair():
|
||||||
x.config.set_cleanup(not x.config.get_cleanup())
|
x.config.set_cleanup(not x.config.get_cleanup())
|
||||||
if x.config.get_cleanup():
|
if x.config.get_cleanup():
|
||||||
return jsonify({"Success": "Cleanup turned ON"})
|
return jsonify({"Success": "Cleanup turned ON"})
|
||||||
|
|
@ -1884,7 +1908,7 @@ def unwrapped_toggle_autoswitch(base,quote):
|
||||||
try:
|
try:
|
||||||
pair_to_toggle = f"{base}/{quote}"
|
pair_to_toggle = f"{base}/{quote}"
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if pair_to_toggle==x.pair:
|
if pair_to_toggle==x.config.get_pair():
|
||||||
if x.config.get_autoswitch():
|
if x.config.get_autoswitch():
|
||||||
broker.logger.log_this("Autoswitch turned OFF",1,f"{base}/{quote}")
|
broker.logger.log_this("Autoswitch turned OFF",1,f"{base}/{quote}")
|
||||||
x.config.set_autoswitch(False)
|
x.config.set_autoswitch(False)
|
||||||
|
|
@ -1913,7 +1937,7 @@ def unwrapped_toggle_check_old_long_price(base,quote):
|
||||||
try:
|
try:
|
||||||
pair_to_toggle = f"{base}/{quote}"
|
pair_to_toggle = f"{base}/{quote}"
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if pair_to_toggle==x.pair:
|
if pair_to_toggle==x.config.get_pair():
|
||||||
if x.config.get_check_old_long_price():
|
if x.config.get_check_old_long_price():
|
||||||
broker.logger.log_this("Check OFF",1,f"{base}/{quote}")
|
broker.logger.log_this("Check OFF",1,f"{base}/{quote}")
|
||||||
x.config.set_check_old_long_price(False)
|
x.config.set_check_old_long_price(False)
|
||||||
|
|
@ -1943,7 +1967,7 @@ def unwrapped_switch_quote_currency(base,quote,new_quote):
|
||||||
try:
|
try:
|
||||||
pair_to_switch = f"{base}/{quote}"
|
pair_to_switch = f"{base}/{quote}"
|
||||||
for trader in running_instances:
|
for trader in running_instances:
|
||||||
if pair_to_switch==trader.pair:
|
if pair_to_switch==trader.config.get_pair():
|
||||||
#Pause the trader
|
#Pause the trader
|
||||||
trader.pause = True
|
trader.pause = True
|
||||||
|
|
||||||
|
|
@ -2122,9 +2146,10 @@ def unwrapped_reload_safety_order(base,quote):
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
for trader in running_instances:
|
for trader in running_instances:
|
||||||
if trader.pair==f"{base}/{quote}":
|
if trader.config.get_pair()==f"{base}/{quote}":
|
||||||
trader.reload_safety_order()
|
trader.config.load_from_file()
|
||||||
return jsonify({"Success": "Safety order reloaded successfully"})
|
return jsonify({"Success": "Safety order reloaded successfully"})
|
||||||
|
return jsonify({"Error": "Trader not found"})
|
||||||
except Exception as e:
|
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)
|
||||||
return jsonify({"Error": "Safety order couldn't be reloaded"})
|
return jsonify({"Error": "Safety order couldn't be reloaded"})
|
||||||
|
|
@ -2151,6 +2176,22 @@ def unwrapped_get_balance(coin):
|
||||||
return jsonify({"Error": "Balance could not be queried"})
|
return jsonify({"Error": "Balance could not be queried"})
|
||||||
|
|
||||||
|
|
||||||
|
def unwrapped_reload_trader_config(base,quote):
|
||||||
|
'''
|
||||||
|
Reloads the config file of the trader
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
base (str): The base currency of the pair.
|
||||||
|
quote (str): The quote currency of the pair.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
jsonify: A jsonified dictionary detailing the outcome of the operation.
|
||||||
|
'''
|
||||||
|
for trader in running_instances:
|
||||||
|
if trader.config.get_pair() == f"{base}/{quote}":
|
||||||
|
return jsonify(worker_status[f"{base}/{quote}"])
|
||||||
|
return jsonify({"Error": "Worker does not exist"})
|
||||||
|
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
|
|
||||||
|
|
|
||||||
5
todo.txt
5
todo.txt
|
|
@ -9,11 +9,10 @@ Mandatory:
|
||||||
6. Multiple safety orders open at the same time (to catch big volatility spikes more effectively)
|
6. Multiple safety orders open at the same time (to catch big volatility spikes more effectively)
|
||||||
7. Things that should be objects (it's not 1994):
|
7. Things that should be objects (it's not 1994):
|
||||||
* Orders.
|
* Orders.
|
||||||
* Config object (instead of a config dictionary).
|
* Config (parameter validation remains to be implemented).
|
||||||
* Status object (instead of a status dictionary).
|
* Status (parameter validation remains to be implemented).
|
||||||
8. Implement the ability to add safety orders to a short trader depending on the amount of free funds available, not just any number of orders.
|
8. Implement the ability to add safety orders to a short trader depending on the amount of free funds available, not just any number of orders.
|
||||||
9. API documentation.
|
9. API documentation.
|
||||||
10. Do not reload the config file every time a deal is closed and add an API endpoint to do it.
|
|
||||||
|
|
||||||
|
|
||||||
Would be nice to have:
|
Would be nice to have:
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ TRADERS
|
||||||
65) toggle_pause 66) toggle_cleanup 67) toggle_autoswitch
|
65) toggle_pause 66) toggle_cleanup 67) toggle_autoswitch
|
||||||
68) toggle_check_old_long_price 69) switch_quote_currency
|
68) toggle_check_old_long_price 69) switch_quote_currency
|
||||||
70) reload_safety_order 71) view_old_long 72) switch_price
|
70) reload_safety_order 71) view_old_long 72) switch_price
|
||||||
|
73) reload_trader_config
|
||||||
|
|
||||||
98) Change broker 99) Exit
|
98) Change broker 99) Exit
|
||||||
'''
|
'''
|
||||||
|
|
@ -782,3 +783,16 @@ if __name__=="__main__":
|
||||||
print(json.loads(requests.get(url,headers=headers).content))
|
print(json.loads(requests.get(url,headers=headers).content))
|
||||||
input("Press ENTER to continue ")
|
input("Press ENTER to continue ")
|
||||||
|
|
||||||
|
elif command==73:
|
||||||
|
print("Reloads from disk the configuration file of a trader")
|
||||||
|
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}/reload_trader_config"
|
||||||
|
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 ")
|
||||||
Loading…
Reference in New Issue