subscribe-redeem test

This commit is contained in:
Nicolás Sánchez 2025-01-04 19:53:36 -03:00
parent 2e3427d448
commit d3b7ccf72f
5 changed files with 132 additions and 31 deletions

View File

@ -40,11 +40,18 @@ class binance_earn:
return None
def subscribe_product(self, product_id, amount, auto_subscribe=True, source_account="SPOT"):
def subscribe_product(self, product_id, amount, auto_subscribe=False, source_account="SPOT"):
'''
autoSubscribe (boolean, optional): true or false, default true.
autoSubscribe (boolean, optional): true or false, default false.
sourceAccount (str, optional): SPOT,FUND,ALL, default SPOT
recvWindow (int, optional): The value cannot be greater than 60000
returns {
purchaseId: int,
success: boolean,
amount: str
}
example: {'purchaseId': 7531473612, 'success': True, 'amount': '10'}
'''
try:
response = self.client.subscribe_flexible_product(productId=product_id, amount=amount, autoSubscribe=auto_subscribe, sourceAccount=source_account, recvWindow=5000)
@ -54,12 +61,14 @@ class binance_earn:
return None
def redeem_product(self, product_id, redeem_all=True, amount=0, destination_account="SPOT"):
def redeem_product(self, product_id, redeem_all=False, amount=0, destination_account="SPOT"):
'''
redeemAll (boolean, optional): true or false, default to false
redeemAll (boolean, optional): true or false, default to false (Note: redeemAll=True didn't seem to work)
amount (float, optional): if redeemAll is false, amount is mandatory
destAccount (str, optional): SPOT,FUND,ALL, default SPOT
recvWindow (int, optional): The value cannot be greater than 60000
example: {'redeemId': 483738233, 'success': True}
'''
try:
response = self.client.redeem_flexible_product(productId=product_id, redeemAll=redeem_all, amount=amount, destAccount=destination_account, recvWindow=5000)
@ -76,6 +85,8 @@ class binance_earn:
current (int, optional): Current querying page. Start from 1. Default:1
size (int, optional): Default:10 Max:100
recvWindow (int, optional): The value cannot be greater than 60000
example: {'total': 1, 'rows': [{'totalAmount': '10.00000299', 'tierAnnualPercentageRate': {'0-500USDT': '0.05000000'}, 'latestAnnualPercentageRate': '0.05229776', 'asset': 'USDT', 'canRedeem': True, 'collateralAmount': '0', 'productId': 'USDT001', 'yesterdayRealTimeRewards': '0', 'cumulativeBonusRewards': '0', 'cumulativeRealTimeRewards': '0.00000299', 'cumulativeTotalRewards': '0.00000299', 'autoSubscribe': False}]}
'''
try:
@ -89,6 +100,8 @@ class binance_earn:
def get_account(self, recv_window=5000):
'''
recvWindow (int, optional): The value cannot be greater than 60000
example: {'totalAmountInBTC': '0.00010133', 'totalAmountInUSDT': '10.00000398', 'totalFlexibleAmountInBTC': '0.00010133', 'totalFlexibleAmountInUSDT': '10.00000398', 'totalLockedInBTC': '0', 'totalLockedInUSDT': '0'}
'''
try:
response = self.client.simple_account(recv_window=recv_window)

View File

@ -58,12 +58,15 @@ class gateio_earn:
def get_available_products(self,coin):
'''
response: {'coin': 'USDT', 'product_id': 'USDT', 'rate': '0.00057', 'min_amount': '1', 'isActive': True}
'''
url = f"/earn/uni/currencies/{coin}"
headers = {"Accept": "application/json", "Content-Type": "application/json"}
query_param = ""
sign_headers = self.gen_sign("GET", self.prefix+url, query_param)
headers.update(sign_headers)
response = requests.get(self.host+self.prefix+url, params=query_param, headers=sign_headers)
response = requests.get(self.host+self.prefix+url, params=query_param, headers=headers)
if response.status_code == 200:
return {"coin": response.json()["currency"],
"product_id": response.json()["currency"],
@ -79,7 +82,7 @@ class gateio_earn:
headers = {"Accept": "application/json", "Content-Type": "application/json"}
sign_headers = self.gen_sign("GET", self.prefix+url)
headers.update(sign_headers)
response = requests.get(self.host+self.prefix+url, headers=sign_headers)
response = requests.get(self.host+self.prefix+url, headers=headers)
if response.status_code == 200:
return {"coin": response.json()["currency"],
"product_id": response.json()["currency"],
@ -89,29 +92,41 @@ class gateio_earn:
else:
return {"Error": response.text}
def get_min_rate(self,coin):
url = f"/earn/uni/currencies/{coin}"
headers = {"Accept": "application/json", "Content-Type": "application/json"}
sign_headers = self.gen_sign("GET", self.prefix+url)
headers.update(sign_headers)
response = requests.get(self.host+self.prefix+url, headers=headers)
if response.status_code == 200:
return {"min_rate": response.json()["min_rate"]}
else:
return {"Error": response.text}
def subscribe_product(self, coin, amount, rate):
url = "/earn/uni/lends"
headers = {"Accept": "application/json", "Content-Type": "application/json"}
query_params = ""
body = {"currency": coin, "amount": str(amount), "min_rate": rate, "type": "lend"}
body = f'{{"currency": "{coin}", "amount": {amount}, "min_rate": {rate}, "type": "lend"}}'
sign_headers = self.gen_sign("POST", self.prefix+url, query_params, body)
headers.update(sign_headers)
response = requests.post(self.host+self.prefix+url, headers=sign_headers, data=body)
response = requests.post(self.host+self.prefix+url, headers=headers, data=body)
if response.status_code == 200:
return response.json()
else:
return {"Error": response.text}
def redeem_product(self, coin, amount, rate):
def redeem_product(self, coin, amount, rate="0"):
url = "/earn/uni/lends"
headers = {"Accept": "application/json", "Content-Type": "application/json"}
query_params = ""
body = {"currency": coin, "amount": str(amount), "min_rate": rate, "type": "redeem"}
body = f'{{"currency": "{coin}", "amount": {amount}, "min_rate": {rate}, "type": "redeem"}}'
sign_headers = self.gen_sign("POST", self.prefix+url, query_params, body)
headers.update(sign_headers)
response = requests.post(self.host+self.prefix+url, headers=sign_headers, data=body)
response = requests.post(self.host+self.prefix+url, headers=headers, data=body)
if response.status_code == 200:
return response.json()
else:
@ -127,7 +142,7 @@ class gateio_earn:
headers = {"Accept": "application/json", "Content-Type": "application/json"}
sign_headers = self.gen_sign("GET", self.prefix+url)
headers.update(sign_headers)
response = requests.get(self.host+self.prefix+url, headers=sign_headers)
response = requests.get(self.host+self.prefix+url, headers=headers)
if response.status_code == 200:
return response.json()
else:
@ -136,7 +151,7 @@ class gateio_earn:
def amend_rate(self,coin,min_rate):
url = f"/earn/uni/lends"
body = {"currency": coin, "min_rate": min_rate}
body = str({"currency": coin, "min_rate": min_rate})
headers = {"Accept": "application/json", "Content-Type": "application/json"}
sign_headers = self.gen_sign("PATCH", self.prefix+url, body)
headers.update(sign_headers)

View File

@ -68,19 +68,21 @@ class kucoin_earn:
"isActive": response.to_dict()["common_response"]["data"][0]["status"]=="ONGOING"}
def subscribe_product(self, product_id, amount, auto_subscribe=True, source_account="SPOT"):
def subscribe_product(self, product_id, amount, auto_subscribe=False, source_account="SPOT"):
'''
source_account: "TRADE" or "MAIN"
auto_subscribe is ignored here
response: {'common_response': {'code': '200000', 'data': {'orderId': '2987632', 'orderTxId': '6681886'}, 'rate_limit': {'limit': 2000, 'remaining': 1995, 'reset': 29901}}, 'orderId': '2987632', 'orderTxId': '6681886'}
'''
if source_account.upper() in ["SPOT","TRADE","ALL"]:
source="trade"
source="TRADE"
elif source_account.upper() in ["FUND","MAIN"]:
source="main" #In Binance SPOT is TRADE and MAIN is FUND
source="MAIN" #In Binance SPOT is TRADE and MAIN is FUND
else:
return {"Error": "Invalid source_account. Values should be TRADE or MAIN for kucoin, SPOT, FUND or ALL for binance"}
request = PurchaseReqBuilder(product_id=product_id, amount=str(amount), account_type=source).build()
request = PurchaseReqBuilder().set_product_id(product_id).set_amount(str(amount)).set_account_type(source).build()
response = self.earn_api().purchase(request)
return response.to_dict()
@ -89,6 +91,8 @@ class kucoin_earn:
'''
source_account is ignored unless orderID=ETH2: "TRADE" or "MAIN"
auto_subscribe is ignored here
returns {'common_response': {'code': '200000', 'data': {'orderTxId': '6681887', 'deliverTime': 1736027626000, 'status': 'SUCCESS', 'amount': '20'}, 'rate_limit': {'limit': 2000, 'remaining': 1990, 'reset': 9770}}, 'orderTxId': '6681887', 'deliverTime': 1736027626000, 'status': <StatusEnum.SUCCESS: 'SUCCESS'>, 'amount': '20'}
'''
if source_account in ["SPOT","TRADE","ALL"]:
@ -98,12 +102,15 @@ class kucoin_earn:
else:
return {"Error": "Invalid source_account. Values should be TRADE or MAIN for kucoin, SPOT, FUND or ALL for binance"}
request = RedeemReqBuilder(order_id=order_id, amount=str(amount), from_account_type=source).build()
response = self.earn_api().purchase(request)
request = RedeemReqBuilder().set_order_id(order_id).set_amount(str(amount)).set_from_account_type(source).build()
response = self.earn_api().redeem(request)
return response.to_dict()
def get_position(self, coin, **kwargs):
'''
Return {'common_response': {'code': '200000', 'data': {'totalNum': 1, 'items': [{'orderId': '2987632', 'productId': '2152', 'productCategory': 'DEMAND', 'productType': 'DEMAND', 'currency': 'USDT', 'incomeCurrency': 'USDT', 'returnRate': '0.04767484', 'holdAmount': '20', 'redeemedAmount': '0', 'redeemingAmount': '0', 'lockStartTime': 1641806718000, 'lockEndTime': None, 'purchaseTime': 1736027283000, 'redeemPeriod': 0, 'status': 'LOCKED', 'earlyRedeemSupported': 0}], 'currentPage': 1, 'pageSize': 15, 'totalPage': 1}, 'rate_limit': {'limit': 2000, 'remaining': 1995, 'reset': 16550}}, 'totalNum': 1, 'items': [{'orderId': '2987632', 'productId': '2152', 'productCategory': 'DEMAND', 'productType': 'DEMAND', 'currency': 'USDT', 'incomeCurrency': 'USDT', 'returnRate': '0.04767484', 'holdAmount': '20', 'redeemedAmount': '0', 'redeemingAmount': '0', 'lockStartTime': 1641806718000, 'purchaseTime': 1736027283000, 'redeemPeriod': 0, 'status': <StatusEnum.LOCKED: 'LOCKED'>, 'earlyRedeemSupported': <EarlyRedeemSupportedEnum.T_0: 0>}], 'currentPage': 1, 'pageSize': 15, 'totalPage': 1}
'''
request = GetAccountHoldingReqBuilder().set_currency(coin).build()
response = self.earn_api().get_account_holding(request)
return response.to_dict()

View File

@ -68,6 +68,8 @@ class okx_earn:
}
]
}
response: {'code': '0', 'data': [{'amt': '10', 'ccy': 'USDT', 'clientId': '', 'from': '18', 'to': '6', 'transId': '1064005710'}], 'msg': ''}
'''
transfer = self.funding_api.funds_transfer(coin,amount,"18","6","0")
@ -93,6 +95,8 @@ class okx_earn:
}
]
}
response: {'code': '0', 'data': [{'amt': '20', 'ccy': 'USDT', 'clientId': '', 'from': '6', 'to': '18', 'transId': '1064008141'}], 'msg': ''}
'''
transfer = self.funding_api.funds_transfer(coin,amount,"6","18","0")
return transfer
@ -123,6 +127,8 @@ class okx_earn:
],
"msg": ""
}
response {'code': '0', 'data': [{'amt': '10', 'ccy': 'USDT', 'clientId': '', 'from': '18', 'instId': '', 'state': 'success', 'subAcct': '', 'to': '6', 'toInstId': '', 'transId': '1064005710', 'type': '0'}], 'msg': ''}
'''
transfer = self.funding_api.transfer_state(transaction_id)
return transfer
@ -141,6 +147,8 @@ class okx_earn:
'''
ONLY ASSETS IN THE FUNDING ACCOUNT CAN BE USED FOR SUBSCRIPTION, MOVE THE FUNDS FROM
THE TRADING ACCOUNT TO THE FUNDING ACCOUNT BEFORE SUBSCRIBING.
response: {'code': '0', 'data': [{'amt': '10', 'ccy': 'USDT', 'rate': '0.1091', 'side': 'purchase'}], 'msg': ''}
'''
if rate is None:
rate = self.get_avg_rate(coin)
@ -151,6 +159,8 @@ class okx_earn:
'''
ASSETS REDEEMED WILL BE PLACED IN THE FUNDING ACCOUNT, MOVE THE FUNDS FROM THE FUNDING ACCOUNT
TO THE TRADING ACCOUNT AFTER REDEMPTION.
response: {'code': '0', 'data': [{'amt': '20', 'ccy': 'USDT', 'rate': '', 'side': 'redempt'}], 'msg': ''}
'''
return self.earning_api.savings_purchase_redemption(coin, str(amount), "redempt", "0")

80
main.py
View File

@ -11,17 +11,73 @@ okx = earn_okx.okx_earn()
gateio = earn_gateio.gateio_earn()
if __name__=="__main__":
#Available products
print("Binance:")
print(binance.get_available_products("USDT"))
print("="*80)
print("Gate.io:")
print(gateio.get_available_products("USDT"))
print("="*80)
print("Kucoin:")
print(kucoin.get_available_products("USDT"))
print("="*80)
print("OKX:")
print(okx.get_available_products("USDT"))
'''
Subscribe workflow in Binance:
1. Get product id
2. Subscribe
Redeem workflow in Binance
1. Redeem with the same product id
'''
#print(binance.get_available_products("USDT"))
#print(binance.subscribe_product("USDT001", "10", auto_subscribe=False))
#print(binance.get_position("USDT"))
#print(binance.redeem_product("USDT001", amount="5.00000746"))
'''
Subscribe workflow in Kucoin
1. Get product id
2. Subscribe
Redeem workflow in Kucoin
1. Get ORDER id (the order id of the position)
2. Redeem
'''
#print(kucoin.get_available_products("USDT"))
#print(kucoin.subscribe_product("2152", "10"))
#print(kucoin.get_position("USDT"))
#print(kucoin.redeem_product(order_id="2987632", amount="20"))
'''
Subscribe workflow in OKX
1. Transfer funds to funding account
2. Confirm transfer via transfer_id
3. Subscribe
Redeem workflow in OKX
1. Reddem product (with coin, no id is required)
2. Transfer funds to trading account
3. Confirm transfer via transfer_id
'''
#print(okx.get_available_products("USDT"))
#print(okx.transfer_to_funding("USDT","10"))
#print(okx.get_transfer_state("1064007151"))
#print(okx.subscribe_product("USDT", "10"))
#print(okx.redeem_product("USDT", "20"))
#print(okx.transfer_to_trading("USDT", "20"))
#print(okx.get_transfer_state("1064008141"))
'''
Subscribe workflow in Gate.io
1. Get minimum rate
2. Subscribe product
3. Use get_account to confirm (request returns error?)
Redeem workflow in Gate.io
1. Reddem product
2. Use get_account to confirm (request returns error?)
'''
#print(gateio.get_min_rate("USDT"))
#print(gateio.redeem_product("USDT", "10", "0.00000452"))
#print(gateio.get_account())
pass