Search code examples
tradingalgorithmic-tradingbinancebinance-api-client

Binance API response shows wrong minimum order quantity


Trying to hit the fapi.binance.com/fapi/v1/exchangeInfo endpoint in order to get the current minimum order quantity for a pair (let's take ETHUSDT as an example).

Here is what Binance UI shows as the minQty: Minimum order quantity for ETH is 0.004ETH

When hitting the above mentioned endpoint and inspecting the ETHUSDT symbol specific response:

{
  "symbol": "ETHUSDT",
  "pair": "ETHUSDT",
  "contractType": "PERPETUAL",
  "deliveryDate": 4133404800000,
  "onboardDate": 1569398400000,
  "status": "TRADING",
  "maintMarginPercent": "2.5000",
  "requiredMarginPercent": "5.0000",
  "baseAsset": "ETH",
  "quoteAsset": "USDT",
  "marginAsset": "USDT",
  "pricePrecision": 2,
  "quantityPrecision": 3,
  "baseAssetPrecision": 8,
  "quotePrecision": 8,
  "underlyingType": "COIN",
  "underlyingSubType": [
    "Layer-1"
  ],
  "settlePlan": 0,
  "triggerProtect": "0.0500",
  "liquidationFee": "0.015000",
  "marketTakeBound": "0.05",
  "filters": [
    {
      "minPrice": "39.86",
      "maxPrice": "306177",
      "filterType": "PRICE_FILTER",
      "tickSize": "0.01"
    },
    {
      "stepSize": "0.001",
      "filterType": "LOT_SIZE",
      "maxQty": "10000",
      "minQty": "0.001"
    },
    {
      "stepSize": "0.001",
      "filterType": "MARKET_LOT_SIZE",
      "maxQty": "2000",
      "minQty": "0.001"
    },
    {
      "limit": 200,
      "filterType": "MAX_NUM_ORDERS"
    },
    {
      "limit": 10,
      "filterType": "MAX_NUM_ALGO_ORDERS"
    },
    {
      "notional": "5",
      "filterType": "MIN_NOTIONAL"
    },
    {
      "multiplierDown": "0.9500",
      "multiplierUp": "1.0500",
      "multiplierDecimal": "4",
      "filterType": "PERCENT_PRICE"
    }
  ],
  "orderTypes": [
    "LIMIT",
    "MARKET",
    "STOP",
    "STOP_MARKET",
    "TAKE_PROFIT",
    "TAKE_PROFIT_MARKET",
    "TRAILING_STOP_MARKET"
  ],
  "timeInForce": [
    "GTC",
    "IOC",
    "FOK",
    "GTX"
  ]
}

We can observe that no data here indicates a correct minQty despite the fact that some documents in the filters array (like LOT_SIZE and MARKET_LOT_SIZE) are trying.

Am I missing something or is this a Binance API bug?


Solution

  • Took a while to figure it out, but I believe I have come to a solution/explanation.

    As I previously noted, we are interested in the filters array found in the response of the fapi.binance.com/fapi/v1/exchangeInfo endpoint, specifically the MARKET_LOT_SIZE (LOT_SIZE if you are not interested in market orders) and MIN_NOTIONAL filters. When I wrote the question I assumed one of those had to be the source of truth, but none of the two were consistently matching the minimum order quantities seen on Binance UI.

    It turns out its not one of them, but the two combined...sort of.

    For inexperienced traders - a quick definition. Base asset - the asset you are buying. Quote asset - the asset you are acquiring the base asset with. In my case (ETHUSDT) ETH was the base asset and USDT was the quote asset.

    MIN_NOTIONAL filter tells you the minimum amount of the quote asset you are required to spend to acquire the base asset. This filter is equal to 5 USDT in the case of ETHUSDT at the time of posting.

    MARKET_LOT_SIZE filter tells you the minimum amount of the base asset you can buy. This filter is equal to 0.001 in the case of ETHUSDT at the time of posting.

    Depending on the price of ETH, 0.001 ETH may cost less than 5 USDT, which would not fill the MIN_NOTIONAL filter's requirement. Similarly, if, due to price, 5 USDT bought less than 0.001 ETH, an order with notional value of 5 USDT would not fill the requirement of the MARKET_LOT_SIZE filter.

    Hence, to calculate the minimum order quantity, we need to take the maximum value of the two with one caveat. We first need to convert the MIN_NOTIONAL filter value of 5 USDT to ETH. We can do that by dividing that value by the current price of ETH. Beware, if the result of the division has more decimal points then the quantity precision of the asset on Binance, we need to round up to that number of decimals.

    Ultimately, the calculation example in Python:

    max(
      MIN_MARKET_LOT_SIZE, 
      round_up((MIN_NOTIONAL / CURRENT_ETH_PRICE), ETH_QUANTITY_PRECISION)
    ) 
    

    An example of the decimal rounding up function can be found here