Merge pull request #1332 from MengShue/add_supported_interval

FEATURE: add supported interval for okex
This commit is contained in:
c9s 2023-10-05 21:47:51 +08:00 committed by GitHub
commit a13c65ef1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 149 additions and 7 deletions

View File

@ -2,7 +2,6 @@ package okex
import (
"fmt"
"regexp"
"strconv"
"strings"
@ -206,11 +205,17 @@ func toGlobalOrderType(orderType okexapi.OrderType) (types.OrderType, error) {
return "", fmt.Errorf("unknown or unsupported okex order type: %s", orderType)
}
func toLocalInterval(src string) string {
var re = regexp.MustCompile(`\d+[hdw]`)
return re.ReplaceAllStringFunc(src, func(w string) string {
return strings.ToUpper(w)
})
func toLocalInterval(interval types.Interval) (string, error) {
if _, ok := SupportedIntervals[interval]; !ok {
return "", fmt.Errorf("interval %s is not supported", interval)
}
in, ok := ToLocalInterval[interval]
if !ok {
return "", fmt.Errorf("interval %s is not supported, got local interval %s", interval, in)
}
return in, nil
}
func toGlobalSide(side okexapi.SideType) (s types.SideType) {

View File

@ -316,7 +316,10 @@ func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval type
return nil, err
}
intervalParam := toLocalInterval(interval.String())
intervalParam, err := toLocalInterval(interval)
if err != nil {
return nil, fmt.Errorf("fail to get interval: %w", err)
}
req := e.client.NewCandlesticksRequest(toLocalSymbol(symbol))
req.Bar(intervalParam)
@ -541,3 +544,12 @@ func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *type
}
return trades, nil
}
func (e *Exchange) SupportedInterval() map[types.Interval]int {
return SupportedIntervals
}
func (e *Exchange) IsSupportedInterval(interval types.Interval) bool {
_, ok := SupportedIntervals[interval]
return ok
}

View File

@ -0,0 +1,85 @@
package okex
import (
"context"
"testing"
"time"
"github.com/c9s/bbgo/pkg/testutil"
"github.com/c9s/bbgo/pkg/types"
"github.com/stretchr/testify/assert"
)
func Test_QueryKlines(t *testing.T) {
key, secret, passphrase, ok := testutil.IntegrationTestWithPassphraseConfigured(t, "OKEX")
if !ok {
t.Skip("Please configure all credentials about OKEX")
}
e := New(key, secret, passphrase)
queryOrder := types.OrderQuery{
Symbol: "BTC-USDT",
}
now := time.Now()
// test supported interval - minute
klineDetail, err := e.QueryKLines(context.Background(), queryOrder.Symbol, types.Interval1m, types.KLineQueryOptions{
Limit: 50,
EndTime: &now})
if assert.NoError(t, err) {
assert.NotEmpty(t, klineDetail)
}
// test supported interval - hour - 1 hour
klineDetail, err = e.QueryKLines(context.Background(), queryOrder.Symbol, types.Interval1h, types.KLineQueryOptions{
Limit: 50,
EndTime: &now})
if assert.NoError(t, err) {
assert.NotEmpty(t, klineDetail)
}
// test supported interval - hour - 6 hour to test UTC time
klineDetail, err = e.QueryKLines(context.Background(), queryOrder.Symbol, types.Interval6h, types.KLineQueryOptions{
Limit: 50,
EndTime: &now})
if assert.NoError(t, err) {
assert.NotEmpty(t, klineDetail)
}
// test supported interval - day
klineDetail, err = e.QueryKLines(context.Background(), queryOrder.Symbol, types.Interval1d, types.KLineQueryOptions{
Limit: 50,
EndTime: &now})
if assert.NoError(t, err) {
assert.NotEmpty(t, klineDetail)
assert.NotEmpty(t, klineDetail[0].Exchange)
assert.NotEmpty(t, klineDetail[0].Symbol)
assert.NotEmpty(t, klineDetail[0].StartTime)
assert.NotEmpty(t, klineDetail[0].EndTime)
assert.NotEmpty(t, klineDetail[0].Interval)
assert.NotEmpty(t, klineDetail[0].Open)
assert.NotEmpty(t, klineDetail[0].Close)
assert.NotEmpty(t, klineDetail[0].High)
assert.NotEmpty(t, klineDetail[0].Low)
assert.NotEmpty(t, klineDetail[0].Volume)
}
// test supported interval - week
klineDetail, err = e.QueryKLines(context.Background(), queryOrder.Symbol, types.Interval1w, types.KLineQueryOptions{
Limit: 50,
EndTime: &now})
if assert.NoError(t, err) {
assert.NotEmpty(t, klineDetail)
}
// test supported interval - month
klineDetail, err = e.QueryKLines(context.Background(), queryOrder.Symbol, types.Interval1mo, types.KLineQueryOptions{
Limit: 50,
EndTime: &now})
if assert.NoError(t, err) {
assert.NotEmpty(t, klineDetail)
}
// test not supported interval
klineDetail, err = e.QueryKLines(context.Background(), queryOrder.Symbol, types.Interval("2m"), types.KLineQueryOptions{
Limit: 50,
EndTime: &now})
if assert.Error(t, err) {
assert.Empty(t, klineDetail)
}
}

View File

@ -0,0 +1,40 @@
package okex
import "github.com/c9s/bbgo/pkg/types"
var (
// below are supported UTC timezone interval for okex
SupportedIntervals = map[types.Interval]int{
types.Interval1m: 1 * 60,
types.Interval3m: 3 * 60,
types.Interval5m: 5 * 60,
types.Interval15m: 15 * 60,
types.Interval30m: 30 * 60,
types.Interval1h: 60 * 60,
types.Interval2h: 60 * 60 * 2,
types.Interval4h: 60 * 60 * 4,
types.Interval6h: 60 * 60 * 6,
types.Interval12h: 60 * 60 * 12,
types.Interval1d: 60 * 60 * 24,
types.Interval3d: 60 * 60 * 24 * 3,
types.Interval1w: 60 * 60 * 24 * 7,
types.Interval1mo: 60 * 60 * 24 * 30,
}
ToLocalInterval = map[types.Interval]string{
types.Interval1m: "1m",
types.Interval3m: "3m",
types.Interval5m: "5m",
types.Interval15m: "15m",
types.Interval30m: "30m",
types.Interval1h: "1H",
types.Interval2h: "2H",
types.Interval4h: "4H",
types.Interval6h: "6Hutc",
types.Interval12h: "12Hutc",
types.Interval1d: "1Dutc",
types.Interval3d: "3Dutc",
types.Interval1w: "1Wutc",
types.Interval1mo: "1Mutc",
}
)