2025.08.15
This commit is contained in:
parent
e11be69f00
commit
30d8e84833
|
|
@ -1,3 +1,7 @@
|
||||||
|
2025.08.15:
|
||||||
|
. "deal order history" is now disabled by default.
|
||||||
|
. CPU optimizations in status string generation.
|
||||||
|
|
||||||
2025.08.14:
|
2025.08.14:
|
||||||
. Refactored gib_so_size.
|
. Refactored gib_so_size.
|
||||||
. Refactored seconds_to_time.
|
. Refactored seconds_to_time.
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ class Broker:
|
||||||
self.retries = self.broker_config["retries"] if "retries" in self.broker_config else 5
|
self.retries = self.broker_config["retries"] if "retries" in self.broker_config else 5
|
||||||
self.slippage_default_threshold = self.broker_config["slippage_default_threshold"] if "slippage_default_threshold" in self.broker_config else .03
|
self.slippage_default_threshold = self.broker_config["slippage_default_threshold"] if "slippage_default_threshold" in self.broker_config else .03
|
||||||
self.logger = Logger(self.broker_config)
|
self.logger = Logger(self.broker_config)
|
||||||
self.write_order_history = True #This should be a toggle in config_file
|
self.follow_order_history = False #This should be a toggle in config_file
|
||||||
|
self.write_order_history = False #This should be a toggle in config_file
|
||||||
|
|
||||||
#Initialize database
|
#Initialize database
|
||||||
self.profits_database_filename = "profits/profits_database.db"
|
self.profits_database_filename = "profits/profits_database.db"
|
||||||
|
|
@ -198,6 +199,9 @@ class Broker:
|
||||||
def get_write_order_history(self):
|
def get_write_order_history(self):
|
||||||
return self.write_order_history
|
return self.write_order_history
|
||||||
|
|
||||||
|
def get_follow_order_history(self):
|
||||||
|
return self.follow_order_history
|
||||||
|
|
||||||
def get_cooldown_multiplier(self):
|
def get_cooldown_multiplier(self):
|
||||||
return self.cooldown_multiplier
|
return self.cooldown_multiplier
|
||||||
|
|
||||||
|
|
|
||||||
10
main.py
10
main.py
|
|
@ -16,7 +16,7 @@ import exchange_wrapper
|
||||||
import trader
|
import trader
|
||||||
|
|
||||||
|
|
||||||
version = "2025.08.14"
|
version = "2025.08.15"
|
||||||
|
|
||||||
'''
|
'''
|
||||||
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
|
||||||
|
|
@ -345,7 +345,9 @@ def main_loop():
|
||||||
screen_buffer.append(str(instance))
|
screen_buffer.append(str(instance))
|
||||||
|
|
||||||
#Updates some global status variables prior to deletion of those
|
#Updates some global status variables prior to deletion of those
|
||||||
global_status["online_workers"] = online_pairs.copy()
|
#global_status["online_workers"] = online_pairs.copy()
|
||||||
|
if len(running_traders)!=len(global_status["online_workers"]):
|
||||||
|
global_status["online_workers"] = [instance.config.get_pair() for instance in running_traders]
|
||||||
|
|
||||||
#Check for paused pairs
|
#Check for paused pairs
|
||||||
global_status["paused_traders"] = [instance.config.get_pair() for instance in running_traders if instance.pause]
|
global_status["paused_traders"] = [instance.config.get_pair() for instance in running_traders if instance.pause]
|
||||||
|
|
@ -2413,9 +2415,9 @@ if __name__=="__main__":
|
||||||
import_mode = True
|
import_mode = True
|
||||||
if "--first_start" in argv:
|
if "--first_start" in argv:
|
||||||
import_mode = False
|
import_mode = False
|
||||||
print(time.strftime("[%Y/%m/%d %H:%M:%S] | Initializing in FIRST START MODE, press enter to start..."))
|
print(time.strftime("[%Y/%m/%d %H:%M:%S] | Initializing in FIRST START MODE, press <Enter> to start..."))
|
||||||
else:
|
else:
|
||||||
print(time.strftime("[%Y/%m/%d %H:%M:%S] | Initializing in IMPORT MODE, press enter to start..."))
|
print(time.strftime("[%Y/%m/%d %H:%M:%S] | Initializing in IMPORT MODE, press <Enter> to start..."))
|
||||||
input()
|
input()
|
||||||
|
|
||||||
#Load exchange config
|
#Load exchange config
|
||||||
|
|
|
||||||
|
|
@ -389,7 +389,8 @@ class StatusHandler:
|
||||||
def update_deal_order_history(self, new_deal: dict):
|
def update_deal_order_history(self, new_deal: dict):
|
||||||
# if not isinstance(new_deal, dict):
|
# if not isinstance(new_deal, dict):
|
||||||
# self.broker.logger.log_this(f"value provided is not a dict",1,self.get_pair())
|
# self.broker.logger.log_this(f"value provided is not a dict",1,self.get_pair())
|
||||||
self.status_dictionary["deal_order_history"].append(self.strip_order(new_deal))
|
if not self.broker.get_follow_order_history():
|
||||||
|
self.status_dictionary["deal_order_history"].append(self.strip_order(new_deal))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def strip_order(self, order):
|
def strip_order(self, order):
|
||||||
|
|
|
||||||
207
trader.py
207
trader.py
|
|
@ -29,6 +29,12 @@ class trader:
|
||||||
self.market_reload_period = 86400 #Market reload period in seconds
|
self.market_reload_period = 86400 #Market reload period in seconds
|
||||||
self.status.set_start_time(int(time.time()))
|
self.status.set_start_time(int(time.time()))
|
||||||
self.last_time_seen = time.time()
|
self.last_time_seen = time.time()
|
||||||
|
|
||||||
|
#Status string caches
|
||||||
|
self.status_string_cache = ""
|
||||||
|
self.low_price_cache = None
|
||||||
|
self.mid_price_cache = None
|
||||||
|
self.high_price_cache = None
|
||||||
|
|
||||||
if self.config.get_is_short():
|
if self.config.get_is_short():
|
||||||
#Check if there is an old_long file. If so, load it.
|
#Check if there is an old_long file. If so, load it.
|
||||||
|
|
@ -71,6 +77,22 @@ class trader:
|
||||||
return self.status.get_status_string()
|
return self.status.get_status_string()
|
||||||
|
|
||||||
|
|
||||||
|
def get_color(self, color):
|
||||||
|
'''
|
||||||
|
Returns white if color does not exist
|
||||||
|
'''
|
||||||
|
colors = {"yellow": "\033[0;33;40m",
|
||||||
|
"green": "\033[0;32;40m",
|
||||||
|
"red": "\033[0;31;40m",
|
||||||
|
"blue": "\033[0;34;40m",
|
||||||
|
"cyan": "\033[0;36;40m",
|
||||||
|
"bright_white": "\033[0;97;40m",
|
||||||
|
"bright_green": "\033[0;92;40m",
|
||||||
|
"white": "\033[0;37;40m"}
|
||||||
|
return colors[color] if color in colors else "\033[0;37;40m"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_status_dict(self):
|
def get_status_dict(self):
|
||||||
return self.status.get_status()
|
return self.status.get_status()
|
||||||
|
|
||||||
|
|
@ -1429,14 +1451,11 @@ class trader:
|
||||||
'''
|
'''
|
||||||
Returns the status string properly formatted for screen output
|
Returns the status string properly formatted for screen output
|
||||||
'''
|
'''
|
||||||
yellow = "\033[0;33;40m"
|
|
||||||
green = "\033[0;32;40m"
|
decimals = 11
|
||||||
red = "\033[0;31;40m"
|
low_percentage = 1
|
||||||
blue = "\033[0;34;40m"
|
mid_percentage = 10
|
||||||
cyan = "\033[0;36;40m"
|
high_percentage = 20
|
||||||
bright_white = "\033[0;97;40m"
|
|
||||||
bright_green = "\033[0;92;40m"
|
|
||||||
white = "\033[0;37;40m"
|
|
||||||
|
|
||||||
def draw_line(price,min_value,max_value,break_even):
|
def draw_line(price,min_value,max_value,break_even):
|
||||||
'''
|
'''
|
||||||
|
|
@ -1452,98 +1471,108 @@ class trader:
|
||||||
self.broker.logger.log_this(f"{e}")
|
self.broker.logger.log_this(f"{e}")
|
||||||
value = 1
|
value = 1
|
||||||
if min_value<max_value:
|
if min_value<max_value:
|
||||||
color = green if price>=break_even else red
|
color = self.get_color("green") if price>=break_even else self.get_color("red")
|
||||||
else:
|
else:
|
||||||
color = red if price>=break_even else green
|
color = self.get_color("red") if price>=break_even else self.get_color("green")
|
||||||
return f"{color}{'='*value}{white}{'='*max(0,(80-value))}"[:100]
|
return f"{color}{'='*value}{self.get_color('white')}{'='*max(0,(80-value))}"[:100]
|
||||||
|
|
||||||
decimals = 11
|
|
||||||
low_percentage = 1
|
|
||||||
mid_percentage = 10
|
|
||||||
high_percentage = 20
|
|
||||||
|
|
||||||
safety_order_string = f"{self.status.get_so_amount()-1}/{self.config.get_no_of_safety_orders()}".rjust(5)
|
|
||||||
|
|
||||||
low_price = self.status.get_next_so_price() if self.status.get_next_so_price() is not None else 0
|
low_price = self.status.get_next_so_price() if self.status.get_next_so_price() is not None else 0
|
||||||
mid_price = self.status.get_price() if self.status.get_price() is not None else 0
|
mid_price = self.status.get_price() if self.status.get_price() is not None else 0
|
||||||
high_price = self.status.get_take_profit_price() if self.status.get_take_profit_price() is not None else 0
|
high_price = self.status.get_take_profit_price() if self.status.get_take_profit_price() is not None else 0
|
||||||
|
|
||||||
low_boundary = '{:.20f}'.format(low_price)[:decimals].center(decimals)
|
if low_price==self.low_price_cache and mid_price==self.mid_price_cache and high_price==self.high_price_cache:
|
||||||
mid_boundary = '{:.20f}'.format(mid_price)[:decimals].center(decimals)
|
#status_string = self.status_string_cache
|
||||||
high_boundary = '{:.20f}'.format(high_price)[:decimals].center(decimals)
|
#Edit uptime
|
||||||
|
position = self.status_string_cache.find("Uptime")
|
||||||
|
new_uptime = self.seconds_to_time(self.status.get_deal_uptime())
|
||||||
|
status_string = self.status_string_cache[:position+8] + new_uptime + self.status_string_cache[position+8+len(new_uptime):]
|
||||||
|
else:
|
||||||
|
#Update caches
|
||||||
|
self.low_price_cache = low_price
|
||||||
|
self.mid_price_cache = mid_price
|
||||||
|
self.high_price_cache = high_price
|
||||||
|
|
||||||
percentage_to_profit = 100
|
#Formatting
|
||||||
pct_to_profit_str = "XX.XX"
|
low_boundary = '{:.20f}'.format(low_price)[:decimals].center(decimals)
|
||||||
if mid_price!=0:
|
mid_boundary = '{:.20f}'.format(mid_price)[:decimals].center(decimals)
|
||||||
diff = abs(high_price-mid_price)
|
high_boundary = '{:.20f}'.format(high_price)[:decimals].center(decimals)
|
||||||
percentage_to_profit = diff/mid_price*100
|
|
||||||
|
percentage_to_profit = 100
|
||||||
|
pct_to_profit_str = "XX.XX"
|
||||||
|
if mid_price!=0:
|
||||||
|
diff = abs(high_price-mid_price)
|
||||||
|
percentage_to_profit = diff/mid_price*100
|
||||||
|
|
||||||
#Formatting (on-screen percentage not longer than 4 digits)
|
#Formatting (on-screen percentage not longer than 4 digits)
|
||||||
pct_to_profit_str = "{:.2f}".format(percentage_to_profit)
|
pct_to_profit_str = "{:.2f}".format(percentage_to_profit)
|
||||||
if len(pct_to_profit_str)==4:
|
if len(pct_to_profit_str)==4:
|
||||||
pct_to_profit_str = f" {pct_to_profit_str}"
|
pct_to_profit_str = f" {pct_to_profit_str}"
|
||||||
elif len(pct_to_profit_str)==6:
|
elif len(pct_to_profit_str)==6:
|
||||||
pct_to_profit_str = pct_to_profit_str[:5]
|
pct_to_profit_str = pct_to_profit_str[:5]
|
||||||
|
|
||||||
line3 = ""
|
line3 = ""
|
||||||
if self.status.get_base_bought()!=0:
|
if self.status.get_base_bought()!=0:
|
||||||
line3 = draw_line(mid_price,low_price,high_price,self.status.get_quote_spent()/self.status.get_base_bought())
|
line3 = draw_line(mid_price,low_price,high_price,self.status.get_quote_spent()/self.status.get_base_bought())
|
||||||
p = "*PAUSED*" if self.pause==True else ""
|
p = "*PAUSED*" if self.pause==True else ""
|
||||||
low_boundary_color = red
|
low_boundary_color = self.get_color("red")
|
||||||
price_color = white
|
price_color = self.get_color("white")
|
||||||
target_price_color = green
|
target_price_color = self.get_color("green")
|
||||||
pair_color = cyan
|
pair_color = self.get_color("cyan")
|
||||||
if self.config.get_is_short():
|
if self.config.get_is_short():
|
||||||
price_color = white
|
price_color = self.get_color("white")
|
||||||
pair_color = yellow
|
pair_color = self.get_color("yellow")
|
||||||
if self.status.get_old_long()!={}:
|
if self.status.get_old_long()!={}:
|
||||||
if mid_price>self.status.get_old_long()["tp_price"]:
|
if mid_price>self.status.get_old_long()["tp_price"]:
|
||||||
price_color = bright_green
|
price_color = self.get_color("bright_green")
|
||||||
if high_price>self.status.get_old_long()["tp_price"]:
|
if high_price>self.status.get_old_long()["tp_price"]:
|
||||||
target_price_color = bright_green
|
target_price_color = self.get_color("bright_green")
|
||||||
|
|
||||||
#Set percentage's color
|
#Set percentage's color
|
||||||
pct_color = white
|
pct_color = self.get_color("white")
|
||||||
if percentage_to_profit<low_percentage:
|
if percentage_to_profit<low_percentage:
|
||||||
pct_color = green
|
pct_color = self.get_color("green")
|
||||||
if percentage_to_profit>mid_percentage:
|
if percentage_to_profit>mid_percentage:
|
||||||
pct_color = yellow
|
pct_color = self.get_color("yellow")
|
||||||
if percentage_to_profit>high_percentage:
|
if percentage_to_profit>high_percentage:
|
||||||
pct_color = red
|
pct_color = self.get_color("red")
|
||||||
|
|
||||||
multiplier = 0
|
multiplier = 0
|
||||||
if self.config.get_is_short() and self.status.get_old_long()!={}:
|
if self.config.get_is_short() and self.status.get_old_long()!={}:
|
||||||
try:
|
try:
|
||||||
#Logic to display switch price
|
#Logic to display switch price
|
||||||
old_target = self.status.get_old_long()["tp_price"]*self.status.get_old_long()["tp_amount"]
|
old_target = self.status.get_old_long()["tp_price"]*self.status.get_old_long()["tp_amount"]
|
||||||
base_left = self.status.get_old_long()["tp_amount"]-self.status.get_base_bought()
|
base_left = self.status.get_old_long()["tp_amount"]-self.status.get_base_bought()
|
||||||
minimum_switch_price = (old_target - self.status.get_quote_spent())/base_left
|
minimum_switch_price = (old_target - self.status.get_quote_spent())/base_left
|
||||||
if old_target-self.status.get_quote_spent()>0 and base_left>0 and minimum_switch_price<low_price:
|
if old_target-self.status.get_quote_spent()>0 and base_left>0 and minimum_switch_price<low_price:
|
||||||
low_boundary_color = bright_green
|
low_boundary_color = self.get_color("bright_green")
|
||||||
low_boundary = '{:.20f}'.format(minimum_switch_price)[:decimals].center(decimals)
|
low_boundary = '{:.20f}'.format(minimum_switch_price)[:decimals].center(decimals)
|
||||||
if mid_price!=0:
|
if mid_price!=0:
|
||||||
multiplier = int(self.status.get_old_long()["tp_price"]/self.status.get_price())
|
multiplier = int(self.status.get_old_long()["tp_price"]/self.status.get_price())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
prices = f"{low_boundary_color}{low_boundary}{white}|{price_color}{mid_boundary}{white}|{target_price_color}{high_boundary}{white}|{pct_color}{pct_to_profit_str}%{white}"
|
safety_order_string = f"{self.status.get_so_amount()-1}/{self.config.get_no_of_safety_orders()}".rjust(5)
|
||||||
line1 = f"{p}{pair_color}{self.config.get_pair().center(13)}{white}| {safety_order_string} |{prices}| Uptime: {self.seconds_to_time(self.status.get_deal_uptime())}"
|
prices = f"{low_boundary_color}{low_boundary}{self.get_color('white')}|{price_color}{mid_boundary}{self.get_color('white')}|{target_price_color}{high_boundary}{self.get_color('white')}|{pct_color}{pct_to_profit_str}%{self.get_color('white')}"
|
||||||
if self.status.get_is_boosted():
|
line1 = f"{p}{pair_color}{self.config.get_pair().center(13)}{self.get_color('white')}| {safety_order_string} |{prices}| Uptime: {self.seconds_to_time(self.status.get_deal_uptime())}"
|
||||||
line1 = f"{line1} | BOOSTED"
|
if self.status.get_is_boosted():
|
||||||
if self.config.get_autoswitch():
|
line1 = f"{line1} | BOOSTED"
|
||||||
auto_color = white
|
if self.config.get_autoswitch():
|
||||||
if self.config.get_liquidate_after_switch():
|
auto_color = self.get_color("white")
|
||||||
auto_color = red
|
if self.config.get_liquidate_after_switch():
|
||||||
line1 = f"{line1} | {auto_color}AUTO{white}"
|
auto_color = self.get_color("red")
|
||||||
if multiplier>1:
|
line1 = f"{line1} | {auto_color}AUTO{self.get_color('white')}"
|
||||||
#Only displays the multiplier if autoswitch is enabled.
|
if multiplier>1:
|
||||||
line1 = f"{line1}{auto_color}x{multiplier}{white}"
|
#Only displays the multiplier if autoswitch is enabled.
|
||||||
if self.config.get_programmed_stop() and time.time()<=self.config.get_programmed_stop_time():
|
line1 = f"{line1}{auto_color}x{multiplier}{self.get_color('white')}"
|
||||||
line1 = f"{line1} | PROGRAMMED LAST DEAL"
|
if self.config.get_programmed_stop() and time.time()<=self.config.get_programmed_stop_time():
|
||||||
if self.status.get_stop_when_profit():
|
line1 = f"{line1} | PROGRAMMED LAST DEAL"
|
||||||
line1 = f"{line1} | LAST DEAL"
|
if self.status.get_stop_when_profit():
|
||||||
|
line1 = f"{line1} | LAST DEAL"
|
||||||
|
|
||||||
|
status_string = f"{self.get_color('white')}{line1}\n{line3}{self.get_color('white')}"
|
||||||
|
self.status_string_cache = status_string
|
||||||
|
|
||||||
return f"{white}{line1}\n{line3}{white}"
|
return status_string
|
||||||
|
|
||||||
|
|
||||||
def load_imported_trader(self, forced_tp_order_id = None, forced_safety_order_id = None) -> int:
|
def load_imported_trader(self, forced_tp_order_id = None, forced_safety_order_id = None) -> int:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue