I'm using the kucoin api to check what is my USDT balance and purchase its equivalent in Bitcoin using Python 3.12.3
Now if I understand correctly there might be two problems:
To solve these two problems, I leave a buffer of 0.01 USDT and I make sure that the trade amount is a multiple of the quote increment. You can see this in the below code:
from kucoin.client import Trade, User, Market
# Replace with your actual API credentials
api_key = 'my key'
api_secret = 'my secret'
api_passphrase = 'my passphrase'
# Initialize the KuCoin clients
trade_client = Trade(key=api_key, secret=api_secret, passphrase=api_passphrase)
user_client = User(key=api_key, secret=api_secret, passphrase=api_passphrase)
market_client = Market(key=api_key, secret=api_secret, passphrase=api_passphrase)
# Get account balances
account_balances = user_client.get_account_list()
# Find the USDT balance
usdt_balance = next((item for item in account_balances if item['currency'] == 'USDT' and item['type'] == 'trade'), None)
# Check if there is enough USDT balance
if usdt_balance and float(usdt_balance['balance']) > 0:
total_usdt_amount = float(usdt_balance['balance'])
buffer_amount = 0.01 # Leaving 0.01 USDT as buffer
usdt_amount = total_usdt_amount - buffer_amount
# Get the symbol info to find the quote increment and minimum size
symbol_info = market_client.get_symbol_list()
btc_usdt_info = next(item for item in symbol_info if item['symbol'] == 'BTC-USDT')
quote_increment = float(btc_usdt_info['quoteIncrement'])
quote_min_size = float(btc_usdt_info['quoteMinSize'])
# Adjust USDT amount to be a multiple of quote_increment
usdt_amount = (usdt_amount // quote_increment) * quote_increment
if usdt_amount < quote_min_size:
print(f"Order amount is too small, minimum required is {quote_min_size} USDT")
else:
# Create the market order to trade all USDT for BTC
try:
order = trade_client.create_market_order('BTC-USDT', 'buy', funds=str(usdt_amount))
print(f"Order successful: Traded {usdt_amount} USDT for BTC")
except Exception as e:
print(f"Order failed: {e}")
else:
print("Insufficient USDT balance or USDT balance not found")
Like you can see, I update the amount this way:
usdt_amount = (usdt_amount // quote_increment) * quote_increment
Which I thought it was correct, but probably I'm missing something because it gives me this error:
Order failed: 200-{"msg":"Funds increment invalid.","code":"400100"}
Your problem likely stems from using floating point numbers, which are not precisely accurate, so instead of 19.99
you probably have 19.990000000000002
, for example. That's what I got trying your solution in a python interpreter:
>>> funds = 20
>>> increment = float(0.01)
>>> (funds // increment) * increment
19.990000000000002
You just need to round the number to the nearest hundreth, which you can do using round()
, passing 2
as the second argument to round to 2 decimal places:
>>> round((funds // increment) * increment, 2)
19.99
Since the increment changes, you can't always use 2
as the second argument, but since quoteIncrement
is given as a string from the API, you could just look at its length to determine what the argument should be. You don't need division at all this way:
>>> funds = 20.00023230234234
>>> quoteIncrement = "0.000001"
>>> len(quoteIncrement) - 2 # subtract 2 for the initial `0.`
6
>>> round(funds, len(quoteIncrement) - 2)
20.000232