work work work

This commit is contained in:
Nicolás Sánchez 2025-01-08 18:19:06 -03:00
parent 7d5581bfff
commit 123a0daf7f
5 changed files with 85 additions and 39 deletions

View File

@ -3,7 +3,7 @@
"binance": { "binance": {
"currency": "USDT", "currency": "USDT",
"minimum_amount_in_trading_account": 1000, "minimum_amount_in_trading_account": 1000,
"step_size": 500, "step_size": 250,
"percentage": 0.5, "percentage": 0.5,
"time_between_subscriptions": 3600, "time_between_subscriptions": 3600,
"time_between_redemptions": 0 "time_between_redemptions": 0
@ -11,7 +11,7 @@
"gateio": { "gateio": {
"currency": "USDT", "currency": "USDT",
"minimum_amount_in_trading_account": 1000, "minimum_amount_in_trading_account": 1000,
"step_size": 500, "step_size": 250,
"percentage": 0.5, "percentage": 0.5,
"time_between_subscriptions": 3600, "time_between_subscriptions": 3600,
"time_between_redemptions": 0 "time_between_redemptions": 0
@ -19,7 +19,7 @@
"kucoin": { "kucoin": {
"currency": "USDT", "currency": "USDT",
"minimum_amount_in_trading_account": 1000, "minimum_amount_in_trading_account": 1000,
"step_size": 500, "step_size": 250,
"percentage": 0.5, "percentage": 0.5,
"time_between_subscriptions": 3600, "time_between_subscriptions": 3600,
"time_between_redemptions": 0 "time_between_redemptions": 0
@ -27,13 +27,13 @@
"okx": { "okx": {
"currency": "USDT", "currency": "USDT",
"minimum_amount_in_trading_account": 1000, "minimum_amount_in_trading_account": 1000,
"step_size": 500, "step_size": 250,
"percentage": 0.5, "percentage": 0.5,
"time_between_subscriptions": 3600, "time_between_subscriptions": 3600,
"time_between_redemptions": 0 "time_between_redemptions": 0
} }
}, },
"lap_time": 10, "lap_time": 30,
"api_port": 5011 "api_port": 5011
} }

View File

@ -1,9 +1,28 @@
def balance_accounts(spot_balance, earn_balance, lower_limit, step_size, percentage): def balance_accounts(spot_balance, earn_balance, lower_limit, step_size, percentage):
'''
args:
spot_balance: float
Current spot balance
earn_balance: float
Current earn balance
lower_limit: float
Lower limit for spot balance
step_size: float
Step size for balance adjustment
percentage: float
Percentage of funds to be allocated to the earn account
returns:
spot_balance: float
Updated spot balance
earn_balance: float
Updated earn balance
'''
spot_balance+=earn_balance spot_balance+=earn_balance
earn_balance=0 earn_balance=0
#target_spot_balance = (spot_balance + earn_balance) * percentage target_spot_balance = spot_balance * (1-percentage)
target_spot_balance = spot_balance * percentage
while abs(spot_balance - target_spot_balance) >= step_size: while abs(spot_balance - target_spot_balance) >= step_size:
if spot_balance < target_spot_balance: if spot_balance < target_spot_balance:

View File

@ -1,4 +1,5 @@
import time import time
import datetime
from libraries.balance_accounts import balance_accounts from libraries.balance_accounts import balance_accounts
from libraries.colors import colors from libraries.colors import colors
@ -20,7 +21,7 @@ class earner:
self.trading_balance = 0 self.trading_balance = 0
self.earning_balance = 0 self.earning_balance = 0
self.is_paused = True self.is_paused = False
self.status_string = "" self.status_string = ""
@ -28,6 +29,10 @@ class earner:
def __str__(self): def __str__(self):
return str(self.connector) return str(self.connector)
def write_to_log(self,message):
with open("earn.log", "a") as f:
f.write(str(self.connector) + datetime.datetime.now().strftime(' [%Y/%m/%d %H:%M:%S] ') + message + "\n")
def toggle_pause(self): def toggle_pause(self):
self.is_paused = not self.is_paused self.is_paused = not self.is_paused
return self.is_paused return self.is_paused
@ -41,6 +46,7 @@ class earner:
return self.step_size return self.step_size
except Exception as e: except Exception as e:
print(e) print(e)
self.write_to_log(str(e))
return 0 return 0
def get_step_size(self): def get_step_size(self):
@ -52,6 +58,7 @@ class earner:
return self.percentage return self.percentage
except Exception as e: except Exception as e:
print(e) print(e)
self.write_to_log(str(e))
return 0 return 0
def get_percentage(self): def get_percentage(self):
@ -63,6 +70,7 @@ class earner:
return self.minimum_amount_in_trading_account return self.minimum_amount_in_trading_account
except Exception as e: except Exception as e:
print(e) print(e)
self.write_to_log(str(e))
return 0 return 0
def get_minimum_amount_in_trading_account(self): def get_minimum_amount_in_trading_account(self):
@ -74,6 +82,7 @@ class earner:
return self.time_between_subscriptions return self.time_between_subscriptions
except Exception as e: except Exception as e:
print(e) print(e)
self.write_to_log(str(e))
return 0 return 0
def get_time_between_subscriptions(self): def get_time_between_subscriptions(self):
@ -85,6 +94,7 @@ class earner:
return self.time_between_redemptions return self.time_between_redemptions
except Exception as e: except Exception as e:
print(e) print(e)
self.write_to_log(str(e))
return 0 return 0
def get_time_between_redemptions(self): def get_time_between_redemptions(self):
@ -107,56 +117,74 @@ class earner:
def subscribe(self,amount): def subscribe(self,amount):
print(f"{str(self.connector)} | Subscribing {amount} {self.currency}") print(f"{datetime.datetime.now().strftime('[%Y/%m/%d %H:%M:%S]')} | {str(self.connector).upper()} | Subscribing {amount} {self.currency}")
self.write_to_log(f"Subscribing {amount} {self.currency}")
available_product = self.connector.get_available_products(self.currency) available_product = self.connector.get_available_products(self.currency)
subscription = {} subscription = {}
if available_product["asset"]==self.currency: if available_product["coin"]==self.currency:
#Every exchange has it own subscription method #Every exchange has it own subscription method
if str(self.connector) in ["binance","kucoin"]: if str(self.connector) in ["binance","kucoin"]:
subscription = self.connector.subscribe_product(available_product["productId"],amount) subscription = self.connector.subscribe_product(available_product["product_id"],amount)
elif str(self.connector)=="gateio": elif str(self.connector)=="gateio":
min_rate = self.connector.get_min_rate(available_product["asset"])["min_rate"] min_rate = self.connector.get_min_rate(available_product["coin"])["min_rate"]
time.sleep(.5) #For the sake of the API time.sleep(.5) #For the sake of the API
subscription = self.connector.subscribe_product(available_product["productId"],amount,min_rate) subscription = self.connector.subscribe_product(available_product["product_id"],amount,min_rate)
elif str(self.connector)=="okx": elif str(self.connector)=="okx":
transfer = self.connector.transfer_to_funding(available_product["asset"],str(amount)) transfer = self.connector.transfer_to_funding(available_product["coin"],str(amount))
if "Success" in transfer:
transfer_state = self.connector.get_transfer_state(transfer["transId"]) transfer_state = self.connector.get_transfer_state(transfer["transId"])
if "Success" in transfer_state: if "Success" in transfer_state:
subscription = self.connector.subscribe_product(available_product["productId"],amount) subscription = self.connector.subscribe_product(available_product["product_id"],amount)
else:
print(f"{str(self.connector)} - Transfer of funds state query failed!")
self.write_to_log("Transfer of funds state query failed! - " + str(subscription))
return 1
else: else:
print(f"{str(self.connector)} - Transfer of funds failed!") print(f"{str(self.connector)} - Transfer of funds failed!")
self.write_to_log("Transfer of funds failed! - " + str(transfer))
return 1 return 1
if "Success" in subscription: if "Success" in subscription:
self.last_subscription_time = time.time() self.last_subscription_time = time.time()
return 0 return 0
self.write_to_log("Subscription failed! - " + str(subscription))
return 1 return 1
def redeem(self,amount): def redeem(self,amount):
print(f"{str(self.connector)} | Redeeming {amount} {self.currency}") print(f"{datetime.datetime.now().strftime('[%Y/%m/%d %H:%M:%S]')} | {str(self.connector).upper()} | Redeeming {amount} {self.currency}")
self.write_to_log(f"Redeeming {amount} {self.currency}")
available_product = self.connector.get_available_products(self.currency) available_product = self.connector.get_available_products(self.currency)
redemption = {} redemption = {}
if available_product["asset"]==self.currency: if available_product["coin"]==self.currency:
if str(self.connector) in ["binance","gateio"]: if str(self.connector) in ["binance","gateio"]:
redemption = self.connector.redeem_product(available_product["productId"],amount=amount) redemption = self.connector.redeem_product(available_product["product_id"],amount=amount)
elif str(self.connector)=="kucoin": elif str(self.connector)=="kucoin":
position = self.connector.get_position(self.currency) position = self.connector.get_position(self.currency)
if "Error" not in position: if "Error" not in position:
redemption = self.connector.redeem_product(position["orderId"],amount=amount) redemption = self.connector.redeem_product(position["orderId"],amount=amount)
else: else:
print(f"{str(self.connector)} - Position not found!") print(f"{str(self.connector)} - Position not found!")
self.write_to_log("Position not found! " + str(position))
return 1 return 1
elif str(self.connector)=="okx": elif str(self.connector)=="okx":
redemption_step = self.connector.redeem_product(self.currency, amount=amount) redemption_step = self.connector.redeem_product(self.currency, amount=amount)
if "Success" in redemption_step: if "Success" in redemption_step:
transfer_step = self.connector.transfer_to_trading(self.currency, redemption_step["amount"]) funding_balance = self.connector.get_funding_balance(self.currency)
transfer_step = self.connector.transfer_to_trading(self.currency, funding_balance[self.currency])
if "Success" in transfer_step:
redemption = self.connector.get_transfer_state(transfer_step["transId"]) redemption = self.connector.get_transfer_state(transfer_step["transId"])
else: else:
print(f"{str(self.connector)} - Redemption failed!") print(f"{str(self.connector)} - Transfer step failed!")
self.write_to_log("Transfer step failed! " + str(transfer_step))
return 1 return 1
if "Sucess" in redemption: else:
print(f"{str(self.connector)} - Redemption step failed!")
self.write_to_log("Redemption step failed! " + str(redemption_step))
return 1
if "Success" in redemption:
self.last_redemption_time = time.time() self.last_redemption_time = time.time()
return 0 return 0
self.write_to_log("Redemption failed! - " + str(redemption))
return 1 return 1
@ -185,7 +213,7 @@ class earner:
else: else:
self.earning_balance = None self.earning_balance = None
paused_string = ""
if not self.is_paused: if not self.is_paused:
target_trading_amount, target_earning_amount = balance_accounts(float(self.trading_balance), target_trading_amount, target_earning_amount = balance_accounts(float(self.trading_balance),
float(self.earning_balance), float(self.earning_balance),
@ -194,7 +222,7 @@ class earner:
self.percentage) self.percentage)
earning_delta = 0 earning_delta = 0
if self.earning_balance is None: if self.earning_balance is None:
print(f"{str(self.connector)} - There was an error fetching earning balance") print(f"{str(self.connector).upper()} - There was an error fetching earning balance")
else: else:
if float(self.earning_balance)!=0: if float(self.earning_balance)!=0:
earning_delta = target_earning_amount - float(self.earning_balance) earning_delta = target_earning_amount - float(self.earning_balance)
@ -202,13 +230,14 @@ class earner:
self.subscribe(earning_delta) self.subscribe(earning_delta)
if earning_delta<-self.step_size and time.time()-self.last_redemption_time>self.time_between_redemptions: if earning_delta<-self.step_size and time.time()-self.last_redemption_time>self.time_between_redemptions:
self.redeem(-earning_delta) self.redeem(-earning_delta)
print(f"{str(self.connector)} - Difference: {earning_delta}") #print(f"{str(self.connector)} - Difference: {earning_delta}")
else: else:
paused_string = "| "+colors.yellow+"PAUSED"+colors.white paused_string = "| "+colors.yellow+"PAUSED"+colors.white
#Output status to status_string #Output status to status_string
balances_string = f"Trading balance: {float(self.trading_balance):.2f} {self.currency} | Earning balance: {float(self.earning_balance):.2f} {self.currency}" balances_string = f"Trading balance: {float(self.trading_balance):.2f} {self.currency} | Earning balance: {float(self.earning_balance):.2f} {self.currency}"
percentages_string = f"On earn: {float(self.earning_balance)/float(self.trading_balance):.2%} {paused_string}" total_balance = float(self.earning_balance)+float(self.trading_balance)
percentages_string = f"On earn: {float(self.earning_balance)/total_balance:.2%} {paused_string}"
self.status_string = f"{colors.cyan}{self}{colors.white} | {balances_string} | {percentages_string}" self.status_string = f"{colors.cyan}{str(self).upper()}{colors.white} | {balances_string} | {percentages_string}"

View File

@ -83,7 +83,7 @@ class binance_earn:
example: {'redeemId': 483738233, 'success': True} example: {'redeemId': 483738233, 'success': True}
''' '''
try: try:
response = self.client.redeem_flexible_product(productId=product_id, redeemAll=redeem_all, amount=amount, destAccount=destination_account, recvWindow=5000) response = self.client.redeem_flexible_product(product_id, redeemAll=redeem_all, amount=amount, destAccount=destination_account, recvWindow=5000)
if response["success"]: if response["success"]:
return {"Success": "", return {"Success": "",
"orderId": response["redeemId"], "orderId": response["redeemId"],

14
main.py
View File

@ -88,7 +88,7 @@ def main():
last_subscription_key = "Never" last_subscription_key = "Never"
last_subscription_value = "" last_subscription_value = ""
else: else:
last_subscription_value = datetime.datetime.fromtimestamp(last_subscription_value).strftime('%Y-%m-%d %H:%M:%S') last_subscription_value = datetime.datetime.fromtimestamp(last_subscription_value).strftime('@%Y/%m/%d %H:%M:%S')
last_redemption = max(redemptions, key=lambda d: next(iter(d.values()))) last_redemption = max(redemptions, key=lambda d: next(iter(d.values())))
last_redemption_key = next(iter(last_redemption.keys())) last_redemption_key = next(iter(last_redemption.keys()))
last_redemption_value = next(iter(last_redemption.values())) last_redemption_value = next(iter(last_redemption.values()))
@ -96,14 +96,16 @@ def main():
last_redemption_key = "Never" last_redemption_key = "Never"
last_redemption_value = "" last_redemption_value = ""
else: else:
last_redemption_value = datetime.datetime.fromtimestamp(last_redemption_value).strftime('%Y-%m-%d %H:%M:%S') last_redemption_value = datetime.datetime.fromtimestamp(last_redemption_value).strftime('@%Y/%m/%d %H:%M:%S')
print("-"*80) print("-"*80)
total_on_trading = sum([item.get_trading_balance() for item in earners]) total_on_trading = sum([item.get_trading_balance() for item in earners])
total_on_earning = sum([item.get_earning_balance() for item in earners]) total_on_earning = sum([item.get_earning_balance() for item in earners])
total_funds = total_on_earning+total_on_trading
time_of_day = datetime.datetime.now().strftime('[%Y/%m/%d %H:%M:%S]') time_of_day = datetime.datetime.now().strftime('[%Y/%m/%d %H:%M:%S]')
print(f"{time_of_day} | Version {version} | Total funds: {total_on_trading+total_on_earning:.2f} | On earn: {total_on_earning:.2f} ({total_on_earning/total_on_trading*100:.2f}%)") print(f"Last subscription: {last_subscription_key}{last_subscription_value} | Last redemption: {last_redemption_key}{last_redemption_value}")
print(f"Uptime: {seconds_to_time(time.time()-start_time)} | Last subscription: {last_subscription_key} - {last_subscription_value} | Last redemption: {last_redemption_key} - {last_redemption_value}") print(f"Version {version} | Total funds: {total_funds:.2f} | On earn: {total_on_earning:.2f} ({total_on_earning/total_funds*100:.2f}%)")
print(f"{time_of_day} | Uptime: {seconds_to_time(time.time()-start_time)}")
print(colors.blue+"="*80+colors.white) print(colors.blue+"="*80+colors.white)
#Wait for next lap #Wait for next lap
time.sleep(config["lap_time"]) time.sleep(config["lap_time"])
@ -384,10 +386,6 @@ def get_total_balance():
return jsonify({'Error': 'broker not found'}) return jsonify({'Error': 'broker not found'})
return jsonify({'Error': 'API key not valid'}), 401 return jsonify({'Error': 'API key not valid'}), 401
'''
Missing endpoints:
/get_total_balance
'''
def run_API(port): def run_API(port):