glitch100 / BinanceDotNet

Official C# Wrapper for the Binance exchange API, with REST and WebSocket endpoints
https://www.nuget.org/packages/BinanceDotNet/
MIT License
161 stars 140 forks source link

Enhance CreateOrder:Request/Response to include ACK, RESULT, OR FULL #23

Closed curious-debug closed 6 years ago

curious-debug commented 6 years ago

The official Binance API's new order(trade) endpoint POST /api/v3/order allows requests to include the type of response desired, whether ACK, RESULT, or FULL via the newOrderRespType parameter in the request. The RESULT and FULL response payloads provide more useful info than the ACK response, particularly the "status". For example, if an order is immediately filled, the developer can know this immediately in the response, and can then move on to the next step in the app flow. However, if the order is not filled, the developer will also know this immediately, and can pause the app flow and check back later (e.g. via QueryOrder, passing in the orderId).

However, in BinanceDotNet, new orders are limited and do not have this functionality, namely, the CreateOrderRequest object in IBinanceClient.CreateOrder(CreateOrderRequest request) does not allow a developer to specify the desired response. Thus, the response only includes an instance of CreateOrderResponse, which currently only provides info from Binance's ACK response, and it does not have other important information (status, etc.) See https://github.com/glitch100/BinanceDotNet/blob/master/BinanceExchange.API/Models/Response/CreateOrderResponse.cs.

So, when using BinanceDotNet, in order to know whether or not an order has been filled after it has been created, a second request must be made to get that information (using IBinanceClient.QueryOrder(QueryOrderRequest request ...). If speedy trades are important to developers/traders (they are), then saving precious milliseconds is vital, so avoiding the need to make this second request is pretty important. Plus, because Binance has API usage limits, not having to make a second request to gather this information would reduce usage against one's API request limit.

Because Binance's API provides this information immediately in its response to the POST /api/v3/order endpoint, I cast a strong vote that BinanceDotNet's CreateOrder:CreateOrderResponse be modified to match Binance's official API new order endpoint, and allow RESULT and FULL response types to be requested and also allow RESULT and FULL payload responses to be returned.

Note: I would attempt to do this myself, but I'd screw it up badly and waste everyone's time. (I'm a technical writer, hence my understanding of APIs and things, but I'm very new to C# and git/github.) Just trying to contribute to the development here by informing everyone where this wrapper could be enhanced for all.

From Binance's API:

https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#new-order--trade

New order (TRADE)

POST /api/v3/order  (HMAC SHA256)

Parameters:

Name Type Mandatory Description
... ... ... ...
newOrderRespType ENUM NO Set the response JSON. ACK, RESULT, or FULL; default: RESULT.
... ... ... ...

Response ACK:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595
}

Response RESULT:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595,
  "price": "0.00000000",
  "origQty": "10.00000000",
  "executedQty": "10.00000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "MARKET",
  "side": "SELL"
}

Response FULL:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595,
  "price": "0.00000000",
  "origQty": "10.00000000",
  "executedQty": "10.00000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "MARKET",
  "side": "SELL",
  "fills": [
    {
      "price": "4000.00000000",
      "qty": "1.00000000",
      "commission": "4.00000000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3999.00000000",
      "qty": "5.00000000",
      "commission": "19.99500000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3998.00000000",
      "qty": "2.00000000",
      "commission": "7.99600000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3997.00000000",
      "qty": "1.00000000",
      "commission": "3.99700000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3995.00000000",
      "qty": "1.00000000",
      "commission": "3.99500000",
      "commissionAsset": "USDT"
    }
  ]
}
glitch100 commented 6 years ago

Looks like there isn't any indicator (an enum or something) of what response type of you will get so always returning the full fat response is the best. I will work on this. Edit: I am a fool - I misread the request! I will start on this!

glitch100 commented 6 years ago

Hi Ryan,

This PR is around the issue raised - please can you test (rc available on PR) https://github.com/glitch100/BinanceDotNet/pull/29

Thanks