mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
Merge pull request #1332 from MengShue/add_supported_interval
FEATURE: add supported interval for okex
This commit is contained in:
commit
a13c65ef1d
|
@ -2,7 +2,6 @@ package okex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -206,11 +205,17 @@ func toGlobalOrderType(orderType okexapi.OrderType) (types.OrderType, error) {
|
||||||
return "", fmt.Errorf("unknown or unsupported okex order type: %s", orderType)
|
return "", fmt.Errorf("unknown or unsupported okex order type: %s", orderType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toLocalInterval(src string) string {
|
func toLocalInterval(interval types.Interval) (string, error) {
|
||||||
var re = regexp.MustCompile(`\d+[hdw]`)
|
if _, ok := SupportedIntervals[interval]; !ok {
|
||||||
return re.ReplaceAllStringFunc(src, func(w string) string {
|
return "", fmt.Errorf("interval %s is not supported", interval)
|
||||||
return strings.ToUpper(w)
|
}
|
||||||
})
|
|
||||||
|
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) {
|
func toGlobalSide(side okexapi.SideType) (s types.SideType) {
|
||||||
|
|
|
@ -316,7 +316,10 @@ func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval type
|
||||||
return nil, err
|
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 := e.client.NewCandlesticksRequest(toLocalSymbol(symbol))
|
||||||
req.Bar(intervalParam)
|
req.Bar(intervalParam)
|
||||||
|
@ -541,3 +544,12 @@ func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *type
|
||||||
}
|
}
|
||||||
return trades, nil
|
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
|
||||||
|
}
|
||||||
|
|
85
pkg/exchange/okex/query_kline_test.go
Normal file
85
pkg/exchange/okex/query_kline_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
40
pkg/exchange/okex/types.go
Normal file
40
pkg/exchange/okex/types.go
Normal 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",
|
||||||
|
}
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user