From c38757a68990858aa989557d2cdfb8be1e7f932f Mon Sep 17 00:00:00 2001 From: Rocky Yang Date: Tue, 17 Aug 2021 12:33:54 +0800 Subject: [PATCH] Binance websocket: Order Detail Execution Report (#750) * * Binance websocket: set commission of order Detail * * Binance websocket: set commissionAsset of order.Detail * * Binance websocket: change CostAsset to type currency.Code * * Binance websocket: call NewCode after checking CommissionAsset is not empty. This guarantees that NULL CommissionAsset is mapped to an empty order.Detail.CostAsset. Otherwise, reflect.DeepEqual will fail on test. Update TestWsOrderExecutionReport json message to BTC commission. * * Binance websocket: binance websocket "ExecutionReport" only provides "trade" status (partially filled), so check that executed amount == total amount before change status to filled --- exchanges/binance/binance_test.go | 5 ++++- exchanges/binance/binance_websocket.go | 9 +++++++++ exchanges/order/order_types.go | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/exchanges/binance/binance_test.go b/exchanges/binance/binance_test.go index 76e8a485..d2ed5262 100644 --- a/exchanges/binance/binance_test.go +++ b/exchanges/binance/binance_test.go @@ -2488,7 +2488,8 @@ func TestSetExchangeOrderExecutionLimits(t *testing.T) { func TestWsOrderExecutionReport(t *testing.T) { // cannot run in parallel due to inspecting the DataHandler result - payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616627567900,"s":"BTCUSDT","c":"c4wyKsIhoAaittTYlIVLqk","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028400","p":"52789.10000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"NEW","X":"NEW","r":"NONE","i":5340845958,"l":"0.00000000","z":"0.00000000","L":"0.00000000","n":"0","N":null,"T":1616627567900,"t":-1,"I":11388173160,"w":true,"m":false,"M":false,"O":1616627567900,"Z":"0.00000000","Y":"0.00000000","Q":"0.00000000"}}`) + payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616627567900,"s":"BTCUSDT","c":"c4wyKsIhoAaittTYlIVLqk","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028400","p":"52789.10000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"NEW","X":"NEW","r":"NONE","i":5340845958,"l":"0.00000000","z":"0.00000000","L":"0.00000000","n":"0","N":"BTC","T":1616627567900,"t":-1,"I":11388173160,"w":true,"m":false,"M":false,"O":1616627567900,"Z":"0.00000000","Y":"0.00000000","Q":"0.00000000"}}`) + // this is a buy BTC order, normally commission is charged in BTC, vice versa. expRes := order.Detail{ Price: 52789.1, Amount: 0.00028400, @@ -2502,6 +2503,8 @@ func TestWsOrderExecutionReport(t *testing.T) { Pair: currency.NewPair(currency.BTC, currency.USDT), RemainingAmount: 0.000284, Date: time.Unix(0, 1616627567900*int64(time.Millisecond)), + Cost: 0, + CostAsset: currency.BTC, } // empty the channel. otherwise mock_test will fail for len(b.Websocket.DataHandler) > 0 { diff --git a/exchanges/binance/binance_websocket.go b/exchanges/binance/binance_websocket.go index d250e25d..446ecf42 100644 --- a/exchanges/binance/binance_websocket.go +++ b/exchanges/binance/binance_websocket.go @@ -234,6 +234,9 @@ func (b *Binance) wsHandleData(respRaw []byte) error { Err: err, } } + if oStatus == order.PartiallyFilled && data.Data.CumulativeFilledQuantity == data.Data.Quantity { + oStatus = order.Filled + } var p currency.Pair var a asset.Item p, a, err = b.GetRequestFormattedPairAndAssetType(data.Data.Symbol) @@ -244,6 +247,10 @@ func (b *Binance) wsHandleData(respRaw []byte) error { if oStatus == order.Cancelled { clientOrderID = data.Data.CancelledClientOrderID } + var costAsset currency.Code + if data.Data.CommissionAsset != "" { + costAsset = currency.NewCode(data.Data.CommissionAsset) + } b.Websocket.DataHandler <- &order.Detail{ Price: data.Data.Price, Amount: data.Data.Quantity, @@ -258,6 +265,8 @@ func (b *Binance) wsHandleData(respRaw []byte) error { Date: data.Data.OrderCreationTime, Pair: p, ClientOrderID: clientOrderID, + Cost: data.Data.Commission, + CostAsset: costAsset, } return nil case "listStatus": diff --git a/exchanges/order/order_types.go b/exchanges/order/order_types.go index d3977c61..686f5ade 100644 --- a/exchanges/order/order_types.go +++ b/exchanges/order/order_types.go @@ -133,6 +133,7 @@ type Detail struct { ExecutedAmount float64 RemainingAmount float64 Cost float64 + CostAsset currency.Code Fee float64 Exchange string InternalOrderID string