You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

92 lines
2.3 KiB

package okx
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sig-pub/pkg/types"
"strings"
"time"
"github.com/go-resty/resty/v2"
"golang.org/x/time/rate"
)
const (
HttpBaseUrl = "https://www.okx.com"
KlineBefore0 int64 = 1672502400000 // k线开始数据 2023-01-01 00:00:00 GMT+8
)
type OkxFetcher struct {
client *resty.Client
httpProxy string
historyKlineLimiter *rate.Limiter
}
func NewOkxFetcher(httpProxy string) (f *OkxFetcher) {
client := resty.New()
client.SetTimeout(30 * time.Second)
client.SetTransport(&http.Transport{
MaxIdleConns: 100,
MaxConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
})
if httpProxy != "" {
client.SetProxy(httpProxy)
}
f = &OkxFetcher{
client: client,
httpProxy: httpProxy,
historyKlineLimiter: rate.NewLimiter(rate.Every(100*time.Millisecond), 20), // rate: 20次/2s
}
return
}
// FetchHistoryKlines 获取交易产品历史K线数据
// https://my.okx.com/docs-v5/zh/#order-book-trading-market-data-get-candlesticks-history
// 周期区间 after > before, (after, before)
func (f *OkxFetcher) FetchHistoryKlines(ctx context.Context, okxInstId string, interval types.Interval, after, before int64) (klines []*types.Kline, err error) {
if okxInstId == "" {
err = errors.New("instid is empty")
return
}
if after <= 0 && before <= 0 {
err = errors.New("time range zero")
return
}
if err = f.historyKlineLimiter.Wait(ctx); err != nil {
return
}
var params []string
params = append(params, fmt.Sprintf("instId=%s", url.QueryEscape(okxInstId)))
params = append(params, "limit=100") // 最大为100
if v, ok := subscribeCandles[interval]; ok {
params = append(params, "bar="+v)
}
if after > 0 {
params = append(params, fmt.Sprintf("after=%d", after))
}
if before > 0 {
params = append(params, fmt.Sprintf("before=%d", before))
}
url := fmt.Sprintf("%s/api/v5/market/history-candles?%s", HttpBaseUrl, strings.Join(params, "&"))
resp, err := f.client.R().Get(url)
if err != nil {
return
}
status := resp.StatusCode()
if status != 200 {
err = fmt.Errorf("request history klines status error: %s, %s", url, resp.Status())
return
}
fmt.Println(string(resp.Body()))
return
}