mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
pkg/exchange: refactor query closed order
This commit is contained in:
parent
03449d0c9a
commit
fa145a3622
|
@ -149,7 +149,7 @@ func toGlobalTrades(orderDetails []okexapi.OrderDetails) ([]types.Trade, error)
|
|||
return trades, nil
|
||||
}
|
||||
|
||||
func openOrderToGlobal(order *okexapi.OpenOrder) (*types.Order, error) {
|
||||
func orderDetailToGlobal(order *okexapi.OrderDetail) (*types.Order, error) {
|
||||
side := toGlobalSide(order.Side)
|
||||
|
||||
orderType, err := toGlobalOrderType(order.OrderType)
|
||||
|
|
|
@ -11,13 +11,13 @@ import (
|
|||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func Test_openOrderToGlobal(t *testing.T) {
|
||||
func Test_orderDetailToGlobal(t *testing.T) {
|
||||
var (
|
||||
assert = assert.New(t)
|
||||
|
||||
orderId = 665576973905014786
|
||||
// {"accFillSz":"0","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"","cTime":"1704957916401","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"0","feeCcy":"USDT","fillPx":"","fillSz":"0","fillTime":"","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665576973905014786","ordType":"limit","pnl":"0","posSide":"net","px":"48174.5","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"live","stpId":"","stpMode":"","sz":"0.00001","tag":"","tdMode":"cash","tgtCcy":"","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"","uTime":"1704957916401"}
|
||||
openOrder = &okexapi.OpenOrder{
|
||||
openOrder = &okexapi.OrderDetail{
|
||||
AccumulatedFillSize: fixedpoint.NewFromFloat(0),
|
||||
AvgPrice: fixedpoint.NewFromFloat(0),
|
||||
CreatedTime: types.NewMillisecondTimestampFromInt(1704957916401),
|
||||
|
@ -62,7 +62,7 @@ func Test_openOrderToGlobal(t *testing.T) {
|
|||
)
|
||||
|
||||
t.Run("succeeds", func(t *testing.T) {
|
||||
order, err := openOrderToGlobal(openOrder)
|
||||
order, err := orderDetailToGlobal(openOrder)
|
||||
assert.NoError(err)
|
||||
assert.Equal(expOrder, order)
|
||||
})
|
||||
|
@ -70,14 +70,14 @@ func Test_openOrderToGlobal(t *testing.T) {
|
|||
t.Run("unexpected order status", func(t *testing.T) {
|
||||
newOrder := *openOrder
|
||||
newOrder.State = "xxx"
|
||||
_, err := openOrderToGlobal(&newOrder)
|
||||
_, err := orderDetailToGlobal(&newOrder)
|
||||
assert.ErrorContains(err, "xxx")
|
||||
})
|
||||
|
||||
t.Run("unexpected order type", func(t *testing.T) {
|
||||
newOrder := *openOrder
|
||||
newOrder.OrderType = "xxx"
|
||||
_, err := openOrderToGlobal(&newOrder)
|
||||
_, err := orderDetailToGlobal(&newOrder)
|
||||
assert.ErrorContains(err, "xxx")
|
||||
})
|
||||
|
||||
|
|
|
@ -24,13 +24,14 @@ var (
|
|||
marketDataLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 5)
|
||||
orderRateLimiter = rate.NewLimiter(rate.Every(300*time.Millisecond), 5)
|
||||
|
||||
queryMarketLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
|
||||
queryTickerLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
|
||||
queryTickersLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
|
||||
queryAccountLimiter = rate.NewLimiter(rate.Every(200*time.Millisecond), 5)
|
||||
placeOrderLimiter = rate.NewLimiter(rate.Every(30*time.Millisecond), 30)
|
||||
batchCancelOrderLimiter = rate.NewLimiter(rate.Every(5*time.Millisecond), 200)
|
||||
queryOpenOrderLimiter = rate.NewLimiter(rate.Every(30*time.Millisecond), 30)
|
||||
queryMarketLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
|
||||
queryTickerLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
|
||||
queryTickersLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
|
||||
queryAccountLimiter = rate.NewLimiter(rate.Every(200*time.Millisecond), 5)
|
||||
placeOrderLimiter = rate.NewLimiter(rate.Every(30*time.Millisecond), 30)
|
||||
batchCancelOrderLimiter = rate.NewLimiter(rate.Every(5*time.Millisecond), 200)
|
||||
queryOpenOrderLimiter = rate.NewLimiter(rate.Every(30*time.Millisecond), 30)
|
||||
queryClosedOrderRateLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -40,6 +41,8 @@ const (
|
|||
PlatformToken = "OKB"
|
||||
|
||||
defaultQueryLimit = 100
|
||||
|
||||
maxHistoricalDataQueryPeriod = 90 * 24 * time.Hour
|
||||
)
|
||||
|
||||
var log = logrus.WithFields(logrus.Fields{
|
||||
|
@ -315,7 +318,7 @@ func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders [
|
|||
}
|
||||
|
||||
for _, o := range openOrders {
|
||||
o, err := openOrderToGlobal(&o)
|
||||
o, err := orderDetailToGlobal(&o.OrderDetail)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert order, err: %v", err)
|
||||
}
|
||||
|
@ -488,27 +491,32 @@ func (e *Exchange) QueryOrderTrades(ctx context.Context, q types.OrderQuery) ([]
|
|||
/*
|
||||
QueryClosedOrders can query closed orders in last 3 months, there are no time interval limitations, as long as until >= since.
|
||||
Please Use lastOrderID as cursor, only return orders later than that order, that order is not included.
|
||||
If you want to query orders by time range, please just pass since and until.
|
||||
If you want to query by cursor, please pass lastOrderID.
|
||||
Because it gets the correct response even when you pass all parameters with the right time interval and invalid lastOrderID, like 0.
|
||||
Time interval boundary unit is second.
|
||||
since is inclusive, ex. order created in 1694155903, get response if query since 1694155903, get empty if query since 1694155904
|
||||
until is not inclusive, ex. order created in 1694155903, get response if query until 1694155904, get empty if query until 1694155903
|
||||
If you want to query all orders within a large time range (e.g. total orders > 100), we recommend using batch.ClosedOrderBatchQuery.
|
||||
|
||||
** since and until are inclusive, you can include the lastTradeId as well. **
|
||||
*/
|
||||
func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since, until time.Time, lastOrderID uint64) ([]types.Order, error) {
|
||||
func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since, until time.Time, lastOrderID uint64) (orders []types.Order, err error) {
|
||||
if symbol == "" {
|
||||
return nil, ErrSymbolRequired
|
||||
}
|
||||
|
||||
if err := orderRateLimiter.Wait(ctx); err != nil {
|
||||
return nil, fmt.Errorf("query closed order rate limiter wait error: %w", err)
|
||||
newSince := since
|
||||
now := time.Now()
|
||||
|
||||
if time.Since(newSince) > maxHistoricalDataQueryPeriod {
|
||||
newSince = now.Add(-maxHistoricalDataQueryPeriod)
|
||||
log.Warnf("!!!OKX EXCHANGE API NOTICE!!! The closed order API cannot query data beyond 90 days from the current date, update %s -> %s", since, newSince)
|
||||
}
|
||||
if until.Before(newSince) {
|
||||
log.Warnf("!!!OKX EXCHANGE API NOTICE!!! The 'until' comes before 'since', update until to now(%s -> %s).", until, now)
|
||||
until = now
|
||||
}
|
||||
if until.Sub(newSince) > maxHistoricalDataQueryPeriod {
|
||||
return nil, fmt.Errorf("the start time %s and end time %s cannot exceed 90 days", newSince, until)
|
||||
}
|
||||
|
||||
var lastOrder string
|
||||
if lastOrderID <= 0 {
|
||||
lastOrder = ""
|
||||
} else {
|
||||
lastOrder = strconv.FormatUint(lastOrderID, 10)
|
||||
if err := queryClosedOrderRateLimiter.Wait(ctx); err != nil {
|
||||
return nil, fmt.Errorf("query closed order rate limiter wait error: %w", err)
|
||||
}
|
||||
|
||||
res, err := e.client.NewGetOrderHistoryRequest().
|
||||
|
@ -516,17 +524,15 @@ func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since,
|
|||
StartTime(since).
|
||||
EndTime(until).
|
||||
Limit(defaultQueryLimit).
|
||||
Before(lastOrder).
|
||||
Before(strconv.FormatUint(lastOrderID, 10)).
|
||||
Do(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to call get order histories error: %w", err)
|
||||
}
|
||||
|
||||
var orders []types.Order
|
||||
|
||||
for _, order := range res {
|
||||
o, err2 := toGlobalOrder(&order)
|
||||
o, err2 := orderDetailToGlobal(&order)
|
||||
if err2 != nil {
|
||||
err = multierr.Append(err, err2)
|
||||
continue
|
||||
|
|
|
@ -3,12 +3,13 @@ package okexapi
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"time"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/testutil"
|
||||
)
|
||||
|
@ -160,6 +161,56 @@ func TestClient_OpenOrdersRequest(t *testing.T) {
|
|||
t.Log(orders)
|
||||
}
|
||||
|
||||
func TestClient_OrderHistoryWithBeforeId(t *testing.T) {
|
||||
client := getTestClientOrSkip(t)
|
||||
ctx := context.Background()
|
||||
|
||||
orders := []OrderDetail{}
|
||||
beforeId := int64(0)
|
||||
for {
|
||||
//>> [{"accFillSz":"0.00001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"48174.5","cTime":"1704957916401","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.000385396","feeCcy":"USDT","fillPx":"48174.5","fillSz":"0.00001","fillTime":"1704983881118","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665576973905014786","ordType":"limit","pnl":"0","posSide":"","px":"48174.5","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00001","tag":"","tdMode":"cash","tgtCcy":"","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"472610696","uTime":"1704983881135"}]
|
||||
//>> [{"accFillSz":"0.00001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"48074.5","cTime":"1704957905283","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.000384596","feeCcy":"USDT","fillPx":"48074.5","fillSz":"0.00001","fillTime":"1704983824237","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665576927272742919","ordType":"limit","pnl":"0","posSide":"","px":"48074.5","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00001","tag":"","tdMode":"cash","tgtCcy":"","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"472601591","uTime":"1704983824240"}]
|
||||
//>> [{"accFillSz":"0.00001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"48073.5","cTime":"1704957892896","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.000384588","feeCcy":"USDT","fillPx":"48073.5","fillSz":"0.00001","fillTime":"1704983824227","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665576875317899302","ordType":"limit","pnl":"0","posSide":"","px":"48073.5","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00001","tag":"","tdMode":"cash","tgtCcy":"","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"472601583","uTime":"1704983824230"}]
|
||||
//>> [{"accFillSz":"0.00016266","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45919.8","cTime":"1704852215160","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000016266","feeCcy":"BTC","fillPx":"45919.8","fillSz":"0.00016266","fillTime":"1704852215162","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665133630767091729","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00016266","tag":"","tdMode":"cash","tgtCcy":"base_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471113058","uTime":"1704852215163"}]
|
||||
//>> [{"accFillSz":"0.00087627","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45647.6","cTime":"1704850530651","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000087627","feeCcy":"BTC","fillPx":"45647.6","fillSz":"0.00087627","fillTime":"1704850530652","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665126565424254976","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"40","tag":"","tdMode":"cash","tgtCcy":"quote_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471105716","uTime":"1704850530654"}]
|
||||
//>> [{"accFillSz":"0.001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45661.3","cTime":"1704850506060","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.0456613","feeCcy":"USDT","fillPx":"45661.3","fillSz":"0.001","fillTime":"1704850506061","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665126462282125313","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.001","tag":"","tdMode":"cash","tgtCcy":"base_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471105593","uTime":"1704850506062"}]
|
||||
//>> [{"accFillSz":"0.00097361","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45743","cTime":"1704849690516","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000097361","feeCcy":"BTC","fillPx":"45743","fillSz":"0.00097361","fillTime":"1704849690517","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665123041642663944","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00097361","tag":"","tdMode":"cash","tgtCcy":"base_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471100149","uTime":"1704849690519"}]
|
||||
//>> [{"accFillSz":"0.00080894","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"46728.2","cTime":"1704789666800","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.037800310108","feeCcy":"USDT","fillPx":"46728.2","fillSz":"0.00080894","fillTime":"1704789666801","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"664871283930550273","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"37.8","tag":"","tdMode":"cash","tgtCcy":"quote_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"470288552","uTime":"1704789666803"}]
|
||||
//>> [{"accFillSz":"0.00085423","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"46825.3","cTime":"1704789220044","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000085423","feeCcy":"BTC","fillPx":"46825.3","fillSz":"0.00085423","fillTime":"1704789220045","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"664869410100072448","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"40","tag":"","tdMode":"cash","tgtCcy":"quote_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"470287675","uTime":"1704789220046"}]
|
||||
c := client.NewGetOrderHistoryRequest().InstrumentID("BTC-USDT").Limit(1).Before(fmt.Sprintf("%d", beforeId))
|
||||
res, err := c.Do(ctx)
|
||||
assert.NoError(t, err)
|
||||
if len(res) != 1 {
|
||||
break
|
||||
}
|
||||
orders = append(orders, res...)
|
||||
beforeId = int64(res[0].OrderId)
|
||||
}
|
||||
|
||||
t.Log(orders)
|
||||
}
|
||||
|
||||
func TestClient_OrderHistoryByTimeRange(t *testing.T) {
|
||||
client := getTestClientOrSkip(t)
|
||||
ctx := context.Background()
|
||||
|
||||
startTime := time.Date(2023, 7, 1, 0, 0, 0, 0, time.UTC)
|
||||
t.Log(time.Since(startTime))
|
||||
//>> [{"accFillSz":"0.00001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"48174.5","cTime":"1704957916401","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.000385396","feeCcy":"USDT","fillPx":"48174.5","fillSz":"0.00001","fillTime":"1704983881118","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665576973905014786","ordType":"limit","pnl":"0","posSide":"","px":"48174.5","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00001","tag":"","tdMode":"cash","tgtCcy":"","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"472610696","uTime":"1704983881135"}]
|
||||
//>> [{"accFillSz":"0.00001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"48074.5","cTime":"1704957905283","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.000384596","feeCcy":"USDT","fillPx":"48074.5","fillSz":"0.00001","fillTime":"1704983824237","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665576927272742919","ordType":"limit","pnl":"0","posSide":"","px":"48074.5","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00001","tag":"","tdMode":"cash","tgtCcy":"","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"472601591","uTime":"1704983824240"}]
|
||||
//>> [{"accFillSz":"0.00001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"48073.5","cTime":"1704957892896","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.000384588","feeCcy":"USDT","fillPx":"48073.5","fillSz":"0.00001","fillTime":"1704983824227","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665576875317899302","ordType":"limit","pnl":"0","posSide":"","px":"48073.5","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00001","tag":"","tdMode":"cash","tgtCcy":"","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"472601583","uTime":"1704983824230"}]
|
||||
//>> [{"accFillSz":"0.00016266","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45919.8","cTime":"1704852215160","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000016266","feeCcy":"BTC","fillPx":"45919.8","fillSz":"0.00016266","fillTime":"1704852215162","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665133630767091729","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00016266","tag":"","tdMode":"cash","tgtCcy":"base_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471113058","uTime":"1704852215163"}]
|
||||
//>> [{"accFillSz":"0.00087627","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45647.6","cTime":"1704850530651","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000087627","feeCcy":"BTC","fillPx":"45647.6","fillSz":"0.00087627","fillTime":"1704850530652","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665126565424254976","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"40","tag":"","tdMode":"cash","tgtCcy":"quote_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471105716","uTime":"1704850530654"}]
|
||||
//>> [{"accFillSz":"0.001","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45661.3","cTime":"1704850506060","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.0456613","feeCcy":"USDT","fillPx":"45661.3","fillSz":"0.001","fillTime":"1704850506061","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665126462282125313","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.001","tag":"","tdMode":"cash","tgtCcy":"base_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471105593","uTime":"1704850506062"}]
|
||||
//>> [{"accFillSz":"0.00097361","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"45743","cTime":"1704849690516","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000097361","feeCcy":"BTC","fillPx":"45743","fillSz":"0.00097361","fillTime":"1704849690517","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"665123041642663944","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"0.00097361","tag":"","tdMode":"cash","tgtCcy":"base_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"471100149","uTime":"1704849690519"}]
|
||||
//>> [{"accFillSz":"0.00080894","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"46728.2","cTime":"1704789666800","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.037800310108","feeCcy":"USDT","fillPx":"46728.2","fillSz":"0.00080894","fillTime":"1704789666801","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"664871283930550273","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"BTC","reduceOnly":"false","side":"sell","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"37.8","tag":"","tdMode":"cash","tgtCcy":"quote_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"470288552","uTime":"1704789666803"}]
|
||||
//>> [{"accFillSz":"0.00085423","algoClOrdId":"","algoId":"","attachAlgoClOrdId":"","attachAlgoOrds":[],"avgPx":"46825.3","cTime":"1704789220044","cancelSource":"","cancelSourceReason":"","category":"normal","ccy":"","clOrdId":"","fee":"-0.00000085423","feeCcy":"BTC","fillPx":"46825.3","fillSz":"0.00085423","fillTime":"1704789220045","instId":"BTC-USDT","instType":"SPOT","lever":"","ordId":"664869410100072448","ordType":"market","pnl":"0","posSide":"","px":"","pxType":"","pxUsd":"","pxVol":"","quickMgnType":"","rebate":"0","rebateCcy":"USDT","reduceOnly":"false","side":"buy","slOrdPx":"","slTriggerPx":"","slTriggerPxType":"","source":"","state":"filled","stpId":"","stpMode":"","sz":"40","tag":"","tdMode":"cash","tgtCcy":"quote_ccy","tpOrdPx":"","tpTriggerPx":"","tpTriggerPxType":"","tradeId":"470287675","uTime":"1704789220046"}]
|
||||
c := client.NewGetOrderHistoryRequest().InstrumentID("BTC-USDT").Limit(100).After("665576927272742919").StartTime(types.NewMillisecondTimestampFromInt(1704789220044).Time())
|
||||
res, err := c.Do(ctx)
|
||||
assert.NoError(t, err)
|
||||
t.Log(res)
|
||||
}
|
||||
|
||||
func TestClient_BatchCancelOrderRequest(t *testing.T) {
|
||||
client := getTestClientOrSkip(t)
|
||||
ctx := context.Background()
|
||||
|
|
|
@ -4,94 +4,25 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
|
||||
type OpenOrder struct {
|
||||
AccumulatedFillSize fixedpoint.Value `json:"accFillSz"`
|
||||
// If none is filled, it will return "".
|
||||
AvgPrice fixedpoint.Value `json:"avgPx"`
|
||||
CreatedTime types.MillisecondTimestamp `json:"cTime"`
|
||||
Category string `json:"category"`
|
||||
ClientOrderId string `json:"clOrdId"`
|
||||
Fee fixedpoint.Value `json:"fee"`
|
||||
FeeCurrency string `json:"feeCcy"`
|
||||
// Last filled time
|
||||
FillTime types.MillisecondTimestamp `json:"fillTime"`
|
||||
InstrumentID string `json:"instId"`
|
||||
InstrumentType InstrumentType `json:"instType"`
|
||||
OrderId types.StrInt64 `json:"ordId"`
|
||||
OrderType OrderType `json:"ordType"`
|
||||
Price fixedpoint.Value `json:"px"`
|
||||
Side SideType `json:"side"`
|
||||
State OrderState `json:"state"`
|
||||
Size fixedpoint.Value `json:"sz"`
|
||||
TargetCurrency string `json:"tgtCcy"`
|
||||
UpdatedTime types.MillisecondTimestamp `json:"uTime"`
|
||||
|
||||
// Margin currency
|
||||
// Only applicable to cross MARGIN orders in Single-currency margin.
|
||||
Currency string `json:"ccy"`
|
||||
TradeId string `json:"tradeId"`
|
||||
// Last filled price
|
||||
FillPrice fixedpoint.Value `json:"fillPx"`
|
||||
// Last filled quantity
|
||||
FillSize fixedpoint.Value `json:"fillSz"`
|
||||
// Leverage, from 0.01 to 125.
|
||||
// Only applicable to MARGIN/FUTURES/SWAP
|
||||
Lever string `json:"lever"`
|
||||
// Profit and loss, Applicable to orders which have a trade and aim to close position. It always is 0 in other conditions
|
||||
Pnl fixedpoint.Value `json:"pnl"`
|
||||
PositionSide string `json:"posSide"`
|
||||
// Options price in USDOnly applicable to options; return "" for other instrument types
|
||||
PriceUsd fixedpoint.Value `json:"pxUsd"`
|
||||
// Implied volatility of the options orderOnly applicable to options; return "" for other instrument types
|
||||
PriceVol fixedpoint.Value `json:"pxVol"`
|
||||
// Price type of options
|
||||
PriceType string `json:"pxType"`
|
||||
// Rebate amount, only applicable to spot and margin, the reward of placing orders from the platform (rebate)
|
||||
// given to user who has reached the specified trading level. If there is no rebate, this field is "".
|
||||
Rebate fixedpoint.Value `json:"rebate"`
|
||||
RebateCcy string `json:"rebateCcy"`
|
||||
// Client-supplied Algo ID when placing order attaching TP/SL.
|
||||
AttachAlgoClOrdId string `json:"attachAlgoClOrdId"`
|
||||
SlOrdPx fixedpoint.Value `json:"slOrdPx"`
|
||||
SlTriggerPx fixedpoint.Value `json:"slTriggerPx"`
|
||||
SlTriggerPxType string `json:"slTriggerPxType"`
|
||||
AttachAlgoOrds []interface{} `json:"attachAlgoOrds"`
|
||||
Source string `json:"source"`
|
||||
// Self trade prevention ID. Return "" if self trade prevention is not applicable
|
||||
StpId string `json:"stpId"`
|
||||
// Self trade prevention mode. Return "" if self trade prevention is not applicable
|
||||
StpMode string `json:"stpMode"`
|
||||
Tag string `json:"tag"`
|
||||
TradeMode string `json:"tdMode"`
|
||||
TpOrdPx fixedpoint.Value `json:"tpOrdPx"`
|
||||
TpTriggerPx fixedpoint.Value `json:"tpTriggerPx"`
|
||||
TpTriggerPxType string `json:"tpTriggerPxType"`
|
||||
ReduceOnly string `json:"reduceOnly"`
|
||||
QuickMgnType string `json:"quickMgnType"`
|
||||
AlgoClOrdId string `json:"algoClOrdId"`
|
||||
AlgoId string `json:"algoId"`
|
||||
OrderDetail
|
||||
QuickMgnType string `json:"quickMgnType"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/v5/trade/orders-pending" -type GetOpenOrdersRequest -responseDataType []OpenOrder
|
||||
type GetOpenOrdersRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
|
||||
instrumentID *string `param:"instId,query"`
|
||||
|
||||
instrumentType InstrumentType `param:"instType,query"`
|
||||
|
||||
orderType *OrderType `param:"ordType,query"`
|
||||
|
||||
state *OrderState `param:"state,query"`
|
||||
category *string `param:"category,query"`
|
||||
instrumentID *string `param:"instId,query"`
|
||||
orderType *OrderType `param:"ordType,query"`
|
||||
state *OrderState `param:"state,query"`
|
||||
category *string `param:"category,query"`
|
||||
// Pagination of data to return records earlier than the requested ordId
|
||||
after *string `param:"after,query"`
|
||||
// Pagination of data to return records newer than the requested ordId
|
||||
|
|
|
@ -4,9 +4,81 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/c9s/requestgen"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
//go:generate GetRequest -url "/api/v5/trade/orders-history-archive" -type GetOrderHistoryRequest -responseDataType .APIResponse
|
||||
//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
|
||||
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data
|
||||
type OrderDetail struct {
|
||||
AccumulatedFillSize fixedpoint.Value `json:"accFillSz"`
|
||||
// If none is filled, it will return "".
|
||||
AvgPrice fixedpoint.Value `json:"avgPx"`
|
||||
CreatedTime types.MillisecondTimestamp `json:"cTime"`
|
||||
Category string `json:"category"`
|
||||
ClientOrderId string `json:"clOrdId"`
|
||||
Fee fixedpoint.Value `json:"fee"`
|
||||
FeeCurrency string `json:"feeCcy"`
|
||||
// Last filled time
|
||||
FillTime types.MillisecondTimestamp `json:"fillTime"`
|
||||
InstrumentID string `json:"instId"`
|
||||
InstrumentType InstrumentType `json:"instType"`
|
||||
OrderId types.StrInt64 `json:"ordId"`
|
||||
OrderType OrderType `json:"ordType"`
|
||||
Price fixedpoint.Value `json:"px"`
|
||||
Side SideType `json:"side"`
|
||||
State OrderState `json:"state"`
|
||||
Size fixedpoint.Value `json:"sz"`
|
||||
TargetCurrency string `json:"tgtCcy"`
|
||||
UpdatedTime types.MillisecondTimestamp `json:"uTime"`
|
||||
|
||||
// Margin currency
|
||||
// Only applicable to cross MARGIN orders in Single-currency margin.
|
||||
Currency string `json:"ccy"`
|
||||
TradeId string `json:"tradeId"`
|
||||
// Last filled price
|
||||
FillPrice fixedpoint.Value `json:"fillPx"`
|
||||
// Last filled quantity
|
||||
FillSize fixedpoint.Value `json:"fillSz"`
|
||||
// Leverage, from 0.01 to 125.
|
||||
// Only applicable to MARGIN/FUTURES/SWAP
|
||||
Lever string `json:"lever"`
|
||||
// Profit and loss, Applicable to orders which have a trade and aim to close position. It always is 0 in other conditions
|
||||
Pnl fixedpoint.Value `json:"pnl"`
|
||||
PositionSide string `json:"posSide"`
|
||||
// Options price in USDOnly applicable to options; return "" for other instrument types
|
||||
PriceUsd fixedpoint.Value `json:"pxUsd"`
|
||||
// Implied volatility of the options orderOnly applicable to options; return "" for other instrument types
|
||||
PriceVol fixedpoint.Value `json:"pxVol"`
|
||||
// Price type of options
|
||||
PriceType string `json:"pxType"`
|
||||
// Rebate amount, only applicable to spot and margin, the reward of placing orders from the platform (rebate)
|
||||
// given to user who has reached the specified trading level. If there is no rebate, this field is "".
|
||||
Rebate fixedpoint.Value `json:"rebate"`
|
||||
RebateCcy string `json:"rebateCcy"`
|
||||
// Client-supplied Algo ID when placing order attaching TP/SL.
|
||||
AttachAlgoClOrdId string `json:"attachAlgoClOrdId"`
|
||||
SlOrdPx fixedpoint.Value `json:"slOrdPx"`
|
||||
SlTriggerPx fixedpoint.Value `json:"slTriggerPx"`
|
||||
SlTriggerPxType string `json:"slTriggerPxType"`
|
||||
AttachAlgoOrds []interface{} `json:"attachAlgoOrds"`
|
||||
Source string `json:"source"`
|
||||
// Self trade prevention ID. Return "" if self trade prevention is not applicable
|
||||
StpId string `json:"stpId"`
|
||||
// Self trade prevention mode. Return "" if self trade prevention is not applicable
|
||||
StpMode string `json:"stpMode"`
|
||||
Tag string `json:"tag"`
|
||||
TradeMode string `json:"tdMode"`
|
||||
TpOrdPx fixedpoint.Value `json:"tpOrdPx"`
|
||||
TpTriggerPx fixedpoint.Value `json:"tpTriggerPx"`
|
||||
TpTriggerPxType string `json:"tpTriggerPxType"`
|
||||
ReduceOnly string `json:"reduceOnly"`
|
||||
AlgoClOrdId string `json:"algoClOrdId"`
|
||||
AlgoId string `json:"algoId"`
|
||||
}
|
||||
|
||||
//go:generate GetRequest -url "/api/v5/trade/orders-history-archive" -type GetOrderHistoryRequest -responseDataType []OrderDetail
|
||||
type GetOrderHistoryRequest struct {
|
||||
client requestgen.AuthenticatedAPIClient
|
||||
|
||||
|
@ -29,8 +101,6 @@ type GetOrderHistoryRequest struct {
|
|||
limit *uint64 `param:"limit,query"`
|
||||
}
|
||||
|
||||
type OrderList []OrderDetails
|
||||
|
||||
// NewGetOrderHistoriesRequest is descending order by createdTime
|
||||
func (c *RestClient) NewGetOrderHistoryRequest() *GetOrderHistoryRequest {
|
||||
return &GetOrderHistoryRequest{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/v5/trade/orders-history-archive -type GetOrderHistoryRequest -responseDataType .OrderList"; DO NOT EDIT.
|
||||
// Code generated by "requestgen -method GET -responseType .APIResponse -responseDataField Data -url /api/v5/trade/orders-history-archive -type GetOrderHistoryRequest -responseDataType []OrderDetail"; DO NOT EDIT.
|
||||
|
||||
package okexapi
|
||||
|
||||
|
@ -286,7 +286,13 @@ func (g *GetOrderHistoryRequest) GetSlugsMap() (map[string]string, error) {
|
|||
return slugs, nil
|
||||
}
|
||||
|
||||
func (g *GetOrderHistoryRequest) Do(ctx context.Context) (OrderList, error) {
|
||||
// GetPath returns the request path of the API
|
||||
func (g *GetOrderHistoryRequest) GetPath() string {
|
||||
return "/api/v5/trade/orders-history-archive"
|
||||
}
|
||||
|
||||
// Do generates the request object and send the request object to the API endpoint
|
||||
func (g *GetOrderHistoryRequest) Do(ctx context.Context) ([]OrderDetail, error) {
|
||||
|
||||
// no body params
|
||||
var params interface{}
|
||||
|
@ -295,7 +301,9 @@ func (g *GetOrderHistoryRequest) Do(ctx context.Context) (OrderList, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
apiURL := "/api/v5/trade/orders-history-archive"
|
||||
var apiURL string
|
||||
|
||||
apiURL = g.GetPath()
|
||||
|
||||
req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
|
||||
if err != nil {
|
||||
|
@ -311,7 +319,19 @@ func (g *GetOrderHistoryRequest) Do(ctx context.Context) (OrderList, error) {
|
|||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data OrderList
|
||||
|
||||
type responseValidator interface {
|
||||
Validate() error
|
||||
}
|
||||
|
||||
validator, ok := interface{}(apiResponse).(responseValidator)
|
||||
if ok {
|
||||
if err := validator.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var data []OrderDetail
|
||||
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ type GetTransactionHistoryRequest struct {
|
|||
limit *uint64 `param:"limit,query"`
|
||||
}
|
||||
|
||||
type OrderList []OrderDetails
|
||||
|
||||
// NewGetOrderHistoriesRequest is descending order by createdTime
|
||||
func (c *RestClient) NewGetTransactionHistoryRequest() *GetTransactionHistoryRequest {
|
||||
return &GetTransactionHistoryRequest{
|
||||
|
|
Loading…
Reference in New Issue
Block a user