python-binance: Filter failure: LOT_SIZE

I cannot get the API to properly make a buy order. My current process is to first get my current USDT total, multiply it by 0.9995 to compensate for the 0.050% fee and then take that USDT total and put it into the “quantity=[amount]”. When I do this, I get:

binance.exceptions.BinanceAPIException: APIError(code=-1013): Filter failure: LOT_SIZE

How can I overcome this?

balance = client.get_asset_balance(asset='USDT') print(balance['free']) quantity = (float(balance['free']))*0.9995 print(quantity) order = client.order_market_buy(symbol='BTCUSDT', quantity=(float(quantity))) orders = client.get_open_orders(symbol='BTCUSDT') print(orders)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 24 (2 by maintainers)

Most upvoted comments

I’ve found a fix after reading a lot of different stuff. Essentially what I had to do was round off the number that came from dividing my current USDT totals into the current BTC price to 6 decimals only. The number I was getting had 18 decimal points.

Here is the code I used to get what I needed, I was close earlier, but did not realize I had to limit the decimal points.

balance = client.get_asset_balance(asset='USDT') trades = client.get_recent_trades(symbol='BTCUSDT') quantity = (float(balance['free']))/float(trades[0]['price'])*0.9995 order = client.order_market_buy(symbol='BTCUSDT', quantity=(round(quantity, 6)))

Instead of rounding to hard-coded 6 digits, you can find actual precision using this API (it can be different for different tokens): https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#lot_size (stepSize). To convert stepSize to the precision, I use this: precision = int(round(-math.log(stepSize, 10), 0)), and then do round(quantity, precision).

Why API do NOT automatically round the order? Why do we need to make it via extra code? Any meaningful reason?

Hi, I think the following code will solve your problem

info = client.get_symbol_info(symbol=pair) f = [i[“stepSize”] for i in info[“filters”] if i[“filterType”] == “LOT_SIZE”][0] qty = round(qty, f.index(“1”) - 1)

from binance.exceptions import *

to import Exception of python-binance

try:
    SELL_YOUR_COIN(coin,amount)
except BinanceAPIException as a:
    if a.message == 'Filter failure: LOT_SIZE':
        na = 3
        while True:
            try:
                SELL_YOUR_COIN(coin,amount)
                break
            except:
                na -= 1
                amount = round(float(amount), na)

this is a really efficient solution to the problem

thank you so much! @goldan @cc345 sym_info = self._client.get_symbol_info(‘BATBNB’) filters = sym_info[‘filters’] for f in filters: print("filter~~~~~~~~~~~~ " + str(f)) if f[‘filterType’] == ‘LOT_SIZE’: self._step_size = float(f[‘stepSize’]) break

def quan(self):
    bal = self._client.get_asset_balance(asset='BNB')
    quantity = (float(bal['free']))/self._price*0.9995
    precision = int(round(-math.log(self._step_size, 10), 0))
    quantity = float(round(quantity, precision))
    return quantity

from binance.exceptions import *

to import Exception of python-binance

try:
    SELL_YOUR_COIN(coin,amount)
except BinanceAPIException as a:
    if a.message == 'Filter failure: LOT_SIZE':
        na = 3
        while True:
            try:
                SELL_YOUR_COIN(coin,amount)
                break
            except:
                na -= 1
                amount = round(float(amount), na)

thank you so much! @goldan @cc345 sym_info = self._client.get_symbol_info(‘BATBNB’) filters = sym_info[‘filters’] for f in filters: print("filter~~~~~~~~~~~~ " + str(f)) if f[‘filterType’] == ‘LOT_SIZE’: self._step_size = float(f[‘stepSize’]) break

def quan(self):
    bal = self._client.get_asset_balance(asset='BNB')
    quantity = (float(bal['free']))/self._price*0.9995
    precision = int(round(-math.log(self._step_size, 10), 0))
    quantity = float(round(quantity, precision))
    return quantity

thank you very much! really useful 😃 We can improve it a little more: instead of hard coding 0.9995 as fee, this can be taken dynamically with API and then turn into % with: (100 - symbol_fee) / 100

i get error: binance.exceptions.BinanceAPIException: APIError(code=-2010): Filter failure: LOT_SIZE

request: client.create_order(symbol='ETHUSDT',side='SELL',type='MARKET', quoteOrderQty=20)

expect: sell eth for USD, and amount for 20usd

who knows what’s the problem?

For whatever reason, crypto currency has to be traded in strange and unusual quantities. You should try something along the lines of what selimozbas suggested

info = client.get_symbol_info(symbol=pair) f = [i[“stepSize”] for i in info[“filters”] if i[“filterType”] == “LOT_SIZE”][0] qty = round(qty, f.index(“1”) - 1)

This is what I have been using (I’m horrible at Python), but it seems to work: for filters:

       ```

sym_info = self._client.get_symbol_info(self._pair)

        filters = sym_info['filters']
        self._min_notional = filters
        for f in filters:
            print("filter~~~~~~~~~~~~ " + str(f))
            if f['filterType'] == 'LOT_SIZE': 
                self._step_size = float(f['stepSize'])
                self._precision_quan = int(round(-math.log(self._step_size, 10), 0))
                print("F precision_quan: " + str(self._precision_quan))
...........
`self.val_to_str(self.quantity_token_I_can_buy(p), self._precision_quan)`
'''''''''''
def does_MIN_NOTIONAL_pass(self, quantity, price):
    print ("in MIN notional " + str(quantity) + " " + str(price) + " " + str(self._min_notional) )
    return (float(quantity) * float(price)) >= float(self._min_notional)
Also, I've notice that Python is doing some funny things when converting long decimals to strings (losing precision, not truncating without rounding up, scientific notation), so I wrote my own function. I'll be happy to hear from you, if you have a more elegant way of doing it:

###############################################################################################

def val_to_str(self, val, precision=14):
    if (precision == None):
        print("!!! precision is None, setting to 14")
        precision = 14
    if(val == None) : return None
    print("val_to_str value:")
    print(val)
    if(precision < 0):
        print("val_to_str output:")
        print(None)
        return None
    string = ""
    if(val < 0): 
        string += "-"
        val *= -1
    whole = float(val) - float(val) % float(1.0)
    print("whole: " + str(whole))
    decimal = val - whole
    print("decimal: " + str(decimal))
    if(whole == 0.0 and decimal == 0.0):
        print("val_to_str output:")
        print("0")
        return "0"
    string += str(int(whole)) +"."
    for i in range (1, precision+1):
        w = int(decimal * 10)
        decimal = decimal * 10.0 - w
        string += str(int(w))

    string = string.rstrip("0").rstrip(".")
    print("val_to_str output:")
    print(string)
    return string

###############################################################################################

Why do we have to /self._price*0.9995 on all coins

It’s to compensate the 0.050% transaction fee