package kucoinapi import ( "fmt" "net/http" "net/url" "strconv" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/types" "github.com/pkg/errors" ) type MarketDataService struct { client *RestClient } type Symbol struct { Symbol string `json:"symbol"` Name string `json:"name"` BaseCurrency string `json:"baseCurrency"` QuoteCurrency string `json:"quoteCurrency"` FeeCurrency string `json:"feeCurrency"` Market string `json:"market"` BaseMinSize fixedpoint.Value `json:"baseMinSize"` QuoteMinSize fixedpoint.Value `json:"quoteMinSize"` BaseIncrement fixedpoint.Value `json:"baseIncrement"` QuoteIncrement fixedpoint.Value `json:"quoteIncrement"` PriceIncrement fixedpoint.Value `json:"priceIncrement"` PriceLimitRate fixedpoint.Value `json:"priceLimitRate"` IsMarginEnabled bool `json:"isMarginEnabled"` EnableTrading bool `json:"enableTrading"` } func (s *MarketDataService) ListSymbols(market ...string) ([]Symbol, error) { var params = url.Values{} if len(market) == 1 { params["market"] = []string{market[0]} } else if len(market) > 1 { return nil, errors.New("symbols api only supports one market parameter") } req, err := s.client.NewRequest("GET", "/api/v1/symbols", params, nil) if err != nil { return nil, err } response, err := s.client.SendRequest(req) if err != nil { return nil, err } var apiResponse struct { Code string `json:"code"` Message string `json:"msg"` Data []Symbol `json:"data"` } if err := response.DecodeJSON(&apiResponse); err != nil { return nil, err } return apiResponse.Data, nil } /* //Get Ticker { "sequence": "1550467636704", "bestAsk": "0.03715004", "size": "0.17", "price": "0.03715005", "bestBidSize": "3.803", "bestBid": "0.03710768", "bestAskSize": "1.788", "time": 1550653727731 } */ type Ticker struct { Sequence string `json:"sequence"` Size fixedpoint.Value `json:"size"` Price fixedpoint.Value `json:"price"` BestAsk fixedpoint.Value `json:"bestAsk"` BestBid fixedpoint.Value `json:"bestBid"` BestBidSize fixedpoint.Value `json:"bestBidSize"` Time types.MillisecondTimestamp `json:"time"` } func (s *MarketDataService) GetTicker(symbol string) (*Ticker, error) { var params = url.Values{} params["symbol"] = []string{symbol} req, err := s.client.NewRequest("GET", "/api/v1/market/orderbook/level1", params, nil) if err != nil { return nil, err } response, err := s.client.SendRequest(req) if err != nil { return nil, err } var apiResponse struct { Code string `json:"code"` Message string `json:"msg"` Data *Ticker `json:"data"` } if err := response.DecodeJSON(&apiResponse); err != nil { return nil, err } return apiResponse.Data, nil } /* { "time":1602832092060, "ticker":[ { "symbol": "BTC-USDT", // symbol "symbolName":"BTC-USDT", // SymbolName of trading pairs, it would change after renaming "buy": "11328.9", // bestAsk "sell": "11329", // bestBid "changeRate": "-0.0055", // 24h change rate "changePrice": "-63.6", // 24h change price "high": "11610", // 24h highest price "low": "11200", // 24h lowest price "vol": "2282.70993217", // 24h volume,the aggregated trading volume in BTC "volValue": "25984946.157790431", // 24h total, the trading volume in quote currency of last 24 hours "last": "11328.9", // last price "averagePrice": "11360.66065903", // 24h average transaction price yesterday "takerFeeRate": "0.001", // Basic Taker Fee "makerFeeRate": "0.001", // Basic Maker Fee "takerCoefficient": "1", // Taker Fee Coefficient "makerCoefficient": "1" // Maker Fee Coefficient } ] } */ type Ticker24H struct { Symbol string `json:"symbol"` SymbolName string `json:"symbolName"` Buy fixedpoint.Value `json:"buy"` Sell fixedpoint.Value `json:"sell"` ChangeRate fixedpoint.Value `json:"changeRate"` ChangePrice fixedpoint.Value `json:"changePrice"` High fixedpoint.Value `json:"high"` Low fixedpoint.Value `json:"low"` Last fixedpoint.Value `json:"last"` AveragePrice fixedpoint.Value `json:"averagePrice"` Volume fixedpoint.Value `json:"vol"` // base volume VolumeValue fixedpoint.Value `json:"volValue"` // quote volume TakerFeeRate fixedpoint.Value `json:"takerFeeRate"` MakerFeeRate fixedpoint.Value `json:"makerFeeRate"` TakerCoefficient fixedpoint.Value `json:"takerCoefficient"` MakerCoefficient fixedpoint.Value `json:"makerCoefficient"` Time types.MillisecondTimestamp `json:"time"` } type AllTickers struct { Time types.MillisecondTimestamp `json:"time"` Ticker []Ticker24H `json:"ticker"` } func (s *MarketDataService) ListTickers() (*AllTickers, error) { req, err := s.client.NewRequest("GET", "/api/v1/market/allTickers", nil, nil) if err != nil { return nil, err } response, err := s.client.SendRequest(req) if err != nil { return nil, err } var apiResponse struct { Code string `json:"code"` Message string `json:"msg"` Data *AllTickers `json:"data"` } if err := response.DecodeJSON(&apiResponse); err != nil { return nil, err } return apiResponse.Data, nil } func (s *MarketDataService) GetTicker24HStat(symbol string) (*Ticker24H, error) { var params = url.Values{} params.Add("symbol", symbol) req, err := s.client.NewRequest("GET", "/api/v1/market/stats", params, nil) if err != nil { return nil, err } response, err := s.client.SendRequest(req) if err != nil { return nil, err } var apiResponse struct { Code string `json:"code"` Message string `json:"msg"` Data *Ticker24H `json:"data"` } if err := response.DecodeJSON(&apiResponse); err != nil { return nil, err } return apiResponse.Data, nil } /* { "sequence": "3262786978", "time": 1550653727731, "bids": [["6500.12", "0.45054140"], ["6500.11", "0.45054140"]], //[price,size] "asks": [["6500.16", "0.57753524"], ["6500.15", "0.57753524"]] } */ type OrderBook struct { Sequence string `json:"sequence"` Time types.MillisecondTimestamp `json:"time"` Bids [][]fixedpoint.Value `json:"bids,omitempty"` Asks [][]fixedpoint.Value `json:"asks,omitempty"` } func (s *MarketDataService) GetOrderBook(symbol string, depth int) (*OrderBook, error) { params := url.Values{} params["symbol"] = []string{symbol} var req *http.Request var err error switch depth { case 20, 100: refURL := "/api/v1/market/orderbook/level2_" + strconv.Itoa(depth) req, err = s.client.NewRequest("GET", refURL, params, nil) if err != nil { return nil, err } case 0: refURL := "/api/v3/market/orderbook/level2" req, err = s.client.NewAuthenticatedRequest("GET", refURL, params, nil) if err != nil { return nil, err } default: return nil, fmt.Errorf("depth %d is not supported, use 20, 100 or 0", depth) } response, err := s.client.SendRequest(req) if err != nil { return nil, err } var apiResponse struct { Code string `json:"code"` Message string `json:"msg"` Data *OrderBook `json:"data"` } if err := response.DecodeJSON(&apiResponse); err != nil { return nil, err } return apiResponse.Data, nil }