use fixedpoint to parse payload directly

This commit is contained in:
c9s 2022-01-11 01:41:33 +08:00
parent e5b4af53e6
commit 71a0604e72
2 changed files with 69 additions and 68 deletions

View File

@ -13,7 +13,6 @@ import (
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"github.com/c9s/bbgo/pkg/util"
) )
/* /*
@ -68,20 +67,20 @@ type ExecutionReportEvent struct {
OrderCreationTime int64 `json:"O"` OrderCreationTime int64 `json:"O"`
TimeInForce string `json:"f"` TimeInForce string `json:"f"`
IcebergQuantity string `json:"F"` IcebergQuantity fixedpoint.Value `json:"F"`
OrderQuantity string `json:"q"` OrderQuantity fixedpoint.Value `json:"q"`
QuoteOrderQuantity string `json:"Q"` QuoteOrderQuantity fixedpoint.Value `json:"Q"`
OrderPrice string `json:"p"` OrderPrice fixedpoint.Value `json:"p"`
StopPrice string `json:"P"` StopPrice fixedpoint.Value `json:"P"`
IsOnBook bool `json:"w"` IsOnBook bool `json:"w"`
IsMaker bool `json:"m"` IsMaker bool `json:"m"`
Ignore bool `json:"M"` Ignore bool `json:"M"`
CommissionAmount string `json:"n"` CommissionAmount fixedpoint.Value `json:"n"`
CommissionAsset string `json:"N"` CommissionAsset string `json:"N"`
CurrentExecutionType string `json:"x"` CurrentExecutionType string `json:"x"`
@ -93,13 +92,13 @@ type ExecutionReportEvent struct {
TradeID int64 `json:"t"` TradeID int64 `json:"t"`
TransactionTime int64 `json:"T"` TransactionTime int64 `json:"T"`
LastExecutedQuantity string `json:"l"` LastExecutedQuantity fixedpoint.Value `json:"l"`
LastExecutedPrice string `json:"L"` LastExecutedPrice fixedpoint.Value `json:"L"`
CumulativeFilledQuantity string `json:"z"` CumulativeFilledQuantity fixedpoint.Value `json:"z"`
CumulativeQuoteAssetTransactedQuantity string `json:"Z"` CumulativeQuoteAssetTransactedQuantity fixedpoint.Value `json:"Z"`
LastQuoteAssetTransactedQuantity string `json:"Y"` LastQuoteAssetTransactedQuantity fixedpoint.Value `json:"Y"`
} }
func (e *ExecutionReportEvent) Order() (*types.Order, error) { func (e *ExecutionReportEvent) Order() (*types.Order, error) {
@ -120,13 +119,13 @@ func (e *ExecutionReportEvent) Order() (*types.Order, error) {
ClientOrderID: e.ClientOrderID, ClientOrderID: e.ClientOrderID,
Side: toGlobalSideType(binance.SideType(e.Side)), Side: toGlobalSideType(binance.SideType(e.Side)),
Type: toGlobalOrderType(binance.OrderType(e.OrderType)), Type: toGlobalOrderType(binance.OrderType(e.OrderType)),
Quantity: util.MustParseFloat(e.OrderQuantity), Quantity: e.OrderQuantity.Float64(),
Price: util.MustParseFloat(e.OrderPrice), Price: e.OrderPrice.Float64(),
TimeInForce: e.TimeInForce, TimeInForce: e.TimeInForce,
}, },
OrderID: uint64(e.OrderID), OrderID: uint64(e.OrderID),
Status: toGlobalOrderStatus(binance.OrderStatusType(e.CurrentOrderStatus)), Status: toGlobalOrderStatus(binance.OrderStatusType(e.CurrentOrderStatus)),
ExecutedQuantity: util.MustParseFloat(e.CumulativeFilledQuantity), ExecutedQuantity: e.CumulativeFilledQuantity.Float64(),
CreationTime: types.Time(orderCreationTime), CreationTime: types.Time(orderCreationTime),
}, nil }, nil
} }
@ -143,13 +142,13 @@ func (e *ExecutionReportEvent) Trade() (*types.Trade, error) {
Symbol: e.Symbol, Symbol: e.Symbol,
OrderID: uint64(e.OrderID), OrderID: uint64(e.OrderID),
Side: toGlobalSideType(binance.SideType(e.Side)), Side: toGlobalSideType(binance.SideType(e.Side)),
Price: util.MustParseFloat(e.LastExecutedPrice), Price: e.LastExecutedPrice.Float64(),
Quantity: util.MustParseFloat(e.LastExecutedQuantity), Quantity: e.LastExecutedQuantity.Float64(),
QuoteQuantity: util.MustParseFloat(e.LastQuoteAssetTransactedQuantity), QuoteQuantity: e.LastQuoteAssetTransactedQuantity.Float64(),
IsBuyer: e.Side == "BUY", IsBuyer: e.Side == "BUY",
IsMaker: e.IsMaker, IsMaker: e.IsMaker,
Time: types.Time(tt), Time: types.Time(tt),
Fee: util.MustParseFloat(e.CommissionAmount), Fee: e.CommissionAmount.Float64(),
FeeCurrency: e.CommissionAsset, FeeCurrency: e.CommissionAsset,
}, nil }, nil
} }
@ -264,12 +263,12 @@ func parseWebSocketEvent(message []byte) (interface{}, error) {
return nil, err return nil, err
} }
//res, err := json.MarshalIndent(message, "", " ") // res, err := json.MarshalIndent(message, "", " ")
//if err != nil { // if err != nil {
// log.Fatal(err) // log.Fatal(err)
//} // }
//str := strings.ReplaceAll(string(res), "\\", "") // str := strings.ReplaceAll(string(res), "\\", "")
//fmt.Println(str) // fmt.Println(str)
eventType := string(val.GetStringBytes("e")) eventType := string(val.GetStringBytes("e"))
if eventType == "" && IsBookTicker(val) { if eventType == "" && IsBookTicker(val) {
eventType = "bookticker" eventType = "bookticker"
@ -348,7 +347,7 @@ func parseWebSocketEvent(message []byte) (interface{}, error) {
} }
// IsBookTicker document ref :https://binance-docs.github.io/apidocs/spot/en/#individual-symbol-book-ticker-streams // IsBookTicker document ref :https://binance-docs.github.io/apidocs/spot/en/#individual-symbol-book-ticker-streams
//use key recognition because there's no identify in the content. // use key recognition because there's no identify in the content.
func IsBookTicker(val *fastjson.Value) bool { func IsBookTicker(val *fastjson.Value) bool {
return !val.Exists("e") && val.Exists("u") && return !val.Exists("e") && val.Exists("u") &&
val.Exists("s") && val.Exists("b") && val.Exists("s") && val.Exists("b") &&
@ -611,20 +610,20 @@ type OrderTrade struct {
Side string `json:"S"` Side string `json:"S"`
OrderType string `json:"o"` OrderType string `json:"o"`
TimeInForce string `json:"f"` TimeInForce string `json:"f"`
OriginalQuantity string `json:"q"` OriginalQuantity fixedpoint.Value `json:"q"`
OriginalPrice string `json:"p"` OriginalPrice fixedpoint.Value `json:"p"`
AveragePrice string `json:"ap"` AveragePrice fixedpoint.Value `json:"ap"`
StopPrice string `json:"sp"` StopPrice fixedpoint.Value `json:"sp"`
CurrentExecutionType string `json:"x"` CurrentExecutionType string `json:"x"`
CurrentOrderStatus string `json:"X"` CurrentOrderStatus string `json:"X"`
OrderId int64 `json:"i"` OrderId int64 `json:"i"`
OrderLastFilledQuantity string `json:"l"` OrderLastFilledQuantity fixedpoint.Value `json:"l"`
OrderFilledAccumulatedQuantity string `json:"z"` OrderFilledAccumulatedQuantity fixedpoint.Value `json:"z"`
LastFilledPrice string `json:"L"` LastFilledPrice fixedpoint.Value `json:"L"`
CommissionAmount string `json:"n"` CommissionAmount fixedpoint.Value `json:"n"`
CommissionAsset string `json:"N"` CommissionAsset string `json:"N"`
OrderTradeTime int64 `json:"T"` OrderTradeTime int64 `json:"T"`
@ -709,13 +708,13 @@ func (e *OrderTradeUpdateEvent) OrderFutures() (*types.Order, error) {
ClientOrderID: e.OrderTrade.ClientOrderID, ClientOrderID: e.OrderTrade.ClientOrderID,
Side: toGlobalFuturesSideType(futures.SideType(e.OrderTrade.Side)), Side: toGlobalFuturesSideType(futures.SideType(e.OrderTrade.Side)),
Type: toGlobalFuturesOrderType(futures.OrderType(e.OrderTrade.OrderType)), Type: toGlobalFuturesOrderType(futures.OrderType(e.OrderTrade.OrderType)),
Quantity: util.MustParseFloat(e.OrderTrade.OriginalQuantity), Quantity: e.OrderTrade.OriginalQuantity.Float64(),
Price: util.MustParseFloat(e.OrderTrade.OriginalPrice), Price: e.OrderTrade.OriginalPrice.Float64(),
TimeInForce: e.OrderTrade.TimeInForce, TimeInForce: e.OrderTrade.TimeInForce,
}, },
OrderID: uint64(e.OrderTrade.OrderId), OrderID: uint64(e.OrderTrade.OrderId),
Status: toGlobalFuturesOrderStatus(futures.OrderStatusType(e.OrderTrade.CurrentOrderStatus)), Status: toGlobalFuturesOrderStatus(futures.OrderStatusType(e.OrderTrade.CurrentOrderStatus)),
ExecutedQuantity: util.MustParseFloat(e.OrderTrade.OrderFilledAccumulatedQuantity), ExecutedQuantity: e.OrderTrade.OrderFilledAccumulatedQuantity.Float64(),
CreationTime: types.Time(orderCreationTime), CreationTime: types.Time(orderCreationTime),
}, nil }, nil
} }
@ -757,12 +756,12 @@ type BookTickerEvent struct {
BuySize fixedpoint.Value `json:"B"` BuySize fixedpoint.Value `json:"B"`
Sell fixedpoint.Value `json:"a"` Sell fixedpoint.Value `json:"a"`
SellSize fixedpoint.Value `json:"A"` SellSize fixedpoint.Value `json:"A"`
//"u":400900217, // order book updateId // "u":400900217, // order book updateId
//"s":"BNBUSDT", // symbol // "s":"BNBUSDT", // symbol
//"b":"25.35190000", // best bid price // "b":"25.35190000", // best bid price
//"B":"31.21000000", // best bid qty // "B":"31.21000000", // best bid qty
//"a":"25.36520000", // best ask price // "a":"25.36520000", // best ask price
//"A":"40.66000000" // best ask qty // "A":"40.66000000" // best ask qty
} }
func (k *BookTickerEvent) BookTicker() types.BookTicker { func (k *BookTickerEvent) BookTicker() types.BookTicker {

View File

@ -5,6 +5,8 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/fixedpoint"
) )
var jsCommentTrimmer = regexp.MustCompile("(?m)//.*$") var jsCommentTrimmer = regexp.MustCompile("(?m)//.*$")
@ -186,15 +188,15 @@ func TestParseOrderUpdate(t *testing.T) {
assert.Equal(t, executionReport.OrderType, "LIMIT") assert.Equal(t, executionReport.OrderType, "LIMIT")
assert.Equal(t, executionReport.OrderCreationTime, int64(1499405658657)) assert.Equal(t, executionReport.OrderCreationTime, int64(1499405658657))
assert.Equal(t, executionReport.TimeInForce, "GTC") assert.Equal(t, executionReport.TimeInForce, "GTC")
assert.Equal(t, executionReport.IcebergQuantity, "0.00000000") assert.Equal(t, executionReport.IcebergQuantity, fixedpoint.MustNewFromString("0.00000000"))
assert.Equal(t, executionReport.OrderQuantity, "1.00000000") assert.Equal(t, executionReport.OrderQuantity, fixedpoint.MustNewFromString("1.00000000"))
assert.Equal(t, executionReport.QuoteOrderQuantity, "2.0") assert.Equal(t, executionReport.QuoteOrderQuantity, fixedpoint.MustNewFromString("2.0"))
assert.Equal(t, executionReport.OrderPrice, "0.10264410") assert.Equal(t, executionReport.OrderPrice, fixedpoint.MustNewFromString("0.10264410"))
assert.Equal(t, executionReport.StopPrice, "0.222") assert.Equal(t, executionReport.StopPrice, fixedpoint.MustNewFromString("0.222"))
assert.Equal(t, executionReport.IsOnBook, true) assert.Equal(t, executionReport.IsOnBook, true)
assert.Equal(t, executionReport.IsMaker, false) assert.Equal(t, executionReport.IsMaker, false)
assert.Equal(t, executionReport.Ignore, true) assert.Equal(t, executionReport.Ignore, true)
assert.Equal(t, executionReport.CommissionAmount, "0") assert.Equal(t, executionReport.CommissionAmount, fixedpoint.MustNewFromString("0"))
assert.Equal(t, executionReport.CommissionAsset, "") assert.Equal(t, executionReport.CommissionAsset, "")
assert.Equal(t, executionReport.CurrentExecutionType, "NEW") assert.Equal(t, executionReport.CurrentExecutionType, "NEW")
assert.Equal(t, executionReport.CurrentOrderStatus, "NEW") assert.Equal(t, executionReport.CurrentOrderStatus, "NEW")
@ -202,11 +204,11 @@ func TestParseOrderUpdate(t *testing.T) {
assert.Equal(t, executionReport.Ignored, int64(8641984)) assert.Equal(t, executionReport.Ignored, int64(8641984))
assert.Equal(t, executionReport.TradeID, int64(-1)) assert.Equal(t, executionReport.TradeID, int64(-1))
assert.Equal(t, executionReport.TransactionTime, int64(1499405658657)) assert.Equal(t, executionReport.TransactionTime, int64(1499405658657))
assert.Equal(t, executionReport.LastExecutedQuantity, "0.00000000") assert.Equal(t, executionReport.LastExecutedQuantity, fixedpoint.MustNewFromString("0.00000000"))
assert.Equal(t, executionReport.LastExecutedPrice, "0.00000001") assert.Equal(t, executionReport.LastExecutedPrice, fixedpoint.MustNewFromString("0.00000001"))
assert.Equal(t, executionReport.CumulativeFilledQuantity, "0.00000000") assert.Equal(t, executionReport.CumulativeFilledQuantity, fixedpoint.MustNewFromString("0.00000000"))
assert.Equal(t, executionReport.CumulativeQuoteAssetTransactedQuantity, "0.1") assert.Equal(t, executionReport.CumulativeQuoteAssetTransactedQuantity, fixedpoint.MustNewFromString("0.1"))
assert.Equal(t, executionReport.LastQuoteAssetTransactedQuantity, "0.00000000") assert.Equal(t, executionReport.LastQuoteAssetTransactedQuantity, fixedpoint.MustNewFromString("0.00000000"))
orderUpdate, err := executionReport.Order() orderUpdate, err := executionReport.Order()
assert.NoError(t, err) assert.NoError(t, err)
@ -395,12 +397,12 @@ func TestParseOrderFuturesUpdate(t *testing.T) {
assert.Equal(t, orderTradeEvent.OrderTrade.OrderType, "MARKET") assert.Equal(t, orderTradeEvent.OrderTrade.OrderType, "MARKET")
assert.Equal(t, orderTradeEvent.Time, int64(1639933384763)) assert.Equal(t, orderTradeEvent.Time, int64(1639933384763))
assert.Equal(t, orderTradeEvent.OrderTrade.OrderTradeTime, int64(1639933384755)) assert.Equal(t, orderTradeEvent.OrderTrade.OrderTradeTime, int64(1639933384755))
assert.Equal(t, orderTradeEvent.OrderTrade.OriginalQuantity, "0.001") assert.Equal(t, orderTradeEvent.OrderTrade.OriginalQuantity, fixedpoint.MustNewFromString("0.001"))
assert.Equal(t, orderTradeEvent.OrderTrade.OrderLastFilledQuantity, "0.001") assert.Equal(t, orderTradeEvent.OrderTrade.OrderLastFilledQuantity, fixedpoint.MustNewFromString("0.001"))
assert.Equal(t, orderTradeEvent.OrderTrade.OrderFilledAccumulatedQuantity, "0.001") assert.Equal(t, orderTradeEvent.OrderTrade.OrderFilledAccumulatedQuantity, fixedpoint.MustNewFromString("0.001"))
assert.Equal(t, orderTradeEvent.OrderTrade.CurrentExecutionType, "TRADE") assert.Equal(t, orderTradeEvent.OrderTrade.CurrentExecutionType, "TRADE")
assert.Equal(t, orderTradeEvent.OrderTrade.CurrentOrderStatus, "FILLED") assert.Equal(t, orderTradeEvent.OrderTrade.CurrentOrderStatus, "FILLED")
assert.Equal(t, orderTradeEvent.OrderTrade.LastFilledPrice, "47202.40") assert.Equal(t, orderTradeEvent.OrderTrade.LastFilledPrice, fixedpoint.MustNewFromString("47202.40"))
assert.Equal(t, orderTradeEvent.OrderTrade.OrderId, int64(38541728873)) assert.Equal(t, orderTradeEvent.OrderTrade.OrderId, int64(38541728873))
assert.Equal(t, orderTradeEvent.OrderTrade.TradeId, int64(1741505949)) assert.Equal(t, orderTradeEvent.OrderTrade.TradeId, int64(1741505949))