first draft
This commit is contained in:
parent
ca85e454f9
commit
6bf3df0418
2
main.py
2
main.py
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
25
trader.py
25
trader.py
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
Loading…
Reference in New Issue