Getting commission of filled LIMIT order, commission clarifications

Hi,

  1. currently when posting a new LIMIT order that’s filled immediately, commission and commission asset can be found in fills.

    However when the order stays in NEW state, there are no fills. Querying order status afterwards (https://binance-docs.github.io/apidocs/spot/en/#query-order-user_data) doesn’t seem to show fills, or is it only because the documentation lists NEW order in this case?

    I currently have no orders to test with, just developing the application.

    This websocket stream apidocs/spot/en/#payload-order-update lists commission and commission asset, but I would like to use polling calls for this task.

    Another possibility is to use account trade list (apidocs/spot/en/#account-trade-list-user_data) but that is expensive (weight 5) and also doesn’t allow to search by order ID so it would be difficult to use this way.

    Is there any practical way to get commission of filled or partially filled order?

    EDIT: learning new things every day! :slight_smile: Working with Binance API for quite some time, didn’t know there is now a spot testnet, woohoo! :slight_smile: https://testnet.binance.vision/ Will try querying some testnet orders tomorrow.

  2. apidocs/spot/en/#payload-order-update - is the commission cumulative or last trade in this case? Why does the documentation say commission asset is null?

  3. can an order have mixed commission assets? E.g. when user runs out of BNB mid-order.

Thank you very much! :slight_smile:

Hi @kbs1 thanks for your feedback.

  1. NEW order means it’s still in open status, that’s why there is no filling. Only order is updated into FILLED or PARTIALLY_FILLED, there will be fills found.
    our testnet is definitely the best resource for learning and testing. And we are bringing liquidity into symbol BNBUSDT, which make it easier to work with.

  2. example payload in the document is for NEW order, as I explained above, it’s null. But if the event came from a fill, then there will be trade fee. It’s the fee for one trade.

  3. No. Only one value for the fee asset. If running out, will be charged from trading asset.

Hi @dino, thank you for your response! :slight_smile:

  1. so is it correct that when I call https://binance-docs.github.io/apidocs/spot/en/#query-order-user_data on FILLED or PARTIALLY_FILLED order, fills will also be returned?
  2. thank you, understood
  3. is it then possible to find an order with fills such that first fill will have commissionAsset BNB and second fill will have commissionAsset USDT for example?
  1. The fills are trades, they may be returned from POST /api/v3/order. If you wish to query, you will need to find them from GET /api/v3/myTrades.

  2. No I don’t think that’s possible.

@dino, is there any way to filter myTrades using orderId or clientOrderId? The use case is,

  1. I open a LIMIT order, it does not immediately fill
  2. later I query it’s status, and it is now FILLED
  3. I need to find it’s fills to get exact commission, but myTrades does not accept orderId or clientOrderId parameter.

Importing all trades just to look for my order is costly as there’s a lot of trades on the account and also the weight is 5.

Thank you! :slight_smile:

I use GET / api / v3 / order (HMAC SHA256) for SPOT and GET / sapi / v1 / margin / order for MARGIN to get the data of any order using the orderId or the origClientOrderId

@Saratoga Yes, but that doesn’t return fills and doesn’t return commission paid, as mentioned in the other thread :confused: executedQty / cummulativeQuoteQty when not paying fees via BNB

So there is no way to get commission for historical filled LIMIT orders (or PARTIALLY_FILLED) without importing myTrades (that is a costly api call) or @dino using websockets, which are unreliable (they can and from experience do get closed from time to time). So it is easy to miss order updates that way.

If the API is not updated to return fills from GET /api/v3/order then the best way seems to be hardcoding commission levels for a particular account, which is unfortunate.

@dino, do you think the API can be expanded to return fills for historical orders from GET /api/v3/order?

Thank you! :slight_smile:

As always the websocket messages are the best source data to query from. I would suggest to store order updates from stream into local db, then query the order id from there. There is no limit, and super fast. :slight_smile:

1 Like

So use myTrades, what is the problem? in fromId pass the orderId you want to consult and in limit put 1 to get only that record

@Saratoga fromId fetches by trade ids, not by order ids, you can’t fetch by order ids using myTrades

So either you continually import all myTrades for all pairs for each account just to look for your orderIds (which is very expensive), or you use websockets which are unreliable. Maybe you could leverage startTime and endTime in GET /api/v3/myTrades but that’s also not an efficient or good solution.

@Saratoga Hi, you are right the documentation has a typo in it (word orders instead of trades):

If fromId is set, it will get id >= that fromId . Otherwise most recent orders are returned.

However I’ve worked with myTrades api a lot in the past, and it allows you to query by trade ID or by startTime and endTime,

So when you pass tradeID 50000 and set limit to 1000, it will return trade IDs 50000 (inclusive) to 50999 (inclusive). When you give it a time range, it will return at most limit trades between that time range ordered by id DESC.

The response itself contains OrderId, but there is no way to query using it. So the only way to get commission for filled order retrospectively is to import ALL user trades on that symbol and query your database using the orderId (what’s worse is that it isn’t even the CLIENT orderId, so you have to store returned binance order ids as well).

Binance could really implement “fills” in GET /v3/order, that would be sweet and make things a lot simpler (also myTrades is expensive).

There is no Trade Id field, neither when you create an order nor when you consult it, there is only orderId and clientorderId, however I was testing the endpoint “allOrders” and “myTrades” to make the query you need and I think there is an error in " myTrades ", the fromId parameter works the same as the limit, that is, if you pass 10 in fromId it returns the last 10 trades of the symbol that you consulted, why have the limit if fromId does the same? When reading the notes at the end of the myTrades endpoint they mention the following:

  • If fromId is set, it will get orders >= that fromId. Otherwise most recent orders are returned.

And in the allOrders endpoint it says almost the same

  • If orderId is set, it will get orders >= that orderId. Otherwise most recent orders are returned

Which makes me think that fromId is the same as orderId, However, as I mentioned, the fromId parameter does not work if you pass it a valid orderId, the query does not return any data as you can see in the following image

Another curious thing is that in Postman the description that appears next to fromId is the same description that appears for limit in the documentation

fromId LONG NO TradeId to fetch from. Default gets most recent trades.
limit INT NO Default 500; max 1000.


.

That is why I conclude that there is an error in the fromId parameter of myTrades

thank you for the feedback, we will review this section from the document.