From 2b02f00798e9f2a0f800494df3006cb4b482bab3 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Thu, 1 Jul 2021 01:06:12 +0800 Subject: [PATCH 01/34] [APIBuilder] api builder add the futures lever configure --- builder/APIBuilder.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/builder/APIBuilder.go b/builder/APIBuilder.go index a76eb748..88a66f05 100644 --- a/builder/APIBuilder.go +++ b/builder/APIBuilder.go @@ -42,6 +42,7 @@ type APIBuilder struct { apiPassphrase string futuresEndPoint string endPoint string + futuresLever float64 } type HttpClientConfig struct { @@ -186,6 +187,11 @@ func (builder *APIBuilder) Endpoint(endpoint string) (_builer *APIBuilder) { return builder } +func (builder *APIBuilder) FuturesLever(lever float64) (_builder *APIBuilder) { + builder.futuresLever = lever + return builder +} + func (builder *APIBuilder) Build(exName string) (api API) { var _api API switch exName { @@ -272,19 +278,22 @@ func (builder *APIBuilder) BuildFuture(exName string) (api FutureRestAPI) { Endpoint: builder.futuresEndPoint, ApiKey: builder.apiKey, ApiSecretKey: builder.secretkey, - ApiPassphrase: builder.apiPassphrase}).OKExFuture + ApiPassphrase: builder.apiPassphrase, + Lever: builder.futuresLever}).OKExFuture case HBDM: return huobi.NewHbdm(&APIConfig{ HttpClient: builder.client, Endpoint: builder.futuresEndPoint, ApiKey: builder.apiKey, - ApiSecretKey: builder.secretkey}) + ApiSecretKey: builder.secretkey, + Lever: builder.futuresLever}) case HBDM_SWAP: return huobi.NewHbdmSwap(&APIConfig{ HttpClient: builder.client, Endpoint: builder.endPoint, ApiKey: builder.apiKey, ApiSecretKey: builder.secretkey, + Lever: builder.futuresLever, }) case OKEX_SWAP: return okex.NewOKEx(&APIConfig{ @@ -292,7 +301,8 @@ func (builder *APIBuilder) BuildFuture(exName string) (api FutureRestAPI) { Endpoint: builder.futuresEndPoint, ApiKey: builder.apiKey, ApiSecretKey: builder.secretkey, - ApiPassphrase: builder.apiPassphrase}).OKExSwap + ApiPassphrase: builder.apiPassphrase, + Lever: builder.futuresLever}).OKExSwap case COINBENE: return coinbene.NewCoinbeneSwap(APIConfig{ HttpClient: builder.client, @@ -300,6 +310,7 @@ func (builder *APIBuilder) BuildFuture(exName string) (api FutureRestAPI) { Endpoint: builder.futuresEndPoint, ApiKey: builder.apiKey, ApiSecretKey: builder.secretkey, + Lever: builder.futuresLever, }) case BINANCE_SWAP: @@ -308,6 +319,7 @@ func (builder *APIBuilder) BuildFuture(exName string) (api FutureRestAPI) { Endpoint: builder.futuresEndPoint, ApiKey: builder.apiKey, ApiSecretKey: builder.secretkey, + Lever: builder.futuresLever, }) case BINANCE, BINANCE_FUTURES: return binance.NewBinanceFutures(&APIConfig{ @@ -315,6 +327,7 @@ func (builder *APIBuilder) BuildFuture(exName string) (api FutureRestAPI) { Endpoint: builder.futuresEndPoint, ApiKey: builder.apiKey, ApiSecretKey: builder.secretkey, + Lever: builder.futuresLever, }) default: println(fmt.Sprintf("%s not support future", exName)) From 2b94a6341d5df95fe98732cbd176bfc0f18c9a18 Mon Sep 17 00:00:00 2001 From: conbanwa Date: Thu, 2 Sep 2021 14:07:32 +0800 Subject: [PATCH 02/34] bfx ws --- bitfinex/bitfinex_ws.go | 17 ++++++++++++++++- builder/APIBuilder.go | 3 +++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/bitfinex/bitfinex_ws.go b/bitfinex/bitfinex_ws.go index 6d6320d8..e9bd0be0 100644 --- a/bitfinex/bitfinex_ws.go +++ b/bitfinex/bitfinex_ws.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "math" + "os" "sync" "time" @@ -23,6 +24,7 @@ type BitfinexWs struct { eventMap map[int64]SubscribeEvent tickerCallback func(*Ticker) + depthCallback func(*Depth) tradeCallback func(*Trade) candleCallback func(*Kline) } @@ -46,7 +48,7 @@ func NewWs() *BitfinexWs { bws := &BitfinexWs{WsBuilder: NewWsBuilder(), eventMap: make(map[int64]SubscribeEvent)} bws.WsBuilder = bws.WsBuilder. WsUrl("wss://api-pub.bitfinex.com/ws/2"). - AutoReconnect(). + AutoReconnect().ProxyUrl(os.Getenv("HTTPS_PROXY")).DisableEnableCompression(). ProtoHandleFunc(bws.handle) return bws } @@ -57,6 +59,15 @@ func (bws *BitfinexWs) SetCallbacks(tickerCallback func(*Ticker), tradeCallback bws.candleCallback = candleCallback } +func (bws *BitfinexWs) TickerCallback(tickerCallback func(*Ticker)) { + bws.tickerCallback = tickerCallback +} +func (bws *BitfinexWs) DepthCallback(depthCallback func(*Depth)) { + bws.depthCallback = depthCallback +} +func (bws *BitfinexWs) TradeCallback(tradeCallback func(*Trade)) { + bws.tradeCallback = tradeCallback +} func (bws *BitfinexWs) SubscribeTicker(pair CurrencyPair) error { if bws.tickerCallback == nil { return fmt.Errorf("please set ticker callback func") @@ -67,6 +78,10 @@ func (bws *BitfinexWs) SubscribeTicker(pair CurrencyPair) error { "symbol": convertPairToBitfinexSymbol("t", pair)}) } +func (bws *BitfinexWs) SubscribeDepth(pair CurrencyPair) error { + panic("not implements") + return nil +} func (bws *BitfinexWs) SubscribeTrade(pair CurrencyPair) error { if bws.tradeCallback == nil { return fmt.Errorf("please set trade callback func") diff --git a/builder/APIBuilder.go b/builder/APIBuilder.go index 88a66f05..1b43146c 100644 --- a/builder/APIBuilder.go +++ b/builder/APIBuilder.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + . "github.com/nntaoli-project/goex" "github.com/nntaoli-project/goex/bigone" "github.com/nntaoli-project/goex/binance" @@ -362,6 +363,8 @@ func (builder *APIBuilder) BuildSpotWs(exName string) (SpotWsApi, error) { return huobi.NewSpotWs(), nil case BINANCE: return binance.NewSpotWs(), nil + case BITFINEX: + return bitfinex.NewWs(), nil } return nil, errors.New("not support the exchange " + exName) } From dbff79e9fcd7c422d19e1ca9442be223939fba86 Mon Sep 17 00:00:00 2001 From: qct Date: Sun, 21 Nov 2021 16:32:47 +0800 Subject: [PATCH 03/34] add GetAllCurrencies to poloniex --- Models.go | 15 +++++++++++++++ poloniex/Poloniex.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/Models.go b/Models.go index 5e277d22..6cde1069 100644 --- a/Models.go +++ b/Models.go @@ -263,6 +263,21 @@ type DepositWithdrawHistory struct { Timestamp time.Time `json:"timestamp"` } +type PoloniexCurrency struct { + ID int `json:"id"` + Name string `json:"name"` + HumanType string `json:"humanType"` + CurrencyType string `json:"currencyType"` + TxFee string `json:"txFee"` + MinConf int `json:"minConf"` + DepositAddress string `json:"depositAddress"` + Disabled int `json:"disabled"` //Designates whether (1) or not (0) deposits and withdrawals are disabled. + Frozen int `json:"frozen"` //Designates whether (1) or not (0) trading for this currency is disabled for trading. + Blockchain string `json:"blockchain"` + Delisted int `json:"delisted"` + IsGeofenced int `json:"isGeofenced"` +} + type OptionalParameter map[string]interface{} func (optional OptionalParameter) Optional(name string, value interface{}) OptionalParameter { diff --git a/poloniex/Poloniex.go b/poloniex/Poloniex.go index 0581e464..e1572b9b 100644 --- a/poloniex/Poloniex.go +++ b/poloniex/Poloniex.go @@ -20,6 +20,7 @@ const ( TRADE_API = BASE_URL + "tradingApi" PUBLIC_URL = BASE_URL + "public" TICKER_API = "?command=returnTicker" + CURRENCIES_API = "?command=returnCurrencies" ORDER_BOOK_API = "?command=returnOrderBook¤cyPair=%s&depth=%d" ) @@ -513,3 +514,33 @@ func (poloniex *Poloniex) MarketBuy(amount, price string, currency CurrencyPair) func (poloniex *Poloniex) MarketSell(amount, price string, currency CurrencyPair) (*Order, error) { panic("unsupport the market order") } + +func (poloniex *Poloniex) GetAllCurrencies() (map[string]*PoloniexCurrency, error) { + respmap, err := HttpGet(poloniex.client, PUBLIC_URL+CURRENCIES_API) + + if err != nil || respmap["error"] != nil { + log.Println(err) + return nil, err + } + + result := map[string]*PoloniexCurrency{} + for k, v := range respmap { + currencyMap := v.(map[string]interface{}) + poloniexCurrency := new(PoloniexCurrency) + poloniexCurrency.ID = int(currencyMap["id"].(float64)) + poloniexCurrency.Name, _ = currencyMap["name"].(string) + poloniexCurrency.TxFee, _ = currencyMap["txFee"].(string) + poloniexCurrency.MinConf = int(currencyMap["minConf"].(float64)) + poloniexCurrency.DepositAddress, _ = currencyMap["depositAddress"].(string) + poloniexCurrency.Disabled = int(currencyMap["disabled"].(float64)) + poloniexCurrency.Delisted = int(currencyMap["delisted"].(float64)) + poloniexCurrency.Frozen = int(currencyMap["frozen"].(float64)) + poloniexCurrency.HumanType, _ = currencyMap["humanType"].(string) + poloniexCurrency.CurrencyType, _ = currencyMap["currencyType"].(string) + poloniexCurrency.Blockchain, _ = currencyMap["blockchain"].(string) + poloniexCurrency.IsGeofenced = int(currencyMap["isGeofenced"].(float64)) + + result[k] = poloniexCurrency + } + return result, nil +} From c2b50208bc7c83f8b5f6c14acfea605c047ab511 Mon Sep 17 00:00:00 2001 From: eric <20572588+beaquant@users.noreply.github.com> Date: Thu, 30 Dec 2021 23:06:54 +0800 Subject: [PATCH 04/34] [okex] implement okex v5 for spot --- okex/v5/OKExV5.go | 672 +++++++++++++++++++++++++++++++++++++ okex/v5/OKExV5Spot.go | 390 +++++++++++++++++++++ okex/v5/OKExV5Spot_test.go | 68 ++++ okex/v5/OKExV5_test.go | 44 +++ 4 files changed, 1174 insertions(+) create mode 100644 okex/v5/OKExV5.go create mode 100644 okex/v5/OKExV5Spot.go create mode 100644 okex/v5/OKExV5Spot_test.go create mode 100644 okex/v5/OKExV5_test.go diff --git a/okex/v5/OKExV5.go b/okex/v5/OKExV5.go new file mode 100644 index 00000000..b1c519e6 --- /dev/null +++ b/okex/v5/OKExV5.go @@ -0,0 +1,672 @@ +package okex + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "github.com/google/uuid" + . "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" +) + +const ( + v5RestBaseUrl = "https://www.okex.com" + v5WsBaseUrl = "wss://ws.okex.com:8443/ws/v5" + + CONTENT_TYPE = "Content-Type" + ACCEPT = "Accept" + APPLICATION_JSON_UTF8 = "application/json; charset=UTF-8" + APPLICATION_JSON = "application/json" + OK_ACCESS_KEY = "OK-ACCESS-KEY" + OK_ACCESS_SIGN = "OK-ACCESS-SIGN" + OK_ACCESS_TIMESTAMP = "OK-ACCESS-TIMESTAMP" + OK_ACCESS_PASSPHRASE = "OK-ACCESS-PASSPHRASE" +) + +// base interface for okex v5 +type OKExV5 struct { + config *APIConfig + customCIDFunc func() string +} + +func NewOKExV5(config *APIConfig) *OKExV5 { + if config.Endpoint == "" { + config.Endpoint = v5RestBaseUrl + } + okex := &OKExV5{config: config} + return okex +} + +func (ok *OKExV5) ExchangeName() string { + return OKEX +} + +func (ok *OKExV5) UUID() string { + return strings.Replace(uuid.New().String(), "-", "", 32) +} + +func (ok *OKExV5) SetCustomCID(f func() string) { + ok.customCIDFunc = f +} + +//获取所有产品行情信息 +//产品类型instType +// SPOT:币币 +// SWAP:永续合约 +// FUTURES:交割合约 +// OPTION:期权 +// func (ok *OKExV5) GetTickersV5(instType, uly string) ([]Ticker, error) { +// urlPath := fmt.Sprintf("/api/v5/market/tickers?instType=%s", instType) +// if instType == "SWAP" || instType == "FUTURES" || instType == "OPTION" { +// urlPath = fmt.Sprintf("%s&uly=%s", urlPath, uly) +// } +// var response spotTickerResponse +// err := ok.OKEx.DoAuthorRequest("GET", urlPath, "", &response) +// if err != nil { +// return nil, err +// } + +// date, _ := time.Parse(time.RFC3339, response.Timestamp) +// return &Ticker{ +// Pair: currency, +// Last: response.Last, +// High: response.High24h, +// Low: response.Low24h, +// Sell: response.BestAsk, +// Buy: response.BestBid, +// Vol: response.BaseVolume24h, +// Date: uint64(time.Duration(date.UnixNano() / int64(time.Millisecond)))}, nil + +// } + +type TickerV5 struct { + InstId string `json:"instId"` + Last float64 `json:"last,string"` + BuyPrice float64 `json:"bidPx,string"` + BuySize float64 `json:"bidSz,string"` + SellPrice float64 `json:"askPx,string"` + SellSize float64 `json:"askSz,string"` + Open float64 `json:"open24h,string"` + High float64 `json:"high24h,string"` + Low float64 `json:"low24h,string"` + Vol float64 `json:"volCcy24h,string"` + VolQuote float64 `json:"vol24h,string"` + Timestamp uint64 `json:"ts,string"` // 单位:ms +} + +func (ok *OKExV5) GetTickerV5(instId string) (*TickerV5, error) { + urlPath := fmt.Sprintf("%s/api/v5/market/ticker?instId=%s", ok.config.Endpoint, instId) + type TickerV5Response struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []TickerV5 `json:"data"` + } + var response TickerV5Response + err := HttpGet4(ok.config.HttpClient, urlPath, nil, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetTickerV5 error:%s", response.Msg) + } + return &response.Data[0], nil +} + +type DepthV5 struct { + Asks [][]string `json:"asks,string"` + Bids [][]string `json:"bids,string"` + Timestamp uint64 `json:"ts,string"` // 单位:ms +} + +func (ok *OKExV5) GetDepthV5(instId string, size int) (*DepthV5, error) { + + urlPath := fmt.Sprintf("%s/api/v5/market/books?instId=%s", ok.config.Endpoint, instId) + if size > 0 { + urlPath = fmt.Sprintf("%s&sz=%d", urlPath, size) + } + type DepthV5Response struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []DepthV5 `json:"data"` + } + var response DepthV5Response + err := HttpGet4(ok.config.HttpClient, urlPath, nil, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetDepthV5 error:%s", response.Msg) + } + return &response.Data[0], nil +} + +func (ok *OKExV5) GetKlineRecordsV5(instId, after, before, bar, limit string) ([][]string, error) { + + urlPath := fmt.Sprintf("%s/api/v5/market/candles?instId=%s", ok.config.Endpoint, instId) + params := url.Values{} + if after != "" { + params.Set("after", after) + } + if before != "" { + params.Set("before", before) + } + if bar != "" { + params.Set("bar", bar) + } + if limit != "" { + params.Set("limit", limit) + } + if params.Encode() != "" { + urlPath = fmt.Sprintf("%s&%s", urlPath, params.Encode()) + } + + type CandleResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data [][]string `json:"data"` + } + var response CandleResponse + err := HttpGet4(ok.config.HttpClient, urlPath, nil, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetKlineRecordsV5 error:%s", response.Msg) + } + return response.Data, nil +} + +/* + Get a iso time + eg: 2018-03-16T18:02:48.284Z +*/ +func IsoTime() string { + utcTime := time.Now().UTC() + iso := utcTime.String() + isoBytes := []byte(iso) + iso = string(isoBytes[:10]) + "T" + string(isoBytes[11:23]) + "Z" + return iso +} + +/* + Get a http request body is a json string and a byte array. +*/ +func (ok *OKExV5) BuildRequestBody(params interface{}) (string, *bytes.Reader, error) { + if params == nil { + return "", nil, errors.New("illegal parameter") + } + data, err := json.Marshal(params) + if err != nil { + //log.Println(err) + return "", nil, errors.New("json convert string error") + } + + jsonBody := string(data) + binBody := bytes.NewReader(data) + + return jsonBody, binBody, nil +} + +func (ok *OKExV5) doParamSign(httpMethod, uri, requestBody string) (string, string) { + timestamp := IsoTime() + preText := fmt.Sprintf("%s%s%s%s", timestamp, strings.ToUpper(httpMethod), uri, requestBody) + //log.Println("preHash", preText) + sign, _ := GetParamHmacSHA256Base64Sign(ok.config.ApiSecretKey, preText) + return sign, timestamp +} + +func (ok *OKExV5) DoAuthorRequest(httpMethod, uri, reqBody string, response interface{}) error { + url := ok.config.Endpoint + uri + sign, timestamp := ok.doParamSign(httpMethod, uri, reqBody) + //logger.Log.Debug("timestamp=", timestamp, ", sign=", sign) + resp, err := NewHttpRequest(ok.config.HttpClient, httpMethod, url, reqBody, map[string]string{ + CONTENT_TYPE: APPLICATION_JSON_UTF8, + ACCEPT: APPLICATION_JSON, + //COOKIE: LOCALE + "en_US", + OK_ACCESS_KEY: ok.config.ApiKey, + OK_ACCESS_PASSPHRASE: ok.config.ApiPassphrase, + OK_ACCESS_SIGN: sign, + OK_ACCESS_TIMESTAMP: fmt.Sprint(timestamp)}) + if err != nil { + //log.Println(err) + return err + } else { + logger.Log.Debug(string(resp)) + return json.Unmarshal(resp, &response) + } +} + +type CreateOrderParam struct { + Symbol string //产品ID + TradeMode string //交易模式, 保证金模式:isolated:逐仓 ;cross:全仓, 非保证金模式:cash:非保证金 + Side string // 订单方向 buy:买 sell:卖 + OrderType string //订单类型 + // market:市价单 + // limit:限价单 + // post_only:只做maker单 + // fok:全部成交或立即取消 + // ioc:立即成交并取消剩余 + + Size string // 委托数量 + PosSide string //持仓方向 在双向持仓模式下必填,且仅可选择 long 或 short + Price string //委托价格,仅适用于限价单 + CCY string // 保证金币种,仅适用于单币种保证金模式下的全仓杠杆订单 + ClientOrdId string //客户自定义订单ID 字母(区分大小写)与数字的组合,可以是纯字母、纯数字且长度要在1-32位之间。 + Tag string //订单标签 字母(区分大小写)与数字的组合,可以是纯字母、纯数字,且长度在1-8位之间。 + ReduceOnly bool //是否只减仓,true 或 false,默认false 仅适用于币币杠杆订单 +} + +type OrderSummaryV5 struct { + OrdId string `json:"ordId"` + ClientOrdId string `json:"clOrdId"` //客户自定义订单ID 字母(区分大小写)与数字的组合,可以是纯字母、纯数字且长度要在1-32位之间。 + Tag string `json:"tag"` + SCode string `json:"sCode"` + SMsg string `json:"sMsg"` +} + +func (ok *OKExV5) CreateOrder(param *CreateOrderParam) (*OrderSummaryV5, error) { + + reqBody := make(map[string]interface{}) + + reqBody["instId"] = param.Symbol + reqBody["tdMode"] = param.TradeMode + reqBody["side"] = param.Side + reqBody["ordType"] = param.OrderType + reqBody["sz"] = param.Size + + if param.CCY != "" { + reqBody["ccy"] = param.CCY + } + if param.ClientOrdId != "" { + reqBody["clOrdId"] = param.ClientOrdId + } else { + if ok.customCIDFunc != nil { + param.ClientOrdId = ok.customCIDFunc() + } else { + param.ClientOrdId = ("0bf60374efe445BC" + strings.Replace(uuid.New().String(), "-", "", 32))[:32] + } + reqBody["clOrdId"] = param.ClientOrdId + } + if param.Tag != "" { + reqBody["tag"] = param.Tag + } + if param.PosSide != "" { + reqBody["posSide"] = param.PosSide + } + if param.Price != "" { + reqBody["px"] = param.Price + } + if param.ReduceOnly != false { + reqBody["reduceOnly"] = param.ReduceOnly + } + + type OrderResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []OrderSummaryV5 `json:"data"` + } + var response OrderResponse + + uri := "/api/v5/trade/order" + + jsonStr, _, _ := ok.BuildRequestBody(reqBody) + err := ok.DoAuthorRequest(http.MethodPost, uri, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + msg := response.Msg + if msg == "" { + if len(response.Data) > 0 { + msg = fmt.Sprintf("code:%d, scode:%s, smsg:%s", response.Code, response.Data[0].SCode, response.Data[0].SMsg) + } else { + msg = fmt.Sprintf("code:%d", response.Code) + } + } + return nil, fmt.Errorf("CreateOrder error:%s", msg) + } + return &response.Data[0], nil +} + +func (ok *OKExV5) CancelOrderV5(instId, ordId, clOrdId string) (*OrderSummaryV5, error) { + + reqBody := make(map[string]interface{}) + + reqBody["instId"] = instId + if ordId != "" { + reqBody["ordId"] = ordId + } + if clOrdId != "" { + reqBody["clOrdId"] = clOrdId + } + + type OrderResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []OrderSummaryV5 `json:"data"` + } + var response OrderResponse + + uri := "/api/v5/trade/cancel-order" + + jsonStr, _, _ := ok.BuildRequestBody(reqBody) + err := ok.DoAuthorRequest(http.MethodPost, uri, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + msg := response.Msg + if msg == "" { + if len(response.Data) > 0 { + msg = fmt.Sprintf("code:%d, scode:%s, smsg:%s", response.Code, response.Data[0].SCode, response.Data[0].SMsg) + } else { + msg = fmt.Sprintf("code:%d", response.Code) + } + } + return nil, fmt.Errorf("CancelOrderV5 error:%s", msg) + } + return &response.Data[0], nil +} + +type PendingOrderParam struct { + InstType string + Uly string + InstId string //产品ID + OrdType string + State string + After string + Before string + Limit string +} + +type OrderV5 struct { + AccFillSz string `json:"accFillSz"` + AvgPx string `json:"avgPx"` + CTime int `json:"cTime,string"` + Category string `json:"category"` + Ccy string `json:"ccy"` + ClOrdID string `json:"clOrdId"` + Fee float64 `json:"fee,string"` + FeeCcy string `json:"feeCcy"` + FillPx string `json:"fillPx"` + FillSz string `json:"fillSz"` + FillTime string `json:"fillTime"` + InstID string `json:"instId"` + InstType string `json:"instType"` + Lever string `json:"lever"` + OrdID string `json:"ordId"` + OrdType string `json:"ordType"` + Pnl string `json:"pnl"` + PosSide string `json:"posSide"` + Px float64 `json:"px,string"` + Rebate string `json:"rebate"` + RebateCcy string `json:"rebateCcy"` + Side string `json:"side"` + SlOrdPx string `json:"slOrdPx"` + SlTriggerPx string `json:"slTriggerPx"` + State string `json:"state"` + Sz float64 `json:"sz,string"` + Tag string `json:"tag"` + TdMode string `json:"tdMode"` + TpOrdPx string `json:"tpOrdPx"` + TpTriggerPx string `json:"tpTriggerPx"` + TradeID string `json:"tradeId"` + UTime int64 `json:"uTime,string"` +} + +func (ok *OKExV5) GetPendingOrders(param *PendingOrderParam) ([]OrderV5, error) { + + reqBody := make(map[string]string) + + if param.InstType != "" { + reqBody["instType"] = param.InstType + } + if param.Uly != "" { + reqBody["uly"] = param.Uly + } + if param.InstId != "" { + reqBody["instId"] = param.InstId + } + if param.OrdType != "" { + reqBody["ordType"] = param.OrdType + } + if param.State != "" { + reqBody["state"] = param.State + } + if param.Before != "" { + reqBody["before"] = param.Before + } + if param.After != "" { + reqBody["after"] = param.After + } + if param.Limit != "" { + reqBody["limit"] = param.Limit + } + + type OrderResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []OrderV5 `json:"data"` + } + var response OrderResponse + + uri := url.Values{} + for k, v := range reqBody { + uri.Set(k, v) + } + path := "/api/v5/trade/orders-pending" + if len(reqBody) > 0 { + path = fmt.Sprintf("%s?%s", path, uri.Encode()) + } + + jsonStr, _, _ := ok.BuildRequestBody(reqBody) + err := ok.DoAuthorRequest(http.MethodGet, path, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetPendingOrders error:%s", response.Msg) + } + return response.Data, nil +} + +func (ok *OKExV5) GetOrderV5(instId, ordId, clOrdId string) (*OrderV5, error) { + + reqBody := make(map[string]string) + + reqBody["instId"] = instId + if ordId != "" { + reqBody["ordId"] = ordId + } + if clOrdId != "" { + reqBody["clOrdId"] = clOrdId + } + + type OrderResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []OrderV5 `json:"data"` + } + var response OrderResponse + + uri := url.Values{} + for k, v := range reqBody { + uri.Set(k, v) + } + path := "/api/v5/trade/order" + if len(reqBody) > 0 { + path = fmt.Sprintf("%s?%s", path, uri.Encode()) + } + + jsonStr, _, _ := ok.BuildRequestBody(reqBody) + err := ok.DoAuthorRequest(http.MethodGet, path, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetOrderV5 error:%s", response.Msg) + } + return &response.Data[0], nil +} + +func (ok *OKExV5) GetOrderHistory(instType, instId, ordType, state, afterID, beforeID string) ([]OrderV5, error) { + + reqBody := make(map[string]string) + + reqBody["instType"] = instType + if instId != "" { + reqBody["instId"] = instId + } + if ordType != "" { + reqBody["ordType"] = ordType + } + if state != "" { + reqBody["state"] = state + } + if afterID != "" { + reqBody["after"] = afterID + } + if beforeID != "" { + reqBody["before"] = beforeID + } + // reqBody["limit"] = "100" + + type OrderResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []OrderV5 `json:"data"` + } + var response OrderResponse + + uri := url.Values{} + for k, v := range reqBody { + uri.Set(k, v) + } + path := "/api/v5/trade/orders-history-archive" + if len(reqBody) > 0 { + path = fmt.Sprintf("%s?%s", path, uri.Encode()) + } + + jsonStr, _, _ := ok.BuildRequestBody(reqBody) + err := ok.DoAuthorRequest(http.MethodGet, path, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetOrderV5 error:%s", response.Msg) + } + return response.Data, nil +} + +type AssetSummary struct { + Currency string `json:"ccy"` + Total float64 `json:"bal"` + Available float64 `json:"availBal,string"` + Frozen float64 `json:"frozenBal,string"` +} + +func (ok *OKExV5) GetAssetBalances(currency string) ([]AssetSummary, error) { + + reqBody := make(map[string]interface{}) + + path := "/api/v5/asset/balances" + jsonStr := "" + reqBody["ccy"] = currency + if currency != "" { + reqBody["ccy"] = currency + jsonStr, _, _ = ok.BuildRequestBody(reqBody) + path = fmt.Sprintf("%s?ccy=%s", path, currency) + } + + type AssetSummaryResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []AssetSummary `json:"data"` + } + var response AssetSummaryResponse + + err := ok.DoAuthorRequest(http.MethodGet, path, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetAssetBalances error:%s", response.Msg) + } + return response.Data, nil +} + +type BalanceV5 struct { + AdjEq string `json:"adjEq"` + Details []BalanceDetail `json:"details"` + Imr string `json:"imr"` + IsoEq string `json:"isoEq"` + MgnRatio string `json:"mgnRatio"` + Mmr string `json:"mmr"` + OrdFroz string `json:"ordFroz"` + TotalEq string `json:"totalEq"` + UTime string `json:"uTime"` +} + +type BalanceDetail struct { + Available string `json:"availBal"` + AvailEq string `json:"availEq"` + CashBal string `json:"cashBal"` + Currency string `json:"ccy"` + DisEq string `json:"disEq"` + Eq string `json:"eq"` + Frozen string `json:"frozenBal"` + Interest string `json:"interest"` + IsoEq string `json:"isoEq"` + Liab string `json:"liab"` + MgnRatio string `json:"mgnRatio"` + OrdFrozen string `json:"ordFrozen"` + UTime string `json:"uTime"` + Upl string `json:"upl"` + UplLiab string `json:"uplLiab"` +} + +func (ok *OKExV5) GetAccountBalances(currency string) (*BalanceV5, error) { + + reqBody := make(map[string]interface{}) + + path := "/api/v5/account/balance" + jsonStr := "" + reqBody["ccy"] = currency + if currency != "" { + reqBody["ccy"] = currency + jsonStr, _, _ = ok.BuildRequestBody(reqBody) + path = fmt.Sprintf("%s?ccy=%s", path, currency) + } + + type BalanceV5Response struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []BalanceV5 `json:"data"` + } + var response BalanceV5Response + + err := ok.DoAuthorRequest(http.MethodGet, path, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + return nil, fmt.Errorf("GetAccountBalances error:%s", response.Msg) + } + return &response.Data[0], nil +} diff --git a/okex/v5/OKExV5Spot.go b/okex/v5/OKExV5Spot.go new file mode 100644 index 00000000..23a6281f --- /dev/null +++ b/okex/v5/OKExV5Spot.go @@ -0,0 +1,390 @@ +package okex + +import ( + "math" + "strconv" + "time" + + "github.com/nntaoli-project/goex" + . "github.com/nntaoli-project/goex" +) + +type OKExV5Spot struct { + *OKExV5 +} + +func NewOKExV5Spot(config *APIConfig) *OKExV5Spot { + if config.Endpoint == "" { + config.Endpoint = v5RestBaseUrl + } + okex := &OKExV5Spot{OKExV5: NewOKExV5(config)} + return okex +} + +// private API +func (ok *OKExV5Spot) LimitBuy(amount, price string, currency CurrencyPair, opt ...LimitOrderOptionalParameter) (*Order, error) { + ty := "limit" + if len(opt) > 0 { + ty = opt[0].String() + } + + response, err := ok.CreateOrder(&CreateOrderParam{ + Symbol: currency.ToSymbol("-"), + TradeMode: "cash", + Side: "buy", + OrderType: ty, + Size: amount, + Price: price, + }) + if err != nil { + return nil, err + } + return &Order{ + Currency: currency, + Price: ToFloat64(price), + Amount: ToFloat64(amount), + Cid: response.ClientOrdId, + OrderID2: response.OrdId, + }, nil + +} +func (ok *OKExV5Spot) LimitSell(amount, price string, currency CurrencyPair, opt ...LimitOrderOptionalParameter) (*Order, error) { + ty := "limit" + if len(opt) > 0 { + ty = opt[0].String() + } + + response, err := ok.CreateOrder(&CreateOrderParam{ + Symbol: currency.ToSymbol("-"), + TradeMode: "cash", + Side: "sell", + OrderType: ty, + Size: amount, + Price: price, + }) + if err != nil { + return nil, err + } + return &Order{ + Currency: currency, + Price: ToFloat64(price), + Amount: ToFloat64(amount), + Cid: response.ClientOrdId, + OrderID2: response.OrdId, + }, nil + +} +func (ok *OKExV5Spot) MarketBuy(amount, price string, currency CurrencyPair) (*Order, error) { + + response, err := ok.CreateOrder(&CreateOrderParam{ + Symbol: currency.ToSymbol("-"), + TradeMode: "cash", + Side: "buy", + OrderType: "market", + Size: amount, + }) + if err != nil { + return nil, err + } + return &Order{ + Currency: currency, + Amount: ToFloat64(amount), + Cid: response.ClientOrdId, + OrderID2: response.OrdId, + }, nil + +} +func (ok *OKExV5Spot) MarketSell(amount, price string, currency CurrencyPair) (*Order, error) { + + response, err := ok.CreateOrder(&CreateOrderParam{ + Symbol: currency.ToSymbol("-"), + TradeMode: "cash", + Side: "sell", + OrderType: "market", + Size: amount, + }) + if err != nil { + return nil, err + } + return &Order{ + Currency: currency, + Amount: ToFloat64(amount), + Cid: response.ClientOrdId, + OrderID2: response.OrdId, + }, nil + +} +func (ok *OKExV5Spot) CancelOrder(orderId string, currency CurrencyPair) (bool, error) { + _, err := ok.CancelOrderV5(currency.ToSymbol("-"), orderId, "") + if err != nil { + return false, err + } + return true, nil + +} +func (ok *OKExV5Spot) GetOneOrder(orderId string, currency CurrencyPair) (*Order, error) { + response, err := ok.GetOrderV5(currency.ToSymbol("-"), orderId, "") + if err != nil { + return nil, err + } + status := ORDER_UNFINISH + switch response.State { + case "canceled": + status = ORDER_CANCEL + case "live": + status = ORDER_UNFINISH + case "partially_filled": + status = ORDER_PART_FINISH + case "filled": + status = ORDER_FINISH + default: + status = ORDER_UNFINISH + } + + side := BUY + if response.Side == "sell" || response.Side == "SELL" { + side = SELL + } + return &Order{ + Price: response.Px, + Amount: response.Sz, + AvgPrice: ToFloat64(response.AvgPx), + DealAmount: ToFloat64(response.AccFillSz), + Fee: response.Fee, + Cid: response.ClOrdID, + OrderID2: response.OrdID, + Status: status, + Currency: currency, + Side: side, + Type: response.OrdType, + OrderTime: response.CTime, + FinishedTime: response.UTime, + }, nil +} + +func (ok *OKExV5Spot) GetUnfinishOrders(currency CurrencyPair) ([]Order, error) { + response, err := ok.GetPendingOrders(&PendingOrderParam{ + InstType: "SPOT", + InstId: currency.ToSymbol("-"), + }) + if err != nil { + return nil, err + } + orders := make([]Order, 0) + for _, v := range response { + status := ORDER_UNFINISH + switch v.State { + case "canceled": + status = ORDER_CANCEL + case "live": + status = ORDER_UNFINISH + case "partially_filled": + status = ORDER_PART_FINISH + case "filled": + status = ORDER_FINISH + default: + status = ORDER_UNFINISH + } + + side := BUY + if v.Side == "sell" || v.Side == "SELL" { + side = SELL + } + orders = append(orders, Order{ + Price: v.Px, + Amount: v.Sz, + AvgPrice: ToFloat64(v.AvgPx), + DealAmount: ToFloat64(v.AccFillSz), + Fee: v.Fee, + Cid: v.ClOrdID, + OrderID2: v.OrdID, + Status: status, + Currency: currency, + Side: side, + Type: v.OrdType, + OrderTime: v.CTime, + FinishedTime: v.UTime, + }) + } + return orders, nil +} + +func (ok *OKExV5Spot) GetOrderHistorys(currency CurrencyPair, opt ...OptionalParameter) ([]Order, error) { + response, err := ok.GetOrderHistory( + "SPOT", + "", //currency.ToSymbol("-"), + "", "", "", "", + ) + if err != nil { + return nil, err + } + orders := make([]Order, 0) + for _, v := range response { + status := ORDER_UNFINISH + switch v.State { + case "canceled": + status = ORDER_CANCEL + case "live": + status = ORDER_UNFINISH + case "partially_filled": + status = ORDER_PART_FINISH + case "filled": + status = ORDER_FINISH + default: + status = ORDER_UNFINISH + } + + side := BUY + if v.Side == "sell" || v.Side == "SELL" { + side = SELL + } + + orders = append(orders, Order{ + Price: v.Px, + Amount: v.Sz, + AvgPrice: ToFloat64(v.AvgPx), + DealAmount: ToFloat64(v.AccFillSz), + Fee: v.Fee, + Cid: v.ClOrdID, + OrderID2: v.OrdID, + Status: status, + Currency: goex.NewCurrencyPair3(v.InstID, "-"), + Side: side, + Type: v.OrdType, + OrderTime: v.CTime, + FinishedTime: v.UTime, + }) + } + return orders, nil +} + +func (ok *OKExV5Spot) GetAccount() (*Account, error) { + response, err := ok.GetAccountBalances("") + if err != nil { + return nil, err + } + account := &Account{ + SubAccounts: make(map[Currency]SubAccount, 2)} + for _, itm := range response.Details { + currency := NewCurrency(itm.Currency, "") + account.SubAccounts[currency] = SubAccount{ + Currency: currency, + ForzenAmount: ToFloat64(itm.Frozen), + Amount: math.Max(ToFloat64(itm.Available), ToFloat64(itm.AvailEq)), + } + } + + return account, nil +} + +// public API + +func (ok *OKExV5Spot) GetTicker(currency CurrencyPair) (*Ticker, error) { + ticker, err := ok.GetTickerV5(currency.ToSymbol("-")) + if err != nil { + return nil, err + } + return &Ticker{ + Pair: currency, + Last: ticker.Last, + Buy: ticker.BuyPrice, + Sell: ticker.SellPrice, + High: ticker.High, + Low: ticker.Low, + Vol: ticker.Vol, + Date: ticker.Timestamp, + }, nil +} + +func (ok *OKExV5Spot) GetDepth(size int, currency CurrencyPair) (*Depth, error) { + d, err := ok.GetDepthV5(currency.ToSymbol("-"), size) + if err != nil { + return nil, err + } + + depth := &Depth{} + + for _, ask := range d.Asks { + depth.AskList = append(depth.AskList, DepthRecord{Price: ToFloat64(ask[0]), Amount: ToFloat64(ask[1])}) + } + for _, bid := range d.Bids { + depth.BidList = append(depth.BidList, DepthRecord{Price: ToFloat64(bid[0]), Amount: ToFloat64(bid[1])}) + } + depth.UTime = time.Unix(0, int64(d.Timestamp)*1000000) + return depth, nil +} + +func (ok *OKExV5Spot) GetKlineRecords(currency CurrencyPair, period KlinePeriod, size int, optional ...OptionalParameter) ([]Kline, error) { + // [1m/3m/5m/15m/30m/1H/2H/4H/6H/12H/1D/1W/1M/3M/6M/1Y] + bar := "1D" + switch period { + case KLINE_PERIOD_1MIN: + bar = "1m" + case KLINE_PERIOD_3MIN: + bar = "3m" + case KLINE_PERIOD_5MIN: + bar = "5m" + case KLINE_PERIOD_15MIN: + bar = "15m" + case KLINE_PERIOD_30MIN: + bar = "30m" + case KLINE_PERIOD_1H, KLINE_PERIOD_60MIN: + bar = "1H" + case KLINE_PERIOD_2H: + bar = "2H" + case KLINE_PERIOD_4H: + bar = "4H" + case KLINE_PERIOD_6H: + bar = "6H" + case KLINE_PERIOD_12H: + bar = "12H" + case KLINE_PERIOD_1DAY: + bar = "1D" + case KLINE_PERIOD_1WEEK: + bar = "1W" + default: + bar = "1D" + } + after, before, limit := "", "", strconv.Itoa(size) + + for _, opt := range optional { + for k, v := range opt { + if k == "after" { + after = v.(string) + } + if k == "before" { + before = v.(string) + } + } + } + kl, err := ok.GetKlineRecordsV5(currency.ToSymbol("-"), after, before, bar, limit) + if err != nil { + return nil, err + } + + klines := make([]Kline, 0) + + for _, k := range kl { + klines = append(klines, Kline{ + Pair: currency, + Timestamp: ToInt64(k[0]), + Open: ToFloat64(k[1]), + High: ToFloat64(k[2]), + Low: ToFloat64(k[3]), + Close: ToFloat64(k[4]), + Vol: ToFloat64(k[5]), + }) + } + + return klines, nil + +} + +//非个人,整个交易所的交易记录 +func (ok *OKExV5Spot) GetTrades(currencyPair CurrencyPair, since int64) ([]Trade, error) { + panic("not support") +} + +func (ok *OKExV5Spot) GetExchangeName() string { + return ok.ExchangeName() + "_v5_spot" +} diff --git a/okex/v5/OKExV5Spot_test.go b/okex/v5/OKExV5Spot_test.go new file mode 100644 index 00000000..22f7e482 --- /dev/null +++ b/okex/v5/OKExV5Spot_test.go @@ -0,0 +1,68 @@ +package okex + +import ( + "net/http" + "net/url" + "testing" + + "github.com/nntaoli-project/goex" +) + +func newOKExV5SpotClient() *OKExV5Spot { + return NewOKExV5Spot(&goex.APIConfig{ + HttpClient: &http.Client{ + Transport: &http.Transport{ + Proxy: func(req *http.Request) (*url.URL, error) { + return &url.URL{ + Scheme: "socks5", + Host: "127.0.0.1:1080"}, nil + }, + }, + }, + Endpoint: "https://www.okex.com", + ApiKey: "", + ApiSecretKey: "", + ApiPassphrase: "", + }) +} + +func TestOKExV5Spot_GetTicker(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.GetTicker(goex.BTC_USDT)) +} + +func TestOKExV5Spot_GetDepth(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.GetDepth(5, goex.BTC_USDT)) +} + +func TestOKExV5SpotGetKlineRecords(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.GetKlineRecords(goex.BTC_USDT, goex.KLINE_PERIOD_1MIN, 10)) +} + +func TestOKExV5Spot_LimitBuy(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.LimitBuy("1", "1.0", goex.XRP_USDT)) + //{"code":"0","data":[{"clOrdId":"0bf60374efe445BC258eddf46df044c3","ordId":"305267682086109184","sCode":"0","sMsg":"","tag":""}],"msg":""}} +} + +func TestOKExV5Spot_CancelOrder(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.CancelOrder("305267682086109184", goex.XRP_USDT)) +} + +func TestOKExV5Spot_GetUnfinishOrders(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.GetUnfinishOrders(goex.XRP_USDT)) +} + +func TestOKExV5Spot_GetOneOrder(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.GetOneOrder("305267682086109184", goex.XRP_USDT)) +} + +func TestOKExV5Spot_GetAccount(t *testing.T) { + c := newOKExV5SpotClient() + t.Log(c.GetAccount()) +} diff --git a/okex/v5/OKExV5_test.go b/okex/v5/OKExV5_test.go new file mode 100644 index 00000000..de0db1cb --- /dev/null +++ b/okex/v5/OKExV5_test.go @@ -0,0 +1,44 @@ +package okex + +import ( + "fmt" + "net/http" + "net/url" + "testing" + + "github.com/nntaoli-project/goex" +) + +func newOKExV5Client() *OKExV5 { + return NewOKExV5(&goex.APIConfig{ + HttpClient: &http.Client{ + Transport: &http.Transport{ + Proxy: func(req *http.Request) (*url.URL, error) { + return &url.URL{ + Scheme: "socks5", + Host: "127.0.0.1:1080"}, nil + }, + }, + }, + Endpoint: "https://www.okex.com", + ApiKey: "", + ApiSecretKey: "", + ApiPassphrase: "", + }) +} + +func TestOKExV5_GetTicker(t *testing.T) { + o := newOKExV5Client() + fmt.Println(o.GetTickerV5("BTC-USD-SWAP")) +} + +func TestOKExV5_GetDepth(t *testing.T) { + o := newOKExV5Client() + fmt.Println(o.GetDepthV5("BTC-USD-SWAP", 0)) +} + +func TestOKExV5_GetKlineRecordsV5(t *testing.T) { + o := newOKExV5Client() + fmt.Println(o.GetKlineRecordsV5("BTC-USDT", "", "", "", "")) + +} From 322ecdb9b1470111a05742186daafb956c55dffa Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Tue, 4 Jan 2022 17:08:37 +0800 Subject: [PATCH 05/34] [APIBuilder] new okex api v5 --- builder/APIBuilder.go | 11 ++++++++++- go.mod | 1 - go.sum | 10 ---------- okex/v5/OKExV5Spot.go | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/builder/APIBuilder.go b/builder/APIBuilder.go index 1b43146c..1e044c96 100644 --- a/builder/APIBuilder.go +++ b/builder/APIBuilder.go @@ -29,6 +29,7 @@ import ( "github.com/nntaoli-project/goex/huobi" "github.com/nntaoli-project/goex/kraken" "github.com/nntaoli-project/goex/okex" + okexV5 "github.com/nntaoli-project/goex/okex/v5" "github.com/nntaoli-project/goex/poloniex" "github.com/nntaoli-project/goex/zb" ) @@ -213,7 +214,7 @@ func (builder *APIBuilder) Build(exName string) (api API) { Endpoint: builder.endPoint, ApiKey: builder.apiKey, ApiSecretKey: builder.secretkey}) - case OKEX_V3, OKEX: + case OKEX_V3: _api = okex.NewOKEx(&APIConfig{ HttpClient: builder.client, ApiKey: builder.apiKey, @@ -221,6 +222,14 @@ func (builder *APIBuilder) Build(exName string) (api API) { ApiPassphrase: builder.apiPassphrase, Endpoint: builder.endPoint, }) + case OKEX: + _api = okexV5.NewOKExV5Spot(&APIConfig{ + HttpClient: builder.client, + ApiKey: builder.apiKey, + ApiSecretKey: builder.secretkey, + ApiPassphrase: builder.apiPassphrase, + Endpoint: builder.endPoint, + }) case BITFINEX: _api = bitfinex.New(builder.client, builder.apiKey, builder.secretkey) case KRAKEN: diff --git a/go.mod b/go.mod index 50b7dc6c..89a0eebe 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/go-openapi/errors v0.19.4 github.com/google/uuid v1.1.1 github.com/gorilla/websocket v1.4.1 - github.com/json-iterator/go v1.1.7 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/nubo/jwt v0.0.0-20150918093313-da5b79c3bbaf github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index 8681b463..c5375383 100644 --- a/go.sum +++ b/go.sum @@ -1,31 +1,22 @@ github.com/Kucoin/kucoin-go-sdk v1.2.7 h1:lh74YnCmcswmnvkk0nMeodw+y17UEjMhyEzrIS14SDs= github.com/Kucoin/kucoin-go-sdk v1.2.7/go.mod h1:Wz3fTuM5gIct9chN6H6OBCXbku10XEcAjH5g/FL3wIY= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-openapi/errors v0.19.4 h1:fSGwO1tSYHFu70NKaWJt5Qh0qoBRtCm/mXS1yhf+0W0= github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/nubo/jwt v0.0.0-20150918093313-da5b79c3bbaf h1:mP7zQzhCrNQgSdCpxFxyZV/JMHbz4LJsyppAZMQVrI0= github.com/nubo/jwt v0.0.0-20150918093313-da5b79c3bbaf/go.mod h1:LuR7jHS+7SJ6EywD7zZiO6h0vwTBSevFk5wunVt3gf4= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -50,7 +41,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/okex/v5/OKExV5Spot.go b/okex/v5/OKExV5Spot.go index 23a6281f..52a3d49e 100644 --- a/okex/v5/OKExV5Spot.go +++ b/okex/v5/OKExV5Spot.go @@ -386,5 +386,5 @@ func (ok *OKExV5Spot) GetTrades(currencyPair CurrencyPair, since int64) ([]Trade } func (ok *OKExV5Spot) GetExchangeName() string { - return ok.ExchangeName() + "_v5_spot" + return ok.ExchangeName() } From 38f7b95741f36aab906301bed0f7c112e0e50b42 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Tue, 4 Jan 2022 17:16:54 +0800 Subject: [PATCH 06/34] upgrade testify version to v1.7.0 --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 89a0eebe..175cc35e 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/gorilla/websocket v1.4.1 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/nubo/jwt v0.0.0-20150918093313-da5b79c3bbaf - github.com/stretchr/testify v1.4.0 + github.com/stretchr/testify v1.7.0 github.com/valyala/fasthttp v1.6.0 golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect ) diff --git a/go.sum b/go.sum index c5375383..73790984 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY= @@ -47,5 +47,5 @@ golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From f52f5d4effc0e81f690adacb0fe40a1400cd5a14 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Thu, 24 Feb 2022 16:43:26 +0800 Subject: [PATCH 07/34] update donate crypt coin address --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b3e94763..c115830f 100644 --- a/README.md +++ b/README.md @@ -59,11 +59,11 @@ require ( donate ----------------- -BTC:13cBHLk6B7t3Uj7caJbCwv1UaiuiA6Qx8z +BTC:bc1qm4fz8vg78yr75syclch9zfnwa0x00efy95972s -LTC:LVxM7y1K2dnpuNBU42ei3dKzPySf4VAm1H +LTC:MPgBjHmecACXDKH3KdmLR6X8mmp5YgAEZS -ETH:0x98573ddb33cdddce480c3bc1f9279ccd88ca1e93 +ETH:0xDEa8C4B6B36294B00b05B6A6A5b63d8aA52A1bF7 ### 欢迎为作者付一碗面钱 From f1f96bf7fd829445fc75ba718555324a36a5de87 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Sat, 26 Feb 2022 11:57:26 +0800 Subject: [PATCH 08/34] simple modifications --- Models.go | 2 +- okex/v5/OKExV5.go | 10 ---------- okex/v5/OKExV5Spot.go | 1 + 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/Models.go b/Models.go index 6cde1069..ef78a556 100644 --- a/Models.go +++ b/Models.go @@ -302,7 +302,7 @@ func (optional OptionalParameter) GetFloat64(name string) float64 { } func (optional OptionalParameter) GetTime(name string) *time.Time { - val := optional["name"] + val := optional[name] if val != nil { t, ok := val.(time.Time) if ok { diff --git a/okex/v5/OKExV5.go b/okex/v5/OKExV5.go index b1c519e6..04aa4701 100644 --- a/okex/v5/OKExV5.go +++ b/okex/v5/OKExV5.go @@ -10,7 +10,6 @@ import ( "strings" "time" - "github.com/google/uuid" . "github.com/nntaoli-project/goex" "github.com/nntaoli-project/goex/internal/logger" ) @@ -47,10 +46,6 @@ func (ok *OKExV5) ExchangeName() string { return OKEX } -func (ok *OKExV5) UUID() string { - return strings.Replace(uuid.New().String(), "-", "", 32) -} - func (ok *OKExV5) SetCustomCID(f func() string) { ok.customCIDFunc = f } @@ -289,11 +284,6 @@ func (ok *OKExV5) CreateOrder(param *CreateOrderParam) (*OrderSummaryV5, error) if param.ClientOrdId != "" { reqBody["clOrdId"] = param.ClientOrdId } else { - if ok.customCIDFunc != nil { - param.ClientOrdId = ok.customCIDFunc() - } else { - param.ClientOrdId = ("0bf60374efe445BC" + strings.Replace(uuid.New().String(), "-", "", 32))[:32] - } reqBody["clOrdId"] = param.ClientOrdId } if param.Tag != "" { diff --git a/okex/v5/OKExV5Spot.go b/okex/v5/OKExV5Spot.go index 52a3d49e..197dfc1f 100644 --- a/okex/v5/OKExV5Spot.go +++ b/okex/v5/OKExV5Spot.go @@ -311,6 +311,7 @@ func (ok *OKExV5Spot) GetDepth(size int, currency CurrencyPair) (*Depth, error) depth.BidList = append(depth.BidList, DepthRecord{Price: ToFloat64(bid[0]), Amount: ToFloat64(bid[1])}) } depth.UTime = time.Unix(0, int64(d.Timestamp)*1000000) + depth.Pair = currency return depth, nil } From 1eba7753d206608a16a3ecd0d10158333155a6b2 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Sat, 26 Feb 2022 12:15:44 +0800 Subject: [PATCH 09/34] [okexv5] GetKlineRecords API --- okex/v5/OKExV5.go | 53 +++++++++++++++++++++++++++----------- okex/v5/OKExV5Spot.go | 50 +++++------------------------------ okex/v5/OKExV5Spot_test.go | 25 ++++++++++-------- okex/v5/OKExV5_test.go | 21 +++++++-------- 4 files changed, 69 insertions(+), 80 deletions(-) diff --git a/okex/v5/OKExV5.go b/okex/v5/OKExV5.go index 04aa4701..1f9b992c 100644 --- a/okex/v5/OKExV5.go +++ b/okex/v5/OKExV5.go @@ -143,31 +143,21 @@ func (ok *OKExV5) GetDepthV5(instId string, size int) (*DepthV5, error) { return &response.Data[0], nil } -func (ok *OKExV5) GetKlineRecordsV5(instId, after, before, bar, limit string) ([][]string, error) { +func (ok *OKExV5) GetKlineRecordsV5(instId string, period KlinePeriod, params *url.Values) ([][]string, error) { + urlPath := fmt.Sprintf("%s/api/v5/market/candles?instId=%s&bar=%s", ok.config.Endpoint, instId, ok.adaptKLineBar(period)) - urlPath := fmt.Sprintf("%s/api/v5/market/candles?instId=%s", ok.config.Endpoint, instId) - params := url.Values{} - if after != "" { - params.Set("after", after) - } - if before != "" { - params.Set("before", before) - } - if bar != "" { - params.Set("bar", bar) - } - if limit != "" { - params.Set("limit", limit) - } if params.Encode() != "" { urlPath = fmt.Sprintf("%s&%s", urlPath, params.Encode()) } + logger.Debugf("[OKExV5] GetKlineRecordsV5 Url: %s", urlPath) + type CandleResponse struct { Code int `json:"code,string"` Msg string `json:"msg"` Data [][]string `json:"data"` } + var response CandleResponse err := HttpGet4(ok.config.HttpClient, urlPath, nil, &response) if err != nil { @@ -660,3 +650,36 @@ func (ok *OKExV5) GetAccountBalances(currency string) (*BalanceV5, error) { } return &response.Data[0], nil } + +func (ok *OKExV5) adaptKLineBar(period KlinePeriod) string { + bar := "1D" + switch period { + case KLINE_PERIOD_1MIN: + bar = "1m" + case KLINE_PERIOD_3MIN: + bar = "3m" + case KLINE_PERIOD_5MIN: + bar = "5m" + case KLINE_PERIOD_15MIN: + bar = "15m" + case KLINE_PERIOD_30MIN: + bar = "30m" + case KLINE_PERIOD_1H, KLINE_PERIOD_60MIN: + bar = "1H" + case KLINE_PERIOD_2H: + bar = "2H" + case KLINE_PERIOD_4H: + bar = "4H" + case KLINE_PERIOD_6H: + bar = "6H" + case KLINE_PERIOD_12H: + bar = "12H" + case KLINE_PERIOD_1DAY: + bar = "1D" + case KLINE_PERIOD_1WEEK: + bar = "1W" + default: + bar = "1D" + } + return bar +} diff --git a/okex/v5/OKExV5Spot.go b/okex/v5/OKExV5Spot.go index 197dfc1f..0e6bd024 100644 --- a/okex/v5/OKExV5Spot.go +++ b/okex/v5/OKExV5Spot.go @@ -1,8 +1,9 @@ package okex import ( + "fmt" "math" - "strconv" + "net/url" "time" "github.com/nntaoli-project/goex" @@ -317,48 +318,11 @@ func (ok *OKExV5Spot) GetDepth(size int, currency CurrencyPair) (*Depth, error) func (ok *OKExV5Spot) GetKlineRecords(currency CurrencyPair, period KlinePeriod, size int, optional ...OptionalParameter) ([]Kline, error) { // [1m/3m/5m/15m/30m/1H/2H/4H/6H/12H/1D/1W/1M/3M/6M/1Y] - bar := "1D" - switch period { - case KLINE_PERIOD_1MIN: - bar = "1m" - case KLINE_PERIOD_3MIN: - bar = "3m" - case KLINE_PERIOD_5MIN: - bar = "5m" - case KLINE_PERIOD_15MIN: - bar = "15m" - case KLINE_PERIOD_30MIN: - bar = "30m" - case KLINE_PERIOD_1H, KLINE_PERIOD_60MIN: - bar = "1H" - case KLINE_PERIOD_2H: - bar = "2H" - case KLINE_PERIOD_4H: - bar = "4H" - case KLINE_PERIOD_6H: - bar = "6H" - case KLINE_PERIOD_12H: - bar = "12H" - case KLINE_PERIOD_1DAY: - bar = "1D" - case KLINE_PERIOD_1WEEK: - bar = "1W" - default: - bar = "1D" - } - after, before, limit := "", "", strconv.Itoa(size) - - for _, opt := range optional { - for k, v := range opt { - if k == "after" { - after = v.(string) - } - if k == "before" { - before = v.(string) - } - } - } - kl, err := ok.GetKlineRecordsV5(currency.ToSymbol("-"), after, before, bar, limit) + param := &url.Values{} + param.Set("limit", fmt.Sprint(size)) + MergeOptionalParameter(param, optional...) + + kl, err := ok.GetKlineRecordsV5(currency.ToSymbol("-"), period, param) if err != nil { return nil, err } diff --git a/okex/v5/OKExV5Spot_test.go b/okex/v5/OKExV5Spot_test.go index 22f7e482..24eaee7f 100644 --- a/okex/v5/OKExV5Spot_test.go +++ b/okex/v5/OKExV5Spot_test.go @@ -1,8 +1,7 @@ package okex import ( - "net/http" - "net/url" + log "github.com/nntaoli-project/goex/internal/logger" "testing" "github.com/nntaoli-project/goex" @@ -10,15 +9,15 @@ import ( func newOKExV5SpotClient() *OKExV5Spot { return NewOKExV5Spot(&goex.APIConfig{ - HttpClient: &http.Client{ - Transport: &http.Transport{ - Proxy: func(req *http.Request) (*url.URL, error) { - return &url.URL{ - Scheme: "socks5", - Host: "127.0.0.1:1080"}, nil - }, - }, - }, + //HttpClient: &http.Client{ + // Transport: &http.Transport{ + // Proxy: func(req *http.Request) (*url.URL, error) { + // return &url.URL{ + // Scheme: "socks5", + // Host: "192.168.1.29:2222"}, nil + // }, + // }, + //}, Endpoint: "https://www.okex.com", ApiKey: "", ApiSecretKey: "", @@ -26,6 +25,10 @@ func newOKExV5SpotClient() *OKExV5Spot { }) } +func init() { + log.SetLevel(log.DEBUG) +} + func TestOKExV5Spot_GetTicker(t *testing.T) { c := newOKExV5SpotClient() t.Log(c.GetTicker(goex.BTC_USDT)) diff --git a/okex/v5/OKExV5_test.go b/okex/v5/OKExV5_test.go index de0db1cb..c99314cf 100644 --- a/okex/v5/OKExV5_test.go +++ b/okex/v5/OKExV5_test.go @@ -2,7 +2,6 @@ package okex import ( "fmt" - "net/http" "net/url" "testing" @@ -11,15 +10,15 @@ import ( func newOKExV5Client() *OKExV5 { return NewOKExV5(&goex.APIConfig{ - HttpClient: &http.Client{ - Transport: &http.Transport{ - Proxy: func(req *http.Request) (*url.URL, error) { - return &url.URL{ - Scheme: "socks5", - Host: "127.0.0.1:1080"}, nil - }, - }, - }, + //HttpClient: &http.Client{ + // Transport: &http.Transport{ + // Proxy: func(req *http.Request) (*url.URL, error) { + // return &url.URL{ + // Scheme: "socks5", + // Host: "127.0.0.1:2222"}, nil + // }, + // }, + //}, Endpoint: "https://www.okex.com", ApiKey: "", ApiSecretKey: "", @@ -39,6 +38,6 @@ func TestOKExV5_GetDepth(t *testing.T) { func TestOKExV5_GetKlineRecordsV5(t *testing.T) { o := newOKExV5Client() - fmt.Println(o.GetKlineRecordsV5("BTC-USDT", "", "", "", "")) + fmt.Println(o.GetKlineRecordsV5("BTC-USD-SWAP", goex.KLINE_PERIOD_1H, &url.Values{})) } From 79c7fc3cb473e2f368aba376f43fda6c2e4913e5 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Mon, 7 Mar 2022 00:22:36 +0800 Subject: [PATCH 10/34] [okex] swap v5 api --- okex/v5/OKExV5Swap.go | 135 +++++++++++++++++++++++++++++++++++++ okex/v5/OKExV5Swap_test.go | 39 +++++++++++ 2 files changed, 174 insertions(+) create mode 100644 okex/v5/OKExV5Swap.go create mode 100644 okex/v5/OKExV5Swap_test.go diff --git a/okex/v5/OKExV5Swap.go b/okex/v5/OKExV5Swap.go new file mode 100644 index 00000000..7db2847e --- /dev/null +++ b/okex/v5/OKExV5Swap.go @@ -0,0 +1,135 @@ +package okex + +import ( + "fmt" + . "github.com/nntaoli-project/goex" + "sort" + "time" +) + +type OKExV5Swap struct { + *OKExV5 +} + +func NewOKExV5Swap(config *APIConfig) *OKExV5Swap { + v5 := new(OKExV5Swap) + v5.OKExV5 = NewOKExV5(config) + return v5 +} + +func (O *OKExV5Swap) GetExchangeName() string { + return OKEX_SWAP +} + +func (O *OKExV5Swap) GetFutureEstimatedPrice(currencyPair CurrencyPair) (float64, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetFutureTicker(currencyPair CurrencyPair, contractType string) (*Ticker, error) { + t, err := O.OKExV5.GetTickerV5(fmt.Sprintf("%s-SWAP", currencyPair.ToSymbol("-"))) + + if err != nil { + return nil, err + } + + return &Ticker{ + Pair: currencyPair, + Last: t.Last, + Buy: t.BuyPrice, + Sell: t.SellPrice, + High: t.High, + Low: t.Low, + Vol: t.Vol, + Date: t.Timestamp, + }, nil +} + +func (O *OKExV5Swap) GetFutureDepth(currencyPair CurrencyPair, contractType string, size int) (*Depth, error) { + instId := fmt.Sprintf("%s-SWAP", currencyPair.ToSymbol("-")) + dep, err := O.OKExV5.GetDepthV5(instId, size) + + if err != nil { + return nil, err + } + + depth := &Depth{} + + for _, ask := range dep.Asks { + depth.AskList = append(depth.AskList, DepthRecord{Price: ToFloat64(ask[0]), Amount: ToFloat64(ask[1])}) + } + + for _, bid := range dep.Bids { + depth.BidList = append(depth.BidList, DepthRecord{Price: ToFloat64(bid[0]), Amount: ToFloat64(bid[1])}) + } + + sort.Sort(sort.Reverse(depth.AskList)) + + depth.Pair = currencyPair + depth.UTime = time.Unix(0, int64(dep.Timestamp)*1000000) + + return depth, nil +} + +func (O *OKExV5Swap) GetFutureIndex(currencyPair CurrencyPair) (float64, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetFutureUserinfo(currencyPair ...CurrencyPair) (*FutureAccount, error) { + panic("implement me") +} + +func (O *OKExV5Swap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, leverRate float64) (string, error) { + panic("implement me") +} + +func (O *OKExV5Swap) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int, opt ...LimitOrderOptionalParameter) (*FutureOrder, error) { + panic("implement me") +} + +func (O *OKExV5Swap) MarketFuturesOrder(currencyPair CurrencyPair, contractType, amount string, openType int) (*FutureOrder, error) { + panic("implement me") +} + +func (O *OKExV5Swap) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetFuturePosition(currencyPair CurrencyPair, contractType string) ([]FuturePosition, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetFutureOrders(orderIds []string, currencyPair CurrencyPair, contractType string) ([]FutureOrder, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetFutureOrder(orderId string, currencyPair CurrencyPair, contractType string) (*FutureOrder, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetUnfinishFutureOrders(currencyPair CurrencyPair, contractType string) ([]FutureOrder, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetFutureOrderHistory(pair CurrencyPair, contractType string, optional ...OptionalParameter) ([]FutureOrder, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetFee() (float64, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetContractValue(currencyPair CurrencyPair) (float64, error) { + panic("implement me") +} + +func (O OKExV5Swap) GetDeliveryTime() (int, int, int, int) { + panic("implement me") +} + +func (O *OKExV5Swap) GetKlineRecords(contractType string, currency CurrencyPair, period KlinePeriod, size int, optional ...OptionalParameter) ([]FutureKline, error) { + panic("implement me") +} + +func (O *OKExV5Swap) GetTrades(contractType string, currencyPair CurrencyPair, since int64) ([]Trade, error) { + panic("implement me") +} diff --git a/okex/v5/OKExV5Swap_test.go b/okex/v5/OKExV5Swap_test.go new file mode 100644 index 00000000..9d203b61 --- /dev/null +++ b/okex/v5/OKExV5Swap_test.go @@ -0,0 +1,39 @@ +package okex + +import ( + "github.com/nntaoli-project/goex" + log "github.com/nntaoli-project/goex/internal/logger" + "net/http" + "testing" +) + +func init() { + log.SetLevel(log.DEBUG) + //os.Setenv("HTTPS_PROXY", "socks5://127.0.0.1:2222") //local socks5 proxy +} + +func TestOKExV5Swap_GetFutureTicker(t *testing.T) { + swap := NewOKExV5Swap(&goex.APIConfig{ + HttpClient: http.DefaultClient, + ApiKey: "", + ApiSecretKey: "", + ApiPassphrase: "", + Lever: 0, + }) + t.Log(swap.GetFutureTicker(goex.BTC_USDT, goex.SWAP_CONTRACT)) +} + +func TestOKExV5Swap_GetFutureDepth(t *testing.T) { + swap := NewOKExV5Swap(&goex.APIConfig{ + HttpClient: http.DefaultClient, + }) + + dep, err := swap.GetFutureDepth(goex.BTC_USDT, goex.SWAP_CONTRACT, 2) + if err != nil { + t.Error(err) + return + } + + t.Log(dep.AskList) + t.Log(dep.BidList) +} From 0a1f1447adefbc526c2fbe617f24d044acf2d396 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 19:22:46 +0000 Subject: [PATCH 11/34] Bump github.com/valyala/fasthttp from 1.6.0 to 1.34.0 Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) from 1.6.0 to 1.34.0. - [Release notes](https://github.com/valyala/fasthttp/releases) - [Commits](https://github.com/valyala/fasthttp/compare/v1.6.0...v1.34.0) --- updated-dependencies: - dependency-name: github.com/valyala/fasthttp dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- go.mod | 3 +-- go.sum | 37 +++++++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 175cc35e..05b8dc04 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,5 @@ require ( github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/nubo/jwt v0.0.0-20150918093313-da5b79c3bbaf github.com/stretchr/testify v1.7.0 - github.com/valyala/fasthttp v1.6.0 - golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect + github.com/valyala/fasthttp v1.34.0 ) diff --git a/go.sum b/go.sum index 73790984..de20202e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/Kucoin/kucoin-go-sdk v1.2.7 h1:lh74YnCmcswmnvkk0nMeodw+y17UEjMhyEzrIS14SDs= github.com/Kucoin/kucoin-go-sdk v1.2.7/go.mod h1:Wz3fTuM5gIct9chN6H6OBCXbku10XEcAjH5g/FL3wIY= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -10,10 +12,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= +github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -34,17 +34,26 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4= +github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From 599d6aa012e738d4fd93c625ee7034e56a82b624 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Sun, 10 Apr 2022 00:07:42 +0800 Subject: [PATCH 12/34] [okex v5] swap GetKlineRecords api --- okex/v5/OKExV5Swap.go | 73 ++++++++++++++++++++++++++------------ okex/v5/OKExV5Swap_test.go | 16 +++++++++ 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/okex/v5/OKExV5Swap.go b/okex/v5/OKExV5Swap.go index 7db2847e..1fe18ccf 100644 --- a/okex/v5/OKExV5Swap.go +++ b/okex/v5/OKExV5Swap.go @@ -3,6 +3,8 @@ package okex import ( "fmt" . "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" + "net/url" "sort" "time" ) @@ -17,16 +19,16 @@ func NewOKExV5Swap(config *APIConfig) *OKExV5Swap { return v5 } -func (O *OKExV5Swap) GetExchangeName() string { +func (ok *OKExV5Swap) GetExchangeName() string { return OKEX_SWAP } -func (O *OKExV5Swap) GetFutureEstimatedPrice(currencyPair CurrencyPair) (float64, error) { +func (ok *OKExV5Swap) GetFutureEstimatedPrice(currencyPair CurrencyPair) (float64, error) { panic("implement me") } -func (O *OKExV5Swap) GetFutureTicker(currencyPair CurrencyPair, contractType string) (*Ticker, error) { - t, err := O.OKExV5.GetTickerV5(fmt.Sprintf("%s-SWAP", currencyPair.ToSymbol("-"))) +func (ok *OKExV5Swap) GetFutureTicker(currencyPair CurrencyPair, contractType string) (*Ticker, error) { + t, err := ok.OKExV5.GetTickerV5(fmt.Sprintf("%s-SWAP", currencyPair.ToSymbol("-"))) if err != nil { return nil, err @@ -44,9 +46,9 @@ func (O *OKExV5Swap) GetFutureTicker(currencyPair CurrencyPair, contractType str }, nil } -func (O *OKExV5Swap) GetFutureDepth(currencyPair CurrencyPair, contractType string, size int) (*Depth, error) { +func (ok *OKExV5Swap) GetFutureDepth(currencyPair CurrencyPair, contractType string, size int) (*Depth, error) { instId := fmt.Sprintf("%s-SWAP", currencyPair.ToSymbol("-")) - dep, err := O.OKExV5.GetDepthV5(instId, size) + dep, err := ok.OKExV5.GetDepthV5(instId, size) if err != nil { return nil, err @@ -70,66 +72,91 @@ func (O *OKExV5Swap) GetFutureDepth(currencyPair CurrencyPair, contractType stri return depth, nil } -func (O *OKExV5Swap) GetFutureIndex(currencyPair CurrencyPair) (float64, error) { +func (ok *OKExV5Swap) GetFutureIndex(currencyPair CurrencyPair) (float64, error) { panic("implement me") } -func (O *OKExV5Swap) GetFutureUserinfo(currencyPair ...CurrencyPair) (*FutureAccount, error) { +func (ok *OKExV5Swap) GetFutureUserinfo(currencyPair ...CurrencyPair) (*FutureAccount, error) { panic("implement me") } -func (O *OKExV5Swap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, leverRate float64) (string, error) { +func (ok *OKExV5Swap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, leverRate float64) (string, error) { panic("implement me") } -func (O *OKExV5Swap) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int, opt ...LimitOrderOptionalParameter) (*FutureOrder, error) { +func (ok *OKExV5Swap) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int, opt ...LimitOrderOptionalParameter) (*FutureOrder, error) { panic("implement me") } -func (O *OKExV5Swap) MarketFuturesOrder(currencyPair CurrencyPair, contractType, amount string, openType int) (*FutureOrder, error) { +func (ok *OKExV5Swap) MarketFuturesOrder(currencyPair CurrencyPair, contractType, amount string, openType int) (*FutureOrder, error) { panic("implement me") } -func (O *OKExV5Swap) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) { +func (ok *OKExV5Swap) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) { panic("implement me") } -func (O *OKExV5Swap) GetFuturePosition(currencyPair CurrencyPair, contractType string) ([]FuturePosition, error) { +func (ok *OKExV5Swap) GetFuturePosition(currencyPair CurrencyPair, contractType string) ([]FuturePosition, error) { panic("implement me") } -func (O *OKExV5Swap) GetFutureOrders(orderIds []string, currencyPair CurrencyPair, contractType string) ([]FutureOrder, error) { +func (ok *OKExV5Swap) GetFutureOrders(orderIds []string, currencyPair CurrencyPair, contractType string) ([]FutureOrder, error) { panic("implement me") } -func (O *OKExV5Swap) GetFutureOrder(orderId string, currencyPair CurrencyPair, contractType string) (*FutureOrder, error) { +func (ok *OKExV5Swap) GetFutureOrder(orderId string, currencyPair CurrencyPair, contractType string) (*FutureOrder, error) { panic("implement me") } -func (O *OKExV5Swap) GetUnfinishFutureOrders(currencyPair CurrencyPair, contractType string) ([]FutureOrder, error) { +func (ok *OKExV5Swap) GetUnfinishFutureOrders(currencyPair CurrencyPair, contractType string) ([]FutureOrder, error) { panic("implement me") } -func (O *OKExV5Swap) GetFutureOrderHistory(pair CurrencyPair, contractType string, optional ...OptionalParameter) ([]FutureOrder, error) { +func (ok *OKExV5Swap) GetFutureOrderHistory(pair CurrencyPair, contractType string, optional ...OptionalParameter) ([]FutureOrder, error) { panic("implement me") } -func (O *OKExV5Swap) GetFee() (float64, error) { +func (ok *OKExV5Swap) GetFee() (float64, error) { panic("implement me") } -func (O *OKExV5Swap) GetContractValue(currencyPair CurrencyPair) (float64, error) { +func (ok *OKExV5Swap) GetContractValue(currencyPair CurrencyPair) (float64, error) { panic("implement me") } -func (O OKExV5Swap) GetDeliveryTime() (int, int, int, int) { +func (ok OKExV5Swap) GetDeliveryTime() (int, int, int, int) { panic("implement me") } -func (O *OKExV5Swap) GetKlineRecords(contractType string, currency CurrencyPair, period KlinePeriod, size int, optional ...OptionalParameter) ([]FutureKline, error) { - panic("implement me") +func (ok *OKExV5Swap) GetKlineRecords(contractType string, currency CurrencyPair, period KlinePeriod, size int, optional ...OptionalParameter) ([]FutureKline, error) { + param := &url.Values{} + param.Set("limit", fmt.Sprint(size)) + MergeOptionalParameter(param, optional...) + + data, err := ok.OKExV5.GetKlineRecordsV5(fmt.Sprintf("%s-SWAP", currency.ToSymbol("-")), period, param) + if err != nil { + return nil, err + } + logger.Debug("[okex v5] kline response data: ", data) + + var klines []FutureKline + for _, item := range data { + klines = append(klines, FutureKline{ + Kline: &Kline{ + Pair: currency, + Timestamp: ToInt64(item[0]) / 1000, + Open: ToFloat64(item[1]), + Close: ToFloat64(item[4]), + High: ToFloat64(item[2]), + Low: ToFloat64(item[3]), + Vol: ToFloat64(item[5]), + }, + }) + } + + return klines, nil } -func (O *OKExV5Swap) GetTrades(contractType string, currencyPair CurrencyPair, since int64) ([]Trade, error) { +func (ok *OKExV5Swap) GetTrades(contractType string, currencyPair CurrencyPair, since int64) ([]Trade, error) { panic("implement me") } diff --git a/okex/v5/OKExV5Swap_test.go b/okex/v5/OKExV5Swap_test.go index 9d203b61..22b3277e 100644 --- a/okex/v5/OKExV5Swap_test.go +++ b/okex/v5/OKExV5Swap_test.go @@ -37,3 +37,19 @@ func TestOKExV5Swap_GetFutureDepth(t *testing.T) { t.Log(dep.AskList) t.Log(dep.BidList) } + +func TestOKExV5Swap_GetKlineRecords(t *testing.T) { + swap := NewOKExV5Swap(&goex.APIConfig{ + HttpClient: http.DefaultClient, + }) + + klines, err := swap.GetKlineRecords(goex.SWAP_CONTRACT, goex.BTC_USDT, goex.KLINE_PERIOD_1H, 2) + if err != nil { + t.Error(err) + return + } + + for _, k := range klines { + t.Logf("%+v", k.Kline) + } +} From 9be1cf4d27f3c15e8dbdd53298129ebcebffcba4 Mon Sep 17 00:00:00 2001 From: WymA Date: Tue, 3 May 2022 23:13:36 +0800 Subject: [PATCH 13/34] 1. fix syntax errors in *_test.go 2. update dependencies --- bigone/BigoneV3_test.go | 5 +++-- binance/BinanceSwap_test.go | 6 +++--- gdax/gdax_test.go | 2 +- go.mod | 8 +++++--- go.sum | 10 ++++++++++ huobi/Hbdm_Ws_test.go | 5 +++-- huobi/Hbdm_test.go | 5 +++-- okex/OKExSwap.go | 3 ++- okex/OKExSwap_test.go | 5 +++-- okex/OKEx_test.go | 9 +++++---- 10 files changed, 38 insertions(+), 20 deletions(-) diff --git a/bigone/BigoneV3_test.go b/bigone/BigoneV3_test.go index 3e36c129..8cb53be5 100644 --- a/bigone/BigoneV3_test.go +++ b/bigone/BigoneV3_test.go @@ -1,10 +1,11 @@ package bigone import ( - . "github.com/nntaoli-project/goex" "net/http" "testing" + . "github.com/nntaoli-project/goex" + "net" "net/url" "time" @@ -52,7 +53,7 @@ func TestBigoneV3_GetUnfinishOrders(t *testing.T) { } func TestBigoneV3_GetOrderHistorys(t *testing.T) { return - t.Log(b1.GetOrderHistorys(BTC_USDT, 1, 1)) + t.Log(b1.GetOrderHistorys(BTC_USDT, OptionalParameter{"test": 1})) } func TestBigoneV3_LimitSell(t *testing.T) { return diff --git a/binance/BinanceSwap_test.go b/binance/BinanceSwap_test.go index ccc65145..0554ea49 100644 --- a/binance/BinanceSwap_test.go +++ b/binance/BinanceSwap_test.go @@ -1,12 +1,13 @@ package binance import ( - goex "github.com/nntaoli-project/goex" "net" "net/http" "net/url" "testing" "time" + + goex "github.com/nntaoli-project/goex" ) var bs = NewBinanceSwap(&goex.APIConfig{ @@ -15,7 +16,6 @@ var bs = NewBinanceSwap(&goex.APIConfig{ Transport: &http.Transport{ Proxy: func(req *http.Request) (*url.URL, error) { return url.Parse("socks5://127.0.0.1:1080") - return nil, nil }, Dial: (&net.Dialer{ Timeout: 10 * time.Second, @@ -40,7 +40,7 @@ func TestBinanceSwap_GetFutureIndex(t *testing.T) { } func TestBinanceSwap_GetKlineRecords(t *testing.T) { - kline, err := bs.GetKlineRecords("", goex.BTC_USDT, goex.KLINE_PERIOD_4H, 1, 0) + kline, err := bs.GetKlineRecords("", goex.BTC_USDT, goex.KLINE_PERIOD_4H, 1, goex.OptionalParameter{"test": 0}) t.Log(err, kline[0].Kline) } diff --git a/gdax/gdax_test.go b/gdax/gdax_test.go index 4836ba5f..d84ffe9a 100644 --- a/gdax/gdax_test.go +++ b/gdax/gdax_test.go @@ -31,5 +31,5 @@ func TestGdax_GetDepth(t *testing.T) { func TestGdax_GetKlineRecords(t *testing.T) { logger.SetLevel(logger.DEBUG) - t.Log(gdax.GetKlineRecords(goex.BTC_USD, goex.KLINE_PERIOD_1DAY, 0, 0)) + t.Log(gdax.GetKlineRecords(goex.BTC_USD, goex.KLINE_PERIOD_1DAY, 0, goex.OptionalParameter{"test": 0})) } diff --git a/go.mod b/go.mod index 05b8dc04..4da86f34 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,12 @@ go 1.12 require ( github.com/Kucoin/kucoin-go-sdk v1.2.7 github.com/go-openapi/errors v0.19.4 - github.com/google/uuid v1.1.1 - github.com/gorilla/websocket v1.4.1 + github.com/google/uuid v1.3.0 + github.com/gorilla/websocket v1.5.0 + github.com/klauspost/compress v1.15.2 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/nubo/jwt v0.0.0-20150918093313-da5b79c3bbaf github.com/stretchr/testify v1.7.0 - github.com/valyala/fasthttp v1.34.0 + github.com/valyala/fasthttp v1.36.0 + golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect ) diff --git a/go.sum b/go.sum index de20202e..2231ae01 100644 --- a/go.sum +++ b/go.sum @@ -9,11 +9,17 @@ github.com/go-openapi/errors v0.19.4 h1:fSGwO1tSYHFu70NKaWJt5Qh0qoBRtCm/mXS1yhf+ github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw= +github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -36,11 +42,15 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4= github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0= +github.com/valyala/fasthttp v1.36.0 h1:NhqfO/cB7Ajn1czkKnWkMHyPYr5nyND14ZGPk23g0/c= +github.com/valyala/fasthttp v1.36.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/huobi/Hbdm_Ws_test.go b/huobi/Hbdm_Ws_test.go index e2f42b52..ff240ace 100644 --- a/huobi/Hbdm_Ws_test.go +++ b/huobi/Hbdm_Ws_test.go @@ -1,10 +1,11 @@ package huobi import ( - "github.com/nntaoli-project/goex" "log" "testing" "time" + + "github.com/nntaoli-project/goex" ) func TestNewHbdmWs(t *testing.T) { @@ -24,7 +25,7 @@ func TestNewHbdmWs(t *testing.T) { }) t.Log(ws.SubscribeTicker(goex.BTC_USD, goex.QUARTER_CONTRACT)) - t.Log(ws.SubscribeDepth(goex.BTC_USD, goex.NEXT_WEEK_CONTRACT, 0)) + t.Log(ws.SubscribeDepth(goex.BTC_USD, goex.NEXT_WEEK_CONTRACT)) t.Log(ws.SubscribeTrade(goex.LTC_USD, goex.THIS_WEEK_CONTRACT)) time.Sleep(time.Minute) } diff --git a/huobi/Hbdm_test.go b/huobi/Hbdm_test.go index 3dfe9f56..e1f372e9 100644 --- a/huobi/Hbdm_test.go +++ b/huobi/Hbdm_test.go @@ -1,9 +1,10 @@ package huobi import ( - "github.com/nntaoli-project/goex" "testing" "time" + + "github.com/nntaoli-project/goex" ) var dm = NewHbdm(&goex.APIConfig{ @@ -58,7 +59,7 @@ func TestHbdm_GetFutureEstimatedPrice(t *testing.T) { } func TestHbdm_GetKlineRecords(t *testing.T) { - klines, _ := dm.GetKlineRecords(goex.QUARTER_CONTRACT, goex.EOS_USD, goex.KLINE_PERIOD_1MIN, 20, 0) + klines, _ := dm.GetKlineRecords(goex.QUARTER_CONTRACT, goex.EOS_USD, goex.KLINE_PERIOD_1MIN, 20, goex.OptionalParameter{"test": 0}) for _, k := range klines { tt := time.Unix(k.Timestamp, 0) t.Log(k.Pair, tt, k.Open, k.Close, k.High, k.Low, k.Vol, k.Vol2) diff --git a/okex/OKExSwap.go b/okex/OKExSwap.go index daebe7ef..59542216 100644 --- a/okex/OKExSwap.go +++ b/okex/OKExSwap.go @@ -4,12 +4,13 @@ import ( "encoding/json" "errors" "fmt" - "github.com/nntaoli-project/goex/internal/logger" "net/url" "strconv" "strings" "time" + "github.com/nntaoli-project/goex/internal/logger" + . "github.com/nntaoli-project/goex" ) diff --git a/okex/OKExSwap_test.go b/okex/OKExSwap_test.go index 65afd1cb..64277d77 100644 --- a/okex/OKExSwap_test.go +++ b/okex/OKExSwap_test.go @@ -1,11 +1,12 @@ package okex import ( - "github.com/nntaoli-project/goex" "net/http" "net/url" "testing" "time" + + "github.com/nntaoli-project/goex" ) var config = &goex.APIConfig{ @@ -75,7 +76,7 @@ func TestOKExSwap_GetHistoricalFunding(t *testing.T) { func TestOKExSwap_GetKlineRecords(t *testing.T) { since := time.Now().Add(-24 * time.Hour).Unix() - kline, err := okExSwap.GetKlineRecords(goex.SWAP_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 0, int(since)) + kline, err := okExSwap.GetKlineRecords(goex.SWAP_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 10, goex.OptionalParameter{"since": since}) t.Log(err, kline[0].Kline) } diff --git a/okex/OKEx_test.go b/okex/OKEx_test.go index a41f67fe..02154355 100644 --- a/okex/OKEx_test.go +++ b/okex/OKEx_test.go @@ -1,12 +1,13 @@ package okex import ( - "github.com/nntaoli-project/goex" - "github.com/nntaoli-project/goex/internal/logger" - "github.com/stretchr/testify/assert" "net/http" "testing" "time" + + "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" + "github.com/stretchr/testify/assert" ) func init() { @@ -137,7 +138,7 @@ func TestOKExFuture_GetRate(t *testing.T) { func TestOKExFuture_GetKlineRecords(t *testing.T) { since := time.Now().Add(-24 * time.Hour).Unix() - kline, err := okex.OKExFuture.GetKlineRecords(goex.QUARTER_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 0, int(since)) + kline, err := okex.OKExFuture.GetKlineRecords(goex.QUARTER_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 10, goex.OptionalParameter{"since": since}) assert.Nil(t, err) for _, k := range kline { t.Logf("%+v", k.Kline) From 60efd9cf79fabe21cefeefd387fbd29ba9760db4 Mon Sep 17 00:00:00 2001 From: WymA Date: Tue, 3 May 2022 23:13:36 +0800 Subject: [PATCH 14/34] 1) fix syntax errors in *_test.go; 2) update dependencies; --- bigone/BigoneV3_test.go | 5 +++-- binance/BinanceSwap_test.go | 6 +++--- gdax/gdax_test.go | 2 +- go.mod | 8 +++++--- go.sum | 10 ++++++++++ huobi/Hbdm_Ws_test.go | 5 +++-- huobi/Hbdm_test.go | 5 +++-- okex/OKExSwap.go | 3 ++- okex/OKExSwap_test.go | 5 +++-- okex/OKEx_test.go | 9 +++++---- 10 files changed, 38 insertions(+), 20 deletions(-) diff --git a/bigone/BigoneV3_test.go b/bigone/BigoneV3_test.go index 3e36c129..8cb53be5 100644 --- a/bigone/BigoneV3_test.go +++ b/bigone/BigoneV3_test.go @@ -1,10 +1,11 @@ package bigone import ( - . "github.com/nntaoli-project/goex" "net/http" "testing" + . "github.com/nntaoli-project/goex" + "net" "net/url" "time" @@ -52,7 +53,7 @@ func TestBigoneV3_GetUnfinishOrders(t *testing.T) { } func TestBigoneV3_GetOrderHistorys(t *testing.T) { return - t.Log(b1.GetOrderHistorys(BTC_USDT, 1, 1)) + t.Log(b1.GetOrderHistorys(BTC_USDT, OptionalParameter{"test": 1})) } func TestBigoneV3_LimitSell(t *testing.T) { return diff --git a/binance/BinanceSwap_test.go b/binance/BinanceSwap_test.go index ccc65145..0554ea49 100644 --- a/binance/BinanceSwap_test.go +++ b/binance/BinanceSwap_test.go @@ -1,12 +1,13 @@ package binance import ( - goex "github.com/nntaoli-project/goex" "net" "net/http" "net/url" "testing" "time" + + goex "github.com/nntaoli-project/goex" ) var bs = NewBinanceSwap(&goex.APIConfig{ @@ -15,7 +16,6 @@ var bs = NewBinanceSwap(&goex.APIConfig{ Transport: &http.Transport{ Proxy: func(req *http.Request) (*url.URL, error) { return url.Parse("socks5://127.0.0.1:1080") - return nil, nil }, Dial: (&net.Dialer{ Timeout: 10 * time.Second, @@ -40,7 +40,7 @@ func TestBinanceSwap_GetFutureIndex(t *testing.T) { } func TestBinanceSwap_GetKlineRecords(t *testing.T) { - kline, err := bs.GetKlineRecords("", goex.BTC_USDT, goex.KLINE_PERIOD_4H, 1, 0) + kline, err := bs.GetKlineRecords("", goex.BTC_USDT, goex.KLINE_PERIOD_4H, 1, goex.OptionalParameter{"test": 0}) t.Log(err, kline[0].Kline) } diff --git a/gdax/gdax_test.go b/gdax/gdax_test.go index 4836ba5f..d84ffe9a 100644 --- a/gdax/gdax_test.go +++ b/gdax/gdax_test.go @@ -31,5 +31,5 @@ func TestGdax_GetDepth(t *testing.T) { func TestGdax_GetKlineRecords(t *testing.T) { logger.SetLevel(logger.DEBUG) - t.Log(gdax.GetKlineRecords(goex.BTC_USD, goex.KLINE_PERIOD_1DAY, 0, 0)) + t.Log(gdax.GetKlineRecords(goex.BTC_USD, goex.KLINE_PERIOD_1DAY, 0, goex.OptionalParameter{"test": 0})) } diff --git a/go.mod b/go.mod index 05b8dc04..4da86f34 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,12 @@ go 1.12 require ( github.com/Kucoin/kucoin-go-sdk v1.2.7 github.com/go-openapi/errors v0.19.4 - github.com/google/uuid v1.1.1 - github.com/gorilla/websocket v1.4.1 + github.com/google/uuid v1.3.0 + github.com/gorilla/websocket v1.5.0 + github.com/klauspost/compress v1.15.2 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/nubo/jwt v0.0.0-20150918093313-da5b79c3bbaf github.com/stretchr/testify v1.7.0 - github.com/valyala/fasthttp v1.34.0 + github.com/valyala/fasthttp v1.36.0 + golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect ) diff --git a/go.sum b/go.sum index de20202e..2231ae01 100644 --- a/go.sum +++ b/go.sum @@ -9,11 +9,17 @@ github.com/go-openapi/errors v0.19.4 h1:fSGwO1tSYHFu70NKaWJt5Qh0qoBRtCm/mXS1yhf+ github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw= +github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -36,11 +42,15 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4= github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0= +github.com/valyala/fasthttp v1.36.0 h1:NhqfO/cB7Ajn1czkKnWkMHyPYr5nyND14ZGPk23g0/c= +github.com/valyala/fasthttp v1.36.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/huobi/Hbdm_Ws_test.go b/huobi/Hbdm_Ws_test.go index e2f42b52..ff240ace 100644 --- a/huobi/Hbdm_Ws_test.go +++ b/huobi/Hbdm_Ws_test.go @@ -1,10 +1,11 @@ package huobi import ( - "github.com/nntaoli-project/goex" "log" "testing" "time" + + "github.com/nntaoli-project/goex" ) func TestNewHbdmWs(t *testing.T) { @@ -24,7 +25,7 @@ func TestNewHbdmWs(t *testing.T) { }) t.Log(ws.SubscribeTicker(goex.BTC_USD, goex.QUARTER_CONTRACT)) - t.Log(ws.SubscribeDepth(goex.BTC_USD, goex.NEXT_WEEK_CONTRACT, 0)) + t.Log(ws.SubscribeDepth(goex.BTC_USD, goex.NEXT_WEEK_CONTRACT)) t.Log(ws.SubscribeTrade(goex.LTC_USD, goex.THIS_WEEK_CONTRACT)) time.Sleep(time.Minute) } diff --git a/huobi/Hbdm_test.go b/huobi/Hbdm_test.go index 3dfe9f56..e1f372e9 100644 --- a/huobi/Hbdm_test.go +++ b/huobi/Hbdm_test.go @@ -1,9 +1,10 @@ package huobi import ( - "github.com/nntaoli-project/goex" "testing" "time" + + "github.com/nntaoli-project/goex" ) var dm = NewHbdm(&goex.APIConfig{ @@ -58,7 +59,7 @@ func TestHbdm_GetFutureEstimatedPrice(t *testing.T) { } func TestHbdm_GetKlineRecords(t *testing.T) { - klines, _ := dm.GetKlineRecords(goex.QUARTER_CONTRACT, goex.EOS_USD, goex.KLINE_PERIOD_1MIN, 20, 0) + klines, _ := dm.GetKlineRecords(goex.QUARTER_CONTRACT, goex.EOS_USD, goex.KLINE_PERIOD_1MIN, 20, goex.OptionalParameter{"test": 0}) for _, k := range klines { tt := time.Unix(k.Timestamp, 0) t.Log(k.Pair, tt, k.Open, k.Close, k.High, k.Low, k.Vol, k.Vol2) diff --git a/okex/OKExSwap.go b/okex/OKExSwap.go index daebe7ef..59542216 100644 --- a/okex/OKExSwap.go +++ b/okex/OKExSwap.go @@ -4,12 +4,13 @@ import ( "encoding/json" "errors" "fmt" - "github.com/nntaoli-project/goex/internal/logger" "net/url" "strconv" "strings" "time" + "github.com/nntaoli-project/goex/internal/logger" + . "github.com/nntaoli-project/goex" ) diff --git a/okex/OKExSwap_test.go b/okex/OKExSwap_test.go index 65afd1cb..64277d77 100644 --- a/okex/OKExSwap_test.go +++ b/okex/OKExSwap_test.go @@ -1,11 +1,12 @@ package okex import ( - "github.com/nntaoli-project/goex" "net/http" "net/url" "testing" "time" + + "github.com/nntaoli-project/goex" ) var config = &goex.APIConfig{ @@ -75,7 +76,7 @@ func TestOKExSwap_GetHistoricalFunding(t *testing.T) { func TestOKExSwap_GetKlineRecords(t *testing.T) { since := time.Now().Add(-24 * time.Hour).Unix() - kline, err := okExSwap.GetKlineRecords(goex.SWAP_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 0, int(since)) + kline, err := okExSwap.GetKlineRecords(goex.SWAP_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 10, goex.OptionalParameter{"since": since}) t.Log(err, kline[0].Kline) } diff --git a/okex/OKEx_test.go b/okex/OKEx_test.go index a41f67fe..02154355 100644 --- a/okex/OKEx_test.go +++ b/okex/OKEx_test.go @@ -1,12 +1,13 @@ package okex import ( - "github.com/nntaoli-project/goex" - "github.com/nntaoli-project/goex/internal/logger" - "github.com/stretchr/testify/assert" "net/http" "testing" "time" + + "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" + "github.com/stretchr/testify/assert" ) func init() { @@ -137,7 +138,7 @@ func TestOKExFuture_GetRate(t *testing.T) { func TestOKExFuture_GetKlineRecords(t *testing.T) { since := time.Now().Add(-24 * time.Hour).Unix() - kline, err := okex.OKExFuture.GetKlineRecords(goex.QUARTER_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 0, int(since)) + kline, err := okex.OKExFuture.GetKlineRecords(goex.QUARTER_CONTRACT, goex.BTC_USD, goex.KLINE_PERIOD_4H, 10, goex.OptionalParameter{"since": since}) assert.Nil(t, err) for _, k := range kline { t.Logf("%+v", k.Kline) From 6d163df05a388019c6503c4ab70a142be2a531ef Mon Sep 17 00:00:00 2001 From: WymA Date: Wed, 4 May 2022 13:04:08 +0800 Subject: [PATCH 15/34] 1) add testnet for binance, 2) add binance futures subscribe depth example --- binance/Binance.go | 10 +++++++++- binance/FuturesWs.go | 11 +++++++---- examples/binance_futures_trade.go | 32 +++++++++++++++++++++++++++++++ websocket.go | 5 +++-- 4 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 examples/binance_futures_trade.go diff --git a/binance/Binance.go b/binance/Binance.go index e0c82615..5ac45d8d 100644 --- a/binance/Binance.go +++ b/binance/Binance.go @@ -4,19 +4,27 @@ import ( "encoding/json" "errors" "fmt" - . "github.com/nntaoli-project/goex" "net/http" "net/url" "sort" "strconv" "strings" "time" + + . "github.com/nntaoli-project/goex" ) const ( GLOBAL_API_BASE_URL = "https://api.binance.com" US_API_BASE_URL = "https://api.binance.us" JE_API_BASE_URL = "https://api.binance.je" + + FUTURE_USD_WS_BASE_URL = "wss://fstream.binance.com/ws" + FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" + + TESTNET_SPOT_API_BASE_URL = "https://api.binance.com" + TESTNET_FUTURE_USD_WS_BASE_URL = "wss://fstream.binance.com/ws" + TESTNET_FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" //API_V1 = API_BASE_URL + "api/v1/" //API_V3 = API_BASE_URL + "api/v3/" diff --git a/binance/FuturesWs.go b/binance/FuturesWs.go index d5128cbe..d8fe165c 100644 --- a/binance/FuturesWs.go +++ b/binance/FuturesWs.go @@ -3,8 +3,6 @@ package binance import ( "encoding/json" "errors" - "github.com/nntaoli-project/goex" - "github.com/nntaoli-project/goex/internal/logger" "net/http" "net/url" "os" @@ -12,6 +10,9 @@ import ( "strings" "sync" "time" + + "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" ) type FuturesWs struct { @@ -59,13 +60,13 @@ func NewFuturesWs() *FuturesWs { func (s *FuturesWs) connectUsdtFutures() { s.fOnce.Do(func() { - s.f = s.wsBuilder.WsUrl("wss://fstream.binance.com/ws").Build() + s.f = s.wsBuilder.WsUrl(TESTNET_FUTURE_USD_WS_BASE_URL).Build() }) } func (s *FuturesWs) connectFutures() { s.dOnce.Do(func() { - s.d = s.wsBuilder.WsUrl("wss://dstream.binance.com/ws").Build() + s.d = s.wsBuilder.WsUrl(TESTNET_FUTURE_COIN_WS_BASE_URL).Build() }) } @@ -84,12 +85,14 @@ func (s *FuturesWs) TradeCallback(f func(trade *goex.Trade, contract string)) { func (s *FuturesWs) SubscribeDepth(pair goex.CurrencyPair, contractType string) error { switch contractType { case goex.SWAP_USDT_CONTRACT: + s.connectUsdtFutures() return s.f.Subscribe(req{ Method: "SUBSCRIBE", Params: []string{pair.AdaptUsdToUsdt().ToLower().ToSymbol("") + "@depth10@100ms"}, Id: 1, }) default: + s.connectFutures() sym, _ := s.base.adaptToSymbol(pair.AdaptUsdtToUsd(), contractType) return s.d.Subscribe(req{ Method: "SUBSCRIBE", diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go new file mode 100644 index 00000000..38babc31 --- /dev/null +++ b/examples/binance_futures_trade.go @@ -0,0 +1,32 @@ +package main + +import ( + "log" + "time" + + "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/binance" + "github.com/nntaoli-project/goex/builder" +) + +const ( + BINANCE_TESTNET_API_KEY = "***REMOVED***" + BINANCE_TESTNET_API_KEY_SECRET = "***REMOVED***" +) + +func main() { + + api, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_WS_BASE_URL).BuildFuturesWs(goex.BINANCE_FUTURES) + + if err != nil { + log.Fatalln(err.Error()) + } + //api.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) + api.DepthCallback(func(depth *goex.Depth) { + log.Println(depth) + }) + api.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) + + time.Sleep(time.Minute) // run for one minute + +} diff --git a/websocket.go b/websocket.go index 9f1ade55..753bd086 100644 --- a/websocket.go +++ b/websocket.go @@ -4,13 +4,14 @@ import ( "encoding/json" "errors" "fmt" - "github.com/gorilla/websocket" - . "github.com/nntaoli-project/goex/internal/logger" "net/http" "net/http/httputil" "net/url" "sync" "time" + + "github.com/gorilla/websocket" + . "github.com/nntaoli-project/goex/internal/logger" ) type WsConfig struct { From 90f631fe94e9e24871440a9070e729a45da86165 Mon Sep 17 00:00:00 2001 From: WymA Date: Wed, 4 May 2022 13:04:08 +0800 Subject: [PATCH 16/34] 1) add testnet for binance, 2) add binance futures subscribe depth example --- binance/Binance.go | 10 +++++++++- binance/FuturesWs.go | 11 +++++++---- examples/binance_futures_trade.go | 32 +++++++++++++++++++++++++++++++ websocket.go | 5 +++-- 4 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 examples/binance_futures_trade.go diff --git a/binance/Binance.go b/binance/Binance.go index e0c82615..5ac45d8d 100644 --- a/binance/Binance.go +++ b/binance/Binance.go @@ -4,19 +4,27 @@ import ( "encoding/json" "errors" "fmt" - . "github.com/nntaoli-project/goex" "net/http" "net/url" "sort" "strconv" "strings" "time" + + . "github.com/nntaoli-project/goex" ) const ( GLOBAL_API_BASE_URL = "https://api.binance.com" US_API_BASE_URL = "https://api.binance.us" JE_API_BASE_URL = "https://api.binance.je" + + FUTURE_USD_WS_BASE_URL = "wss://fstream.binance.com/ws" + FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" + + TESTNET_SPOT_API_BASE_URL = "https://api.binance.com" + TESTNET_FUTURE_USD_WS_BASE_URL = "wss://fstream.binance.com/ws" + TESTNET_FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" //API_V1 = API_BASE_URL + "api/v1/" //API_V3 = API_BASE_URL + "api/v3/" diff --git a/binance/FuturesWs.go b/binance/FuturesWs.go index d5128cbe..d8fe165c 100644 --- a/binance/FuturesWs.go +++ b/binance/FuturesWs.go @@ -3,8 +3,6 @@ package binance import ( "encoding/json" "errors" - "github.com/nntaoli-project/goex" - "github.com/nntaoli-project/goex/internal/logger" "net/http" "net/url" "os" @@ -12,6 +10,9 @@ import ( "strings" "sync" "time" + + "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" ) type FuturesWs struct { @@ -59,13 +60,13 @@ func NewFuturesWs() *FuturesWs { func (s *FuturesWs) connectUsdtFutures() { s.fOnce.Do(func() { - s.f = s.wsBuilder.WsUrl("wss://fstream.binance.com/ws").Build() + s.f = s.wsBuilder.WsUrl(TESTNET_FUTURE_USD_WS_BASE_URL).Build() }) } func (s *FuturesWs) connectFutures() { s.dOnce.Do(func() { - s.d = s.wsBuilder.WsUrl("wss://dstream.binance.com/ws").Build() + s.d = s.wsBuilder.WsUrl(TESTNET_FUTURE_COIN_WS_BASE_URL).Build() }) } @@ -84,12 +85,14 @@ func (s *FuturesWs) TradeCallback(f func(trade *goex.Trade, contract string)) { func (s *FuturesWs) SubscribeDepth(pair goex.CurrencyPair, contractType string) error { switch contractType { case goex.SWAP_USDT_CONTRACT: + s.connectUsdtFutures() return s.f.Subscribe(req{ Method: "SUBSCRIBE", Params: []string{pair.AdaptUsdToUsdt().ToLower().ToSymbol("") + "@depth10@100ms"}, Id: 1, }) default: + s.connectFutures() sym, _ := s.base.adaptToSymbol(pair.AdaptUsdtToUsd(), contractType) return s.d.Subscribe(req{ Method: "SUBSCRIBE", diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go new file mode 100644 index 00000000..67807b4e --- /dev/null +++ b/examples/binance_futures_trade.go @@ -0,0 +1,32 @@ +package main + +import ( + "log" + "time" + + "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/binance" + "github.com/nntaoli-project/goex/builder" +) + +const ( + BINANCE_TESTNET_API_KEY = "e78d5b2ce4cf436da0194610c1da797bf6fa3ea7c4342b984f13d42fd17fd515" + BINANCE_TESTNET_API_KEY_SECRET = "5cea0042c43db6438b1577860096c3ba83bcc20b34e76b920b31684de712d9d2" +) + +func main() { + + api, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_WS_BASE_URL).BuildFuturesWs(goex.BINANCE_FUTURES) + + if err != nil { + log.Fatalln(err.Error()) + } + //api.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) + api.DepthCallback(func(depth *goex.Depth) { + log.Println(depth) + }) + api.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) + + time.Sleep(time.Minute) // run for one minute + +} diff --git a/websocket.go b/websocket.go index 9f1ade55..753bd086 100644 --- a/websocket.go +++ b/websocket.go @@ -4,13 +4,14 @@ import ( "encoding/json" "errors" "fmt" - "github.com/gorilla/websocket" - . "github.com/nntaoli-project/goex/internal/logger" "net/http" "net/http/httputil" "net/url" "sync" "time" + + "github.com/gorilla/websocket" + . "github.com/nntaoli-project/goex/internal/logger" ) type WsConfig struct { From 9c5ed6d16d675e3679fa29fb84b9d6fee3b738fa Mon Sep 17 00:00:00 2001 From: Matthias L W Date: Wed, 4 May 2022 15:50:14 +0800 Subject: [PATCH 17/34] Create go.yml --- .github/workflows/go.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/go.yml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 00000000..a7eb5725 --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,25 @@ +name: Go + +on: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.18 + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v ./... From c24ae7bf3aa8b2c6000412dec218baf247e0f1f2 Mon Sep 17 00:00:00 2001 From: Matthias L W Date: Wed, 4 May 2022 15:50:14 +0800 Subject: [PATCH 18/34] Create go.yml --- .github/workflows/go.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/go.yml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 00000000..a7eb5725 --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,25 @@ +name: Go + +on: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.18 + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v ./... From 9f927258962615697e4e9293e5713e26f41a5e50 Mon Sep 17 00:00:00 2001 From: WymA Date: Wed, 4 May 2022 22:44:43 +0800 Subject: [PATCH 19/34] temporary remove test in github action --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index a7eb5725..1ecea0aa 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,5 +21,5 @@ jobs: - name: Build run: go build -v ./... - - name: Test - run: go test -v ./... + # - name: Test + # run: go test -v ./... From dfb5f2f9545db80383feb0f03dd21b9dbfee8167 Mon Sep 17 00:00:00 2001 From: WymA Date: Wed, 4 May 2022 22:44:43 +0800 Subject: [PATCH 20/34] temporary remove test in github action --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index a7eb5725..1ecea0aa 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,5 +21,5 @@ jobs: - name: Build run: go build -v ./... - - name: Test - run: go test -v ./... + # - name: Test + # run: go test -v ./... From d7d288c341bdaf60ce4875834163dad52cc43444 Mon Sep 17 00:00:00 2001 From: WymA Date: Thu, 5 May 2022 00:35:05 +0800 Subject: [PATCH 21/34] update examples/binance_futures_trade.go --- binance/BinanceSwap.go | 3 ++- examples/binance_futures_trade.go | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/binance/BinanceSwap.go b/binance/BinanceSwap.go index 075e076a..419715e0 100644 --- a/binance/BinanceSwap.go +++ b/binance/BinanceSwap.go @@ -4,12 +4,13 @@ import ( "encoding/json" "errors" "fmt" - . "github.com/nntaoli-project/goex" "net/url" "strconv" "strings" "sync" "time" + + . "github.com/nntaoli-project/goex" ) const ( diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go index 38babc31..2c5c643b 100644 --- a/examples/binance_futures_trade.go +++ b/examples/binance_futures_trade.go @@ -21,9 +21,12 @@ func main() { if err != nil { log.Fatalln(err.Error()) } - //api.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) + api.TickerCallback(func(ticker *goex.FutureTicker) { + log.Printf("%+v\n", *ticker.Ticker) + }) + api.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) api.DepthCallback(func(depth *goex.Depth) { - log.Println(depth) + log.Printf("%+v\n", *depth) }) api.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) From 225155c362480f92f094bf9ab1a5aebb132d53cf Mon Sep 17 00:00:00 2001 From: WymA Date: Thu, 5 May 2022 00:35:05 +0800 Subject: [PATCH 22/34] update examples/binance_futures_trade.go --- binance/BinanceSwap.go | 3 ++- examples/binance_futures_trade.go | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/binance/BinanceSwap.go b/binance/BinanceSwap.go index 075e076a..419715e0 100644 --- a/binance/BinanceSwap.go +++ b/binance/BinanceSwap.go @@ -4,12 +4,13 @@ import ( "encoding/json" "errors" "fmt" - . "github.com/nntaoli-project/goex" "net/url" "strconv" "strings" "sync" "time" + + . "github.com/nntaoli-project/goex" ) const ( diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go index 67807b4e..101c011c 100644 --- a/examples/binance_futures_trade.go +++ b/examples/binance_futures_trade.go @@ -21,9 +21,12 @@ func main() { if err != nil { log.Fatalln(err.Error()) } - //api.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) + api.TickerCallback(func(ticker *goex.FutureTicker) { + log.Printf("%+v\n", *ticker.Ticker) + }) + api.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) api.DepthCallback(func(depth *goex.Depth) { - log.Println(depth) + log.Printf("%+v\n", *depth) }) api.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) From dd4b2a503dbc3dc66114084dbd8103951758a4cd Mon Sep 17 00:00:00 2001 From: WymA Date: Thu, 5 May 2022 10:55:28 +0800 Subject: [PATCH 23/34] remove sensitive data --- examples/binance_futures_trade.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go index 2c5c643b..c3c197d5 100644 --- a/examples/binance_futures_trade.go +++ b/examples/binance_futures_trade.go @@ -10,8 +10,8 @@ import ( ) const ( - BINANCE_TESTNET_API_KEY = "***REMOVED***" - BINANCE_TESTNET_API_KEY_SECRET = "***REMOVED***" + BINANCE_TESTNET_API_KEY = "YOUR_KEY" + BINANCE_TESTNET_API_KEY_SECRET = "YOUR_KEY_SECRET" ) func main() { From ce947ef8366946aabe1ac745d39561c4396f4c1b Mon Sep 17 00:00:00 2001 From: WymA Date: Thu, 5 May 2022 11:04:01 +0800 Subject: [PATCH 24/34] add go build github action badge --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c115830f..04129974 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ +![build](https://github.com/WymA/goex/actions/workflows/go.yml/badge.svg?branch=dev) + + ### goex目标 goex项目是为了统一并标准化各个数字资产交易平台的接口而设计,同一个策略可以随时切换到任意一个交易平台,而不需要更改任何代码。 From 34f66452f43c8cc9498cdf99a982e1e0403727c0 Mon Sep 17 00:00:00 2001 From: WymA Date: Thu, 5 May 2022 11:10:58 +0800 Subject: [PATCH 25/34] add workflow badge in README_en.md --- README.md | 1 - README_en.md | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04129974..5be5f322 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ ![build](https://github.com/WymA/goex/actions/workflows/go.yml/badge.svg?branch=dev) - ### goex目标 goex项目是为了统一并标准化各个数字资产交易平台的接口而设计,同一个策略可以随时切换到任意一个交易平台,而不需要更改任何代码。 diff --git a/README_en.md b/README_en.md index f4a70cec..bdf2b1de 100644 --- a/README_en.md +++ b/README_en.md @@ -2,6 +2,8 @@ goex +![build](https://github.com/WymA/goex/actions/workflows/go.yml/badge.svg?branch=dev) + ### goex goex project is designed to unify and standardize the interfaces of each digital asset trading platform. The same strategy can be switched to any trading platform at any time without changing any code. From dc0d5b59ecd1325d415d0c9fdd13fe17121d3514 Mon Sep 17 00:00:00 2001 From: WymA Date: Thu, 5 May 2022 23:41:18 +0800 Subject: [PATCH 26/34] update examples/binance_futures_trade.go, add binance futures testnet Endpoint URL --- binance/Binance.go | 1 + binance/BinanceFutures.go | 5 ++-- examples/binance_futures_trade.go | 50 +++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/binance/Binance.go b/binance/Binance.go index 5ac45d8d..49cec815 100644 --- a/binance/Binance.go +++ b/binance/Binance.go @@ -23,6 +23,7 @@ const ( FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" TESTNET_SPOT_API_BASE_URL = "https://api.binance.com" + TESTNET_FUTURE_USD_BASE_URL = "https://testnet.binancefuture.com" TESTNET_FUTURE_USD_WS_BASE_URL = "wss://fstream.binance.com/ws" TESTNET_FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" //API_V1 = API_BASE_URL + "api/v1/" diff --git a/binance/BinanceFutures.go b/binance/BinanceFutures.go index dabe4e6d..dac0e020 100644 --- a/binance/BinanceFutures.go +++ b/binance/BinanceFutures.go @@ -4,8 +4,6 @@ import ( "encoding/json" "errors" "fmt" - . "github.com/nntaoli-project/goex" - "github.com/nntaoli-project/goex/internal/logger" "math" "net/http" "net/url" @@ -13,6 +11,9 @@ import ( "strings" "sync" "time" + + . "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" ) type BaseResponse struct { diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go index c3c197d5..2a1951e5 100644 --- a/examples/binance_futures_trade.go +++ b/examples/binance_futures_trade.go @@ -2,7 +2,6 @@ package main import ( "log" - "time" "github.com/nntaoli-project/goex" "github.com/nntaoli-project/goex/binance" @@ -16,20 +15,53 @@ const ( func main() { - api, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_WS_BASE_URL).BuildFuturesWs(goex.BINANCE_FUTURES) + binanceWs, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_WS_BASE_URL).BuildFuturesWs(goex.BINANCE_FUTURES) if err != nil { log.Fatalln(err.Error()) } - api.TickerCallback(func(ticker *goex.FutureTicker) { - log.Printf("%+v\n", *ticker.Ticker) + binanceWs.TickerCallback(func(ticker *goex.FutureTicker) { + //log.Printf("%+v\n", *ticker.Ticker) }) - api.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) - api.DepthCallback(func(depth *goex.Depth) { - log.Printf("%+v\n", *depth) + binanceWs.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) + binanceWs.DepthCallback(func(depth *goex.Depth) { + //log.Printf("%+v\n", *depth) }) - api.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) + binanceWs.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) - time.Sleep(time.Minute) // run for one minute + //time.Sleep(time.Minute) // run for one minute + binanceApi := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_BASE_URL).BuildFuture(goex.BINANCE_SWAP) + + depth, err := binanceApi.GetFutureDepth(goex.BTC_USD, goex.SWAP_USDT_CONTRACT, 100) + if err != nil { + log.Fatalln(err.Error()) + } + + askTotalAmount, bidTotalAmount := 0.0, 0.0 + askTotalVol, bidTotalVol := 0.0, 0.0 + + for _, v := range depth.AskList { + askTotalAmount += v.Amount + askTotalVol += v.Price * v.Amount + } + + for _, v := range depth.BidList { + bidTotalAmount += v.Amount + bidTotalVol += v.Price * v.Amount + } + + markPrice, err := binanceApi.GetFutureIndex(goex.BTC_USD) + if err != nil { + log.Fatalln(err.Error()) + } + + log.Printf("CURRENT mark price: %f", markPrice) + + log.Printf("ContractType: %s ContractId: %s Pair: %s UTime: %s AmountTickSize: %d\n", depth.ContractType, depth.ContractId, depth.Pair, depth.UTime.String(), depth.Pair.AmountTickSize) + log.Printf("askTotalAmount: %f, bidTotalAmount: %f, askTotalVol: %f, bidTotalVol: %f", askTotalAmount, bidTotalAmount, askTotalVol, bidTotalVol) + log.Printf("ask price averge: %f, bid price averge: %f,", askTotalVol/askTotalAmount, bidTotalVol/bidTotalAmount) + log.Printf("ask-bid spread: %f%%,", 100*(depth.AskList[0].Price-depth.BidList[0].Price)/markPrice) + + //select {} } From 734851808a4486432b97a3935aaf2c83c4c913c5 Mon Sep 17 00:00:00 2001 From: WymA Date: Fri, 6 May 2022 12:58:03 +0800 Subject: [PATCH 27/34] implement SubscribeTrade in binance/FuturesWs.go and binance/SpotWs.go --- binance/FuturesWs.go | 47 +++++++++++++++++++++++++++- binance/SpotWs.go | 51 +++++++++++++++++++++++++++++-- examples/binance_futures_trade.go | 44 ++++++++++++++------------ 3 files changed, 119 insertions(+), 23 deletions(-) diff --git a/binance/FuturesWs.go b/binance/FuturesWs.go index d8fe165c..4c7cc560 100644 --- a/binance/FuturesWs.go +++ b/binance/FuturesWs.go @@ -125,7 +125,23 @@ func (s *FuturesWs) SubscribeTicker(pair goex.CurrencyPair, contractType string) } func (s *FuturesWs) SubscribeTrade(pair goex.CurrencyPair, contractType string) error { - panic("implement me") + switch contractType { + case goex.SWAP_USDT_CONTRACT: + s.connectUsdtFutures() + return s.f.Subscribe(req{ + Method: "SUBSCRIBE", + Params: []string{pair.AdaptUsdToUsdt().ToLower().ToSymbol("") + "@aggTrade"}, + Id: 1, + }) + default: + s.connectFutures() + sym, _ := s.base.adaptToSymbol(pair.AdaptUsdtToUsd(), contractType) + return s.d.Subscribe(req{ + Method: "SUBSCRIBE", + Params: []string{strings.ToLower(sym) + "@aggTrade"}, + Id: 1, + }) + } } func (s *FuturesWs) handle(data []byte) error { @@ -157,6 +173,13 @@ func (s *FuturesWs) handle(data []byte) error { return nil } + if e, ok := m["e"].(string); ok && e == "aggTrade" { + + contractType := m["s"].(string) + s.tradeCalFn(s.tradeHandle(m), contractType) + return nil + } + logger.Warn("unknown ws response:", string(data)) return nil @@ -207,3 +230,25 @@ func (s *FuturesWs) tickerHandle(m map[string]interface{}) *goex.FutureTicker { return &ticker } + +func (s *FuturesWs) tradeHandle(m map[string]interface{}) *goex.Trade { + var trade goex.Trade + + symbol, ok := m["s"].(string) // Symbol + if ok { + trade.Pair = adaptSymbolToCurrencyPair(symbol) //usdt swap + } + + trade.Tid = goex.ToInt64(m["a"]) // Aggregate trade ID + trade.Date = goex.ToInt64(m["E"]) // Event time + trade.Amount = goex.ToFloat64(m["q"]) // Quantity + trade.Price = goex.ToFloat64(m["p"]) // Price + + if m["m"].(bool) { + trade.Type = goex.BUY_MARKET + } else { + trade.Type = goex.SELL_MARKET + } + + return &trade +} diff --git a/binance/SpotWs.go b/binance/SpotWs.go index ad33efe8..6f554be0 100644 --- a/binance/SpotWs.go +++ b/binance/SpotWs.go @@ -3,13 +3,14 @@ package binance import ( json2 "encoding/json" "fmt" - "github.com/nntaoli-project/goex" - "github.com/nntaoli-project/goex/internal/logger" "os" "sort" "strings" "sync" "time" + + "github.com/nntaoli-project/goex" + "github.com/nntaoli-project/goex/internal/logger" ) type req struct { @@ -103,8 +104,20 @@ func (s *SpotWs) SubscribeTicker(pair goex.CurrencyPair) error { }) } +// TODO: test func (s *SpotWs) SubscribeTrade(pair goex.CurrencyPair) error { - panic("implement me") + + defer func() { + s.reqId++ + }() + + s.connect() + + return s.c.Subscribe(req{ + Method: "SUBSCRIBE", + Params: []string{pair.ToLower().ToSymbol("") + "@aggTrade"}, + Id: s.reqId, + }) } func (s *SpotWs) handle(data []byte) error { @@ -123,6 +136,10 @@ func (s *SpotWs) handle(data []byte) error { return s.tickerHandle(r.Data, adaptStreamToCurrencyPair(r.Stream)) } + if strings.HasSuffix(r.Stream, "@aggTrade") { + return s.tradeHandle(r.Data, adaptStreamToCurrencyPair(r.Stream)) + } + logger.Warn("unknown ws response:", string(data)) return nil @@ -190,3 +207,31 @@ func (s *SpotWs) tickerHandle(data json2.RawMessage, pair goex.CurrencyPair) err return nil } + +func (s *SpotWs) tradeHandle(data json2.RawMessage, pair goex.CurrencyPair) error { + + var ( + tradeData = make(map[string]interface{}, 4) + trade goex.Trade + ) + + err := json2.Unmarshal(data, &tradeData) + if err != nil { + logger.Errorf("unmarshal ticker response data error [%s] , data = %s", err, string(data)) + return err + } + + trade.Pair = pair //Symbol + trade.Tid = goex.ToInt64(tradeData["a"]) // Aggregate trade ID + trade.Date = goex.ToInt64(tradeData["E"]) // Event time + trade.Amount = goex.ToFloat64(tradeData["q"]) // Quantity + trade.Price = goex.ToFloat64(tradeData["p"]) // Price + + if tradeData["m"].(bool) { + trade.Type = goex.BUY_MARKET + } else { + trade.Type = goex.SELL_MARKET + } + + return nil +} diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go index 2a1951e5..8529fd46 100644 --- a/examples/binance_futures_trade.go +++ b/examples/binance_futures_trade.go @@ -13,24 +13,7 @@ const ( BINANCE_TESTNET_API_KEY_SECRET = "YOUR_KEY_SECRET" ) -func main() { - - binanceWs, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_WS_BASE_URL).BuildFuturesWs(goex.BINANCE_FUTURES) - - if err != nil { - log.Fatalln(err.Error()) - } - binanceWs.TickerCallback(func(ticker *goex.FutureTicker) { - //log.Printf("%+v\n", *ticker.Ticker) - }) - binanceWs.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) - binanceWs.DepthCallback(func(depth *goex.Depth) { - //log.Printf("%+v\n", *depth) - }) - binanceWs.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) - - //time.Sleep(time.Minute) // run for one minute - +func fetchFutureDepthAndIndex() { binanceApi := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_BASE_URL).BuildFuture(goex.BINANCE_SWAP) depth, err := binanceApi.GetFutureDepth(goex.BTC_USD, goex.SWAP_USDT_CONTRACT, 100) @@ -62,6 +45,29 @@ func main() { log.Printf("askTotalAmount: %f, bidTotalAmount: %f, askTotalVol: %f, bidTotalVol: %f", askTotalAmount, bidTotalAmount, askTotalVol, bidTotalVol) log.Printf("ask price averge: %f, bid price averge: %f,", askTotalVol/askTotalAmount, bidTotalVol/bidTotalAmount) log.Printf("ask-bid spread: %f%%,", 100*(depth.AskList[0].Price-depth.BidList[0].Price)/markPrice) +} + +func main() { + + binanceWs, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_WS_BASE_URL).BuildFuturesWs(goex.BINANCE_FUTURES) + + if err != nil { + log.Fatalln(err.Error()) + } + binanceWs.TickerCallback(func(ticker *goex.FutureTicker) { + //log.Printf("%+v\n", *ticker.Ticker) + }) + binanceWs.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) + binanceWs.DepthCallback(func(depth *goex.Depth) { + //log.Printf("%+v\n", *depth) + }) + binanceWs.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) + + binanceWs.TradeCallback(func(trade *goex.Trade, contractType string) { + log.Printf("%+v\n", *trade) + }) + binanceWs.SubscribeTrade(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) + + select {} - //select {} } From 5564b1c7ce6e9b8a46b321960ad9d4d64bfef279 Mon Sep 17 00:00:00 2001 From: WymA Date: Fri, 6 May 2022 23:56:29 +0800 Subject: [PATCH 28/34] update examples/binance_futures_trade.go --- examples/binance_futures_trade.go | 35 ++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go index 8529fd46..bdc8730c 100644 --- a/examples/binance_futures_trade.go +++ b/examples/binance_futures_trade.go @@ -47,8 +47,7 @@ func fetchFutureDepthAndIndex() { log.Printf("ask-bid spread: %f%%,", 100*(depth.AskList[0].Price-depth.BidList[0].Price)/markPrice) } -func main() { - +func subscribeFutureMarketData() { binanceWs, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_WS_BASE_URL).BuildFuturesWs(goex.BINANCE_FUTURES) if err != nil { @@ -59,7 +58,7 @@ func main() { }) binanceWs.SubscribeTicker(goex.BTC_USD, goex.SWAP_USDT_CONTRACT) binanceWs.DepthCallback(func(depth *goex.Depth) { - //log.Printf("%+v\n", *depth) + log.Printf("%+v\n", *depth) }) binanceWs.SubscribeDepth(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) @@ -68,6 +67,36 @@ func main() { }) binanceWs.SubscribeTrade(goex.BTC_USDT, goex.SWAP_USDT_CONTRACT) + select {} +} + +func subscribeSpotMarketData() { + + binanceWs, err := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_BASE_URL).BuildSpotWs(goex.BINANCE) + + if err != nil { + log.Fatalln(err.Error()) + } + binanceWs.TickerCallback(func(ticker *goex.Ticker) { + log.Printf("%+v\n", *ticker) + }) + binanceWs.SubscribeTicker(goex.BTC_USD) + binanceWs.DepthCallback(func(depth *goex.Depth) { + log.Printf("%+v\n", *depth) + }) + binanceWs.SubscribeDepth(goex.BTC_USDT) + + binanceWs.TradeCallback(func(trade *goex.Trade) { + log.Printf("%+v\n", *trade) + }) + binanceWs.SubscribeTrade(goex.BTC_USDT) + select {} } + +func main() { + //subscribeFutureMarketData() + //subscribeFutureMarketData() + subscribeSpotMarketData() +} From 472db59a81c70f845383e41751fa3edea9275a67 Mon Sep 17 00:00:00 2001 From: WymA Date: Sat, 7 May 2022 00:08:38 +0800 Subject: [PATCH 29/34] 1) add spot ws and stream base url; 2) update example/binance --- binance/Binance.go | 2 ++ binance/FuturesWs.go | 3 --- binance/SpotWs.go | 2 +- examples/binance_futures_trade.go | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/binance/Binance.go b/binance/Binance.go index 49cec815..72bddf57 100644 --- a/binance/Binance.go +++ b/binance/Binance.go @@ -23,6 +23,8 @@ const ( FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" TESTNET_SPOT_API_BASE_URL = "https://api.binance.com" + TESTNET_SPOT_WS_BASE_URL = "wss://testnet.binance.vision/ws" + TESTNET_SPOT_STREAM_BASE_URL = "wss://testnet.binance.vision/stream" TESTNET_FUTURE_USD_BASE_URL = "https://testnet.binancefuture.com" TESTNET_FUTURE_USD_WS_BASE_URL = "wss://fstream.binance.com/ws" TESTNET_FUTURE_COIN_WS_BASE_URL = "wss://dstream.binance.com/ws" diff --git a/binance/FuturesWs.go b/binance/FuturesWs.go index 4c7cc560..2d612806 100644 --- a/binance/FuturesWs.go +++ b/binance/FuturesWs.go @@ -2,7 +2,6 @@ package binance import ( "encoding/json" - "errors" "net/http" "net/url" "os" @@ -100,7 +99,6 @@ func (s *FuturesWs) SubscribeDepth(pair goex.CurrencyPair, contractType string) Id: 2, }) } - return errors.New("contract is error") } func (s *FuturesWs) SubscribeTicker(pair goex.CurrencyPair, contractType string) error { @@ -121,7 +119,6 @@ func (s *FuturesWs) SubscribeTicker(pair goex.CurrencyPair, contractType string) Id: 2, }) } - return errors.New("contract is error") } func (s *FuturesWs) SubscribeTrade(pair goex.CurrencyPair, contractType string) error { diff --git a/binance/SpotWs.go b/binance/SpotWs.go index 6f554be0..01c27123 100644 --- a/binance/SpotWs.go +++ b/binance/SpotWs.go @@ -47,7 +47,7 @@ func NewSpotWs() *SpotWs { logger.Debugf("proxy url: %s", os.Getenv("HTTPS_PROXY")) spotWs.wsBuilder = goex.NewWsBuilder(). - WsUrl("wss://stream.binance.com:9443/stream?streams=depth/miniTicker/ticker/trade"). + WsUrl(TESTNET_SPOT_STREAM_BASE_URL + "?streams=depth/miniTicker/ticker/trade"). ProxyUrl(os.Getenv("HTTPS_PROXY")). ProtoHandleFunc(spotWs.handle).AutoReconnect() diff --git a/examples/binance_futures_trade.go b/examples/binance_futures_trade.go index bdc8730c..34d4a114 100644 --- a/examples/binance_futures_trade.go +++ b/examples/binance_futures_trade.go @@ -14,7 +14,7 @@ const ( ) func fetchFutureDepthAndIndex() { - binanceApi := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_FUTURE_USD_BASE_URL).BuildFuture(goex.BINANCE_SWAP) + binanceApi := builder.DefaultAPIBuilder.APIKey(BINANCE_TESTNET_API_KEY).APISecretkey(BINANCE_TESTNET_API_KEY_SECRET).Endpoint(binance.TESTNET_SPOT_WS_BASE_URL).BuildFuture(goex.BINANCE_SWAP) depth, err := binanceApi.GetFutureDepth(goex.BTC_USD, goex.SWAP_USDT_CONTRACT, 100) if err != nil { @@ -80,7 +80,7 @@ func subscribeSpotMarketData() { binanceWs.TickerCallback(func(ticker *goex.Ticker) { log.Printf("%+v\n", *ticker) }) - binanceWs.SubscribeTicker(goex.BTC_USD) + binanceWs.SubscribeTicker(goex.BTC_USDT) binanceWs.DepthCallback(func(depth *goex.Depth) { log.Printf("%+v\n", *depth) }) From 35e6047c49123a3816ca37f7242bf412edf21f27 Mon Sep 17 00:00:00 2001 From: bigbigbigfish <244249463@qq.com> Date: Sat, 7 May 2022 14:44:58 +0800 Subject: [PATCH 30/34] Update OKExV5.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加closePosition接口,修改createorder 错误msg返回不对应问题 --- okex/v5/OKExV5.go | 48 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/okex/v5/OKExV5.go b/okex/v5/OKExV5.go index 1f9b992c..d03981f9 100644 --- a/okex/v5/OKExV5.go +++ b/okex/v5/OKExV5.go @@ -305,14 +305,13 @@ func (ok *OKExV5) CreateOrder(param *CreateOrderParam) (*OrderSummaryV5, error) } if response.Code != 0 { - msg := response.Msg - if msg == "" { - if len(response.Data) > 0 { - msg = fmt.Sprintf("code:%d, scode:%s, smsg:%s", response.Code, response.Data[0].SCode, response.Data[0].SMsg) - } else { - msg = fmt.Sprintf("code:%d", response.Code) - } + msg := "" + if len(response.Data) > 0 { + msg = fmt.Sprintf("code:%d, scode:%s, smsg:%s", response.Code, response.Data[0].SCode, response.Data[0].SMsg) + } else { + msg = fmt.Sprintf("code:%d", response.Code) } + return nil, fmt.Errorf("CreateOrder error:%s", msg) } return &response.Data[0], nil @@ -359,6 +358,41 @@ func (ok *OKExV5) CancelOrderV5(instId, ordId, clOrdId string) (*OrderSummaryV5, return &response.Data[0], nil } +func (ok *OKExV5) ClosePositions(instId, mgnMode, posSide string) (*OrderSummaryV5, error) { + reqBody := make(map[string]interface{}) + reqBody["instId"] = instId + reqBody["mgnMode"] = mgnMode + reqBody["posSide"] = posSide + + type OrderResponse struct { + Code int `json:"code,string"` + Msg string `json:"msg"` + Data []OrderSummaryV5 `json:"data"` + } + var response OrderResponse + + uri := "/api/v5/trade/close-position" + + jsonStr, _, _ := ok.BuildRequestBody(reqBody) + err := ok.DoAuthorRequest(http.MethodPost, uri, jsonStr, &response) + if err != nil { + return nil, err + } + + if response.Code != 0 { + msg := response.Msg + if msg == "" { + if len(response.Data) > 0 { + msg = fmt.Sprintf("code:%d, scode:%s, smsg:%s", response.Code, response.Data[0].SCode, response.Data[0].SMsg) + } else { + msg = fmt.Sprintf("code:%d", response.Code) + } + } + return nil, fmt.Errorf("ClosePositions error:%s", msg) + } + return &response.Data[0], nil +} + type PendingOrderParam struct { InstType string Uly string From 3db227a13ae8212f8b927482e9d97a115c78ae6a Mon Sep 17 00:00:00 2001 From: bit_he <2767415655@qq.com> Date: Sun, 15 May 2022 14:47:43 +0800 Subject: [PATCH 31/34] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5be5f322..b29eef93 100644 --- a/README.md +++ b/README.md @@ -61,12 +61,10 @@ require ( donate ----------------- -BTC:bc1qm4fz8vg78yr75syclch9zfnwa0x00efy95972s +BTC: 1GoExWZop4JCJQkjb1UgtVGpjBKmP4DvG8 -LTC:MPgBjHmecACXDKH3KdmLR6X8mmp5YgAEZS - -ETH:0xDEa8C4B6B36294B00b05B6A6A5b63d8aA52A1bF7 +USDT(TRC20): TGoExC6xvzE4wSA9cYZnwcPaXEjibA5Vtc ### 欢迎为作者付一碗面钱 -![微信](wx_pay.JPG) ![支付宝](IMG_1177.jpg) \ No newline at end of file +![微信](wx_pay.JPG) ![支付宝](IMG_1177.jpg) From 1a1c06cf61789c0f1db3078d2825509075507993 Mon Sep 17 00:00:00 2001 From: bit_he <2767415655@qq.com> Date: Sun, 15 May 2022 14:49:48 +0800 Subject: [PATCH 32/34] Update README.md --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index b29eef93..6598bc1c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,3 @@ -
-goex - -
- ![build](https://github.com/WymA/goex/actions/workflows/go.yml/badge.svg?branch=dev) ### goex目标 From 717970b7e5a8b4bb775fb4e434e147d5ab9a3315 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Thu, 23 Jun 2022 16:35:17 +0800 Subject: [PATCH 33/34] [binance] support futures two-way position mode --- Const.go | 1 + binance/BinanceFutures.go | 14 ++++++++++++-- binance/BinanceSwap.go | 29 +++++++++++++++++++++-------- go.sum | 8 -------- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Const.go b/Const.go index 2ef285af..a214e663 100644 --- a/Const.go +++ b/Const.go @@ -193,4 +193,5 @@ const ( PostOnly LimitOrderOptionalParameter = iota + 1 Ioc Fok + Futures_Twoway_Position_Mode //币安双向持仓模式 ) diff --git a/binance/BinanceFutures.go b/binance/BinanceFutures.go index dac0e020..37fc4ad0 100644 --- a/binance/BinanceFutures.go +++ b/binance/BinanceFutures.go @@ -276,6 +276,10 @@ func (bs *BinanceFutures) GetFutureUserinfo(currencyPair ...CurrencyPair) (*Futu } func (bs *BinanceFutures) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, leverRate float64) (string, error) { + return bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, matchPrice) +} + +func (bs *BinanceFutures) PlaceFutureOrder2(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, opt ...LimitOrderOptionalParameter) (string, error) { apiPath := "order" symbol, err := bs.adaptToSymbol(currencyPair, contractType) if err != nil { @@ -299,8 +303,14 @@ func (bs *BinanceFutures) PlaceFutureOrder(currencyPair CurrencyPair, contractTy switch openType { case OPEN_BUY, CLOSE_SELL: param.Set("side", "BUY") + if len(opt) > 0 && opt[0] == Futures_Twoway_Position_Mode { + param.Set("positionSide", "LONG") + } case OPEN_SELL, CLOSE_BUY: param.Set("side", "SELL") + if len(opt) > 0 && opt[0] == Futures_Twoway_Position_Mode { + param.Set("positionSide", "SHORT") + } } bs.base.buildParamsSigned(¶m) @@ -332,7 +342,7 @@ func (bs *BinanceFutures) PlaceFutureOrder(currencyPair CurrencyPair, contractTy } func (bs *BinanceFutures) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int, opt ...LimitOrderOptionalParameter) (*FutureOrder, error) { - orderId, err := bs.PlaceFutureOrder(currencyPair, contractType, price, amount, openType, 0, 10) + orderId, err := bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, 0, opt...) return &FutureOrder{ OrderID2: orderId, Currency: currencyPair, @@ -344,7 +354,7 @@ func (bs *BinanceFutures) LimitFuturesOrder(currencyPair CurrencyPair, contractT } func (bs *BinanceFutures) MarketFuturesOrder(currencyPair CurrencyPair, contractType, amount string, openType int) (*FutureOrder, error) { - orderId, err := bs.PlaceFutureOrder(currencyPair, contractType, "", amount, openType, 1, 10) + orderId, err := bs.PlaceFutureOrder2(currencyPair, contractType, "", amount, openType, 1, 10) return &FutureOrder{ OrderID2: orderId, Currency: currencyPair, diff --git a/binance/BinanceSwap.go b/binance/BinanceSwap.go index 419715e0..b1fa749b 100644 --- a/binance/BinanceSwap.go +++ b/binance/BinanceSwap.go @@ -310,13 +310,13 @@ func (bs *BinanceSwap) Transfer(currency Currency, transferType int, amount floa } func (bs *BinanceSwap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, leverRate float64) (string, error) { - fOrder, err := bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, matchPrice, leverRate) + fOrder, err := bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, matchPrice) return fOrder.OrderID2, err } -func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, leverRate float64) (*FutureOrder, error) { +func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice int, opt ...LimitOrderOptionalParameter) (*FutureOrder, error) { if contractType == SWAP_CONTRACT { - orderId, err := bs.f.PlaceFutureOrder(currencyPair.AdaptUsdtToUsd(), contractType, price, amount, openType, matchPrice, leverRate) + orderId, err := bs.f.PlaceFutureOrder2(currencyPair.AdaptUsdtToUsd(), contractType, price, amount, openType, matchPrice, opt...) return &FutureOrder{ OrderID2: orderId, Price: ToFloat64(price), @@ -324,7 +324,7 @@ func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType Status: ORDER_UNFINISH, Currency: currencyPair, OType: openType, - LeverRate: leverRate, + LeverRate: 0, ContractName: contractType, }, err } @@ -339,7 +339,7 @@ func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType Price: ToFloat64(price), Amount: ToFloat64(amount), OrderType: openType, - LeverRate: leverRate, + LeverRate: 0, ContractName: contractType, } @@ -353,9 +353,16 @@ func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType switch openType { case OPEN_BUY, CLOSE_SELL: params.Set("side", "BUY") + if len(opt) > 0 && opt[0] == Futures_Twoway_Position_Mode { + params.Set("positionSide", "LONG") + } case OPEN_SELL, CLOSE_BUY: params.Set("side", "SELL") + if len(opt) > 0 && opt[0] == Futures_Twoway_Position_Mode { + params.Set("positionSide", "SHORT") + } } + if matchPrice == 0 { params.Set("type", "LIMIT") params.Set("price", price) @@ -365,6 +372,7 @@ func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType } bs.buildParamsSigned(¶ms) + resp, err := HttpPostForm2(bs.httpClient, path, params, map[string]string{"X-MBX-APIKEY": bs.accessKey}) if err != nil { @@ -387,11 +395,11 @@ func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType } func (bs *BinanceSwap) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int, opt ...LimitOrderOptionalParameter) (*FutureOrder, error) { - return bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, 0, 10) + return bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, 0, opt...) } func (bs *BinanceSwap) MarketFuturesOrder(currencyPair CurrencyPair, contractType, amount string, openType int) (*FutureOrder, error) { - return bs.PlaceFutureOrder2(currencyPair, contractType, "0", amount, openType, 1, 10) + return bs.PlaceFutureOrder2(currencyPair, contractType, "0", amount, openType, 1) } func (bs *BinanceSwap) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) { @@ -407,7 +415,12 @@ func (bs *BinanceSwap) FutureCancelOrder(currencyPair CurrencyPair, contractType path := bs.apiV1 + ORDER_URI params := url.Values{} params.Set("symbol", bs.adaptCurrencyPair(currencyPair).ToSymbol("")) - params.Set("orderId", orderId) + + if strings.HasPrefix(orderId, "goex") { //goex default clientOrderId Features + params.Set("origClientOrderId", orderId) + } else { + params.Set("orderId", orderId) + } bs.buildParamsSigned(¶ms) diff --git a/go.sum b/go.sum index 2231ae01..3db6d164 100644 --- a/go.sum +++ b/go.sum @@ -7,16 +7,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-openapi/errors v0.19.4 h1:fSGwO1tSYHFu70NKaWJt5Qh0qoBRtCm/mXS1yhf+0W0= github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw= github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -40,14 +35,11 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4= -github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0= github.com/valyala/fasthttp v1.36.0 h1:NhqfO/cB7Ajn1czkKnWkMHyPYr5nyND14ZGPk23g0/c= github.com/valyala/fasthttp v1.36.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= From 3e58f5e8b0cd293fda43fe9ff02c0448f7c81592 Mon Sep 17 00:00:00 2001 From: nntaoli <2767415655@qq.com> Date: Thu, 23 Jun 2022 16:38:27 +0800 Subject: [PATCH 34/34] [binance] futures market order --- binance/BinanceFutures.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binance/BinanceFutures.go b/binance/BinanceFutures.go index 37fc4ad0..25ea1bef 100644 --- a/binance/BinanceFutures.go +++ b/binance/BinanceFutures.go @@ -354,7 +354,7 @@ func (bs *BinanceFutures) LimitFuturesOrder(currencyPair CurrencyPair, contractT } func (bs *BinanceFutures) MarketFuturesOrder(currencyPair CurrencyPair, contractType, amount string, openType int) (*FutureOrder, error) { - orderId, err := bs.PlaceFutureOrder2(currencyPair, contractType, "", amount, openType, 1, 10) + orderId, err := bs.PlaceFutureOrder2(currencyPair, contractType, "", amount, openType, 1) return &FutureOrder{ OrderID2: orderId, Currency: currencyPair,