Compare commits
7 Commits
2025.10.09
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
4a1f1c844d | |
|
|
536866364c | |
|
|
7c33dd231d | |
|
|
96d1cf6d78 | |
|
|
b69b0d2f15 | |
|
|
18506dbaf3 | |
|
|
ca43b3dad5 |
|
|
@ -1,3 +1,31 @@
|
||||||
|
2025.12.01:
|
||||||
|
. Modified log output of new_market_order.
|
||||||
|
. Modified Kucoin's case in min_amount_of_base.
|
||||||
|
|
||||||
|
2025.11.11:
|
||||||
|
. deals_cache and log_list cache are now 20 items long.
|
||||||
|
. Less log spam.
|
||||||
|
|
||||||
|
2025.11.08:
|
||||||
|
. broker.set_default_order_size() now saves the config file to disk after changing the value.
|
||||||
|
. Variable renaming and other small stuff.
|
||||||
|
|
||||||
|
2025.10.24:
|
||||||
|
. Toggling liquidate_after_switch now writes the config file to disk so the setting persists between trades.
|
||||||
|
. Manually switching to long now sets double_check_price to false.
|
||||||
|
. Added a few comments to switch_to_long.
|
||||||
|
|
||||||
|
2025.10.12:
|
||||||
|
. do_cleanup relocated after generating the safety orders' prices.
|
||||||
|
|
||||||
|
2025.10.11:
|
||||||
|
. Minor simplification in do_cleanup.
|
||||||
|
. Removed a couple of (no longer needed?) pauses.
|
||||||
|
|
||||||
|
2025.10.10:
|
||||||
|
. New endpoint: /refresh_log_cache.
|
||||||
|
. Fixed an error in /add_so endpoint that incremented the config setting but not the status setting.
|
||||||
|
|
||||||
2025.10.09:
|
2025.10.09:
|
||||||
. Cleanup is done as soon as the trader starts, rather than after sending the take profit and safety orders.
|
. Cleanup is done as soon as the trader starts, rather than after sending the take profit and safety orders.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,7 @@ class ConfigHandler:
|
||||||
# self.broker.logger.log_this(f"liquidate_after_switch must be a boolean",1,self.get_pair())
|
# self.broker.logger.log_this(f"liquidate_after_switch must be a boolean",1,self.get_pair())
|
||||||
# return 1
|
# return 1
|
||||||
self.config_dictionary["liquidate_after_switch"] = liquidate_after_switch
|
self.config_dictionary["liquidate_after_switch"] = liquidate_after_switch
|
||||||
|
self.save_to_file()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def set_tp_mode(self, tp_mode: int):
|
def set_tp_mode(self, tp_mode: int):
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class Broker:
|
||||||
self.markets = self.exchange.load_markets()
|
self.markets = self.exchange.load_markets()
|
||||||
|
|
||||||
#Populates deals cache
|
#Populates deals cache
|
||||||
self.deals_cache_length = 10
|
self.deals_cache_length = 20
|
||||||
self.deals_list = self.preload_deals(amount_to_preload=self.deals_cache_length)
|
self.deals_list = self.preload_deals(amount_to_preload=self.deals_cache_length)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -224,6 +224,7 @@ class Broker:
|
||||||
def set_default_order_size(self,size):
|
def set_default_order_size(self,size):
|
||||||
try:
|
try:
|
||||||
self.broker_config["default_order_size"] = float(size)
|
self.broker_config["default_order_size"] = float(size)
|
||||||
|
self.rewrite_config_file()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.log_this(f"Exception in set_default_order_size: {e}",1)
|
self.logger.log_this(f"Exception in set_default_order_size: {e}",1)
|
||||||
return 1
|
return 1
|
||||||
|
|
@ -788,7 +789,7 @@ class Broker:
|
||||||
|
|
||||||
return self.get_order(order_to_send["id"],symbol)
|
return self.get_order(order_to_send["id"],symbol)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.log_this(f"Exception in new_market_order: {e}",1,symbol)
|
self.logger.log_this(f"Exception in new_market_order: {e} - Side: {side} - Size: {size}",1,symbol)
|
||||||
if no_retries:
|
if no_retries:
|
||||||
break
|
break
|
||||||
time.sleep(self.wait_time)
|
time.sleep(self.wait_time)
|
||||||
|
|
@ -987,7 +988,7 @@ class Broker:
|
||||||
if self.get_exchange_name() in ["okex","bybit"]:
|
if self.get_exchange_name() in ["okex","bybit"]:
|
||||||
return float(market["limits"]["amount"]["min"])
|
return float(market["limits"]["amount"]["min"])
|
||||||
elif self.get_exchange_name() in ["kucoin"]:
|
elif self.get_exchange_name() in ["kucoin"]:
|
||||||
return (float(market["limits"]["cost"]["min"])+.25)/self.get_ticker_price(pair)
|
return max(float(market["limits"]["amount"]["min"]),(float(market["limits"]["cost"]["min"])+.25)/self.get_ticker_price(pair))
|
||||||
elif self.get_exchange_name() in ["gateio"]:
|
elif self.get_exchange_name() in ["gateio"]:
|
||||||
return (float(market["limits"]["cost"]["min"])+.1)/self.get_ticker_price(pair)
|
return (float(market["limits"]["cost"]["min"])+.1)/self.get_ticker_price(pair)
|
||||||
elif self.get_exchange_name()=="binance":
|
elif self.get_exchange_name()=="binance":
|
||||||
|
|
@ -1051,7 +1052,7 @@ class Logger:
|
||||||
self.broker_config = broker_config
|
self.broker_config = broker_config
|
||||||
self.exchange_name = self.broker_config["exchange"]
|
self.exchange_name = self.broker_config["exchange"]
|
||||||
self.tg_credentials = credentials.get_credentials("telegram")
|
self.tg_credentials = credentials.get_credentials("telegram")
|
||||||
self.log_list_max_length = 10
|
self.log_list_max_length = 20 # log cache
|
||||||
self.log_list = collections.deque(maxlen=self.log_list_max_length)
|
self.log_list = collections.deque(maxlen=self.log_list_max_length)
|
||||||
self.preload_logs()
|
self.preload_logs()
|
||||||
|
|
||||||
|
|
@ -1067,6 +1068,16 @@ class Logger:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
def refresh_logs(self):
|
||||||
|
try:
|
||||||
|
self.log_list.clear()
|
||||||
|
self.preload_logs()
|
||||||
|
return 0
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def set_log_list_max_length(self, amount):
|
def set_log_list_max_length(self, amount):
|
||||||
self.log_list_max_length = amount
|
self.log_list_max_length = amount
|
||||||
return self.log_list_max_length
|
return self.log_list_max_length
|
||||||
|
|
|
||||||
39
main.py
39
main.py
|
|
@ -18,7 +18,7 @@ import exchange_wrapper
|
||||||
import trader
|
import trader
|
||||||
|
|
||||||
|
|
||||||
version = "2025.10.09"
|
version = "2025.12.01"
|
||||||
|
|
||||||
'''
|
'''
|
||||||
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
|
||||||
|
|
@ -1308,6 +1308,21 @@ def get_log_list():
|
||||||
return unwrapped_get_log_list()
|
return unwrapped_get_log_list()
|
||||||
|
|
||||||
|
|
||||||
|
@base_api.route("/refresh_log_cache", methods=['POST'])
|
||||||
|
def refresh_log_cache():
|
||||||
|
'''
|
||||||
|
POST request
|
||||||
|
'''
|
||||||
|
|
||||||
|
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
|
||||||
|
return jsonify({'Error': 'API key invalid'}), 401
|
||||||
|
try:
|
||||||
|
return unwrapped_refresh_log_cache()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return jsonify({'Error': 'Halp'})
|
||||||
|
|
||||||
|
|
||||||
@base_api.route("/get_balance", methods=['GET'])
|
@base_api.route("/get_balance", methods=['GET'])
|
||||||
def get_balance():
|
def get_balance():
|
||||||
'''
|
'''
|
||||||
|
|
@ -1627,7 +1642,7 @@ def unwrapped_switch_to_long(base,quote,calculate_profits):
|
||||||
for instance in running_traders:
|
for instance in running_traders:
|
||||||
if f"{base}/{quote}"==instance.status.get_pair():
|
if f"{base}/{quote}"==instance.status.get_pair():
|
||||||
instance.set_pause(True, "Switching to long mode")
|
instance.set_pause(True, "Switching to long mode")
|
||||||
if instance.switch_to_long(ignore_old_long=ignore_old_long)==1:
|
if instance.switch_to_long(ignore_old_long=ignore_old_long,double_check_price=False)==1:
|
||||||
return jsonify({"Error": "Error in switch_to_long()"})
|
return jsonify({"Error": "Error in switch_to_long()"})
|
||||||
if instance.start_trader()==1:
|
if instance.start_trader()==1:
|
||||||
instance.quit = True
|
instance.quit = True
|
||||||
|
|
@ -1795,8 +1810,7 @@ def unwrapped_add_safety_orders(base,quote,amount):
|
||||||
for instance in running_traders:
|
for instance in running_traders:
|
||||||
if symbol==instance.status.get_pair():
|
if symbol==instance.status.get_pair():
|
||||||
instance.set_pause(True, "Adding safety orders")
|
instance.set_pause(True, "Adding safety orders")
|
||||||
#x.no_of_safety_orders += int(amount)
|
instance.status.set_no_of_safety_orders(instance.status.get_no_of_safety_orders()+int(amount))
|
||||||
instance.config.set_no_of_safety_orders(instance.config.get_no_of_safety_orders()+int(amount))
|
|
||||||
broker.logger.log_this("Recalculating safety price table...",1,symbol)
|
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()))
|
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)
|
broker.logger.log_this(f"Done. Added {amount} safety orders",1,symbol)
|
||||||
|
|
@ -2266,6 +2280,7 @@ def unwrapped_toggle_autoswitch(base,quote):
|
||||||
broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,symbol)
|
broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,symbol)
|
||||||
return jsonify({"Error": "Halp"})
|
return jsonify({"Error": "Halp"})
|
||||||
|
|
||||||
|
|
||||||
def unwrapped_toggle_liquidate_after_switch(base,quote):
|
def unwrapped_toggle_liquidate_after_switch(base,quote):
|
||||||
'''
|
'''
|
||||||
Signals a trader to enable or disable quitting after switching from short to long.
|
Signals a trader to enable or disable quitting after switching from short to long.
|
||||||
|
|
@ -2459,6 +2474,22 @@ def unwrapped_get_log_list():
|
||||||
return jsonify({"Logs": broker.logger.get_log_list()})
|
return jsonify({"Logs": broker.logger.get_log_list()})
|
||||||
|
|
||||||
|
|
||||||
|
def unwrapped_refresh_log_cache():
|
||||||
|
'''
|
||||||
|
Reloads the log file cache.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
jsonify: A jsonified dictionary containing the last n entries from the log file.
|
||||||
|
'''
|
||||||
|
if broker.logger.refresh_logs()==0:
|
||||||
|
return jsonify({"Success": "Logs refreshed"})
|
||||||
|
else:
|
||||||
|
return jsonify({"Error": "Error while refreshing logs"})
|
||||||
|
|
||||||
|
|
||||||
def unwrapped_get_deals_cache():
|
def unwrapped_get_deals_cache():
|
||||||
'''
|
'''
|
||||||
Retrieves the last n entries from the broker's logger.
|
Retrieves the last n entries from the broker's logger.
|
||||||
|
|
|
||||||
59
trader.py
59
trader.py
|
|
@ -42,8 +42,8 @@ class trader:
|
||||||
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.
|
||||||
try:
|
try:
|
||||||
with open(f"status/{self.base}{self.quote}.oldlong") as ol:
|
with open(f"status/{self.base}{self.quote}.oldlong") as old_long_file_handler:
|
||||||
self.status.set_old_long(load(ol))
|
self.status.set_old_long(load(old_long_file_handler))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.broker.logger.log_this(f"Exception: No old_long file. {e}",1,base_quote)
|
self.broker.logger.log_this(f"Exception: No old_long file. {e}",1,base_quote)
|
||||||
|
|
||||||
|
|
@ -277,15 +277,15 @@ class trader:
|
||||||
self.broker.logger.log_this("Error sending take profit order. Aborting.",1,self.status.get_pair())
|
self.broker.logger.log_this("Error sending take profit order. Aborting.",1,self.status.get_pair())
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
# Generate the safety prices table
|
||||||
|
self.status.set_start_price(self.broker.price_to_precision(self.status.get_pair(),self.status.get_quote_spent()/self.status.get_base_bought()))
|
||||||
|
self.status.set_safety_price_table(self.calculate_safety_prices(self.status.get_start_price(),self.status.get_no_of_safety_orders(),self.config.get_safety_order_deviance()))
|
||||||
|
|
||||||
# Send cleanup order (if cleanup)
|
# Send cleanup order (if cleanup)
|
||||||
self.status.set_pause_reason("start_trader - doing cleanup (if needed)")
|
self.status.set_pause_reason("start_trader - doing cleanup (if needed)")
|
||||||
if self.config.get_cleanup() and not self.config.get_is_short(): #Short traders do not need cleanup.
|
if self.config.get_cleanup() and not self.config.get_is_short(): #Short traders do not need cleanup.
|
||||||
self.do_cleanup()
|
self.do_cleanup()
|
||||||
|
|
||||||
# Generate the safety prices table
|
|
||||||
self.status.set_start_price(self.broker.price_to_precision(self.status.get_pair(),self.status.get_quote_spent()/self.status.get_base_bought()))
|
|
||||||
self.status.set_safety_price_table(self.calculate_safety_prices(self.status.get_start_price(),self.status.get_no_of_safety_orders(),self.config.get_safety_order_deviance()))
|
|
||||||
|
|
||||||
# Send the initial batch of safety orders
|
# Send the initial batch of safety orders
|
||||||
self.status.set_pause_reason("start_trader - sending safety orders")
|
self.status.set_pause_reason("start_trader - sending safety orders")
|
||||||
self.broker.logger.log_this("Sending safety orders...",2,self.status.get_pair())
|
self.broker.logger.log_this("Sending safety orders...",2,self.status.get_pair())
|
||||||
|
|
@ -450,14 +450,10 @@ class trader:
|
||||||
self.broker.logger.log_this("Can't fetch free base",1,self.status.get_pair())
|
self.broker.logger.log_this("Can't fetch free base",1,self.status.get_pair())
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
#If the balance is greater than the size of the first safety order, sell the difference.
|
if balance_in_account*self.status.get_start_price()>self.broker.get_min_quote_size(self.status.get_pair()):
|
||||||
# Sometimes when an order is filled the balance is not updated immediately, so having a bit of a buffer irons out a couple of issues.
|
self.broker.logger.log_this(f"Balance to clean: {balance_in_account} {self.base}",2,self.status.get_pair())
|
||||||
min_size = self.config.get_order_size()/self.status.get_take_profit_price()
|
|
||||||
|
|
||||||
if (balance_in_account-min_size)*self.status.get_start_price()>self.broker.get_min_quote_size(self.status.get_pair()):
|
|
||||||
self.broker.logger.log_this(f"Balance to clean: {balance_in_account-min_size} {self.base}",2,self.status.get_pair())
|
|
||||||
self.broker.logger.log_this("Sending cleanup order...",2,self.status.get_pair())
|
self.broker.logger.log_this("Sending cleanup order...",2,self.status.get_pair())
|
||||||
cleanup_order = self.broker.new_limit_order(self.status.get_pair(),balance_in_account-min_size,"sell",self.status.get_take_profit_price(),no_retries=True,log="cleanup")
|
cleanup_order = self.broker.new_limit_order(self.status.get_pair(),balance_in_account,"sell",self.status.get_take_profit_price(),no_retries=True,log="cleanup")
|
||||||
if cleanup_order is None:
|
if cleanup_order is None:
|
||||||
self.broker.logger.log_this("Problems with the cleanup order, new_limit_order returned None",1,self.status.get_pair())
|
self.broker.logger.log_this("Problems with the cleanup order, new_limit_order returned None",1,self.status.get_pair())
|
||||||
return 1
|
return 1
|
||||||
|
|
@ -576,8 +572,8 @@ class trader:
|
||||||
"datetime": time.strftime("[%Y/%m/%d %H:%M:%S]")
|
"datetime": time.strftime("[%Y/%m/%d %H:%M:%S]")
|
||||||
})
|
})
|
||||||
try:
|
try:
|
||||||
with open(f"status/{self.base}{self.quote}.oldlong","w") as s:
|
with open(f"status/{self.base}{self.quote}.oldlong","w") as old_long_file_handler:
|
||||||
s.write(dumps(self.status.get_old_long(),indent=4))
|
old_long_file_handler.write(dumps(self.status.get_old_long(),indent=4))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.broker.logger.log_this(f"Exception while saving old_long file: {e}",1,self.status.get_pair())
|
self.broker.logger.log_this(f"Exception while saving old_long file: {e}",1,self.status.get_pair())
|
||||||
|
|
||||||
|
|
@ -610,17 +606,19 @@ class trader:
|
||||||
|
|
||||||
if double_check_price:
|
if double_check_price:
|
||||||
#Waits a moment to see if the price has moved too much
|
#Waits a moment to see if the price has moved too much
|
||||||
|
self.broker.logger.log_this("Confirming price...",2,self.status.get_pair())
|
||||||
time.sleep(self.broker.get_wait_time()*4)
|
time.sleep(self.broker.get_wait_time()*4)
|
||||||
if not self.check_old_long(True):
|
if not self.check_old_long(True):
|
||||||
self.broker.logger.log_this("False positive. Nothing to do.",1,self.status.get_pair())
|
self.broker.logger.log_this("False positive. Nothing to do.",1,self.status.get_pair())
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
#Check old_long data
|
#Check old_long data
|
||||||
|
self.broker.logger.log_this("Checking if old long data is valid.",2,self.status.get_pair())
|
||||||
if not ignore_old_long and self.status.get_old_long()=={}:
|
if not ignore_old_long and self.status.get_old_long()=={}:
|
||||||
self.broker.logger.log_this("Can't find old long info on status_dict, searching for oldlong file",1,self.status.get_pair())
|
self.broker.logger.log_this("Can't find old long info on status_dict, searching for oldlong file",1,self.status.get_pair())
|
||||||
try:
|
try:
|
||||||
with open(f"status/{self.base}{self.quote}.oldlong") as f:
|
with open(f"status/{self.base}{self.quote}.oldlong") as old_long_file_handler:
|
||||||
self.status.set_old_long(load(f))
|
self.status.set_old_long(load(old_long_file_handler))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
#self.write_to_log(time.strftime(f"[%Y/%m/%d %H:%M:%S] | {self.status.get_pair()} | Can't find old long file"))
|
#self.write_to_log(time.strftime(f"[%Y/%m/%d %H:%M:%S] | {self.status.get_pair()} | Can't find old long file"))
|
||||||
self.broker.logger.log_this(f"Can't file oldlong file. Exception: {e}",1,self.status.get_pair())
|
self.broker.logger.log_this(f"Can't file oldlong file. Exception: {e}",1,self.status.get_pair())
|
||||||
|
|
@ -628,6 +626,7 @@ class trader:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
#Cancel open orders
|
#Cancel open orders
|
||||||
|
self.broker.logger.log_this("Cancelling open orders",2,self.status.get_pair())
|
||||||
for order in self.status.get_safety_orders():
|
for order in self.status.get_safety_orders():
|
||||||
self.broker.cancel_order(order["id"],self.status.get_pair())
|
self.broker.cancel_order(order["id"],self.status.get_pair())
|
||||||
if self.status.get_take_profit_order() is not None:
|
if self.status.get_take_profit_order() is not None:
|
||||||
|
|
@ -636,18 +635,21 @@ class trader:
|
||||||
self.broker.logger.log_this("Safety order is None",1,self.status.get_pair())
|
self.broker.logger.log_this("Safety order is None",1,self.status.get_pair())
|
||||||
|
|
||||||
#Sell all base currency
|
#Sell all base currency
|
||||||
|
self.broker.logger.log_this(f"Selling {self.status.get_pair().split('/')[0]}",2,self.status.get_pair())
|
||||||
self.liquidate_base(ignore_profits=ignore_old_long, already_received_quote=already_received_quote)
|
self.liquidate_base(ignore_profits=ignore_old_long, already_received_quote=already_received_quote)
|
||||||
|
|
||||||
if self.config.get_liquidate_after_switch():
|
if self.config.get_liquidate_after_switch():
|
||||||
|
self.broker.logger.log_this("Liquidate after switch active. Raising quit flag.",1,self.status.get_pair())
|
||||||
self.quit = True
|
self.quit = True
|
||||||
return 1
|
return 0
|
||||||
|
|
||||||
#Rewrite config file (if it exists)
|
#Rewrite config file (if it exists)
|
||||||
if path.isfile(f"configs/{self.base}{self.quote}.bak") and path.isfile(f"configs/{self.base}{self.quote}.json"):
|
if path.isfile(f"configs/{self.base}{self.quote}.bak") and path.isfile(f"configs/{self.base}{self.quote}.json"):
|
||||||
with open(f"configs/{self.base}{self.quote}.bak") as c:
|
self.broker.logger.log_this("Restoring config file from backup",2,self.status.get_pair())
|
||||||
old_config = load(c)
|
with open(f"configs/{self.base}{self.quote}.bak") as backup_config_file_handler:
|
||||||
with open(f"configs/{self.base}{self.quote}.json","w") as c:
|
old_config = load(backup_config_file_handler)
|
||||||
c.write(dumps(old_config, indent=4))
|
with open(f"configs/{self.base}{self.quote}.json","w") as config_file_handler:
|
||||||
|
config_file_handler.write(dumps(old_config, indent=4))
|
||||||
if self.config.load_from_file()==1:
|
if self.config.load_from_file()==1:
|
||||||
self.config.reset_to_default()
|
self.config.reset_to_default()
|
||||||
else:
|
else:
|
||||||
|
|
@ -669,6 +671,7 @@ class trader:
|
||||||
self.status.set_so_amount(0)
|
self.status.set_so_amount(0)
|
||||||
|
|
||||||
#Done. Ready for start_trader
|
#Done. Ready for start_trader
|
||||||
|
self.broker.logger.log_this("Finished setting up the switch to long.",2,self.status.get_pair())
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -805,11 +808,11 @@ class trader:
|
||||||
partial_profit = market_order["cost"]-(avg_buy_price*partial_filled_amount)-self.parse_fees(market_order)[1]
|
partial_profit = market_order["cost"]-(avg_buy_price*partial_filled_amount)-self.parse_fees(market_order)[1]
|
||||||
self.status.set_partial_profit(self.status.get_partial_profit()+partial_profit)
|
self.status.set_partial_profit(self.status.get_partial_profit()+partial_profit)
|
||||||
break
|
break
|
||||||
self.broker.logger.log_this("Waiting for partial fill sell order to fill.",1,self.status.get_pair())
|
self.broker.logger.log_this("Waiting for partial fill sell order to fill.",2,self.status.get_pair())
|
||||||
tries-=1
|
tries-=1
|
||||||
time.sleep(self.broker.get_wait_time())
|
time.sleep(self.broker.get_wait_time())
|
||||||
if tries==0:
|
if tries==0:
|
||||||
self.broker.logger.log_this("Partial fill sell order not filling.",1,self.status.get_pair())
|
self.broker.logger.log_this("Partial fill sell order not filled.",1,self.status.get_pair())
|
||||||
break
|
break
|
||||||
|
|
||||||
if not self.broker.check_for_duplicate_profit_in_db(filled_order):
|
if not self.broker.check_for_duplicate_profit_in_db(filled_order):
|
||||||
|
|
@ -1018,7 +1021,7 @@ class trader:
|
||||||
self.status.set_fees_paid_in_base(self.status.get_fees_paid_in_base() + self.parse_fees(old_tp_order)[0])
|
self.status.set_fees_paid_in_base(self.status.get_fees_paid_in_base() + self.parse_fees(old_tp_order)[0])
|
||||||
|
|
||||||
#Cooldown
|
#Cooldown
|
||||||
time.sleep(self.broker.get_wait_before_new_safety_order())
|
#time.sleep(self.broker.get_wait_before_new_safety_order())
|
||||||
|
|
||||||
#Send new TP order
|
#Send new TP order
|
||||||
if self.send_new_tp_order()==1:
|
if self.send_new_tp_order()==1:
|
||||||
|
|
@ -1028,7 +1031,7 @@ class trader:
|
||||||
return 4
|
return 4
|
||||||
|
|
||||||
#Cooldown
|
#Cooldown
|
||||||
time.sleep(self.broker.get_wait_before_new_safety_order())
|
#time.sleep(self.broker.get_wait_before_new_safety_order())
|
||||||
|
|
||||||
#Send new safety order(s)
|
#Send new safety order(s)
|
||||||
#Do not send new orders if the max amount is reached or surpassed.
|
#Do not send new orders if the max amount is reached or surpassed.
|
||||||
|
|
@ -1542,8 +1545,8 @@ class trader:
|
||||||
#If there is an old_long file, also copy it
|
#If there is an old_long file, also copy it
|
||||||
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:
|
||||||
with open(f"status/{self.base}{self.quote}.oldlong","w") as c:
|
with open(f"status/{self.base}{self.quote}.oldlong","w") as old_long_file_handler:
|
||||||
c.write(dumps(self.status.get_old_long(), indent=4))
|
old_long_file_handler.write(dumps(self.status.get_old_long(), indent=4))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.broker.logger.log_this(f"Exception while writing new old_long file: {e}",1,self.status.get_pair())
|
self.broker.logger.log_this(f"Exception while writing new old_long file: {e}",1,self.status.get_pair())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ INSTANCE
|
||||||
13) paused_traders 14) fetch_log 15) edit_cooldown_multiplier
|
13) paused_traders 14) fetch_log 15) edit_cooldown_multiplier
|
||||||
16) get_balance 17) cancel_global_last_call
|
16) get_balance 17) cancel_global_last_call
|
||||||
18) mod_default_order_size 19) toggle_log_orders
|
18) mod_default_order_size 19) toggle_log_orders
|
||||||
|
20) refresh_log_cache
|
||||||
|
|
||||||
EARN
|
EARN
|
||||||
31) toggle_pause 32) get_step_size 33) set_step_size
|
31) toggle_pause 32) get_step_size 33) set_step_size
|
||||||
|
|
@ -347,7 +348,13 @@ if __name__=="__main__":
|
||||||
url = f"{base_url}{port}/toggle_log_orders"
|
url = f"{base_url}{port}/toggle_log_orders"
|
||||||
print(json.loads(requests.post(url, headers=headers).content))
|
print(json.loads(requests.post(url, headers=headers).content))
|
||||||
input("Press ENTER to continue ")
|
input("Press ENTER to continue ")
|
||||||
|
|
||||||
|
elif command==20:
|
||||||
|
print("refresh_log_cache refreshes the log cache")
|
||||||
|
if input("Proceed? (Y/n) ") in ["Y","y",""]:
|
||||||
|
url = f"{base_url}{port}/refresh_log_cache"
|
||||||
|
print(json.loads(requests.post(url, headers=headers).content))
|
||||||
|
input("Press ENTER to continue ")
|
||||||
|
|
||||||
######################
|
######################
|
||||||
######## EARN ########
|
######## EARN ########
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,8 @@ import calendar
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import os
|
import os
|
||||||
from collections import deque
|
|
||||||
from typing import Iterable, List, Tuple
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from flask import Flask, jsonify, request, Response
|
from flask import Flask, jsonify, request
|
||||||
from waitress import serve
|
from waitress import serve
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue