first draft

This commit is contained in:
Nicolás Sánchez 2025-08-24 09:05:12 -03:00
parent ca85e454f9
commit 6bf3df0418
4 changed files with 28 additions and 15 deletions

View File

@ -18,7 +18,7 @@ import exchange_wrapper
import trader
version = "2025.08.19"
version = "2025.08.23"
'''
Color definitions. If you want to change them, check the reference at https://en.wikipedia.org/wiki/ANSI_escape_code#Colors

View File

@ -13,6 +13,7 @@ class StatusHandler:
"take_profit_order": broker.get_empty_order(),
"take_profit_price": 0.0,
"safety_orders": [],
"safety_orders_filled": 0,
"next_so_price": 0.0,
"order_size": 0.0,
"partial_profit": 0.0,
@ -64,6 +65,9 @@ class StatusHandler:
"""
return self.status_dictionary["safety_orders"]
def get_safety_orders_filled(self):
return self.status_dictionary["safety_orders_filled"]
def get_next_so_price(self):
return self.status_dictionary["next_so_price"]
@ -191,6 +195,10 @@ class StatusHandler:
self.status_dictionary["safety_orders"] = orders
return 0
def set_safety_orders_filled(self, amount: int):
self.status_dictionary["safety_orders_filled"] = amount
return 0
def set_next_so_price(self, price: float):
# if not isinstance(price, float):
# self.broker.logger.log_this(f"Price provided is not a float",1,self.get_pair())

View File

@ -5,7 +5,7 @@ from config_handler import ConfigHandler
from status_handler import StatusHandler
class trader:
def __init__(self, broker, pair: str, is_import: bool = False, forced_tp_id = None, forced_so_id = None):
def __init__(self, broker, pair: str, is_import: bool = False):
#Flags
self.pause = True
@ -91,7 +91,6 @@ class trader:
return colors[color] if color in colors else "\033[0;37;40m"
def get_status_dict(self):
return self.status.get_status()
@ -116,6 +115,7 @@ class trader:
self.status.clear_deal_order_history()
self.status.set_take_profit_order(self.broker.get_empty_order())
self.status.set_safety_orders([])
self.status.set_safety_orders_filled(0)
#Reloads the market
new_market_data = self.broker.fetch_market(self.config.get_pair())
@ -437,7 +437,7 @@ class trader:
return 1
#balance_to_clean /= 2 #Maybe it's a good idea, sort of DCAing the dust.
min_base_size = self.broker.get_min_base_size(self.config.get_pair())
minimum_cleanup_size = self.status.get_safety_order()["amount"]*2 # type: ignore
minimum_cleanup_size = self.status.get_safety_orders()[0]["amount"]*2
if balance_to_clean-minimum_cleanup_size >= min_base_size:
self.broker.logger.log_this(f"Balance to clean: {balance_to_clean-minimum_cleanup_size} {self.base}",2,self.config.get_pair())
@ -724,7 +724,7 @@ class trader:
#Cancel all the safety orders ASAP
for order in self.status.get_safety_orders():
self.broker.cancel_order(order["id"])
self.broker.cancel_order(order["id"],self.config.get_pair())
#Check if some safety orders were filled
for order in self.status.get_safety_orders():
closed_order = self.broker.get_order(order["id"],self.config.get_pair())
@ -831,7 +831,8 @@ class trader:
if orders_to_place<1:
return 0
orders_placed = 0
for _ in range(orders_to_place):
for i in range(orders_to_place):
self.broker.logger.log_this(f"Sending a new safety order ({i+1}/{orders_to_place})",2,self.config.get_pair())
so_size = self.gib_so_size(self.status.get_order_size(),self.status.get_so_amount()+1,self.config.get_safety_order_scale())
if self.config.get_is_short():
new_order = self.broker.new_limit_order(self.config.get_pair(),so_size,"sell",self.status.get_safety_price_table()[self.status.get_so_amount()+1])
@ -901,8 +902,6 @@ class trader:
return 2
#Check if old TP order was partially filled
# TODO: This should also be taken into account for the profit calculation
# Do the partial profit calculation and save it for later
old_tp_order = self.broker.get_order(self.status.get_take_profit_order()["id"],self.config.get_pair())
if old_tp_order["filled"]>0:
self.broker.logger.log_this(f"Old take profit order is partially filled, id {old_tp_order['id']}",1,self.config.get_pair())
@ -910,11 +909,10 @@ class trader:
self.status.update_deal_order_history(old_tp_order)
#self.status.set_base_bought(old_tp_order["remaining"])
# Partial profit calculation
#if not self.config.get_is_short():
# current_deal_price = self.status.get_base_bought()/self.status.get_quote_spent()
# self.status.set_partial_profit(self.status.get_partial_profit()+old_tp_order["cost"]-(old_tp_order["filled"]*current_deal_price)-self.parse.fees(old_tp_order)[1])
# self.update_status(True)
#
if not self.config.get_is_short():
current_deal_price = self.status.get_base_bought()/self.status.get_quote_spent()
self.status.set_partial_profit(self.status.get_partial_profit()+old_tp_order["cost"]-(old_tp_order["filled"]*current_deal_price)-self.parse_fees(old_tp_order)[1])
self.update_status(True)
self.status.set_base_bought(self.status.get_base_bought() - old_tp_order["filled"] - self.parse_fees(old_tp_order)[0])
self.status.set_quote_spent(self.status.get_quote_spent() - old_tp_order["cost"])
self.status.set_fees_paid_in_quote(self.status.get_fees_paid_in_quote() + self.parse_fees(old_tp_order)[1])
@ -1094,6 +1092,7 @@ class trader:
if filled_ids!=[]:
closed_orders = self.broker.get_closed_orders(self.config.get_pair())
filled_orders = [item for item in closed_orders if item["id"] in filled_ids and item["status"]=="closed"] #maybe item["status"] in ["closed", "canceled", ""]?
self.status.set_safety_orders_filled(self.status.get_safety_orders_filled()+len(filled_orders))
renew_outcome = self.renew_tp_and_so_routine(filled_orders)
#0 OK, 1 take profit order is None, 2 not enough funds, 3 can't cancel TP (filled?), 4 can't send new TP
if renew_outcome==1:
@ -1553,7 +1552,7 @@ class trader:
except Exception as e:
print(e)
safety_order_string = f"{self.status.get_so_amount()-1}/{self.config.get_no_of_safety_orders()}".rjust(5)
safety_order_string = f"{self.status.get_safety_orders_filled()}/{self.config.get_no_of_safety_orders()}{self.get_color('cyan')} {len(self.status.get_safety_orders())}{self.get_color('white')}".rjust(6)
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')}"
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())}"
if self.status.get_is_boosted():

View File

@ -11,6 +11,12 @@ try:
api_key = credentials.get_credentials("testnet_api_key")["key"]
base_url = credentials.get_url("testnet") #type: ignore
exchanges = {"Binance":"/binance"}
if sys.argv[1]=="--local_testnet":
is_testnet = True
string_to_add = "LOCAL TESTNET "
api_key = credentials.get_credentials("local_testnet_api_key")["key"]
base_url = credentials.get_url("local_testnet") #type: ignore
exchanges = {"Binance":":5001"}
elif sys.argv[1]=="--mainnet":
is_testnet = False
string_to_add = "MAINNET "