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 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 sourceAccount (str, optional): SPOT,FUND,ALL, default SPOT
recvWindow (int, optional): The value cannot be greater than 60000 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: try:
response = self.client.subscribe_flexible_product(productId=product_id, amount=amount, autoSubscribe=auto_subscribe, sourceAccount=source_account, recvWindow=5000) 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 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 amount (float, optional): if redeemAll is false, amount is mandatory
destAccount (str, optional): SPOT,FUND,ALL, default SPOT destAccount (str, optional): SPOT,FUND,ALL, default SPOT
recvWindow (int, optional): The value cannot be greater than 60000 recvWindow (int, optional): The value cannot be greater than 60000
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(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 current (int, optional): Current querying page. Start from 1. Default:1
size (int, optional): Default:10 Max:100 size (int, optional): Default:10 Max:100
recvWindow (int, optional): The value cannot be greater than 60000 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: try:
@ -89,6 +100,8 @@ class binance_earn:
def get_account(self, recv_window=5000): def get_account(self, recv_window=5000):
''' '''
recvWindow (int, optional): The value cannot be greater than 60000 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: try:
response = self.client.simple_account(recv_window=recv_window) response = self.client.simple_account(recv_window=recv_window)

View File

@ -58,12 +58,15 @@ class gateio_earn:
def get_available_products(self,coin): 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}" url = f"/earn/uni/currencies/{coin}"
headers = {"Accept": "application/json", "Content-Type": "application/json"} headers = {"Accept": "application/json", "Content-Type": "application/json"}
query_param = "" query_param = ""
sign_headers = self.gen_sign("GET", self.prefix+url, query_param) sign_headers = self.gen_sign("GET", self.prefix+url, query_param)
headers.update(sign_headers) 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: if response.status_code == 200:
return {"coin": response.json()["currency"], return {"coin": response.json()["currency"],
"product_id": response.json()["currency"], "product_id": response.json()["currency"],
@ -79,7 +82,7 @@ class gateio_earn:
headers = {"Accept": "application/json", "Content-Type": "application/json"} headers = {"Accept": "application/json", "Content-Type": "application/json"}
sign_headers = self.gen_sign("GET", self.prefix+url) sign_headers = self.gen_sign("GET", self.prefix+url)
headers.update(sign_headers) 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: if response.status_code == 200:
return {"coin": response.json()["currency"], return {"coin": response.json()["currency"],
"product_id": response.json()["currency"], "product_id": response.json()["currency"],
@ -90,28 +93,40 @@ class gateio_earn:
return {"Error": response.text} 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): def subscribe_product(self, coin, amount, rate):
url = "/earn/uni/lends" url = "/earn/uni/lends"
headers = {"Accept": "application/json", "Content-Type": "application/json"} headers = {"Accept": "application/json", "Content-Type": "application/json"}
query_params = "" 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) sign_headers = self.gen_sign("POST", self.prefix+url, query_params, body)
headers.update(sign_headers) 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: if response.status_code == 200:
return response.json() return response.json()
else: else:
return {"Error": response.text} return {"Error": response.text}
def redeem_product(self, coin, amount, rate): def redeem_product(self, coin, amount, rate="0"):
url = "/earn/uni/lends" url = "/earn/uni/lends"
headers = {"Accept": "application/json", "Content-Type": "application/json"} headers = {"Accept": "application/json", "Content-Type": "application/json"}
query_params = "" 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) sign_headers = self.gen_sign("POST", self.prefix+url, query_params, body)
headers.update(sign_headers) 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: if response.status_code == 200:
return response.json() return response.json()
else: else:
@ -127,7 +142,7 @@ class gateio_earn:
headers = {"Accept": "application/json", "Content-Type": "application/json"} headers = {"Accept": "application/json", "Content-Type": "application/json"}
sign_headers = self.gen_sign("GET", self.prefix+url) sign_headers = self.gen_sign("GET", self.prefix+url)
headers.update(sign_headers) 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: if response.status_code == 200:
return response.json() return response.json()
else: else:
@ -136,7 +151,7 @@ class gateio_earn:
def amend_rate(self,coin,min_rate): def amend_rate(self,coin,min_rate):
url = f"/earn/uni/lends" 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"} headers = {"Accept": "application/json", "Content-Type": "application/json"}
sign_headers = self.gen_sign("PATCH", self.prefix+url, body) sign_headers = self.gen_sign("PATCH", self.prefix+url, body)
headers.update(sign_headers) headers.update(sign_headers)

View File

@ -68,19 +68,21 @@ class kucoin_earn:
"isActive": response.to_dict()["common_response"]["data"][0]["status"]=="ONGOING"} "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" source_account: "TRADE" or "MAIN"
auto_subscribe is ignored here 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"]: if source_account.upper() in ["SPOT","TRADE","ALL"]:
source="trade" source="TRADE"
elif source_account.upper() in ["FUND","MAIN"]: 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: else:
return {"Error": "Invalid source_account. Values should be TRADE or MAIN for kucoin, SPOT, FUND or ALL for binance"} 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) response = self.earn_api().purchase(request)
return response.to_dict() return response.to_dict()
@ -89,6 +91,8 @@ class kucoin_earn:
''' '''
source_account is ignored unless orderID=ETH2: "TRADE" or "MAIN" source_account is ignored unless orderID=ETH2: "TRADE" or "MAIN"
auto_subscribe is ignored here 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"]: if source_account in ["SPOT","TRADE","ALL"]:
@ -98,12 +102,15 @@ class kucoin_earn:
else: else:
return {"Error": "Invalid source_account. Values should be TRADE or MAIN for kucoin, SPOT, FUND or ALL for binance"} 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() request = RedeemReqBuilder().set_order_id(order_id).set_amount(str(amount)).set_from_account_type(source).build()
response = self.earn_api().purchase(request) response = self.earn_api().redeem(request)
return response.to_dict() return response.to_dict()
def get_position(self, coin, **kwargs): 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() request = GetAccountHoldingReqBuilder().set_currency(coin).build()
response = self.earn_api().get_account_holding(request) response = self.earn_api().get_account_holding(request)
return response.to_dict() 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") 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") transfer = self.funding_api.funds_transfer(coin,amount,"6","18","0")
return transfer return transfer
@ -123,6 +127,8 @@ class okx_earn:
], ],
"msg": "" "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) transfer = self.funding_api.transfer_state(transaction_id)
return transfer return transfer
@ -141,6 +147,8 @@ class okx_earn:
''' '''
ONLY ASSETS IN THE FUNDING ACCOUNT CAN BE USED FOR SUBSCRIPTION, MOVE THE FUNDS FROM ONLY ASSETS IN THE FUNDING ACCOUNT CAN BE USED FOR SUBSCRIPTION, MOVE THE FUNDS FROM
THE TRADING ACCOUNT TO THE FUNDING ACCOUNT BEFORE SUBSCRIBING. 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: if rate is None:
rate = self.get_avg_rate(coin) 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 ASSETS REDEEMED WILL BE PLACED IN THE FUNDING ACCOUNT, MOVE THE FUNDS FROM THE FUNDING ACCOUNT
TO THE TRADING ACCOUNT AFTER REDEMPTION. 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") 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() gateio = earn_gateio.gateio_earn()
if __name__=="__main__": if __name__=="__main__":
#Available products
print("Binance:") '''
print(binance.get_available_products("USDT")) Subscribe workflow in Binance:
print("="*80) 1. Get product id
print("Gate.io:") 2. Subscribe
print(gateio.get_available_products("USDT"))
print("="*80) Redeem workflow in Binance
print("Kucoin:") 1. Redeem with the same product id
print(kucoin.get_available_products("USDT")) '''
print("="*80) #print(binance.get_available_products("USDT"))
print("OKX:") #print(binance.subscribe_product("USDT001", "10", auto_subscribe=False))
print(okx.get_available_products("USDT")) #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