queryOrder() and test for it

This commit is contained in:
Alan.sung 2023-08-11 09:28:58 +08:00
parent 1c5d2dc759
commit ea5b45bfe4
6 changed files with 106 additions and 56 deletions

1
go.sum
View File

@ -1000,7 +1000,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.0.0-20190226202314-149afe6ec0b6/go.mod h1:jevfED4GnIEnJrWW55YmY9DMhajHcnkqVnEXmEtMyNI= gonum.org/v1/gonum v0.0.0-20190226202314-149afe6ec0b6/go.mod h1:jevfED4GnIEnJrWW55YmY9DMhajHcnkqVnEXmEtMyNI=
gonum.org/v1/gonum v0.0.0-20190902003836-43865b531bee/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/gonum v0.0.0-20190902003836-43865b531bee/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=

View File

@ -2,6 +2,7 @@ package okex
import ( import (
"fmt" "fmt"
"hash/fnv"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@ -172,10 +173,7 @@ func toGlobalOrders(orderDetails []okexapi.OrderDetails) ([]types.Order, error)
side := types.SideType(strings.ToUpper(string(orderDetail.Side))) side := types.SideType(strings.ToUpper(string(orderDetail.Side)))
orderType, err := toGlobalOrderType(orderDetail.OrderType) orderType := toGlobalOrderType(orderDetail.OrderType)
if err != nil {
return orders, err
}
timeInForce := types.TimeInForceGTC timeInForce := types.TimeInForceGTC
switch orderDetail.OrderType { switch orderDetail.OrderType {
@ -186,10 +184,7 @@ func toGlobalOrders(orderDetails []okexapi.OrderDetails) ([]types.Order, error)
} }
orderStatus, err := toGlobalOrderStatus(orderDetail.State) orderStatus := toGlobalOrderStatus(orderDetail.State)
if err != nil {
return orders, err
}
isWorking := false isWorking := false
switch orderStatus { switch orderStatus {
@ -258,16 +253,21 @@ func toLocalOrderType(orderType types.OrderType) (okexapi.OrderType, error) {
func toGlobalOrderType(orderType okexapi.OrderType) types.OrderType { func toGlobalOrderType(orderType okexapi.OrderType) types.OrderType {
switch orderType { switch orderType {
case okexapi.OrderTypeMarket: case okexapi.OrderTypeMarket, okexapi.OrderTypeMarketMakerProtection:
return types.OrderTypeMarket return types.OrderTypeMarket
case okexapi.OrderTypeLimit: case okexapi.OrderTypeLimit:
return types.OrderTypeLimit return types.OrderTypeLimit
case okexapi.OrderTypePostOnly: case okexapi.OrderTypePostOnly:
return types.OrderTypeLimitMaker return types.OrderTypeLimitMaker
case okexapi.OrderTypeFOK:
return types.OrderTypeFillOrKill case okexapi.OrderTypeIOC, okexapi.OrderTypeFOK:
case okexapi.OrderTypeIOC: return types.OrderTypeMarket
return types.OrderTypeIOC
case okexapi.OrderTypeMarektMakerProtectionPostOnly:
return types.OrderTypeLimitMaker
default: default:
log.Errorf("unsupported order type: %v", orderType) log.Errorf("unsupported order type: %v", orderType)
return "" return ""
@ -280,3 +280,34 @@ func toLocalInterval(src string) string {
return strings.ToUpper(w) return strings.ToUpper(w)
}) })
} }
func hashStringID(s string) uint64 {
h := fnv.New64a()
h.Write([]byte(s))
return h.Sum64()
}
func toGlobalOrder(okexOrder *okexapi.OrderDetails, isMargin bool) (*types.Order, error) {
timeInForce := types.TimeInForceFOK
if okexOrder.OrderType == okexapi.OrderTypeIOC {
timeInForce = types.TimeInForceIOC
}
return &types.Order{
SubmitOrder: types.SubmitOrder{
ClientOrderID: okexOrder.ClientOrderID,
Symbol: okexOrder.InstrumentID,
Side: types.SideType(okexOrder.Side),
Type: toGlobalOrderType(okexOrder.OrderType),
Quantity: okexOrder.Quantity,
Price: okexOrder.Price,
TimeInForce: types.TimeInForce(timeInForce),
},
Exchange: types.ExchangeOKEx,
OrderID: hashStringID(okexOrder.OrderID),
Status: toGlobalOrderStatus(okexOrder.State),
ExecutedQuantity: okexOrder.FilledQuantity,
CreationTime: types.Time(okexOrder.CreationTime),
UpdateTime: types.Time(okexOrder.UpdateTime),
IsMargin: isMargin,
}, nil
}

View File

@ -351,37 +351,18 @@ func (e *Exchange) QueryOrder(ctx context.Context, q types.OrderQuery) (*types.O
req.InstrumentID(q.Symbol). req.InstrumentID(q.Symbol).
OrderID(q.OrderID). OrderID(q.OrderID).
ClientOrderID(q.ClientOrderID) ClientOrderID(q.ClientOrderID)
orderID, err := strconv.ParseInt(q.OrderID, 10, 64)
if err != nil {
return nil, err
}
var order *okexapi.OrderDetails var order *okexapi.OrderDetails
order, err = req.Do(ctx) order, err := req.Do(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
timeInForce := types.TimeInForceFOK isMargin := false
if order.OrderType == okexapi.OrderTypeIOC { if order.InstrumentType == string(okexapi.InstrumentTypeMARGIN) {
timeInForce = types.TimeInForceIOC isMargin = true
} }
return &types.Order{
SubmitOrder: types.SubmitOrder{ return toGlobalOrder(order, isMargin)
ClientOrderID: order.ClientOrderID,
Symbol: order.InstrumentID,
Side: types.SideType(order.Side),
Type: toGlobalOrderType(order.OrderType),
Quantity: order.Quantity,
Price: order.Price,
TimeInForce: types.TimeInForce(timeInForce),
},
Exchange: types.ExchangeOKEx,
OrderID: uint64(orderID),
Status: toGlobalOrderStatus(order.State),
ExecutedQuantity: order.FilledQuantity,
CreationTime: types.Time(order.CreationTime),
UpdateTime: types.Time(order.UpdateTime),
}, nil
} }

View File

@ -38,6 +38,8 @@ const (
OrderTypePostOnly OrderType = "post_only" OrderTypePostOnly OrderType = "post_only"
OrderTypeFOK OrderType = "fok" OrderTypeFOK OrderType = "fok"
OrderTypeIOC OrderType = "ioc" OrderTypeIOC OrderType = "ioc"
OrderTypeMarketMakerProtection OrderType = "mmp"
OrderTypeMarektMakerProtectionPostOnly OrderType = "mmp_and_post_only"
) )
type InstrumentType string type InstrumentType string
@ -47,6 +49,7 @@ const (
InstrumentTypeSwap InstrumentType = "SWAP" InstrumentTypeSwap InstrumentType = "SWAP"
InstrumentTypeFutures InstrumentType = "FUTURES" InstrumentTypeFutures InstrumentType = "FUTURES"
InstrumentTypeOption InstrumentType = "OPTION" InstrumentTypeOption InstrumentType = "OPTION"
InstrumentTypeMARGIN InstrumentType = "MARGIN"
) )
type OrderState string type OrderState string

View File

@ -63,16 +63,16 @@ func TestClient_PlaceOrderRequest(t *testing.T) {
req := srv.NewPlaceOrderRequest() req := srv.NewPlaceOrderRequest()
order, err := req. order, err := req.
InstrumentID("XTZ-BTC"). InstrumentID("BTC-USDT").
TradeMode("cash"). TradeMode("cash").
Side(SideTypeSell). Side(SideTypeBuy).
OrderType(OrderTypeLimit). OrderType(OrderTypeLimit).
Price("0.001"). Price("15000").
Quantity("0.01"). Quantity("0.0001").
Do(ctx) Do(ctx)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEmpty(t, order) assert.NotEmpty(t, order)
t.Logf("order: %+v", order) // Right now account has no money t.Logf("place order: %+v", order)
} }
func TestClient_GetPendingOrderRequest(t *testing.T) { func TestClient_GetPendingOrderRequest(t *testing.T) {
@ -83,12 +83,12 @@ func TestClient_GetPendingOrderRequest(t *testing.T) {
odr_type := []string{string(OrderTypeLimit), string(OrderTypeIOC)} odr_type := []string{string(OrderTypeLimit), string(OrderTypeIOC)}
pending_order, err := req. pending_order, err := req.
InstrumentID("XTZ-BTC"). InstrumentID("BTC-USDT").
OrderTypes(odr_type). OrderTypes(odr_type).
Do(ctx) Do(ctx)
assert.NoError(t, err) assert.NoError(t, err)
assert.Empty(t, pending_order) assert.NotEmpty(t, pending_order)
t.Logf("order: %+v", pending_order) t.Logf("pending order: %+v", pending_order)
} }
func TestClient_GetOrderDetailsRequest(t *testing.T) { func TestClient_GetOrderDetailsRequest(t *testing.T) {
@ -99,9 +99,9 @@ func TestClient_GetOrderDetailsRequest(t *testing.T) {
orderDetail, err := req. orderDetail, err := req.
InstrumentID("BTC-USDT"). InstrumentID("BTC-USDT").
OrderID("xxx-test-order-id"). OrderID("609869603774656544").
Do(ctx) Do(ctx)
assert.Error(t, err) // Right now account has no orders assert.NoError(t, err)
assert.Empty(t, orderDetail) assert.NotEmpty(t, orderDetail)
t.Logf("err: %+v", err) t.Logf("order detail: %+v", orderDetail)
} }

View File

@ -0,0 +1,36 @@
package okex
import (
"context"
"os"
"testing"
"github.com/c9s/bbgo/pkg/types"
"github.com/stretchr/testify/assert"
)
func Test_QueryOrder(t *testing.T) {
key := os.Getenv("OKEX_API_KEY")
secret := os.Getenv("OKEX_API_SECRET")
passphrase := os.Getenv("OKEX_API_PASSPHRASE")
if len(key) == 0 && len(secret) == 0 {
t.Skip("api key/secret are not configured")
return
}
if len(passphrase) == 0 {
t.Skip("passphrase are not configured")
return
}
e := New(key, secret, passphrase)
queryOrder := types.OrderQuery{
Symbol: "BTC-USDT",
OrderID: "609869603774656544",
}
orderDetail, err := e.QueryOrder(context.Background(), queryOrder)
if assert.NoError(t, err) {
assert.NotEmpty(t, orderDetail)
}
t.Logf("order detail: %+v", orderDetail)
}