- Fixed tp mode 2 non-functional
- Fixed duster binance fee estimation - Fixed executor variable shadowing breaking graceful shutdown - Fixed infinite loop in cancel_order - Fixed modifying running_traders during iteration - Fixed missing "status/" prefix in old_long file paths - Removed double TP order cancellation while switching to short. - Added locks to prevent race conditions on running_traders.
This commit is contained in:
parent
12999a2189
commit
ffe58e2c0d
|
|
@ -1,3 +1,13 @@
|
|||
2026.06.03:
|
||||
. Fixed tp mode 2 non-functional
|
||||
. Fixed duster binance fee estimation
|
||||
. Fixed executor variable shadowing breaking graceful shutdown
|
||||
. Fixed infinite loop in cancel_order
|
||||
. Fixed modifying running_traders during iteration
|
||||
. Fixed missing "status/" prefix in old_long file paths
|
||||
. Removed double TP order cancellation while switching to short.
|
||||
. Added locks to prevent race conditions on running_traders.
|
||||
|
||||
2025.12.01:
|
||||
. Modified log output of new_market_order.
|
||||
. Modified Kucoin's case in min_amount_of_base.
|
||||
|
|
|
|||
|
|
@ -189,7 +189,8 @@ class duster:
|
|||
|
||||
if self.broker.get_exchange_name()=="binance": #CCXT still to this day does not take Binance fees into account.
|
||||
try:
|
||||
fee_rate = self.broker.fetch_market["maker"] if order["type"]=="limit" else self.broker.fetch_market["taker"]
|
||||
market = self.broker.fetch_maker(self.duster_status["pair"])
|
||||
fee_rate = market["maker"] if order["type"]=="limit" else market["taker"]
|
||||
except Exception as e:
|
||||
self.broker.logger.log_this(f"Exception fetching market information: {e}. Using default fee rate of 0.1%",1,f"{base}{quote}")
|
||||
fee_rate = 0.001
|
||||
|
|
|
|||
|
|
@ -622,22 +622,40 @@ class Broker:
|
|||
:return: 0 if order was succesfully canceled, 1 if not
|
||||
'''
|
||||
|
||||
tries = self.retries//2
|
||||
while tries>0:
|
||||
cancel_attempts = self.retries//2
|
||||
while cancel_attempts > 0:
|
||||
try:
|
||||
while self.get_order(id,symbol)["status"]=="open":
|
||||
self.exchange.cancel_order(id,symbol)
|
||||
time.sleep(self.wait_time)
|
||||
return 0
|
||||
self.exchange.cancel_order(id, symbol)
|
||||
time.sleep(self.wait_time)
|
||||
if self.get_order(id, symbol)["status"] != "open":
|
||||
return 0
|
||||
except Exception as e:
|
||||
if self.get_order(id,symbol)["status"]=="canceled":
|
||||
if self.get_order(id, symbol)["status"] == "canceled":
|
||||
return 0
|
||||
self.logger.log_this(f"Exception in cancel_order: id {id} - exception: {e}",1)
|
||||
if no_retries:
|
||||
break
|
||||
time.sleep(self.wait_time)
|
||||
tries-=1
|
||||
cancel_attempts -= 1
|
||||
time.sleep(self.wait_time)
|
||||
return 1
|
||||
|
||||
|
||||
# tries = self.retries//2
|
||||
# while tries>0:
|
||||
# try:
|
||||
# while self.get_order(id,symbol)["status"]=="open":
|
||||
# self.exchange.cancel_order(id,symbol)
|
||||
# time.sleep(self.wait_time)
|
||||
# return 0
|
||||
# except Exception as e:
|
||||
# if self.get_order(id,symbol)["status"]=="canceled":
|
||||
# return 0
|
||||
# self.logger.log_this(f"Exception in cancel_order: id {id} - exception: {e}",1)
|
||||
# if no_retries:
|
||||
# break
|
||||
# time.sleep(self.wait_time)
|
||||
# tries-=1
|
||||
# return 1
|
||||
|
||||
|
||||
def amount_to_precision(self,pair,amount):
|
||||
|
|
|
|||
652
main.py
652
main.py
|
|
@ -5,7 +5,7 @@ from sys import argv
|
|||
from os import _exit as os_exit
|
||||
from json import load
|
||||
from datetime import date
|
||||
from threading import Thread
|
||||
from threading import Thread, Lock
|
||||
from waitress import serve
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ import exchange_wrapper
|
|||
import trader
|
||||
|
||||
|
||||
version = "2025.12.01"
|
||||
version = "2026.06.03"
|
||||
|
||||
'''
|
||||
Color definitions. If you want to change them, check the reference at https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
||||
|
|
@ -43,7 +43,7 @@ executor = None
|
|||
def shutdown_handler(signum, _):
|
||||
broker.logger.log_this(f"Received signal {signum}, shutting down.", 2)
|
||||
if executor:
|
||||
executor.shutdown(wait=True, timeout=5)
|
||||
executor.shutdown(wait=True)
|
||||
os_exit(0)
|
||||
|
||||
# Register signals for shutdown handler
|
||||
|
|
@ -119,10 +119,11 @@ def add_instance(base: str, quote: str) -> int:
|
|||
|
||||
#Check if the pair is already running
|
||||
pair = f"{base}{quote}"
|
||||
for instance in running_traders:
|
||||
if f"{instance.base}{instance.quote}"==pair:
|
||||
broker.logger.log_this(f"Pair already running, duplicate traders are not allowed",1,pair)
|
||||
return 1
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if f"{instance.base}{instance.quote}"==pair:
|
||||
broker.logger.log_this(f"Pair already running, duplicate traders are not allowed",1,pair)
|
||||
return 1
|
||||
|
||||
#Initialize the trader object and add the pair to the tickers list
|
||||
instances_to_add.append(trader.trader(broker,f"{base}/{quote}"))
|
||||
|
|
@ -143,7 +144,8 @@ def initialize_instance(base: str, quote: str) -> int:
|
|||
int: 0 if successful
|
||||
'''
|
||||
broker.logger.log_this(f"Initializing {f'{base}/{quote}'}")
|
||||
running_traders.append(trader.trader(broker,f'{base}/{quote}'))
|
||||
with traders_lock:
|
||||
running_traders.append(trader.trader(broker,f'{base}/{quote}'))
|
||||
if f'{base}{quote}' not in tickers:
|
||||
tickers.append(f'{base}{quote}')
|
||||
return 0
|
||||
|
|
@ -246,33 +248,34 @@ def restart_pair_no_json(base: str, quote: str) -> int:
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.set_pause(True, "Restarting trader")
|
||||
#Backing up old status file
|
||||
instance.status.save_to_file(is_backup=True)
|
||||
|
||||
broker.logger.log_this(f"Cancelling old take profit order",2,symbol)
|
||||
try:
|
||||
old_tp_order = instance.status.get_take_profit_order()
|
||||
broker.cancel_order(old_tp_order["id"],old_tp_order["symbol"])
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Error canceling old take profit order: {e}",2,symbol)
|
||||
|
||||
broker.logger.log_this(f"Cancelling old take safety orders",2,symbol)
|
||||
for item in instance.status.get_safety_orders():
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.set_pause(True, "Restarting trader")
|
||||
#Backing up old status file
|
||||
instance.status.save_to_file(is_backup=True)
|
||||
|
||||
broker.logger.log_this(f"Cancelling old take profit order",2,symbol)
|
||||
try:
|
||||
broker.cancel_order(item["id"],item["symbol"])
|
||||
old_tp_order = instance.status.get_take_profit_order()
|
||||
broker.cancel_order(old_tp_order["id"],old_tp_order["symbol"])
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Error canceling old safety order: {e}",2,symbol)
|
||||
|
||||
try:
|
||||
running_traders.remove(instance)
|
||||
except ValueError:
|
||||
broker.logger.log_this(f"Instance {instance.status.get_pair()} not found in running_traders.",1,instance.status.get_pair())
|
||||
add_instance(base,quote)
|
||||
return 0
|
||||
return 1
|
||||
broker.logger.log_this(f"Error canceling old take profit order: {e}",2,symbol)
|
||||
|
||||
broker.logger.log_this(f"Cancelling old take safety orders",2,symbol)
|
||||
for item in instance.status.get_safety_orders():
|
||||
try:
|
||||
broker.cancel_order(item["id"],item["symbol"])
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Error canceling old safety order: {e}",2,symbol)
|
||||
|
||||
try:
|
||||
running_traders.remove(instance)
|
||||
except ValueError:
|
||||
broker.logger.log_this(f"Instance {instance.status.get_pair()} not found in running_traders.",1,instance.status.get_pair())
|
||||
add_instance(base,quote)
|
||||
return 0
|
||||
return 1
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Exception in restart_pair_no_json: {e}",1,symbol)
|
||||
return 1
|
||||
|
|
@ -282,6 +285,7 @@ def main_routine():
|
|||
global last_market_reload
|
||||
global reload_interval
|
||||
global screen_buffer
|
||||
global executor
|
||||
|
||||
executor = ThreadPoolExecutor(max_workers=len(broker.get_config()["pairs"])+worker_threads_overprovisioning)
|
||||
is_testnet = "TESTNET " if broker.get_config()["is_sandbox"] else ""
|
||||
|
|
@ -290,42 +294,51 @@ def main_routine():
|
|||
|
||||
while True:
|
||||
#Restart traders that have the restart flag raised and remove traders that have the quit flag raised
|
||||
for instance in running_traders:
|
||||
if instance.restart and instance.config.get_attempt_restart():
|
||||
broker.logger.log_this(f"Restarting trader",1,instance.status.get_pair())
|
||||
restart_pair_no_json(instance.base,instance.quote)
|
||||
if instance.quit:
|
||||
#Here, check if a duster is needed
|
||||
broker.logger.log_this(f"{broker.get_exchange_name()} | Quit flag raised, removing trader.",0,instance.status.get_pair())
|
||||
broker.logger.log_this(f"{broker.get_exchange_name()} | Quit flag raised, removing trader: {instance.status.get_pair()}",-1) #Forced message to TG
|
||||
if f"{instance.base}{instance.quote}" in tickers:
|
||||
tickers.remove(f"{instance.base}{instance.quote}")
|
||||
broker.remove_pair_from_config(f"{instance.base}{instance.quote}")
|
||||
broker.rewrite_config_file()
|
||||
try:
|
||||
running_traders.remove(instance)
|
||||
except ValueError:
|
||||
broker.logger.log_this(f"Instance {instance.status.get_pair()} not found in running_traders.",1,instance.status.get_pair())
|
||||
to_restart = []
|
||||
to_remove = []
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if instance.restart and instance.config.get_attempt_restart():
|
||||
to_restart.append(instance)
|
||||
if instance.quit:
|
||||
to_remove.append(instance)
|
||||
for instance in to_restart:
|
||||
broker.logger.log_this(f"Restarting trader",1,instance.status.get_pair())
|
||||
restart_pair_no_json(instance.base,instance.quote)
|
||||
for instance in to_remove:
|
||||
#Here, check if a duster is needed
|
||||
broker.logger.log_this(f"{broker.get_exchange_name()} | Quit flag raised, removing trader.",0,instance.status.get_pair())
|
||||
broker.logger.log_this(f"{broker.get_exchange_name()} | Quit flag raised, removing trader: {instance.status.get_pair()}",-1) #Forced message to TG
|
||||
if f"{instance.base}{instance.quote}" in tickers:
|
||||
tickers.remove(f"{instance.base}{instance.quote}")
|
||||
broker.remove_pair_from_config(f"{instance.base}{instance.quote}")
|
||||
broker.rewrite_config_file()
|
||||
try:
|
||||
running_traders.remove(instance)
|
||||
except ValueError:
|
||||
broker.logger.log_this(f"Instance {instance.status.get_pair()} not found in running_traders.",1,instance.status.get_pair())
|
||||
|
||||
#Adds pending traders
|
||||
if bool(instances_to_add):
|
||||
for instance in instances_to_add:
|
||||
running_traders.append(instance)
|
||||
instances_to_add.clear()
|
||||
with traders_lock:
|
||||
for instance in instances_to_add:
|
||||
running_traders.append(instance)
|
||||
instances_to_add.clear()
|
||||
|
||||
#Prepares the trader threads
|
||||
futures = []
|
||||
pairs_to_fetch = []
|
||||
online_pairs = []
|
||||
|
||||
for instance in running_traders:
|
||||
pairs_to_fetch.append(instance.status.get_pair())
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
pairs_to_fetch.append(instance.status.get_pair())
|
||||
|
||||
open_orders = broker.fetch_open_orders(pairs_to_fetch)
|
||||
for instance in running_traders:
|
||||
future = executor.submit(instance.check_status, open_orders)
|
||||
futures.append(future)
|
||||
online_pairs.append(f"{instance.base}{instance.quote}")
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
future = executor.submit(instance.check_status, open_orders)
|
||||
futures.append(future)
|
||||
online_pairs.append(f"{instance.base}{instance.quote}")
|
||||
|
||||
#Fetch prices
|
||||
price_list = broker.get_prices(pairs_to_fetch)
|
||||
|
|
@ -343,24 +356,26 @@ def main_routine():
|
|||
short_traders_status_strings = []
|
||||
paused_traders_status_strings = []
|
||||
global_status["paused_traders"].clear()
|
||||
for instance in running_traders:
|
||||
if not instance.config.get_is_short():
|
||||
curr += int(instance.status.get_so_amount()) # For the safety order occupancy percentage calculation
|
||||
top += int(instance.config.get_no_of_safety_orders())
|
||||
if "status_string" in instance.get_status_dict():
|
||||
long_traders_status_strings.append(str(instance))
|
||||
elif "status_string" in instance.get_status_dict():
|
||||
short_traders_status_strings.append(str(instance))
|
||||
try:
|
||||
if instance.status.get_pair() in price_list and price_list[instance.status.get_pair()] is not None:
|
||||
instance.get_status_dict()["price"] = price_list[instance.status.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.status.get_pair())
|
||||
|
||||
#Add paused traders to the paused trader list
|
||||
if instance.pause:
|
||||
global_status["paused_traders"].append(instance.status.get_pair())
|
||||
paused_traders_status_strings.append(f"{cyan}Paused pairs: {list(global_status['paused_traders'])}{white}")
|
||||
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if not instance.config.get_is_short():
|
||||
curr += int(instance.status.get_so_amount()) # For the safety order occupancy percentage calculation
|
||||
top += int(instance.config.get_no_of_safety_orders())
|
||||
if "status_string" in instance.get_status_dict():
|
||||
long_traders_status_strings.append(str(instance))
|
||||
elif "status_string" in instance.get_status_dict():
|
||||
short_traders_status_strings.append(str(instance))
|
||||
try:
|
||||
if instance.status.get_pair() in price_list and price_list[instance.status.get_pair()] is not None:
|
||||
instance.get_status_dict()["price"] = price_list[instance.status.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.status.get_pair())
|
||||
|
||||
#Add paused traders to the paused trader list
|
||||
if instance.pause:
|
||||
global_status["paused_traders"].append(instance.status.get_pair())
|
||||
paused_traders_status_strings.append(f"{cyan}Paused pairs: {list(global_status['paused_traders'])}{white}")
|
||||
|
||||
#Delete no longer used data
|
||||
del price_list
|
||||
|
|
@ -374,7 +389,8 @@ def main_routine():
|
|||
|
||||
#Updates some global status variables prior to deletion of those
|
||||
if len(running_traders)!=len(global_status["online_workers"]):
|
||||
global_status["online_workers"] = [instance.status.get_pair() for instance in running_traders]
|
||||
with traders_lock:
|
||||
global_status["online_workers"] = [instance.status.get_pair() for instance in running_traders]
|
||||
|
||||
#Prints general info
|
||||
instance_uptime = int(time.time()) - instance_start_time
|
||||
|
|
@ -409,9 +425,10 @@ def main_routine():
|
|||
|
||||
#Toggle pauses
|
||||
if toggle_pauses:
|
||||
for instance in running_traders:
|
||||
if instance.status.get_pair() in toggle_pauses:
|
||||
instance.pause = not instance.pause
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if instance.status.get_pair() in toggle_pauses:
|
||||
instance.pause = not instance.pause
|
||||
toggle_pauses.clear()
|
||||
|
||||
#Checks if market reload is due
|
||||
|
|
@ -1505,9 +1522,10 @@ def unwrapped_return_worker_status(base,quote):
|
|||
dict: The status dictionary of the trader.
|
||||
'''
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if instance.status.get_pair() == symbol:
|
||||
return jsonify(instance.status.get_status())
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if instance.status.get_pair() == symbol:
|
||||
return jsonify(instance.status.get_status())
|
||||
return jsonify({"Error": "Worker does not exist"})
|
||||
|
||||
|
||||
|
|
@ -1518,8 +1536,8 @@ def unwrapped_return_all_worker_status():
|
|||
Returns:
|
||||
dict: The status dictionary of all traders.
|
||||
'''
|
||||
|
||||
return {instance.status.get_pair(): instance.status.get_status() for instance in running_traders}
|
||||
with traders_lock:
|
||||
return {instance.status.get_pair(): instance.status.get_status() for instance in running_traders}
|
||||
|
||||
|
||||
def unwrapped_add_pair(base,quote):
|
||||
|
|
@ -1538,10 +1556,11 @@ def unwrapped_add_pair(base,quote):
|
|||
symbol = f"{base}/{quote}"
|
||||
|
||||
#Check if the trader is already running
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
broker.logger.log_this(f"Pair already running",1,symbol)
|
||||
return jsonify({"Error": "Pair already running"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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(symbol):
|
||||
|
|
@ -1571,10 +1590,11 @@ def unwrapped_remove_pair(base,quote):
|
|||
'''
|
||||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.quit = True
|
||||
symbol = f"{base}/{quote}"
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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,symbol)
|
||||
|
|
@ -1639,15 +1659,16 @@ def unwrapped_switch_to_long(base,quote,calculate_profits):
|
|||
#Close trader and orders and pull info our of the orders
|
||||
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.status.get_pair():
|
||||
instance.set_pause(True, "Switching to long mode")
|
||||
if instance.switch_to_long(ignore_old_long=ignore_old_long,double_check_price=False)==1:
|
||||
return jsonify({"Error": "Error in switch_to_long()"})
|
||||
if instance.start_trader()==1:
|
||||
instance.quit = True
|
||||
return jsonify({"Error": "Error switching to long mode (wAPI)"})
|
||||
return jsonify({"Success": "Pair switched to long mode"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if f"{base}/{quote}"==instance.status.get_pair():
|
||||
instance.set_pause(True, "Switching to long mode")
|
||||
if instance.switch_to_long(ignore_old_long=ignore_old_long,double_check_price=False)==1:
|
||||
return jsonify({"Error": "Error in switch_to_long()"})
|
||||
if instance.start_trader()==1:
|
||||
instance.quit = True
|
||||
return jsonify({"Error": "Error switching to long mode (wAPI)"})
|
||||
return jsonify({"Success": "Pair switched to long mode"})
|
||||
return jsonify({"Error": "Pair not found"})
|
||||
|
||||
|
||||
|
|
@ -1667,27 +1688,29 @@ def unwrapped_switch_to_short(base,quote):
|
|||
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 symbol==instance.status.get_pair() and instance.switch_to_short()==1:
|
||||
return jsonify({"Error": "Error in switch_to_short()"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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,symbol)
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.status.set_take_profit_order(instance.broker.empty_order)
|
||||
instance.so = instance.broker.empty_order
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.status.set_take_profit_order(instance.broker.empty_order)
|
||||
instance.so = instance.broker.empty_order
|
||||
|
||||
#Reloading config file
|
||||
instance.config.load_from_file()
|
||||
#Reloading config file
|
||||
instance.config.load_from_file()
|
||||
|
||||
#Enabling autoswitch
|
||||
instance.config.set_autoswitch(True)
|
||||
if instance.start_trader()==1:
|
||||
instance.quit = True
|
||||
return jsonify({"Error": "Error switching to short mode (wAPI)"})
|
||||
return jsonify({"Success": "Pair switched to short mode"})
|
||||
#Enabling autoswitch
|
||||
instance.config.set_autoswitch(True)
|
||||
if instance.start_trader()==1:
|
||||
instance.quit = True
|
||||
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,symbol)
|
||||
return jsonify({"Error": "Can't initialize trader"})
|
||||
|
|
@ -1709,7 +1732,7 @@ def unwrapped_load_old_long(base,quote):
|
|||
#Load the file
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
with open(f"{base}{quote}.oldlong") as ol:
|
||||
with open(f"status/{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,symbol)
|
||||
|
|
@ -1723,11 +1746,12 @@ def unwrapped_load_old_long(base,quote):
|
|||
#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.status.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"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if instance.status.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"})
|
||||
return jsonify({"Error": "Pair not found"})
|
||||
|
||||
|
||||
|
|
@ -1747,14 +1771,15 @@ 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:
|
||||
with open(f"status/{base}{quote}.oldlong") as ol:
|
||||
old_long = load(ol)
|
||||
return jsonify(old_long)
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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,symbol)
|
||||
|
|
@ -1776,16 +1801,17 @@ def unwrapped_switch_to_long_price(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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"]
|
||||
base_left = instance.get_status_dict()["old_long"]["tp_amount"]-instance.get_status_dict()["base_bought"]
|
||||
minimum_switch_price = (old_target - instance.get_status_dict()["quote_spent"])/base_left
|
||||
return jsonify({"switch_price": minimum_switch_price})
|
||||
return jsonify({"Error": "No old_long info found"})
|
||||
return jsonify({"Error": "Pair not found"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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"]
|
||||
base_left = instance.get_status_dict()["old_long"]["tp_amount"]-instance.get_status_dict()["base_bought"]
|
||||
minimum_switch_price = (old_target - instance.get_status_dict()["quote_spent"])/base_left
|
||||
return jsonify({"switch_price": minimum_switch_price})
|
||||
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,symbol)
|
||||
return jsonify({"Error": f"{e}"})
|
||||
|
|
@ -1807,17 +1833,18 @@ def unwrapped_add_safety_orders(base,quote,amount):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.set_pause(True, "Adding safety orders")
|
||||
instance.status.set_no_of_safety_orders(instance.status.get_no_of_safety_orders()+int(amount))
|
||||
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,symbol)
|
||||
instance.update_status(True)
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Success": f"Done. Added {amount} safety orders"})
|
||||
return jsonify({"Error": "Pair not found"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.set_pause(True, "Adding safety orders")
|
||||
instance.status.set_no_of_safety_orders(instance.status.get_no_of_safety_orders()+int(amount))
|
||||
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,symbol)
|
||||
instance.update_status(True)
|
||||
instance.set_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,symbol)
|
||||
return jsonify({"Error": "Error adding safety orders"})
|
||||
|
|
@ -1837,14 +1864,15 @@ def unwrapped_base_add_so_calculation(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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"})
|
||||
amount_of_orders = instance.base_add_calculation(free_base)
|
||||
return jsonify({"Amount": amount_of_orders, "Free base on exchange": free_base})
|
||||
return jsonify({"Error": "Can't find the pair in the running instances"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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"})
|
||||
amount_of_orders = instance.base_add_calculation(free_base)
|
||||
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,symbol)
|
||||
return jsonify({"Error": "Error in unwrapped_base_add_so_calculation"})
|
||||
|
|
@ -1865,9 +1893,10 @@ def unwrapped_mod_tp_level(base,quote,amount):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.config.set_tp_level(float(amount))
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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,symbol)
|
||||
return jsonify({"Success": "Success. The change will take effect when the next TP order is placed"})
|
||||
except Exception:
|
||||
|
|
@ -1890,10 +1919,11 @@ def unwrapped_mod_order_size(base,quote,amount):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.config.set_order_size(float(amount))
|
||||
instance.config.save_to_file()
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.config.set_order_size(float(amount))
|
||||
instance.config.save_to_file()
|
||||
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:
|
||||
|
|
@ -1916,10 +1946,11 @@ def unwrapped_mod_concurrent_safety_orders(base,quote,amount):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.config.set_concurrent_safety_orders(int(amount))
|
||||
instance.config.save_to_file()
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.config.set_concurrent_safety_orders(int(amount))
|
||||
instance.config.save_to_file()
|
||||
broker.logger.log_this("Done. The change will take effect as new safety orders are sent or filled",2,symbol)
|
||||
return jsonify({"Success": "Success. The change will take effect as new safety orders are sent or filled"})
|
||||
except Exception:
|
||||
|
|
@ -1942,10 +1973,11 @@ def unwrapped_mod_boosted_concurrent_safety_orders(base,quote,amount):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.config.set_boosted_concurrent_safety_orders(int(amount))
|
||||
instance.config.save_to_file()
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.config.set_boosted_concurrent_safety_orders(int(amount))
|
||||
instance.config.save_to_file()
|
||||
broker.logger.log_this("Done. The change will take effect as new safety orders are sent or filled",2,symbol)
|
||||
return jsonify({"Success": "Success. The change will take effect as new safety orders are sent or filled"})
|
||||
except Exception:
|
||||
|
|
@ -1983,13 +2015,13 @@ def unwrapped_mod_global_tp_level(amount):
|
|||
Returns:
|
||||
jsonify: A jsonified dictionary detailing the outcome of the operation
|
||||
'''
|
||||
|
||||
for instance in running_traders:
|
||||
try:
|
||||
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)
|
||||
except Exception:
|
||||
broker.logger.log_this("Error changing percentage. Ignoring.",2)
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
try:
|
||||
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)
|
||||
except Exception:
|
||||
broker.logger.log_this("Error changing percentage. Ignoring.",2)
|
||||
return jsonify({"Success": "Success. The change will take effect when the next TP order is placed"})
|
||||
|
||||
|
||||
|
|
@ -2007,16 +2039,17 @@ def unwrapped_last_call(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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():
|
||||
instance.config.set_autoswitch(False)
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
instance.status.set_stop_when_profit(not instance.status.get_stop_when_profit())
|
||||
instance.update_status(True)
|
||||
return jsonify({"Success": "Trader scheduled to go offline when profit is reached"})
|
||||
return jsonify({"Success": "Last call cancelled"})
|
||||
return jsonify({"Error": "Trader does not exist"})
|
||||
if instance.status.get_stop_when_profit():
|
||||
instance.config.set_autoswitch(False)
|
||||
instance.update_status(True)
|
||||
return jsonify({"Success": "Trader scheduled to go offline when profit is reached"})
|
||||
return jsonify({"Success": "Last call cancelled"})
|
||||
return jsonify({"Error": "Trader does not exist"})
|
||||
except Exception:
|
||||
return jsonify({"Error": "Halp"})
|
||||
|
||||
|
|
@ -2041,12 +2074,13 @@ def unwrapped_deferred_last_call(base,quote,yyyymmdd):
|
|||
limit = time_to_unix(year,month,day)
|
||||
if limit==0:
|
||||
return jsonify({"Error": "Can't convert date to unix"})
|
||||
for instance in running_traders:
|
||||
if f"{base}{quote}"==instance.status.get_pair():
|
||||
instance.config.set_programmed_stop_time(limit)
|
||||
instance.config.set_programmed_stop(True)
|
||||
#save config file to disk
|
||||
instance.broker.rewrite_config_file()
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if f"{base}{quote}"==instance.status.get_pair():
|
||||
instance.config.set_programmed_stop_time(limit)
|
||||
instance.config.set_programmed_stop(True)
|
||||
#save config file to disk
|
||||
instance.broker.rewrite_config_file()
|
||||
return jsonify({"Success": f"Trader scheduled to go offline when profit is reached after {limit}"})
|
||||
except Exception:
|
||||
return jsonify({"Error": "Halp"})
|
||||
|
|
@ -2068,13 +2102,14 @@ def unwrapped_toggle_pause(base,quote):
|
|||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
toggle_pauses.append(symbol)
|
||||
for instance in running_traders:
|
||||
if instance.status.get_pair()==symbol:
|
||||
if instance.pause:
|
||||
instance.status.set_pause_reason("")
|
||||
return jsonify({"Success": "Trader will be resumed"})
|
||||
instance.status.set_pause_reason("User requested pause")
|
||||
return jsonify({"Success": "Trader will be paused"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if instance.status.get_pair()==symbol:
|
||||
if instance.pause:
|
||||
instance.status.set_pause_reason("")
|
||||
return jsonify({"Success": "Trader will be resumed"})
|
||||
instance.status.set_pause_reason("User requested pause")
|
||||
return jsonify({"Success": "Trader will be paused"})
|
||||
return jsonify({"Error": "Trader does not exist"})
|
||||
except Exception:
|
||||
return jsonify({"Error": "Halp"})
|
||||
|
|
@ -2088,10 +2123,11 @@ def unwrapped_global_last_call():
|
|||
jsonify: A jsonified dictionary detailing the outcome of the operation.
|
||||
'''
|
||||
try:
|
||||
for instance in running_traders:
|
||||
instance.status.set_stop_when_profit(True)
|
||||
instance.config.set_autoswitch(False)
|
||||
broker.logger.log_this("Modified flag",2,f"{instance.base}/{instance.quote}")
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
instance.status.set_stop_when_profit(True)
|
||||
instance.config.set_autoswitch(False)
|
||||
broker.logger.log_this("Modified flag",2,f"{instance.base}/{instance.quote}")
|
||||
return jsonify({"Success": "All traders scheduled to go offline when profit is reached"})
|
||||
except Exception:
|
||||
return jsonify({"Error": "Halp"})
|
||||
|
|
@ -2105,9 +2141,10 @@ def unwrapped_cancel_global_last_call():
|
|||
jsonify: A jsonified dictionary detailing the outcome of the operation.
|
||||
'''
|
||||
try:
|
||||
for instance in running_traders:
|
||||
instance.status.set_stop_when_profit(False)
|
||||
broker.logger.log_this("Modified flag",2,f"{instance.base}/{instance.quote}")
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
instance.status.set_stop_when_profit(False)
|
||||
broker.logger.log_this("Modified flag",2,f"{instance.base}/{instance.quote}")
|
||||
return jsonify({"Success": "Last call canceled"})
|
||||
except Exception:
|
||||
return jsonify({"Error": "Halp"})
|
||||
|
|
@ -2126,58 +2163,58 @@ def unwrapped_add_quote(base,quote,amount):
|
|||
Returns:
|
||||
json: A jsonified dictionary detailing the outcome of the operation.
|
||||
'''
|
||||
|
||||
for instance in running_traders:
|
||||
if f"{base}/{quote}"==instance.status.get_pair():
|
||||
if instance.config.get_is_short():
|
||||
return jsonify({"Error": "Quote can't be added to short traders"})
|
||||
instance.set_pause(True, "Adding quote")
|
||||
new_average_price = (instance.status.get_quote_spent()+float(amount))/(instance.status.get_base_bought()+(float(amount)/instance.status.get_price()))
|
||||
broker.logger.log_this(f"Your new average buy price will be {new_average_price} {quote}",2,instance.status.get_pair())
|
||||
broker.logger.log_this(f"Your new take profit price price will be {new_average_price*instance.get_tp_level()} {quote}",2,instance.status.get_pair())
|
||||
new_order = broker.new_market_order(instance.status.get_pair(),float(amount),"buy")
|
||||
if new_order is None:
|
||||
broker.logger.log_this("Error: Market order returned None",2,instance.status.get_pair())
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Error": "Market order returned None"})
|
||||
while True:
|
||||
time.sleep(broker.get_wait_time())
|
||||
returned_order = broker.get_order(new_order["id"],instance.status.get_pair())
|
||||
if returned_order==broker.empty_order:
|
||||
broker.logger.log_this("Problems sending the order",2,instance.status.get_pair())
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if f"{base}/{quote}"==instance.status.get_pair():
|
||||
if instance.config.get_is_short():
|
||||
return jsonify({"Error": "Quote can't be added to short traders"})
|
||||
instance.set_pause(True, "Adding quote")
|
||||
new_average_price = (instance.status.get_quote_spent()+float(amount))/(instance.status.get_base_bought()+(float(amount)/instance.status.get_price()))
|
||||
broker.logger.log_this(f"Your new average buy price will be {new_average_price} {quote}",2,instance.status.get_pair())
|
||||
broker.logger.log_this(f"Your new take profit price price will be {new_average_price*instance.get_tp_level()} {quote}",2,instance.status.get_pair())
|
||||
new_order = broker.new_market_order(instance.status.get_pair(),float(amount),"buy")
|
||||
if new_order is None:
|
||||
broker.logger.log_this("Error: Market order returned None",2,instance.status.get_pair())
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Error": "Problems sending the order"})
|
||||
elif returned_order["status"]=="expired":
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Error": "New order expired"})
|
||||
elif returned_order["status"]=="closed":
|
||||
broker.logger.log_this("Order sent",2,instance.status.get_pair())
|
||||
new_fees_in_base, new_fees_in_quote = instance.parse_fees(returned_order)
|
||||
instance.status.set_fees_paid_in_base(instance.status.get_fees_paid_in_base() + new_fees_in_base)
|
||||
instance.status.set_fees_paid_in_quote(instance.status.get_fees_paid_in_quote() + new_fees_in_quote)
|
||||
instance.status.set_base_bought(instance.status.get_base_bought() + returned_order["filled"] - new_fees_in_base)
|
||||
instance.status.set_quote_spent(instance.status.get_quote_spent()+returned_order["cost"])
|
||||
broker.logger.log_this("Cancelling old take profit order and sending a new one",2,instance.status.get_pair())
|
||||
attempts = 5
|
||||
while broker.cancel_order(instance.status.get_take_profit_order()["id"],instance.status.get_pair())==1:
|
||||
broker.logger.log_this("Can't cancel old take profit order, retrying...",2,instance.status.get_pair())
|
||||
time.sleep(broker.get_wait_time())
|
||||
attempts-=1
|
||||
if attempts==0:
|
||||
broker.logger.log_this("Can't cancel old take profit order, cancelling...",2,instance.status.get_pair())
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Error": "Can't cancel old take profit order."})
|
||||
instance.status.set_take_profit_price(instance.status.get_quote_spent()/instance.status.get_base_bought()*instance.get_tp_level())
|
||||
instance.status.set_take_profit_order(broker.new_limit_order(instance.status.get_pair(),instance.status.get_base_bought(),"sell",instance.status.get_take_profit_price()))
|
||||
instance.update_status(True)
|
||||
break
|
||||
else:
|
||||
broker.logger.log_this("Waiting for initial order to get filled",2,instance.status.get_pair())
|
||||
broker.logger.log_this(f"{returned_order}",2,instance.status.get_pair())
|
||||
return jsonify({"Error": "Market order returned None"})
|
||||
while True:
|
||||
time.sleep(broker.get_wait_time())
|
||||
instance.set_pause(False)
|
||||
broker.logger.log_this("Done",2,instance.status.get_pair())
|
||||
return jsonify({"Success": "Quote added successfully"})
|
||||
returned_order = broker.get_order(new_order["id"],instance.status.get_pair())
|
||||
if returned_order==broker.empty_order:
|
||||
broker.logger.log_this("Problems sending the order",2,instance.status.get_pair())
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Error": "Problems sending the order"})
|
||||
elif returned_order["status"]=="expired":
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Error": "New order expired"})
|
||||
elif returned_order["status"]=="closed":
|
||||
broker.logger.log_this("Order sent",2,instance.status.get_pair())
|
||||
new_fees_in_base, new_fees_in_quote = instance.parse_fees(returned_order)
|
||||
instance.status.set_fees_paid_in_base(instance.status.get_fees_paid_in_base() + new_fees_in_base)
|
||||
instance.status.set_fees_paid_in_quote(instance.status.get_fees_paid_in_quote() + new_fees_in_quote)
|
||||
instance.status.set_base_bought(instance.status.get_base_bought() + returned_order["filled"] - new_fees_in_base)
|
||||
instance.status.set_quote_spent(instance.status.get_quote_spent()+returned_order["cost"])
|
||||
broker.logger.log_this("Cancelling old take profit order and sending a new one",2,instance.status.get_pair())
|
||||
attempts = 5
|
||||
while broker.cancel_order(instance.status.get_take_profit_order()["id"],instance.status.get_pair())==1:
|
||||
broker.logger.log_this("Can't cancel old take profit order, retrying...",2,instance.status.get_pair())
|
||||
time.sleep(broker.get_wait_time())
|
||||
attempts-=1
|
||||
if attempts==0:
|
||||
broker.logger.log_this("Can't cancel old take profit order, cancelling...",2,instance.status.get_pair())
|
||||
instance.set_pause(False)
|
||||
return jsonify({"Error": "Can't cancel old take profit order."})
|
||||
instance.status.set_take_profit_price(instance.status.get_quote_spent()/instance.status.get_base_bought()*instance.get_tp_level())
|
||||
instance.status.set_take_profit_order(broker.new_limit_order(instance.status.get_pair(),instance.status.get_base_bought(),"sell",instance.status.get_take_profit_price()))
|
||||
instance.update_status(True)
|
||||
break
|
||||
else:
|
||||
broker.logger.log_this("Waiting for initial order to get filled",2,instance.status.get_pair())
|
||||
broker.logger.log_this(f"{returned_order}",2,instance.status.get_pair())
|
||||
time.sleep(broker.get_wait_time())
|
||||
instance.set_pause(False)
|
||||
broker.logger.log_this("Done",2,instance.status.get_pair())
|
||||
return jsonify({"Success": "Quote added successfully"})
|
||||
return jsonify({"Error": "Something horrible happened :S"})
|
||||
|
||||
|
||||
|
|
@ -2213,12 +2250,13 @@ def unwrapped_toggle_cleanup(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.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,symbol)
|
||||
return jsonify({"Error": "Halp"})
|
||||
|
|
@ -2239,13 +2277,14 @@ def unwrapped_force_trader_close(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
outcome = instance.force_close()
|
||||
if outcome==0:
|
||||
return jsonify({"Success": "Trader closed position successfully"})
|
||||
return jsonify({"Error": "Error while forcing trader to close position"})
|
||||
return jsonify({"Error": "Trader not found"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
outcome = instance.force_close()
|
||||
if outcome==0:
|
||||
return jsonify({"Success": "Trader closed position successfully"})
|
||||
return jsonify({"Error": "Error while forcing trader to close position"})
|
||||
return jsonify({"Error": "Trader not found"})
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Exception while forcing trader to close position: {e}",1,symbol)
|
||||
return jsonify({"Error": "Halp"})
|
||||
|
|
@ -2265,16 +2304,17 @@ def unwrapped_toggle_autoswitch(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
if instance.config.get_autoswitch():
|
||||
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,symbol)
|
||||
instance.config.set_autoswitch(True)
|
||||
return jsonify({"Success": "Autoswitch is now ON"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
if instance.config.get_autoswitch():
|
||||
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,symbol)
|
||||
instance.config.set_autoswitch(True)
|
||||
return jsonify({"Success": "Autoswitch is now ON"})
|
||||
return jsonify({"Error": "Trader not running"})
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,symbol)
|
||||
|
|
@ -2295,16 +2335,17 @@ def unwrapped_toggle_liquidate_after_switch(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
if instance.config.get_liquidate_after_switch():
|
||||
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,symbol)
|
||||
instance.config.set_liquidate_after_switch(True)
|
||||
return jsonify({"Success": "Liquidate after switch is now ON"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
if instance.config.get_liquidate_after_switch():
|
||||
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,symbol)
|
||||
instance.config.set_liquidate_after_switch(True)
|
||||
return jsonify({"Success": "Liquidate after switch is now ON"})
|
||||
return jsonify({"Error": "Trader not running"})
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Exception while toggling liquidate after switch: {e}",1,symbol)
|
||||
|
|
@ -2325,16 +2366,17 @@ def unwrapped_toggle_check_old_long_price(base,quote):
|
|||
|
||||
try:
|
||||
symbol = f"{base}/{quote}"
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
if instance.config.get_check_old_long_price():
|
||||
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,symbol)
|
||||
instance.config.set_check_old_long_price(True)
|
||||
return jsonify({"Success": "Old long price check turned ON"})
|
||||
with traders_lock:
|
||||
for instance in running_traders:
|
||||
if symbol==instance.status.get_pair():
|
||||
if instance.config.get_check_old_long_price():
|
||||
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,symbol)
|
||||
instance.config.set_check_old_long_price(True)
|
||||
return jsonify({"Success": "Old long price check turned ON"})
|
||||
return jsonify({"Error": "Trader not running"})
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Exception while toggling check_old_long_price: {e}",1,symbol)
|
||||
|
|
@ -2439,7 +2481,8 @@ def unwrapped_trader_time():
|
|||
'''
|
||||
|
||||
try:
|
||||
return jsonify({"Time": max(instance.last_time_seen for instance in running_traders)})
|
||||
with traders_lock:
|
||||
return jsonify({"Time": max(instance.last_time_seen for instance in running_traders)})
|
||||
except Exception as e:
|
||||
broker.logger.log_this(f"Exception while retrieving trader_time: {e}",1)
|
||||
return jsonify({"Error": str(e)})
|
||||
|
|
@ -2634,6 +2677,7 @@ if __name__=="__main__":
|
|||
broker = exchange_wrapper.Broker(exchange,read_config,argv[1]) #Also passes the config filename
|
||||
|
||||
#Declaring some variables
|
||||
traders_lock = Lock()
|
||||
running_traders = []
|
||||
instances_to_add = []
|
||||
online_pairs = []
|
||||
|
|
|
|||
|
|
@ -560,8 +560,6 @@ class trader:
|
|||
self.broker.logger.log_this("Can't cancel the take profit order. Can't switch mode",1,self.status.get_pair())
|
||||
self.set_pause(False)
|
||||
return 1
|
||||
if self.status.get_take_profit_order()["id"]!="":
|
||||
self.broker.cancel_order(self.status.get_take_profit_order()["id"],self.status.get_pair())
|
||||
|
||||
#Save the old take profit order info for later use
|
||||
self.broker.logger.log_this("Saving state in status_dict",2,self.status.get_pair())
|
||||
|
|
@ -1307,7 +1305,8 @@ class trader:
|
|||
if len(self.config.get_tp_table())>=order_index:
|
||||
tp_level = self.config.get_tp_table()[order_index] #Custom percentage table
|
||||
tp_level = self.config.get_tp_table()[-1]
|
||||
tp_level = self.config.get_tp_level()
|
||||
else:
|
||||
tp_level = self.config.get_tp_level()
|
||||
elif self.config.get_tp_mode()==3: #Linear percentage table
|
||||
profit_table = self.linear_space(self.config.get_tp_level()+0.005,self.config.get_tp_level()-0.005,self.status.get_no_of_safety_orders())
|
||||
tp_level = profit_table[-1]
|
||||
|
|
|
|||
Loading…
Reference in New Issue