bbgo_origin/pkg/exchange/okex/okexapi/market.go
2022-05-03 11:14:53 +08:00

269 lines
5.5 KiB
Go

package okexapi
import (
"context"
"fmt"
"net/url"
"strconv"
"time"
"github.com/c9s/bbgo/pkg/fixedpoint"
)
type Candle struct {
InstrumentID string
Interval string
Time time.Time
Open fixedpoint.Value
High fixedpoint.Value
Low fixedpoint.Value
Close fixedpoint.Value
Volume fixedpoint.Value
VolumeInCurrency fixedpoint.Value
}
type CandlesticksRequest struct {
client *RestClient
instId string `param:"instId"`
limit *int `param:"limit"`
bar *string `param:"bar"`
after *int64 `param:"after,seconds"`
before *int64 `param:"before,seconds"`
}
func (r *CandlesticksRequest) After(after int64) *CandlesticksRequest {
r.after = &after
return r
}
func (r *CandlesticksRequest) Before(before int64) *CandlesticksRequest {
r.before = &before
return r
}
func (r *CandlesticksRequest) Bar(bar string) *CandlesticksRequest {
r.bar = &bar
return r
}
func (r *CandlesticksRequest) Limit(limit int) *CandlesticksRequest {
r.limit = &limit
return r
}
func (r *CandlesticksRequest) InstrumentID(instId string) *CandlesticksRequest {
r.instId = instId
return r
}
func (r *CandlesticksRequest) Do(ctx context.Context) ([]Candle, error) {
// SPOT, SWAP, FUTURES, OPTION
var params = url.Values{}
params.Add("instId", r.instId)
if r.bar != nil {
params.Add("bar", *r.bar)
}
if r.before != nil {
params.Add("before", strconv.FormatInt(*r.before, 10))
}
if r.after != nil {
params.Add("after", strconv.FormatInt(*r.after, 10))
}
if r.limit != nil {
params.Add("limit", strconv.Itoa(*r.limit))
}
req, err := r.client.newRequest("GET", "/api/v5/market/candles", params, nil)
if err != nil {
return nil, err
}
resp, err := r.client.sendRequest(req)
if err != nil {
return nil, err
}
type candleEntry [7]string
var candlesResponse struct {
Code string `json:"code"`
Message string `json:"msg"`
Data []candleEntry `json:"data"`
}
if err := resp.DecodeJSON(&candlesResponse); err != nil {
return nil, err
}
var candles []Candle
for _, entry := range candlesResponse.Data {
timestamp, err := strconv.ParseInt(entry[0], 10, 64)
if err != nil {
return candles, err
}
open, err := fixedpoint.NewFromString(entry[1])
if err != nil {
return candles, err
}
high, err := fixedpoint.NewFromString(entry[2])
if err != nil {
return candles, err
}
low, err := fixedpoint.NewFromString(entry[3])
if err != nil {
return candles, err
}
cls, err := fixedpoint.NewFromString(entry[4])
if err != nil {
return candles, err
}
vol, err := fixedpoint.NewFromString(entry[5])
if err != nil {
return candles, err
}
volCcy, err := fixedpoint.NewFromString(entry[6])
if err != nil {
return candles, err
}
var interval = "1m"
if r.bar != nil {
interval = *r.bar
}
candles = append(candles, Candle{
InstrumentID: r.instId,
Interval: interval,
Time: time.Unix(0, timestamp*int64(time.Millisecond)),
Open: open,
High: high,
Low: low,
Close: cls,
Volume: vol,
VolumeInCurrency: volCcy,
})
}
return candles, nil
}
type MarketTickersRequest struct {
client *RestClient
instType string
}
func (r *MarketTickersRequest) InstrumentType(instType string) *MarketTickersRequest {
r.instType = instType
return r
}
func (r *MarketTickersRequest) Do(ctx context.Context) ([]MarketTicker, error) {
// SPOT, SWAP, FUTURES, OPTION
var params = url.Values{}
params.Add("instType", string(r.instType))
req, err := r.client.newRequest("GET", "/api/v5/market/tickers", params, nil)
if err != nil {
return nil, err
}
response, err := r.client.sendRequest(req)
if err != nil {
return nil, err
}
var tickerResponse struct {
Code string `json:"code"`
Message string `json:"msg"`
Data []MarketTicker `json:"data"`
}
if err := response.DecodeJSON(&tickerResponse); err != nil {
return nil, err
}
return tickerResponse.Data, nil
}
type MarketTickerRequest struct {
client *RestClient
instId string
}
func (r *MarketTickerRequest) InstrumentID(instId string) *MarketTickerRequest {
r.instId = instId
return r
}
func (r *MarketTickerRequest) Do(ctx context.Context) (*MarketTicker, error) {
// SPOT, SWAP, FUTURES, OPTION
var params = url.Values{}
params.Add("instId", r.instId)
req, err := r.client.newRequest("GET", "/api/v5/market/ticker", params, nil)
if err != nil {
return nil, err
}
response, err := r.client.sendRequest(req)
if err != nil {
return nil, err
}
var tickerResponse struct {
Code string `json:"code"`
Message string `json:"msg"`
Data []MarketTicker `json:"data"`
}
if err := response.DecodeJSON(&tickerResponse); err != nil {
return nil, err
}
if len(tickerResponse.Data) == 0 {
return nil, fmt.Errorf("ticker of %s not found", r.instId)
}
return &tickerResponse.Data[0], nil
}
type MarketDataService struct {
client *RestClient
}
func (c *MarketDataService) NewMarketTickerRequest(instId string) *MarketTickerRequest {
return &MarketTickerRequest{
client: c.client,
instId: instId,
}
}
func (c *MarketDataService) NewMarketTickersRequest(instType string) *MarketTickersRequest {
return &MarketTickersRequest{
client: c.client,
instType: instType,
}
}
func (c *MarketDataService) NewCandlesticksRequest(instId string) *CandlesticksRequest {
return &CandlesticksRequest{
client: c.client,
instId: instId,
}
}