Relationship between different types of volume

I am working with GET /api/v3/klines endpoint.

Suppose we take BNXUSDT 1h kline for (2024-04-02T06:00:00.0Z, 2024-04-02T06:59:59.999Z) period:

https://api.binance.com/api/v3/klines?symbol=BNXUSDT&interval=1h&startTime=1712037600000&limit=1

[
[
1712037600000, // Kline open time
“0.61420000”, // Open price
“0.63820000”, // High price
“0.60910000”, // Low price
“0.63650000”, // Close price
“3387726.80000000”, // Volume
1712041199999, // Kline Close time
“2107340.01990000”, // Quote asset volume
20116, // Number of trades
“1797761.40000000”, // Taker buy base asset volume
“1120004.58341000”, // Taker buy quote asset volume
“0” // Unused field, ignore.
]
]

I would like to understand the relationships between Volume, Quote asset volume, Taker buy base asset volume, Taker buy quote asset volume.

My questions:

  1. Is the “Volume” field the number of BNX tokens?

  2. Is the “Quote asset volume” field the number of USDT tokens?

  3. Which price do binance use to get “Quote asset volume” from “Volume”? Volume (3387726.80000000) * Close price (0.63650000) = 2,156,288.1082. And it doesn’t equal to “Quote asset volume”, spread ~ 2%

  4. It was discussed here https://dev.binance.vision/t/taker-buy-base-asset-volume/602 that
    “Volume” = “Taker buy base asset volume” + “Maker sell base asset volume” + “Taker sell base asset volume” + “Maker buy base asset volume”
    “Taker buy base asset volume” = “Maker sell base asset volume”
    “Taker sell base asset volume” = “Maker buy base asset volume”

    It means that:
    “Volume” = 2 * “Taker buy base asset volume” + 2 * “Taker sell base asset volume”
    “Taker sell base asset volume” = “Volume” / 2 - “Taker buy base asset volume”

    But if we try to use this formula on the real data we can get unexpected negative values:
    “Taker sell base asset volume” = 3387726.80000000 / 2 - 1797761.40000000 = -103,898

    You’ll see a similar pattern on any asset, so I think the problem is in the formula.

    So I would like to understand the relation between buy and sell, maker and taker volumes and how can I calculate “Taker sell base asset volume” and “Taker sell quote asset volume” correctly?

Yes. Volume is always the amount of the base asset.

Correct. Quote asset is the one in which prices are expressed.

The prices of individual trades.

Quote asset volume is the total amount of quote asset paid for the total volume of base asset. That is, you can compute the average price in the kline interval by dividing quote asset volume by volume.

To calculate quote asset volume, you need to sum up individual trades.

For example, you can use the GET /api/v3/aggTrades endpoint:

  1. Use kline startTime to find the first aggtrade in the interval:

    $ curl 'https://api.binance.com/api/v3/aggTrades?symbol=BNXUSDT&startTime=1712037600000&limit=1'
    [{"a":14416184,"p":"0.61420000","q":"828.60000000","f":25394471,"l":25394471,"T":1712037600729,"m":true,"M":true}]
    
  2. Use kline endTime to find the last aggtrade in the interval:

    $ curl 'https://api.binance.com/api/v3/aggTrades?symbol=BNXUSDT&endTime=1712041199999&limit=1'
    [{"a":14428230,"p":"0.63650000","q":"300.50000000","f":25414586,"l":25414586,"T":1712041198943,"m":true,"M":true}]
    
  3. Now use fromId to paginate through aggtrades from "a":14416184 to 14428230.

    $ curl 'https://api.binance.com/api/v3/aggTrades?symbol=BNXUSDT&fromId=14416184&limit=3'
    [
      {"a":14416184,"p":"0.61420000","q":"828.60000000","f":25394471,"l":25394471,"T":1712037600729,"m":true,"M":true},
      {"a":14416185,"p":"0.61410000","q":"249.30000000","f":25394472,"l":25394473,"T":1712037600729,"m":true,"M":true},
      {"a":14416186,"p":"0.61400000","q":"27.80000000","f":25394474,"l":25394474,"T":1712037600729,"m":true,"M":true},
      ...
    ]
    

    What you’re interested in here is "p" × "q", that is price × quantity = quote asset volume. Compute that for each aggtrade, sum them up. That would be the total quote asset volume.

    Maximum limit on the API is 1000 aggtrades, so you’ll need to do 13 queries for that. For longer intervals or more active markets you should instead consider downloading data dumps from data.binance.vision.

Imagine an order book that looks like this:

...
SELL 0.5 @ 0.45
SELL 1.5 @ 0.44
SELL 2.0 @ 0.43
---------------
BUY  1.0 @ 0.42
BUY  1.0 @ 0.42
BUY  1.0 @ 0.41
BUY  0.5 @ 0.40
...

These are all makers willing to sell or buy some ABC for at given prices in XYZ.


Now, someone places a LIMIT GTC order to SELL 5.0 ABC at 0.41 XYZ apiece, it matches like this:

BUY  1.0 @ 0.42 => 1.0 ABC sold for 0.42 XYZ (-1.0 ABC, +0.42 XYZ total)
BUY  1.0 @ 0.42 => 1.0 ABC sold for 0.42 XYZ (-2.0 ABC, +0.84 XYZ total)
BUY  1.0 @ 0.41 => 1.0 ABC sold for 0.41 XYZ (-3.0 ABC, +1.25 XYZ total)
BUY  0.5 @ 0.40    the price is lower than requested 0.41
                   2.0 ABC left unsold

and the order book now looks like this:

...
SELL 0.5 @ 0.45
SELL 1.5 @ 0.44
SELL 2.0 @ 0.43
SELL 2.0 @ 0.41 -- new maker order
---------------
BUY  0.5 @ 0.40
...

Here

  • 3 trades happen (two at 0.42 XYZ per ABC, and one at 0.41)
    • or, 2 aggtrades happen (one at 0.42 XYZ per ABC, one at 0.41)
  • total base asset volume traded is 3.0 ABC
  • total quote asset volume traded is 1.25 XYZ
  • the taker sold 3.0 ABC and got 1.25 XYZ
    • taker sell base asset volume is 3.0 ABC
    • taker sell quote asset volume is 1.25 XYZ
    • taker buy volume is zero, since taker never bought anything
  • the makers together bought 3.0 ABC and paid 1.25 XYZ
    • maker buy base asset volume is 3.0 ABC
    • maker buy quote asset volume is 1.25 XYZ
    • maker sell volume is zero, since makers never sold anything

Still with me? Now, given that order book

...
SELL 0.5 @ 0.45
SELL 1.5 @ 0.44
SELL 2.0 @ 0.43
SELL 2.0 @ 0.41
---------------
BUY  0.5 @ 0.40
...

assume the next trader places a LIMIT GTC order to BUY 5.0 ABC at 0.44 XYZ apiece. The order matches like this:

SELL 2.0 @ 0.41 => 2.0 ABC bought for 0.82 USDT (+2.0 ABC, -0.82 XYZ total)
SELL 2.0 @ 0.43 => 2.0 ABC bought for 0.86 USDT (+4.0 ABC, -1.68 XYZ total)
SELL 1.5 @ 0.44 => 1.0 ABC bought for 0.44 USDT (+5.0 ABC, -2.12 XYZ total)
                   taker's BUY order is completely filled
                   0.5 ABC left unsold by the maker

The order book ends up looks like this after the trades:

...
SELL 0.5 @ 0.45
SELL 0.5 @ 0.44
---------------
BUY  0.5 @ 0.40
...

Here

  • 3 trades (and 3 aggtrades) happen
  • total base volume traded is 5.0 ABC
  • total quote asset volume traded is 2.12 XYZ
  • the taker bought 5.0 BNX and paid 2.12 XYZ
    • taker buy base asset volume is 5.0 ABC
    • taker buy quote asset volume is 2.12 XYZ
    • taker sell volume is zero, since taker never sold anything
  • the makers together sold 5.0 BNX and got 2.12 XYZ
    • maker sell base asset volume is 5.0 ABC
    • maker sell quote asset volume is 2.12 XYZ
    • maker buy volume is zero, since makers never bought anything

Now, if you sum those two situations together:

Indicator Value
Total base asset volume 8.00 ABC
Total quote asset volume 3.37 XYZ
Indicator Value
Taker buy base asset volume 5.00 BNX
Taker buy quote asset volume 2.12 XYZ
Taker sell base asset volume 3.00 BNX
Taker sell quote asset volume 1.25 XYZ
Indicator Value
Maker buy base asset volume 3.00 BNX
Maker buy quote asset volume 1.25 XYZ
Maker sell base asset volume 5.00 BNX
Maker sell quote asset volume 2.12 XYZ

Kline data gives you taker buy base/quote asset volume. You can compute the other values by subtracting that from the total volume.

Observe that

  • taker buy base asset volume = maker sell base asset volume
  • taker sell base asset volume = maker buy base asset volume

since in order for a taker to sell something there must be a maker counterparty willing to buy it, and vice versa for the other direction of the trade.

Total volume is total amount of asset changing hands in both directions, that is

  • base asset volume = taker buy base asset volume + taker sell base asset volume
  • base asset volume = maker buy base asset volume + maker sell base asset volume

however you like to look at it.

For example, with that BNXUSDT kline:

[
  [
    1712037600000,      // Kline open time
    “0.61420000”,       // Open price
    “0.63820000”,       // High price
    “0.60910000”,       // Low price
    “0.63650000”,       // Close price
    “3387726.80000000”, // Volume
    1712041199999,      // Kline Close time
    “2107340.01990000”, // Quote asset volume
    20116,              // Number of trades
    “1797761.40000000”, // Taker buy base asset volume
    “1120004.58341000”, // Taker buy quote asset volume
    “0”                 // Unused field, ignore.
  ]
]

the taker sell base asset volume is

  • 3387726.80000000 BNX – 1797761.40000000 BNX = 1589965.40000000 BNX

which is the same value as maker buy base asset volume, as makers bought all the BNX that takes sold.

Similarly, the taker sell quote asset volume is

  • 2107340.01990000 USDT – 1120004.58341000 USDT = 987335.436490000 USDT
1 Like

Thank you very much for the detailed answer! Now everything is clear.

1 Like