Support binance order update execution type convertion

This commit is contained in:
c9s 2020-10-25 18:56:07 +08:00
parent 391767953a
commit fa30f6b52a
5 changed files with 108 additions and 4 deletions

View File

@ -306,6 +306,10 @@ func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder
} }
clientOrderID := uuid.New().String() clientOrderID := uuid.New().String()
if len(order.ClientOrderID) > 0 {
clientOrderID = order.ClientOrderID
}
req := e.Client.NewCreateOrderService(). req := e.Client.NewCreateOrderService().
Symbol(order.Symbol). Symbol(order.Symbol).
Side(binance.SideType(order.Side)). Side(binance.SideType(order.Side)).

View File

@ -75,7 +75,7 @@ type ExecutionReportEvent struct {
CurrentExecutionType string `json:"x"` CurrentExecutionType string `json:"x"`
CurrentOrderStatus string `json:"X"` CurrentOrderStatus string `json:"X"`
OrderID int `json:"i"` OrderID uint64 `json:"i"`
TradeID int64 `json:"t"` TradeID int64 `json:"t"`
TransactionTime int64 `json:"T"` TransactionTime int64 `json:"T"`
@ -85,7 +85,34 @@ type ExecutionReportEvent struct {
LastExecutedPrice string `json:"L"` LastExecutedPrice string `json:"L"`
LastQuoteAssetTransactedQuantity string `json:"Y"` LastQuoteAssetTransactedQuantity string `json:"Y"`
OrderCreationTime int `json:"O"` OrderCreationTime int64 `json:"O"`
}
func (e *ExecutionReportEvent) Order() (*types.Order, error) {
switch e.CurrentExecutionType {
case "NEW", "CANCELED", "REJECTED", "EXPIRED":
case "REPLACED":
default:
return nil, errors.New("execution report type is not for order")
}
orderCreationTime := time.Unix(0, e.OrderCreationTime*int64(time.Millisecond))
return &types.Order{
SubmitOrder: types.SubmitOrder{
Symbol: e.Symbol,
ClientOrderID: e.ClientOrderID,
Side: toGlobalSideType(binance.SideType(e.Side)),
Type: toGlobalOrderType(binance.OrderType(e.OrderType)),
Quantity: util.MustParseFloat(e.OrderQuantity),
Price: util.MustParseFloat(e.OrderPrice),
TimeInForce: e.TimeInForce,
},
OrderID: e.OrderID,
Status: toGlobalOrderStatus(binance.OrderStatusType(e.CurrentOrderStatus)),
ExecutedQuantity: util.MustParseFloat(e.CumulativeFilledQuantity),
CreationTime: orderCreationTime,
}, nil
} }
func (e *ExecutionReportEvent) Trade() (*types.Trade, error) { func (e *ExecutionReportEvent) Trade() (*types.Trade, error) {
@ -97,10 +124,10 @@ func (e *ExecutionReportEvent) Trade() (*types.Trade, error) {
return &types.Trade{ return &types.Trade{
ID: e.TradeID, ID: e.TradeID,
Symbol: e.Symbol, Symbol: e.Symbol,
Side: toGlobalSideType(binance.SideType(e.Side)),
Price: util.MustParseFloat(e.LastExecutedPrice), Price: util.MustParseFloat(e.LastExecutedPrice),
Quantity: util.MustParseFloat(e.LastExecutedQuantity), Quantity: util.MustParseFloat(e.LastExecutedQuantity),
QuoteQuantity: util.MustParseFloat(e.LastQuoteAssetTransactedQuantity), QuoteQuantity: util.MustParseFloat(e.LastQuoteAssetTransactedQuantity),
Side: toGlobalSideType(binance.SideType(e.Side)),
IsBuyer: e.Side == "BUY", IsBuyer: e.Side == "BUY",
IsMaker: e.IsMaker, IsMaker: e.IsMaker,
Time: tt, Time: tt,

View File

@ -0,0 +1,61 @@
package binance
import (
"regexp"
"testing"
"github.com/stretchr/testify/assert"
)
var jsCommentTrimmer = regexp.MustCompile("(?m)//.*$")
func TestParseOrderUpdate(t *testing.T) {
payload := `{
"e": "executionReport", // Event type
"E": 1499405658658, // Event time
"s": "ETHBTC", // Symbol
"c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
"S": "BUY", // Side
"o": "LIMIT", // Order type
"f": "GTC", // Time in force
"q": "1.00000000", // Order quantity
"p": "0.10264410", // Order price
"P": "0.00000000", // Stop price
"F": "0.00000000", // Iceberg quantity
"g": -1, // OrderListId
"C": null, // Original client order ID; This is the ID of the order being canceled
"x": "NEW", // Current execution type
"X": "NEW", // Current order status
"r": "NONE", // Order reject reason; will be an error code.
"i": 4293153, // Order ID
"l": "0.00000000", // Last executed quantity
"z": "0.00000000", // Cumulative filled quantity
"L": "0.00000000", // Last executed price
"n": "0", // Commission amount
"N": null, // Commission asset
"T": 1499405658657, // Transaction time
"t": -1, // Trade ID
"I": 8641984, // Ignore
"w": true, // Is the order on the book?
"m": false, // Is this trade the maker side?
"M": false, // Ignore
"O": 1499405658657, // Order creation time
"Z": "0.00000000", // Cumulative quote asset transacted quantity
"Y": "0.00000000", // Last quote asset transacted quantity (i.e. lastPrice * lastQty)
"Q": "0.00000000" // Quote Order Qty
}`
payload = jsCommentTrimmer.ReplaceAllLiteralString(payload, "")
event, err := ParseEvent(payload)
assert.NoError(t, err)
assert.NotNil(t, event)
executionReport, ok := event.(*ExecutionReportEvent)
assert.True(t, ok)
assert.NotNil(t, executionReport)
orderUpdate, err := executionReport.Order()
assert.NoError(t, err)
assert.NotNil(t, orderUpdate)
}

View File

@ -98,6 +98,10 @@ func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder
} }
clientOrderID := uuid.New().String() clientOrderID := uuid.New().String()
if len(order.ClientOrderID) > 0 {
clientOrderID = order.ClientOrderID
}
req := e.client.OrderService.NewCreateOrderRequest(). req := e.client.OrderService.NewCreateOrderRequest().
Market(toLocalSymbol(order.Symbol)). Market(toLocalSymbol(order.Symbol)).
OrderType(string(orderType)). OrderType(string(orderType)).

View File

@ -1,6 +1,8 @@
package types package types
import ( import (
"time"
"github.com/slack-go/slack" "github.com/slack-go/slack"
) )
@ -30,18 +32,24 @@ type Order struct {
OrderID uint64 `json:"orderID"` // order id OrderID uint64 `json:"orderID"` // order id
Status OrderStatus `json:"status"` Status OrderStatus `json:"status"`
ExecutedQuantity float64 `json:"executedQuantity"` ExecutedQuantity float64 `json:"executedQuantity"`
CreationTime time.Time
} }
type SubmitOrder struct { type SubmitOrder struct {
ClientOrderID string `json:"clientOrderID"`
Symbol string Symbol string
Side SideType Side SideType
Type OrderType Type OrderType
Quantity float64 Quantity float64
Price float64 Price float64
StopPrice float64
Market Market Market Market
// TODO: we can probably remove these field
StopPriceString string
PriceString string PriceString string
QuantityString string QuantityString string