From 8a0c5f95d5ed50a399f6e0578860f13a62648690 Mon Sep 17 00:00:00 2001 From: Adrian Gallagher Date: Thu, 26 Sep 2019 09:39:28 +1000 Subject: [PATCH] Remove HADAX exchange support (#362) * Remove Huobi HADAX * Remove Hadax from root_readme.tmpl --- README.md | 1 - config/config_test.go | 2 +- config_example.json | 46 - exchange.go | 3 - exchanges/huobihadax/README.md | 140 --- exchanges/huobihadax/huobihadax.go | 1024 ----------------- exchanges/huobihadax/huobihadax_test.go | 670 ----------- exchanges/huobihadax/huobihadax_types.go | 535 --------- exchanges/huobihadax/huobihadax_websocket.go | 475 -------- exchanges/huobihadax/huobihadax_wrapper.go | 475 -------- testdata/configtest.json | 46 - tools/documentation/documentation.go | 2 - .../exchanges_templates/huobihadax.tmpl | 105 -- .../root_templates/root_readme.tmpl | 1 - 14 files changed, 1 insertion(+), 3524 deletions(-) delete mode 100644 exchanges/huobihadax/README.md delete mode 100644 exchanges/huobihadax/huobihadax.go delete mode 100644 exchanges/huobihadax/huobihadax_test.go delete mode 100644 exchanges/huobihadax/huobihadax_types.go delete mode 100644 exchanges/huobihadax/huobihadax_websocket.go delete mode 100644 exchanges/huobihadax/huobihadax_wrapper.go delete mode 100644 tools/documentation/exchanges_templates/huobihadax.tmpl diff --git a/README.md b/README.md index 041a2fdd..86708b4c 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader | Gemini | Yes | Yes | No | | HitBTC | Yes | Yes | No | | Huobi.Pro | Yes | Yes | NA | -| Huobi.Hadax | Yes | Yes | NA | | ItBit | Yes | NA | No | | Kraken | Yes | Yes | NA | | Lbank | Yes | No | NA | diff --git a/config/config_test.go b/config/config_test.go index c5f59b18..24a48434 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -13,7 +13,7 @@ import ( const ( // Default number of enabled exchanges. Modify this whenever an exchange is // added or removed - defaultEnabledExchanges = 28 + defaultEnabledExchanges = 27 ) func TestGetCurrencyConfig(t *testing.T) { diff --git a/config_example.json b/config_example.json index 7d92f421..2cb350a9 100644 --- a/config_example.json +++ b/config_example.json @@ -933,52 +933,6 @@ } ] }, - { - "name": "HuobiHadax", - "enabled": true, - "verbose": false, - "websocket": false, - "useSandbox": false, - "restPollingDelay": 10, - "httpTimeout": 15000000000, - "websocketResponseCheckTimeout": 30000000, - "websocketResponseMaxLimit": 7000000000, - "websocketOrderbookBufferLimit": 5, - "httpUserAgent": "", - "httpDebugging": false, - "authenticatedApiSupport": false, - "authenticatedWebsocketApiSupport": false, - "apiKey": "Key", - "apiSecret": "Secret", - "apiAuthPemKey": "-----BEGIN EC PRIVATE KEY-----\nJUSTADUMMY\n-----END EC PRIVATE KEY-----\n", - "apiUrl": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API", - "apiUrlSecondary": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API", - "proxyAddress": "", - "websocketUrl": "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API", - "availablePairs": "EGCC-ETH,BKBT-BTC,YCC-ETH,SEELE-BTC,INC-BTC,BUT-ETH,UIP-BTC,PC-BTC,TRIO-ETH,GSC-BTC,DAC-BTC,HOT-BTC,UC-ETH,REN-ETH,GET-ETH,LYM-BTC,IDT-ETH,MEX-BTC,MUSK-BTC,UUU-BTC,MEX-ETH,ZJLT-ETH,SSP-ETH,XMX-ETH,18C-ETH,CDC-ETH,SEXC-ETH,HPT-BTC,HPT-HT,TOS-ETH,UC-BTC,EKT-BTC,CVCOIN-ETH,BCV-BTC,EKT-ETH,CDC-BTC,MAN-ETH,CVCOIN-BTC,MAN-BTC,SEXC-BTC,HPT-USDT,LXT-ETH,GVE-BTC,TOS-BTC,18C-BTC,YCC-BTC,CNN-BTC,RTE-ETH,GVE-ETH,CNN-ETH,PORTAL-BTC,LXT-BTC,PORTAL-ETH,ZJLT-BTC,DAC-ETH,REN-BTC,PC-ETH,GSC-ETH,RTE-BTC,BKBT-ETH,TRIO-BTC,GTC-BTC,IIC-BTC,BUT-BTC,SEELE-ETH,SHE-BTC,UIP-ETH,NCC-ETH,EGCC-BTC,MUSK-ETH,BCV-ETH,RCCC-BTC,UUU-ETH,IDT-BTC,XMX-BTC,SSP-BTC,AE-ETH,MT-HT,NCC-BTC,AAC-BTC,KCASH-BTC,DATX-BTC,HOT-ETH,LYM-ETH,GET-BTC,FAIR-ETH,GTC-ETH,IIC-ETH,INC-ETH,RCCC-ETH,FAIR-BTC,AE-BTC,KCASH-HT,MT-ETH,MT-BTC,SHE-ETH,PNT-ETH,DATX-ETH,AAC-ETH,PNT-BTC,KCASH-ETH,FTI-ETH,FTI-BTC", - "enabledPairs": "NCC-BTC", - "baseCurrencies": "USD", - "assetTypes": "SPOT", - "supportsAutoPairUpdates": true, - "configCurrencyPairFormat": { - "uppercase": true, - "delimiter": "-" - }, - "requestCurrencyPairFormat": { - "uppercase": false - }, - "bankAccounts": [ - { - "bankName": "", - "bankAddress": "", - "accountName": "", - "accountNumber": "", - "swiftCode": "", - "iban": "", - "supportedCurrencies": "" - } - ] - }, { "name": "ITBIT", "enabled": true, diff --git a/exchange.go b/exchange.go index b8f8c731..1d36f001 100644 --- a/exchange.go +++ b/exchange.go @@ -24,7 +24,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/gemini" "github.com/thrasher-corp/gocryptotrader/exchanges/hitbtc" "github.com/thrasher-corp/gocryptotrader/exchanges/huobi" - "github.com/thrasher-corp/gocryptotrader/exchanges/huobihadax" "github.com/thrasher-corp/gocryptotrader/exchanges/itbit" "github.com/thrasher-corp/gocryptotrader/exchanges/kraken" "github.com/thrasher-corp/gocryptotrader/exchanges/lakebtc" @@ -166,8 +165,6 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { exch = new(hitbtc.HitBTC) case "huobi": exch = new(huobi.HUOBI) - case "huobihadax": - exch = new(huobihadax.HUOBIHADAX) case "itbit": exch = new(itbit.ItBit) case "kraken": diff --git a/exchanges/huobihadax/README.md b/exchanges/huobihadax/README.md deleted file mode 100644 index 689bb168..00000000 --- a/exchanges/huobihadax/README.md +++ /dev/null @@ -1,140 +0,0 @@ -# GoCryptoTrader package Huobihadax - - - - -[![Build Status](https://travis-ci.org/thrasher-corp/gocryptotrader.svg?branch=master)](https://travis-ci.org/thrasher-corp/gocryptotrader) -[![Software License](https://img.shields.io/badge/License-MIT-orange.svg?style=flat-square)](https://github.com/thrasher-corp/gocryptotrader/blob/master/LICENSE) -[![GoDoc](https://godoc.org/github.com/thrasher-corp/gocryptotrader?status.svg)](https://godoc.org/github.com/thrasher-corp/gocryptotrader/exchanges/huobihadax) -[![Coverage Status](http://codecov.io/github/thrasher-corp/gocryptotrader/coverage.svg?branch=master)](http://codecov.io/github/thrasher-corp/gocryptotrader?branch=master) -[![Go Report Card](https://goreportcard.com/badge/github.com/thrasher-corp/gocryptotrader)](https://goreportcard.com/report/github.com/thrasher-corp/gocryptotrader) - - -This huobihadax package is part of the GoCryptoTrader codebase. - -## This is still in active development - -You can track ideas, planned features and what's in progresss on this Trello board: [https://trello.com/b/ZAhMhpOy/gocryptotrader](https://trello.com/b/ZAhMhpOy/gocryptotrader). - -Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk) - -## HuobiHadax Exchange - -### Current Features - -+ REST functions - -### How to enable - -+ [Enable via configuration](https://github.com/thrasher-corp/gocryptotrader/tree/master/config#enable-exchange-via-config-example) - -+ Individual package example below: - -```go - // Exchanges will be abstracted out in further updates and examples will be - // supplied then -``` - -### How to do REST public/private calls - -+ If enabled via "configuration".json file the exchange will be added to the -IBotExchange array in the ```go var bot Bot``` and you will only be able to use -the wrapper interface functions for accessing exchange data. View routines.go -for an example of integration usage with GoCryptoTrader. Rudimentary example -below: - -main.go -```go -var h exchange.IBotExchange - -for i := range bot.exchanges { - if bot.exchanges[i].GetName() == "HuobiHadax" { - h = bot.exchanges[i] - } -} - -// Public calls - wrapper functions - -// Fetches current ticker information -tick, err := h.GetTickerPrice() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := h.GetOrderbookEx() -if err != nil { - // Handle error -} - -// Private calls - wrapper functions - make sure your APIKEY and APISECRET are -// set and AuthenticatedAPISupport is set to true - -// Fetches current account information -accountInfo, err := h.GetAccountInfo() -if err != nil { - // Handle error -} -``` - -+ If enabled via individually importing package, rudimentary example below: - -```go -// Public calls - -// Fetches current ticker information -ticker, err := h.GetTicker() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := h.GetOrderBook() -if err != nil { - // Handle error -} - -// Private calls - make sure your APIKEY and APISECRET are set and -// AuthenticatedAPISupport is set to true - -// GetUserInfo returns account info -accountInfo, err := h.GetUserInfo(...) -if err != nil { - // Handle error -} - -// Submits an order and the exchange and returns its tradeID -tradeID, err := h.Trade(...) -if err != nil { - // Handle error -} -``` - -### How to do LongPolling public/private calls - -```go - // Exchanges will be abstracted out in further updates and examples will be - // supplied then -``` - -### Please click GoDocs chevron above to view current GoDoc information for this package - -## Contribution - -Please feel free to submit any pull requests or suggest any desired features to be added. - -When submitting a PR, please abide by our coding guidelines: - -+ Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). -+ Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines. -+ Code must adhere to our [coding style](https://github.com/thrasher-corp/gocryptotrader/blob/master/doc/coding_style.md). -+ Pull requests need to be based on and opened against the `master` branch. - -## Donations - - - -If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to: - -***1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB*** - diff --git a/exchanges/huobihadax/huobihadax.go b/exchanges/huobihadax/huobihadax.go deleted file mode 100644 index f312fa72..00000000 --- a/exchanges/huobihadax/huobihadax.go +++ /dev/null @@ -1,1024 +0,0 @@ -package huobihadax - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "net/http" - "net/url" - "strconv" - "time" - - "github.com/thrasher-corp/gocryptotrader/common" - "github.com/thrasher-corp/gocryptotrader/config" - "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" - "github.com/thrasher-corp/gocryptotrader/exchanges/request" - "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" - "github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler" - log "github.com/thrasher-corp/gocryptotrader/logger" -) - -const ( - huobihadaxAPIURL = "https://api.hadax.com" - huobihadaxAPIVersion = "1" - huobihadaxAPIName = "hadax" - - huobihadaxMarketHistoryKline = "market/history/kline" - huobihadaxMarketDetail = "market/detail" - huobihadaxMarketDetailMerged = "market/detail/merged" - huobihadaxMarketDepth = "market/depth" - huobihadaxMarketTrade = "market/trade" - huobihadaxMarketTradeHistory = "market/history/trade" - huobihadaxSymbols = "common/symbols" - huobihadaxCurrencies = "common/currencys" - huobihadaxTimestamp = "common/timestamp" - huobihadaxAccounts = "account/accounts" - huobihadaxAggregatedBalance = "subuser/aggregate-balance" - huobihadaxAccountBalance = "account/accounts/%s/balance" - huobihadaxOrderPlace = "order/orders/place" - huobihadaxOrderCancel = "order/orders/%s/submitcancel" - huobihadaxGetOpenOrders = "order/openOrders" - huobihadaxOrderCancelBatch = "order/orders/batchcancel" - huobiHadaxBatchCancelOpenOrders = "order/orders/batchCancelOpenOrders" - huobihadaxGetOrder = "order/orders/%s" - huobihadaxGetOrderMatch = "order/orders/%s/matchresults" - huobihadaxGetOrders = "order/orders" - huobihadaxGetOrdersMatch = "orders/matchresults" - huobihadaxMarginTransferIn = "dw/transfer-in/margin" - huobihadaxMarginTransferOut = "dw/transfer-out/margin" - huobihadaxMarginOrders = "margin/orders" - huobihadaxMarginRepay = "margin/orders/%s/repay" - huobihadaxMarginLoanOrders = "margin/loan-orders" - huobihadaxMarginAccountBalance = "margin/accounts/balance" - huobihadaxWithdrawCreate = "dw/withdraw/api/create" - huobihadaxWithdrawCancel = "dw/withdraw-virtual/%s/cancel" - huobiHadaxDepositAddress = "query/deposit-withdraw" - - huobihadaxAuthRate = 100 - huobihadaxUnauthRate = 100 -) - -// HUOBIHADAX is the overarching type across this package -type HUOBIHADAX struct { - WebsocketConn *wshandler.WebsocketConnection - AuthenticatedWebsocketConn *wshandler.WebsocketConnection - exchange.Base -} - -// SetDefaults sets default values for the exchange -func (h *HUOBIHADAX) SetDefaults() { - h.Name = "HuobiHadax" - h.Enabled = false - h.Fee = 0 - h.Verbose = false - h.RESTPollingDelay = 10 - h.APIWithdrawPermissions = exchange.AutoWithdrawCryptoWithSetup | - exchange.NoFiatWithdrawals - h.RequestCurrencyPairFormat.Delimiter = "" - h.RequestCurrencyPairFormat.Uppercase = false - h.ConfigCurrencyPairFormat.Delimiter = "-" - h.ConfigCurrencyPairFormat.Uppercase = true - h.AssetTypes = []string{ticker.Spot} - h.SupportsAutoPairUpdating = true - h.SupportsRESTTickerBatching = false - h.Requester = request.New(h.Name, - request.NewRateLimit(time.Second*10, huobihadaxAuthRate), - request.NewRateLimit(time.Second*10, huobihadaxUnauthRate), - common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout)) - h.APIUrlDefault = huobihadaxAPIURL - h.APIUrl = h.APIUrlDefault - h.Websocket = wshandler.New() - h.Websocket.Functionality = wshandler.WebsocketKlineSupported | - wshandler.WebsocketTradeDataSupported | - wshandler.WebsocketOrderbookSupported | - wshandler.WebsocketSubscribeSupported | - wshandler.WebsocketUnsubscribeSupported | - wshandler.WebsocketAuthenticatedEndpointsSupported | - wshandler.WebsocketAccountDataSupported | - wshandler.WebsocketMessageCorrelationSupported - h.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - h.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - h.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit - -} - -// Setup sets user configuration -func (h *HUOBIHADAX) Setup(exch *config.ExchangeConfig) { - if !exch.Enabled { - h.SetEnabled(false) - } else { - h.Enabled = true - h.AuthenticatedAPISupport = exch.AuthenticatedAPISupport - h.AuthenticatedWebsocketAPISupport = exch.AuthenticatedWebsocketAPISupport - h.SetAPIKeys(exch.APIKey, exch.APISecret, "", false) - h.APIAuthPEMKeySupport = exch.APIAuthPEMKeySupport - h.APIAuthPEMKey = exch.APIAuthPEMKey - h.SetHTTPClientTimeout(exch.HTTPTimeout) - h.SetHTTPClientUserAgent(exch.HTTPUserAgent) - h.RESTPollingDelay = exch.RESTPollingDelay - h.Verbose = exch.Verbose - h.HTTPDebugging = exch.HTTPDebugging - h.BaseCurrencies = exch.BaseCurrencies - h.AvailablePairs = exch.AvailablePairs - h.EnabledPairs = exch.EnabledPairs - err := h.SetCurrencyPairFormat() - if err != nil { - log.Fatal(err) - } - err = h.SetAssetTypes() - if err != nil { - log.Fatal(err) - } - err = h.SetAutoPairDefaults() - if err != nil { - log.Fatal(err) - } - err = h.SetAPIURL(exch) - if err != nil { - log.Fatal(err) - } - err = h.SetClientProxyAddress(exch.ProxyAddress) - if err != nil { - log.Fatal(err) - } - err = h.Websocket.Setup(h.WsConnect, - h.Subscribe, - h.Unsubscribe, - exch.Name, - exch.Websocket, - exch.Verbose, - HuobiHadaxSocketIOAddress, - exch.WebsocketURL, - exch.AuthenticatedWebsocketAPISupport) - if err != nil { - log.Fatal(err) - } - h.WebsocketConn = &wshandler.WebsocketConnection{ - ExchangeName: h.Name, - URL: HuobiHadaxSocketIOAddress, - ProxyURL: h.Websocket.GetProxyAddress(), - Verbose: h.Verbose, - RateLimit: rateLimit, - ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, - ResponseMaxLimit: exch.WebsocketResponseMaxLimit, - } - h.AuthenticatedWebsocketConn = &wshandler.WebsocketConnection{ - ExchangeName: h.Name, - URL: wsAccountsOrdersURL, - ProxyURL: h.Websocket.GetProxyAddress(), - Verbose: h.Verbose, - RateLimit: rateLimit, - ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, - ResponseMaxLimit: exch.WebsocketResponseMaxLimit, - } - h.Websocket.Orderbook.Setup( - exch.WebsocketOrderbookBufferLimit, - false, - false, - false, - false, - exch.Name) - } -} - -// GetSpotKline returns kline data -// KlinesRequestParams holds the Kline request params -func (h *HUOBIHADAX) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) { - vals := url.Values{} - vals.Set("symbol", arg.Symbol) - vals.Set("period", string(arg.Period)) - - if arg.Size != 0 { - vals.Set("size", strconv.Itoa(arg.Size)) - } - - type response struct { - Response - Data []KlineItem `json:"data"` - } - - var result response - urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketHistoryKline) - - err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Data, err -} - -// GetMarketDetailMerged returns the ticker for the specified symbol -func (h *HUOBIHADAX) GetMarketDetailMerged(symbol string) (DetailMerged, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - - type response struct { - Response - Tick DetailMerged `json:"tick"` - } - - var result response - urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDetailMerged) - - err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) - if result.ErrorMessage != "" { - return result.Tick, errors.New(result.ErrorMessage) - } - return result.Tick, err -} - -// GetDepth returns the depth for the specified symbol -func (h *HUOBIHADAX) GetDepth(symbol, depthType string) (Orderbook, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - - if depthType != "" { - vals.Set("type", depthType) - } - - type response struct { - Response - Depth Orderbook `json:"tick"` - } - - var result response - urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDepth) - - err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) - if result.ErrorMessage != "" { - return result.Depth, errors.New(result.ErrorMessage) - } - return result.Depth, err -} - -// GetTrades returns the trades for the specified symbol -func (h *HUOBIHADAX) GetTrades(symbol string) ([]Trade, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - - type response struct { - Response - Tick struct { - Data []Trade `json:"data"` - } `json:"tick"` - } - - var result response - urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketTrade) - - err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Tick.Data, err -} - -// GetLatestSpotPrice returns latest spot price of symbol -// -// symbol: string of currency pair -func (h *HUOBIHADAX) GetLatestSpotPrice(symbol string) (float64, error) { - list, err := h.GetTradeHistory(symbol, "1") - - if err != nil { - return 0, err - } - if len(list) == 0 { - return 0, errors.New("the length of the list is 0") - } - - return list[0].Trades[0].Price, nil -} - -// GetTradeHistory returns the trades for the specified symbol -func (h *HUOBIHADAX) GetTradeHistory(symbol, size string) ([]TradeHistory, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - - if size != "" { - vals.Set("size", size) - } - - type response struct { - Response - TradeHistory []TradeHistory `json:"data"` - } - - var result response - urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketTradeHistory) - - err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.TradeHistory, err -} - -// GetMarketDetail returns the ticker for the specified symbol -func (h *HUOBIHADAX) GetMarketDetail(symbol string) (Detail, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - - type response struct { - Response - Tick Detail `json:"tick"` - } - - var result response - urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDetail) - - err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) - if result.ErrorMessage != "" { - return result.Tick, errors.New(result.ErrorMessage) - } - return result.Tick, err -} - -// GetSymbols returns an array of symbols supported by Huobi -func (h *HUOBIHADAX) GetSymbols() ([]Symbol, error) { - type response struct { - Response - Symbols []Symbol `json:"data"` - } - - var result response - urlPath := fmt.Sprintf("%s/v%s/%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxAPIName, huobihadaxSymbols) - - err := h.SendHTTPRequest(urlPath, &result) - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Symbols, err -} - -// GetCurrencies returns a list of currencies supported by Huobi -func (h *HUOBIHADAX) GetCurrencies() ([]string, error) { - type response struct { - Response - Currencies []string `json:"data"` - } - - var result response - urlPath := fmt.Sprintf("%s/v%s/%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxAPIName, huobihadaxCurrencies) - - err := h.SendHTTPRequest(urlPath, &result) - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Currencies, err -} - -// GetTimestamp returns the Huobi server time -func (h *HUOBIHADAX) GetTimestamp() (int64, error) { - type response struct { - Response - Timestamp int64 `json:"data"` - } - - var result response - urlPath := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxTimestamp) - - err := h.SendHTTPRequest(urlPath, &result) - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.Timestamp, err -} - -// GetAccounts returns the Huobi user accounts -func (h *HUOBIHADAX) GetAccounts() ([]Account, error) { - type response struct { - Response - AccountData []Account `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobihadaxAccounts, url.Values{}, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.AccountData, err -} - -// GetAccountBalance returns the users Huobi account balance -func (h *HUOBIHADAX) GetAccountBalance(accountID string) ([]AccountBalanceDetail, error) { - type response struct { - Response - AccountBalanceData AccountBalance `json:"data"` - } - - var result response - endpoint := fmt.Sprintf("%s/%s", huobihadaxAPIName, fmt.Sprintf(huobihadaxAccountBalance, accountID)) - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, url.Values{}, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.AccountBalanceData.AccountBalanceDetails, err -} - -// GetAggregatedBalance returns the balances of all the sub-account aggregated. -func (h *HUOBIHADAX) GetAggregatedBalance() ([]AggregatedBalance, error) { - type response struct { - Response - AggregatedBalances []AggregatedBalance `json:"data"` - } - - var result response - - err := h.SendAuthenticatedHTTPRequest( - http.MethodGet, - huobihadaxAggregatedBalance, - url.Values{}, - &result, - ) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.AggregatedBalances, err -} - -// SpotNewOrder submits an order to Huobi -func (h *HUOBIHADAX) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) { - vals := make(map[string]string) - vals["account-id"] = fmt.Sprintf("%d", arg.AccountID) - vals["amount"] = strconv.FormatFloat(arg.Amount, 'f', -1, 64) - - // Only set price if order type is not equal to buy-market or sell-market - if arg.Type != SpotNewOrderRequestTypeBuyMarket && arg.Type != SpotNewOrderRequestTypeSellMarket { - vals["price"] = strconv.FormatFloat(arg.Price, 'f', -1, 64) - } - - if arg.Source != "" { - vals["source"] = arg.Source - } - - vals["symbol"] = arg.Symbol - vals["type"] = string(arg.Type) - - type response struct { - Response - OrderID int64 `json:"data,string"` - } - - // The API indicates that for the POST request, the parameters of each method are not signed and authenticated. That is, only the AccessKeyId, SignatureMethod, SignatureVersion, and Timestamp parameters are required for the POST request. The other parameters are placed in the body. - // So re-encode the Post parameter - bytesParams, _ := json.Marshal(vals) - postBodyParams := string(bytesParams) - if h.Verbose { - fmt.Println("Post params:", postBodyParams) - } - - var result response - endpoint := fmt.Sprintf("%s/%s", huobihadaxAPIName, huobihadaxOrderPlace) - err := h.SendAuthenticatedHTTPPostRequest(http.MethodPost, endpoint, postBodyParams, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.OrderID, err -} - -// CancelExistingOrder cancels an order on Huobi -func (h *HUOBIHADAX) CancelExistingOrder(orderID int64) (int64, error) { - type response struct { - Response - OrderID int64 `json:"data,string"` - } - - var result response - endpoint := fmt.Sprintf(huobihadaxOrderCancel, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, url.Values{}, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.OrderID, err -} - -// CancelOrderBatch cancels a batch of orders -- to-do -func (h *HUOBIHADAX) CancelOrderBatch(orderIDs []int64) (CancelOrderBatch, error) { - type response struct { - Status string `json:"status"` - Data CancelOrderBatch `json:"data"` - } - - // Used to send param formatting - type postBody struct { - List []int64 `json:"order-ids"` - } - - // Format to JSON - bytesParams, _ := common.JSONEncode(&postBody{List: orderIDs}) - postBodyParams := string(bytesParams) - - var result response - err := h.SendAuthenticatedHTTPPostRequest(http.MethodPost, huobihadaxOrderCancelBatch, postBodyParams, &result) - - if len(result.Data.Failed) != 0 { - errJSON, _ := common.JSONEncode(result.Data.Failed) - return CancelOrderBatch{}, errors.New(string(errJSON)) - } - return result.Data, err -} - -// CancelOpenOrdersBatch cancels a batch of orders -- to-do -func (h *HUOBIHADAX) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrdersBatch, error) { - params := url.Values{} - - params.Set("account-id", accountID) - var result CancelOpenOrdersBatch - - data := struct { - AccountID string `json:"account-id"` - Symbol string `json:"symbol"` - }{ - AccountID: accountID, - Symbol: symbol, - } - - bytesParams, _ := common.JSONEncode(data) - postBodyParams := string(bytesParams) - - err := h.SendAuthenticatedHTTPPostRequest(http.MethodPost, huobiHadaxBatchCancelOpenOrders, postBodyParams, &result) - - if result.Data.FailedCount > 0 { - return result, fmt.Errorf("there were %v failed order cancellations", result.Data.FailedCount) - } - - return result, err -} - -// GetOpenOrders returns a list of orders -func (h *HUOBIHADAX) GetOpenOrders(accountID, symbol, side string, size int) ([]OrderInfo, error) { - type response struct { - Response - Orders []OrderInfo `json:"data"` - } - - vals := url.Values{} - vals.Set("symbol", symbol) - vals.Set("accountID", accountID) - if len(side) > 0 { - vals.Set("side", side) - } - vals.Set("size", fmt.Sprintf("%v", size)) - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobihadaxGetOpenOrders, vals, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - - return result.Orders, err -} - -// GetOrder returns order information for the specified order -func (h *HUOBIHADAX) GetOrder(orderID int64) (OrderInfo, error) { - type response struct { - Response - Order OrderInfo `json:"data"` - } - - var result response - endpoint := fmt.Sprintf(huobihadaxGetOrder, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, url.Values{}, &result) - - if result.ErrorMessage != "" { - return result.Order, errors.New(result.ErrorMessage) - } - return result.Order, err -} - -// GetOrderMatchResults returns matched order info for the specified order -func (h *HUOBIHADAX) GetOrderMatchResults(orderID int64) ([]OrderMatchInfo, error) { - type response struct { - Response - Orders []OrderMatchInfo `json:"data"` - } - - var result response - endpoint := fmt.Sprintf(huobihadaxGetOrderMatch, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, url.Values{}, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Orders, err -} - -// GetOrders returns a list of orders -func (h *HUOBIHADAX) GetOrders(symbol, types, start, end, states, from, direct, size string) ([]OrderInfo, error) { - type response struct { - Response - Orders []OrderInfo `json:"data"` - } - - vals := url.Values{} - vals.Set("symbol", symbol) - vals.Set("states", states) - - if types != "" { - vals.Set("types", types) - } - - if start != "" { - vals.Set("start-date", start) - } - - if end != "" { - vals.Set("end-date", end) - } - - if from != "" { - vals.Set("from", from) - } - - if direct != "" { - vals.Set("direct", direct) - } - - if size != "" { - vals.Set("size", size) - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobihadaxGetOrders, vals, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Orders, err -} - -// GetOrdersMatch returns a list of matched orders -func (h *HUOBIHADAX) GetOrdersMatch(symbol, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) { - type response struct { - Response - Orders []OrderMatchInfo `json:"data"` - } - - vals := url.Values{} - vals.Set("symbol", symbol) - - if types != "" { - vals.Set("types", types) - } - - if start != "" { - vals.Set("start-date", start) - } - - if end != "" { - vals.Set("end-date", end) - } - - if from != "" { - vals.Set("from", from) - } - - if direct != "" { - vals.Set("direct", direct) - } - - if size != "" { - vals.Set("size", size) - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobihadaxGetOrdersMatch, vals, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Orders, err -} - -// MarginTransfer transfers assets into or out of the margin account -func (h *HUOBIHADAX) MarginTransfer(symbol, currency string, amount float64, in bool) (int64, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - vals.Set("currency", currency) - vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - - path := huobihadaxMarginTransferIn - if !in { - path = huobihadaxMarginTransferOut - } - - type response struct { - Response - TransferID int64 `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, path, vals, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.TransferID, err -} - -// MarginOrder submits a margin order application -func (h *HUOBIHADAX) MarginOrder(symbol, currency string, amount float64) (int64, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - vals.Set("currency", currency) - vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - - type response struct { - Response - MarginOrderID int64 `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobihadaxMarginOrders, vals, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.MarginOrderID, err -} - -// MarginRepayment repays a margin amount for a margin ID -func (h *HUOBIHADAX) MarginRepayment(orderID int64, amount float64) (int64, error) { - vals := url.Values{} - vals.Set("order-id", strconv.FormatInt(orderID, 10)) - vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - - type response struct { - Response - MarginOrderID int64 `json:"data"` - } - - var result response - endpoint := fmt.Sprintf(huobihadaxMarginRepay, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, vals, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.MarginOrderID, err -} - -// GetMarginLoanOrders returns the margin loan orders -func (h *HUOBIHADAX) GetMarginLoanOrders(symbol, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) { - vals := url.Values{} - vals.Set("symbol", symbol) - vals.Set("currency", currency) - - if start != "" { - vals.Set("start-date", start) - } - - if end != "" { - vals.Set("end-date", end) - } - - if states != "" { - vals.Set("states", states) - } - - if from != "" { - vals.Set("from", from) - } - - if direct != "" { - vals.Set("direct", direct) - } - - if size != "" { - vals.Set("size", size) - } - - type response struct { - Response - MarginLoanOrders []MarginOrder `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobihadaxMarginLoanOrders, vals, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.MarginLoanOrders, err -} - -// GetMarginAccountBalance returns the margin account balances -func (h *HUOBIHADAX) GetMarginAccountBalance(symbol string) ([]MarginAccountBalance, error) { - type response struct { - Response - Balances []MarginAccountBalance `json:"data"` - } - - vals := url.Values{} - if symbol != "" { - vals.Set("symbol", symbol) - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobihadaxMarginAccountBalance, vals, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Balances, err -} - -// Withdraw withdraws the desired amount and currency -func (h *HUOBIHADAX) Withdraw(c currency.Code, address, addrTag string, amount, fee float64) (int64, error) { - type response struct { - Response - WithdrawID int64 `json:"data"` - } - data := struct { - Address string `json:"address"` - Amount string `json:"amount"` - Currency string `json:"currency"` - Fee string `json:"fee,omitempty"` - AddrTag string `json:"addr-tag,omitempty"` - }{ - Address: address, - Currency: c.Lower().String(), - Amount: strconv.FormatFloat(amount, 'f', -1, 64), - } - - if fee > 0 { - data.Fee = strconv.FormatFloat(fee, 'f', -1, 64) - } - - if c == currency.XRP { - data.AddrTag = addrTag - } - - var result response - bytesParams, _ := common.JSONEncode(data) - postBodyParams := string(bytesParams) - err := h.SendAuthenticatedHTTPPostRequest(http.MethodPost, huobihadaxWithdrawCreate, postBodyParams, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.WithdrawID, err -} - -// CancelWithdraw cancels a withdraw request -func (h *HUOBIHADAX) CancelWithdraw(withdrawID int64) (int64, error) { - type response struct { - Response - WithdrawID int64 `json:"data"` - } - - vals := url.Values{} - vals.Set("withdraw-id", strconv.FormatInt(withdrawID, 10)) - - var result response - endpoint := fmt.Sprintf(huobihadaxWithdrawCancel, strconv.FormatInt(withdrawID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, vals, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.WithdrawID, err -} - -// SendHTTPRequest sends an unauthenticated HTTP request -func (h *HUOBIHADAX) SendHTTPRequest(path string, result interface{}) error { - return h.SendPayload(http.MethodGet, - path, - nil, - nil, - result, - false, - false, - h.Verbose, - h.HTTPDebugging, - h.HTTPRecording) -} - -// SendAuthenticatedHTTPPostRequest sends authenticated requests to the HUOBI API -func (h *HUOBIHADAX) SendAuthenticatedHTTPPostRequest(method, endpoint, postBodyValues string, result interface{}) error { - if !h.AuthenticatedAPISupport { - return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, h.Name) - } - - signatureParams := url.Values{} - signatureParams.Set("AccessKeyId", h.APIKey) - signatureParams.Set("SignatureMethod", "HmacSHA256") - signatureParams.Set("SignatureVersion", "2") - signatureParams.Set("Timestamp", time.Now().UTC().Format("2006-01-02T15:04:05")) - - endpoint = fmt.Sprintf("/v%s/%s", huobihadaxAPIVersion, endpoint) - payload := fmt.Sprintf("%s\napi.hadax.com\n%s\n%s", - method, endpoint, signatureParams.Encode()) - - headers := make(map[string]string) - headers["Content-Type"] = "application/json" - headers["Accept-Language"] = "zh-cn" - - hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret)) - signatureParams.Set("Signature", common.Base64Encode(hmac)) - urlPath := common.EncodeURLValues(fmt.Sprintf("%s%s", h.APIUrl, endpoint), - signatureParams) - return h.SendPayload(method, - urlPath, - headers, - bytes.NewBufferString(postBodyValues), - result, - true, - false, - h.Verbose, - h.HTTPDebugging, - h.HTTPRecording) -} - -// SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API -func (h *HUOBIHADAX) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, result interface{}) error { - if !h.AuthenticatedAPISupport { - return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, h.Name) - } - - values.Set("AccessKeyId", h.APIKey) - values.Set("SignatureMethod", "HmacSHA256") - values.Set("SignatureVersion", "2") - values.Set("Timestamp", time.Now().UTC().Format("2006-01-02T15:04:05")) - - endpoint = fmt.Sprintf("/v%s/%s", huobihadaxAPIVersion, endpoint) - payload := fmt.Sprintf("%s\napi.hadax.com\n%s\n%s", - method, endpoint, values.Encode()) - - headers := make(map[string]string) - headers["Content-Type"] = "application/x-www-form-urlencoded" - - hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret)) - values.Set("Signature", common.Base64Encode(hmac)) - - urlPath := common.EncodeURLValues(fmt.Sprintf("%s%s", h.APIUrl, endpoint), - values) - return h.SendPayload(method, - urlPath, - headers, - bytes.NewBufferString(""), - result, - true, - false, - h.Verbose, - h.HTTPDebugging, - h.HTTPRecording) -} - -// GetFee returns an estimate of fee based on type of transaction -func (h *HUOBIHADAX) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { - var fee float64 - if feeBuilder.FeeType == exchange.OfflineTradeFee || feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { - fee = calculateTradingFee(feeBuilder.Pair, feeBuilder.PurchasePrice, feeBuilder.Amount) - } - if fee < 0 { - fee = 0 - } - - return fee, nil -} - -func calculateTradingFee(c currency.Pair, price, amount float64) float64 { - if c.IsCryptoFiatPair() { - return 0.001 * price * amount - } - return 0.002 * price * amount -} - -// GetDepositWithdrawalHistory returns deposit or withdrawal data -func (h *HUOBIHADAX) GetDepositWithdrawalHistory(associatedID, currency string, isDeposit bool, size int64) ([]History, error) { - var resp = struct { - Response - Data []History `json:"data"` - }{} - - vals := url.Values{} - - if isDeposit { - vals.Set("type", "deposit") - } else { - vals.Set("type", "withdraw") - } - - vals.Set("from", associatedID) - vals.Set("size", strconv.FormatInt(size, 10)) - vals.Set("currency", common.StringToLower(currency)) - - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, - huobiHadaxDepositAddress, - vals, - &resp) - - if resp.ErrorMessage != "" { - return resp.Data, errors.New(resp.ErrorMessage) - } - return resp.Data, err -} diff --git a/exchanges/huobihadax/huobihadax_test.go b/exchanges/huobihadax/huobihadax_test.go deleted file mode 100644 index f6ea96e3..00000000 --- a/exchanges/huobihadax/huobihadax_test.go +++ /dev/null @@ -1,670 +0,0 @@ -package huobihadax - -import ( - "fmt" - "strconv" - "testing" - - "github.com/gorilla/websocket" - "github.com/thrasher-corp/gocryptotrader/common" - "github.com/thrasher-corp/gocryptotrader/config" - "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" - "github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues" - "github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler" -) - -// Please supply your own APIKEYS here for due diligence testing - -const ( - apiKey = "" - apiSecret = "" - canManipulateRealOrders = false - testSymbol = "btcusdt" -) - -var h HUOBIHADAX -var wsSetupRan bool - -func TestSetDefaults(t *testing.T) { - h.SetDefaults() -} - -func TestSetup(t *testing.T) { - cfg := config.GetConfig() - cfg.LoadConfig("../../testdata/configtest.json") - hadaxConfig, err := cfg.GetExchangeConfig("HuobiHadax") - if err != nil { - t.Error("Test Failed - HuobiHadax Setup() init error") - } - hadaxConfig.AuthenticatedAPISupport = true - hadaxConfig.AuthenticatedWebsocketAPISupport = true - hadaxConfig.APIKey = apiKey - hadaxConfig.APISecret = apiSecret - - h.Setup(&hadaxConfig) -} - -func setupWsTests(t *testing.T) { - if wsSetupRan { - return - } - TestSetDefaults(t) - TestSetup(t) - if !h.Websocket.IsEnabled() && !h.AuthenticatedWebsocketAPISupport || !areTestAPIKeysSet() { - t.Skip(wshandler.WebsocketNotEnabled) - } - comms = make(chan WsMessage, sharedtestvalues.WebsocketChannelOverrideCapacity) - h.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride() - h.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride() - go h.WsHandleData() - h.AuthenticatedWebsocketConn = &wshandler.WebsocketConnection{ - ExchangeName: h.Name, - URL: wsAccountsOrdersURL, - Verbose: h.Verbose, - ResponseMaxLimit: exchange.DefaultWebsocketResponseMaxLimit, - ResponseCheckTimeout: exchange.DefaultWebsocketResponseCheckTimeout, - } - h.WebsocketConn = &wshandler.WebsocketConnection{ - ExchangeName: h.Name, - URL: HuobiHadaxSocketIOAddress, - Verbose: h.Verbose, - ResponseMaxLimit: exchange.DefaultWebsocketResponseMaxLimit, - ResponseCheckTimeout: exchange.DefaultWebsocketResponseCheckTimeout, - } - var dialer websocket.Dialer - err := h.wsAuthenticatedDial(&dialer) - if err != nil { - t.Fatal(err) - } - err = h.wsLogin() - if err != nil { - t.Fatal(err) - } - - wsSetupRan = true -} - -func TestGetSpotKline(t *testing.T) { - t.Parallel() - _, err := h.GetSpotKline(KlinesRequestParams{ - Symbol: testSymbol, - Period: TimeIntervalHour, - Size: 0, - }) - if err != nil { - t.Errorf("Test failed - Huobi TestGetSpotKline: %s", err) - } -} - -func TestGetMarketDetailMerged(t *testing.T) { - t.Parallel() - _, err := h.GetMarketDetailMerged(testSymbol) - if err != nil { - t.Errorf("Test failed - Huobi TestGetMarketDetailMerged: %s", err) - } -} - -func TestGetDepth(t *testing.T) { - t.Parallel() - _, err := h.GetDepth(testSymbol, "step1") - if err != nil { - t.Errorf("Test failed - Huobi TestGetDepth: %s", err) - } -} - -func TestGetTrades(t *testing.T) { - t.Parallel() - _, err := h.GetTrades(testSymbol) - if err != nil { - t.Errorf("Test failed - Huobi TestGetTrades: %s", err) - } -} - -func TestGetLatestSpotPrice(t *testing.T) { - t.Parallel() - _, err := h.GetLatestSpotPrice(testSymbol) - if err != nil { - t.Errorf("Test failed - Huobi GetLatestSpotPrice: %s", err) - } -} - -func TestGetTradeHistory(t *testing.T) { - t.Parallel() - _, err := h.GetTradeHistory(testSymbol, "50") - if err != nil { - t.Errorf("Test failed - Huobi TestGetTradeHistory: %s", err) - } -} - -func TestGetMarketDetail(t *testing.T) { - t.Parallel() - _, err := h.GetMarketDetail(testSymbol) - if err != nil { - t.Errorf("Test failed - Huobi TestGetTradeHistory: %s", err) - } -} - -func TestGetSymbols(t *testing.T) { - t.Parallel() - _, err := h.GetSymbols() - if err != nil { - t.Errorf("Test failed - Huobi TestGetSymbols: %s", err) - } -} - -func TestGetCurrencies(t *testing.T) { - t.Parallel() - _, err := h.GetCurrencies() - if err != nil { - t.Errorf("Test failed - Huobi TestGetCurrencies: %s", err) - } -} - -func TestGetTimestamp(t *testing.T) { - t.Parallel() - _, err := h.GetTimestamp() - if err != nil { - t.Errorf("Test failed - Huobi TestGetTimestamp: %s", err) - } -} - -func TestGetAccounts(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - _, err := h.GetAccounts() - if err != nil { - t.Errorf("Test failed - Huobi GetAccounts: %s", err) - } -} - -func TestGetAccountBalance(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - result, err := h.GetAccounts() - if err != nil { - t.Errorf("Test failed - Huobi GetAccounts: %s", err) - } - - userID := strconv.FormatInt(result[0].ID, 10) - _, err = h.GetAccountBalance(userID) - if err != nil { - t.Errorf("Test failed - Huobi GetAccountBalance: %s", err) - } -} - -func TestGetAggregatedBalance(t *testing.T) { - t.Parallel() - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - _, err := h.GetAggregatedBalance() - if err != nil { - t.Errorf("Test failed - Huobi GetAggregatedBalance: %s", err) - } -} - -func TestSpotNewOrder(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - arg := SpotNewOrderRequestParams{ - Symbol: testSymbol, - AccountID: 000000, - Amount: 0.01, - Price: 10.1, - Type: SpotNewOrderRequestTypeBuyLimit, - } - - newOrderID, err := h.SpotNewOrder(arg) - if err != nil { - t.Errorf("Test failed - Huobi SpotNewOrder: %s", err) - } else { - fmt.Println(newOrderID) - } -} - -func TestCancelExistingOrder(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - _, err := h.CancelExistingOrder(1337) - if err == nil { - t.Error("Test failed - Huobi TestCancelExistingOrder: Invalid orderID returned true") - } -} - -func TestGetOrder(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - _, err := h.GetOrder(1337) - if err == nil { - t.Error("Test failed - Huobi TestCancelOrder: Invalid orderID returned true") - } -} - -func TestGetMarginLoanOrders(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - _, err := h.GetMarginLoanOrders(testSymbol, "", "", "", "", "", "", "") - if err != nil { - t.Errorf("Test failed - Huobi TestGetMarginLoanOrders: %s", err) - } -} - -func TestGetMarginAccountBalance(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - _, err := h.GetMarginAccountBalance(testSymbol) - if err != nil { - t.Errorf("Test failed - Huobi TestGetMarginAccountBalance: %s", err) - } -} - -func TestCancelWithdraw(t *testing.T) { - t.Parallel() - - if h.APIKey == "" || h.APISecret == "" || h.APIAuthPEMKey == "" { - t.Skip() - } - - _, err := h.CancelWithdraw(1337) - if err == nil { - t.Error("Test failed - Huobi TestCancelWithdraw: Invalid withdraw-ID was valid") - } -} - -func setFeeBuilder() *exchange.FeeBuilder { - return &exchange.FeeBuilder{ - Amount: 1, - FeeType: exchange.CryptocurrencyTradeFee, - Pair: currency.NewPairWithDelimiter(currency.BTC.String(), - currency.LTC.String(), - "_"), - PurchasePrice: 1, - FiatCurrency: currency.USD, - BankTransactionType: exchange.WireTransfer, - } -} - -// TestGetFeeByTypeOfflineTradeFee logic test -func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { - var feeBuilder = setFeeBuilder() - h.GetFeeByType(feeBuilder) - if apiKey == "" || apiSecret == "" { - if feeBuilder.FeeType != exchange.OfflineTradeFee { - t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) - } - } else { - if feeBuilder.FeeType != exchange.CryptocurrencyTradeFee { - t.Errorf("Expected %v, received %v", exchange.CryptocurrencyTradeFee, feeBuilder.FeeType) - } - } -} - -func TestGetFee(t *testing.T) { - t.Parallel() - var feeBuilder = setFeeBuilder() - // CryptocurrencyTradeFee Basic - if resp, err := h.GetFee(feeBuilder); resp != float64(0.002) || err != nil { - t.Error(err) - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.002), resp) - } - - // CryptocurrencyTradeFee High quantity - feeBuilder = setFeeBuilder() - feeBuilder.Amount = 1000 - feeBuilder.PurchasePrice = 1000 - if resp, err := h.GetFee(feeBuilder); resp != float64(2000) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(2000), resp) - t.Error(err) - } - - // CryptocurrencyTradeFee IsMaker - feeBuilder = setFeeBuilder() - feeBuilder.IsMaker = true - if resp, err := h.GetFee(feeBuilder); resp != float64(0.002) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.002), resp) - t.Error(err) - } - - // CryptocurrencyTradeFee Negative purchase price - feeBuilder = setFeeBuilder() - feeBuilder.PurchasePrice = -1000 - if resp, err := h.GetFee(feeBuilder); resp != float64(0) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp) - t.Error(err) - } - // CryptocurrencyWithdrawalFee Basic - feeBuilder = setFeeBuilder() - feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if resp, err := h.GetFee(feeBuilder); resp != float64(0) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp) - t.Error(err) - } - - // CryptocurrencyWithdrawalFee Invalid currency - feeBuilder = setFeeBuilder() - feeBuilder.Pair.Base = currency.NewCode("hello") - feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if resp, err := h.GetFee(feeBuilder); resp != float64(0) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp) - t.Error(err) - } - - // CyptocurrencyDepositFee Basic - feeBuilder = setFeeBuilder() - feeBuilder.FeeType = exchange.CyptocurrencyDepositFee - if resp, err := h.GetFee(feeBuilder); resp != float64(0) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp) - t.Error(err) - } - - // InternationalBankDepositFee Basic - feeBuilder = setFeeBuilder() - feeBuilder.FeeType = exchange.InternationalBankDepositFee - if resp, err := h.GetFee(feeBuilder); resp != float64(0) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp) - t.Error(err) - } - - // InternationalBankWithdrawalFee Basic - feeBuilder = setFeeBuilder() - feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee - feeBuilder.FiatCurrency = currency.USD - if resp, err := h.GetFee(feeBuilder); resp != float64(0) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp) - t.Error(err) - } -} - -func TestFormatWithdrawPermissions(t *testing.T) { - h.SetDefaults() - expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.NoFiatWithdrawalsText - - withdrawPermissions := h.FormatWithdrawPermissions() - - if withdrawPermissions != expectedResult { - t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) - } -} - -func TestGetActiveOrders(t *testing.T) { - h.SetDefaults() - TestSetup(t) - - var getOrdersRequest = exchange.GetOrdersRequest{ - OrderType: exchange.AnyOrderType, - Currencies: []currency.Pair{currency.NewPair(currency.BTC, currency.USDT)}, - } - - _, err := h.GetActiveOrders(&getOrdersRequest) - if areTestAPIKeysSet() && err != nil { - t.Errorf("Could not get open orders: %s", err) - } else if !areTestAPIKeysSet() && err == nil { - t.Error("Expecting an error when no keys are set") - } -} - -func TestGetOrderHistory(t *testing.T) { - h.SetDefaults() - TestSetup(t) - - var getOrdersRequest = exchange.GetOrdersRequest{ - OrderType: exchange.AnyOrderType, - Currencies: []currency.Pair{currency.NewPair(currency.BTC, currency.USDT)}, - } - - _, err := h.GetOrderHistory(&getOrdersRequest) - if areTestAPIKeysSet() && err != nil { - t.Errorf("Could not get order history: %s", err) - } else if !areTestAPIKeysSet() && err == nil { - t.Error("Expecting an error when no keys are set") - } -} - -// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them -// ---------------------------------------------------------------------------------------------------------------------------- -func areTestAPIKeysSet() bool { - if h.APIKey != "" && h.APIKey != "Key" && - h.APISecret != "" && h.APISecret != "Secret" { - return true - } - return false -} - -func TestSubmitOrder(t *testing.T) { - h.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - if (h.APIKey == "" || h.APIKey == "Key") && - (h.APISecret == "" || h.APISecret == "Secret") { - t.Skip() - } - - var p = currency.Pair{ - Delimiter: "", - Base: currency.BTC, - Quote: currency.USDT, - } - - accounts, err := h.GetAccounts() - if err != nil { - t.Errorf("Failed to get accounts. Err: %s", err) - } - - response, err := h.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 10, strconv.FormatInt(accounts[0].ID, 10)) - if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { - t.Errorf("Order failed to be placed: %v", err) - } else if !areTestAPIKeysSet() && err == nil { - t.Error("Expecting an error when no keys are set") - } -} - -func TestCancelExchangeOrder(t *testing.T) { - h.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - currencyPair := currency.NewPair(currency.LTC, currency.BTC) - - var orderCancellation = &exchange.OrderCancellation{ - OrderID: "1", - WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", - AccountID: "1", - CurrencyPair: currencyPair, - } - - err := h.CancelOrder(orderCancellation) - if !areTestAPIKeysSet() && err == nil { - t.Error("Expecting an error when no keys are set") - } - if areTestAPIKeysSet() && err != nil { - t.Errorf("Could not cancel orders: %v", err) - } -} - -func TestCancelAllExchangeOrders(t *testing.T) { - h.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - currencyPair := currency.NewPair(currency.LTC, currency.BTC) - - var orderCancellation = &exchange.OrderCancellation{ - OrderID: "1", - WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", - AccountID: "1", - CurrencyPair: currencyPair, - } - - resp, err := h.CancelAllOrders(orderCancellation) - - if !areTestAPIKeysSet() && err == nil { - t.Error("Expecting an error when no keys are set") - } - if areTestAPIKeysSet() && err != nil { - t.Errorf("Could not cancel orders: %v", err) - } - - if len(resp.OrderStatus) > 0 { - t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) - } -} - -func TestGetAccountInfo(t *testing.T) { - if apiKey == "" || apiSecret == "" { - _, err := h.GetAccountInfo() - if err == nil { - t.Error("Test Failed - GetAccountInfo() error") - } - } else { - _, err := h.GetAccountInfo() - if err != nil { - t.Error("Test Failed - GetAccountInfo() error", err) - } - } -} - -func TestModifyOrder(t *testing.T) { - _, err := h.ModifyOrder(&exchange.ModifyOrder{}) - if err == nil { - t.Error("Test failed - ModifyOrder() error") - } -} - -func TestWithdraw(t *testing.T) { - h.SetDefaults() - TestSetup(t) - var withdrawCryptoRequest = exchange.WithdrawRequest{ - Amount: 100, - Currency: currency.BTC, - Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", - Description: "WITHDRAW IT ALL", - } - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - _, err := h.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) - if !areTestAPIKeysSet() && err == nil { - t.Error("Expecting an error when no keys are set") - } - if areTestAPIKeysSet() && err != nil { - t.Errorf("Withdraw failed to be placed: %v", err) - } -} - -func TestWithdrawFiat(t *testing.T) { - h.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - var withdrawFiatRequest = exchange.WithdrawRequest{} - - _, err := h.WithdrawFiatFunds(&withdrawFiatRequest) - if err != common.ErrFunctionNotSupported { - t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) - } -} - -func TestWithdrawInternationalBank(t *testing.T) { - h.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - var withdrawFiatRequest = exchange.WithdrawRequest{} - - _, err := h.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) - if err != common.ErrFunctionNotSupported { - t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) - } -} - -func TestGetDepositAddress(t *testing.T) { - _, err := h.GetDepositAddress(currency.BTC, "") - if err == nil { - t.Error("Test Failed - GetDepositAddress() error cannot be nil") - } -} - -// TestWsGetAccountsList connects to WS, logs in, gets account list -func TestWsGetAccountsList(t *testing.T) { - setupWsTests(t) - resp, err := h.wsGetAccountsList(currency.NewPairFromString("ethbtc")) - if err != nil { - t.Fatal(err) - } - if resp.ErrorCode > 0 { - t.Error(resp.ErrorMessage) - } -} - -// TestWsGetOrderList connects to WS, logs in, gets order list -func TestWsGetOrderList(t *testing.T) { - setupWsTests(t) - resp, err := h.wsGetOrdersList(1, currency.NewPairFromString("ethbtc")) - if err != nil { - t.Fatal(err) - } - if resp.ErrorCode > 0 { - t.Error(resp.ErrorMessage) - } -} - -// TestWsGetOrderDetails connects to WS, logs in, gets order details -func TestWsGetOrderDetails(t *testing.T) { - setupWsTests(t) - orderID := "123" - resp, err := h.wsGetOrderDetails(orderID) - if err != nil { - t.Fatal(err) - } - if resp.ErrorCode > 0 && (orderID == "123" && resp.ErrorCode != 10022) { - t.Error(resp.ErrorMessage) - } -} diff --git a/exchanges/huobihadax/huobihadax_types.go b/exchanges/huobihadax/huobihadax_types.go deleted file mode 100644 index fd8149c9..00000000 --- a/exchanges/huobihadax/huobihadax_types.go +++ /dev/null @@ -1,535 +0,0 @@ -package huobihadax - -import ( - "github.com/thrasher-corp/gocryptotrader/currency" -) - -// Response stores the Huobi response information -type Response struct { - Status string `json:"status"` - Channel string `json:"ch"` - Timestamp int64 `json:"ts"` - ErrorCode string `json:"err-code"` - ErrorMessage string `json:"err-msg"` -} - -// KlineItem stores a kline item -type KlineItem struct { - ID int64 `json:"id"` - Open float64 `json:"open"` - Close float64 `json:"close"` - Low float64 `json:"low"` - High float64 `json:"high"` - Amount float64 `json:"amount"` - Vol float64 `json:"vol"` - Count int `json:"count"` -} - -// DetailMerged stores the ticker detail merged data -type DetailMerged struct { - Detail - Version int `json:"version"` - Ask []float64 `json:"ask"` - Bid []float64 `json:"bid"` -} - -// Orderbook stores the orderbook data -type Orderbook struct { - ID int64 `json:"id"` - Timetstamp int64 `json:"ts"` - Bids [][]float64 `json:"bids"` - Asks [][]float64 `json:"asks"` -} - -// Trade stores the trade data -type Trade struct { - ID float64 `json:"id"` - Price float64 `json:"price"` - Amount float64 `json:"amount"` - Direction string `json:"direction"` - Timestamp int64 `json:"ts"` -} - -// CancelOpenOrdersBatch stores open order batch response data -type CancelOpenOrdersBatch struct { - Data struct { - FailedCount int `json:"failed-count"` - NextID int `json:"next-id"` - SuccessCount int `json:"success-count"` - } `json:"data"` - Status string `json:"status"` - ErrorMessage string `json:"err-msg"` -} - -// TradeHistory stores the the trade history data -type TradeHistory struct { - ID int64 `json:"id"` - Timestamp int64 `json:"ts"` - Trades []Trade `json:"data"` -} - -// Detail stores the ticker detail data -type Detail struct { - Amount float64 `json:"amount"` - Open float64 `json:"open"` - Close float64 `json:"close"` - High float64 `json:"high"` - Timestamp int64 `json:"timestamp"` - ID int `json:"id"` - Count int `json:"count"` - Low float64 `json:"low"` - Volume float64 `json:"vol"` -} - -// Symbol stores the symbol data -type Symbol struct { - BaseCurrency string `json:"base-currency"` - QuoteCurrency string `json:"quote-currency"` - PricePrecision int `json:"price-precision"` - AmountPrecision int `json:"amount-precision"` - SymbolPartition string `json:"symbol-partition"` -} - -// Account stores the account data -type Account struct { - ID int64 `json:"id"` - Type string `json:"type"` - SubType string `json:"subtype"` - State string `json:"state"` -} - -// AccountBalance stores the user all account balance -type AccountBalance struct { - ID int64 `json:"id"` - Type string `json:"type"` - State string `json:"state"` - AccountBalanceDetails []AccountBalanceDetail `json:"list"` -} - -// AccountBalanceDetail stores the user account balance -type AccountBalanceDetail struct { - Currency string `json:"currency"` - Type string `json:"type"` - Balance float64 `json:"balance,string"` -} - -// AggregatedBalance stores balances of all the sub-account -type AggregatedBalance struct { - Currency string `json:"currency"` - Balance float64 `json:"balance,string"` -} - -// CancelOrderBatch stores the cancel order batch data -type CancelOrderBatch struct { - Success []string `json:"success"` - Failed []struct { - OrderID int64 `json:"order-id,string"` - ErrorCode string `json:"err-code"` - ErrorMessage string `json:"err-msg"` - } `json:"failed"` -} - -// OrderInfo stores the order info -type OrderInfo struct { - ID int `json:"id"` - Symbol string `json:"symbol"` - AccountID float64 `json:"account-id"` - Amount float64 `json:"amount,string"` - Price float64 `json:"price,string"` - CreatedAt int64 `json:"created-at"` - Type string `json:"type"` - FieldAmount float64 `json:"field-amount,string"` - FieldCashAmount float64 `json:"field-cash-amount,string"` - Fieldees float64 `json:"field-fees,string"` - FilledAmount float64 `json:"filled-amount,string"` - FilledCashAmount float64 `json:"filled-cash-amount,string"` - FilledFees float64 `json:"filled-fees,string"` - FinishedAt int64 `json:"finished-at"` - UserID int `json:"user-id"` - Source string `json:"source"` - State string `json:"state"` - CanceledAt int `json:"canceled-at"` - Exchange string `json:"exchange"` - Batch string `json:"batch"` -} - -// OrderMatchInfo stores the order match info -type OrderMatchInfo struct { - ID int `json:"id"` - OrderID int `json:"order-id"` - MatchID int `json:"match-id"` - Symbol string `json:"symbol"` - Type string `json:"type"` - Source string `json:"source"` - Price string `json:"price"` - FilledAmount string `json:"filled-amount"` - FilledFees string `json:"filled-fees"` - CreatedAt int64 `json:"created-at"` -} - -// MarginOrder stores the margin order info -type MarginOrder struct { - Currency string `json:"currency"` - Symbol string `json:"symbol"` - AccruedAt int64 `json:"accrued-at"` - LoanAmount string `json:"loan-amount"` - LoanBalance string `json:"loan-balance"` - InterestBalance string `json:"interest-balance"` - CreatedAt int64 `json:"created-at"` - InterestAmount string `json:"interest-amount"` - InterestRate string `json:"interest-rate"` - AccountID int `json:"account-id"` - UserID int `json:"user-id"` - UpdatedAt int64 `json:"updated-at"` - ID int `json:"id"` - State string `json:"state"` -} - -// MarginAccountBalance stores the margin account balance info -type MarginAccountBalance struct { - ID int `json:"id"` - Type string `json:"type"` - State string `json:"state"` - Symbol string `json:"symbol"` - FlPrice string `json:"fl-price"` - FlType string `json:"fl-type"` - RiskRate string `json:"risk-rate"` - List []AccountBalance `json:"list"` -} - -// SpotNewOrderRequestParams holds the params required to place -// an order -type SpotNewOrderRequestParams struct { - AccountID int `json:"account-id"` // Account ID, obtained using the accounts method. Curency trades use the accountid of the ‘spot’ account; for loan asset transactions, please use the accountid of the ‘margin’ account. - Amount float64 `json:"amount"` // The limit price indicates the quantity of the order, the market price indicates how much to buy when the order is paid, and the market price indicates how much the coin is sold when the order is sold. - Price float64 `json:"price"` // Order price, market price does not use this parameter - Source string `json:"source"` // Order source, api: API call, margin-api: loan asset transaction - Symbol string `json:"symbol"` // The symbol to use; example btcusdt, bccbtc...... - Type SpotNewOrderRequestParamsType `json:"type"` // Order type as listed below (buy-market, sell-market etc) -} - -// SpotNewOrderRequestParamsType order types -type SpotNewOrderRequestParamsType string - -var ( - // SpotNewOrderRequestTypeBuyMarket buy market order - SpotNewOrderRequestTypeBuyMarket = SpotNewOrderRequestParamsType("buy-market") - - // SpotNewOrderRequestTypeSellMarket sell market order - SpotNewOrderRequestTypeSellMarket = SpotNewOrderRequestParamsType("sell-market") - - // SpotNewOrderRequestTypeBuyLimit buy limit order - SpotNewOrderRequestTypeBuyLimit = SpotNewOrderRequestParamsType("buy-limit") - - // SpotNewOrderRequestTypeSellLimit sell limit order - SpotNewOrderRequestTypeSellLimit = SpotNewOrderRequestParamsType("sell-limit") -) - -// KlinesRequestParams represents Klines request data. -type KlinesRequestParams struct { - Symbol string // Symbol; btcusdt, bccbtc...... - Period TimeInterval // Kline data time interval; 1min, 5min, 15min...... - Size int // Size [1-2000] -} - -// TimeInterval base value -type TimeInterval string - -// TimeInterval vars -var ( - TimeIntervalMinute = TimeInterval("1min") - TimeIntervalFiveMinutes = TimeInterval("5min") - TimeIntervalFifteenMinutes = TimeInterval("15min") - TimeIntervalThirtyMinutes = TimeInterval("30min") - TimeIntervalHour = TimeInterval("60min") - TimeIntervalDay = TimeInterval("1day") - TimeIntervalWeek = TimeInterval("1week") - TimeIntervalMohth = TimeInterval("1mon") - TimeIntervalYear = TimeInterval("1year") -) - -// History defines currency deposit or withdrawal data -type History struct { - ID int64 `json:"id"` - Type string `json:"type"` - Currency string `json:"currency"` - TxHash string `json:"tx-hash"` - Amount float64 `json:"amount"` - Address string `json:"address"` - Fee float64 `json:"fee"` - State string `json:"state"` - CreatedAt int64 `json:"created-at"` - UpdatedAt int64 `json:"Updated-at"` -} - -// WsRequest defines a request data structure -type WsRequest struct { - Topic string `json:"req,omitempty"` - Subscribe string `json:"sub,omitempty"` - Unsubscribe string `json:"unsub,omitempty"` - ClientGeneratedID string `json:"id,omitempty"` -} - -// WsResponse defines a response from the websocket connection when there -// is an error -type WsResponse struct { - TS int64 `json:"ts"` - Status string `json:"status"` - ErrorCode interface{} `json:"err-code"` - ErrorMessage string `json:"err-msg"` - Ping int64 `json:"ping"` - Channel string `json:"ch"` - Subscribed string `json:"subbed"` -} - -// WsHeartBeat defines a heartbeat request -type WsHeartBeat struct { - ClientNonce int64 `json:"ping"` -} - -// WsDepth defines market depth websocket response -type WsDepth struct { - Channel string `json:"ch"` - Timestamp int64 `json:"ts"` - Tick struct { - Bids []interface{} `json:"bids"` - Asks []interface{} `json:"asks"` - Timestamp int64 `json:"ts"` - Version int64 `json:"version"` - } `json:"tick"` -} - -// WsKline defines market kline websocket response -type WsKline struct { - Channel string `json:"ch"` - Timestamp int64 `json:"ts"` - Tick struct { - ID int64 `json:"id"` - Open float64 `json:"open"` - Close float64 `json:"close"` - Low float64 `json:"low"` - High float64 `json:"high"` - Amount float64 `json:"amount"` - Volume float64 `json:"vol"` - Count int64 `json:"count"` - } -} - -// WsTrade defines market trade websocket response -type WsTrade struct { - Channel string `json:"ch"` - Timestamp int64 `json:"ts"` - Tick struct { - ID int64 `json:"id"` - Timestamp int64 `json:"ts"` - Data []struct { - Amount float64 `json:"amount"` - Timestamp int64 `json:"ts"` - ID float64 `json:"id"` - Price float64 `json:"price"` - Direction string `json:"direction"` - } `json:"data"` - } -} - -// WsAuthenticationRequest data for login -type WsAuthenticationRequest struct { - Op string `json:"op"` - AccessKeyID string `json:"AccessKeyId"` - SignatureMethod string `json:"SignatureMethod"` - SignatureVersion string `json:"SignatureVersion"` - Timestamp string `json:"Timestamp"` - Signature string `json:"Signature"` - ClientID int64 `json:"cid,string,omitempty"` -} - -// WsMessage defines read data from the websocket connection -type WsMessage struct { - Raw []byte - URL string -} - -// WsAuthenticatedSubscriptionRequest request for subscription on authenticated connection -type WsAuthenticatedSubscriptionRequest struct { - Op string `json:"op"` - AccessKeyID string `json:"AccessKeyId"` - SignatureMethod string `json:"SignatureMethod"` - SignatureVersion string `json:"SignatureVersion"` - Timestamp string `json:"Timestamp"` - Signature string `json:"Signature"` - Topic string `json:"topic"` - ClientID int64 `json:"cid,string,omitempty"` -} - -// WsAuthenticatedAccountsListRequest request for account list authenticated connection -type WsAuthenticatedAccountsListRequest struct { - Op string `json:"op"` - AccessKeyID string `json:"AccessKeyId"` - SignatureMethod string `json:"SignatureMethod"` - SignatureVersion string `json:"SignatureVersion"` - Timestamp string `json:"Timestamp"` - Signature string `json:"Signature"` - Topic string `json:"topic"` - Symbol currency.Pair `json:"symbol"` - ClientID int64 `json:"cid,string,omitempty"` -} - -// WsAuthenticatedOrderDetailsRequest request for order details authenticated connection -type WsAuthenticatedOrderDetailsRequest struct { - Op string `json:"op"` - AccessKeyID string `json:"AccessKeyId"` - SignatureMethod string `json:"SignatureMethod"` - SignatureVersion string `json:"SignatureVersion"` - Timestamp string `json:"Timestamp"` - Signature string `json:"Signature"` - Topic string `json:"topic"` - OrderID string `json:"order-id"` - ClientID int64 `json:"cid,string,omitempty"` -} - -// WsAuthenticatedOrdersListRequest request for orderslist authenticated connection -type WsAuthenticatedOrdersListRequest struct { - Op string `json:"op"` - AccessKeyID string `json:"AccessKeyId"` - SignatureMethod string `json:"SignatureMethod"` - SignatureVersion string `json:"SignatureVersion"` - Timestamp string `json:"Timestamp"` - Signature string `json:"Signature"` - Topic string `json:"topic"` - States string `json:"states"` - AccountID int64 `json:"account-id"` - Symbol currency.Pair `json:"symbol"` - ClientID int64 `json:"cid,string,omitempty"` -} - -// WsAuthenticatedDataResponse response from authenticated connection -type WsAuthenticatedDataResponse struct { - Op string `json:"op,omitempty"` - Ts int64 `json:"ts,omitempty"` - Topic string `json:"topic,omitempty"` - ErrorCode int64 `json:"err-code,omitempty"` - ErrorMessage string `json:"err-msg,omitempty"` - Ping int64 `json:"ping,omitempty"` - ClientID int64 `json:"cid,string,omitempty"` -} - -// WsAuthenticatedAccountsResponse response from Accounts authenticated subscription -type WsAuthenticatedAccountsResponse struct { - WsAuthenticatedDataResponse - Data WsAuthenticatedAccountsResponseData `json:"data"` -} - -// WsAuthenticatedAccountsResponseData account data -type WsAuthenticatedAccountsResponseData struct { - Event string `json:"event"` - List []WsAuthenticatedAccountsResponseDataList `json:"list"` -} - -// WsAuthenticatedAccountsResponseDataList detailed account data -type WsAuthenticatedAccountsResponseDataList struct { - AccountID int64 `json:"account-id"` - Currency string `json:"currency"` - Type string `json:"type"` - Balance float64 `json:"balance,string"` -} - -// WsAuthenticatedOrdersUpdateResponse response from OrdersUpdate authenticated subscription -type WsAuthenticatedOrdersUpdateResponse struct { - WsAuthenticatedDataResponse - Data WsAuthenticatedOrdersUpdateResponseData `json:"data"` -} - -// WsAuthenticatedOrdersUpdateResponseData order updatedata -type WsAuthenticatedOrdersUpdateResponseData struct { - UnfilledAmount float64 `json:"unfilled-amount,string"` - FilledAmount float64 `json:"filled-amount,string"` - Price float64 `json:"price,string"` - OrderID int64 `json:"order-id"` - Symbol currency.Pair `json:"symbol"` - MatchID int64 `json:"match-id"` - FilledCashAmount float64 `json:"filled-cash-amount,string"` - Role string `json:"role"` - OrderState string `json:"order-state"` -} - -// WsAuthenticatedOrdersResponse response from Orders authenticated subscription -type WsAuthenticatedOrdersResponse struct { - WsAuthenticatedDataResponse - Data []WsAuthenticatedOrdersResponseData `json:"data"` -} - -// WsAuthenticatedOrdersResponseData order data -type WsAuthenticatedOrdersResponseData struct { - SeqID int64 `json:"seq-id"` - OrderID int64 `json:"order-id"` - Symbol currency.Pair `json:"symbol"` - AccountID int64 `json:"account-id"` - OrderAmount float64 `json:"order-amount,string"` - OrderPrice float64 `json:"order-price,string"` - CreatedAt int64 `json:"created-at"` - OrderType string `json:"order-type"` - OrderSource string `json:"order-source"` - OrderState string `json:"order-state"` - Role string `json:"role"` - Price float64 `json:"price,string"` - FilledAmount float64 `json:"filled-amount,string"` - UnfilledAmount float64 `json:"unfilled-amount,string"` - FilledCashAmount float64 `json:"filled-cash-amount,string"` - FilledFees float64 `json:"filled-fees,string"` -} - -// WsAuthenticatedAccountsListResponse response from AccountsList authenticated endpoint -type WsAuthenticatedAccountsListResponse struct { - WsAuthenticatedDataResponse - Data []WsAuthenticatedAccountsListResponseData `json:"data"` -} - -// WsAuthenticatedAccountsListResponseData account data -type WsAuthenticatedAccountsListResponseData struct { - ID int64 `json:"id"` - Type string `json:"type"` - State string `json:"state"` - List []WsAuthenticatedAccountsListResponseDataList `json:"list"` -} - -// WsAuthenticatedAccountsListResponseDataList detailed account data -type WsAuthenticatedAccountsListResponseDataList struct { - Currency string `json:"currency"` - Type string `json:"type"` - Balance float64 `json:"balance,string"` -} - -// WsAuthenticatedOrdersListResponse response from OrdersList authenticated endpoint -type WsAuthenticatedOrdersListResponse struct { - WsAuthenticatedDataResponse - Data []WsAuthenticatedOrdersListResponseData `json:"data"` -} - -// WsAuthenticatedOrdersListResponseData contains order details -type WsAuthenticatedOrdersListResponseData struct { - ID int64 `json:"id"` - Symbol currency.Pair `json:"symbol"` - AccountID int64 `json:"account-id"` - Amount float64 `json:"amount,string"` - Price float64 `json:"price,string"` - CreatedAt int64 `json:"created-at"` - Type string `json:"type"` - FilledAmount float64 `json:"filled-amount,string"` - FilledCashAmount float64 `json:"filled-cash-amount,string"` - FilledFees float64 `json:"filled-fees,string"` - FinishedAt int64 `json:"finished-at"` - Source string `json:"source"` - State string `json:"state"` - CanceledAt int64 `json:"canceled-at"` -} - -// WsAuthenticatedOrderDetailResponse response from OrderDetail authenticated endpoint -type WsAuthenticatedOrderDetailResponse struct { - WsAuthenticatedDataResponse - Data WsAuthenticatedOrdersListResponseData `json:"data"` -} - -// WsPong sent for pong messages -type WsPong struct { - Pong int64 `json:"pong"` -} diff --git a/exchanges/huobihadax/huobihadax_websocket.go b/exchanges/huobihadax/huobihadax_websocket.go deleted file mode 100644 index dbb70159..00000000 --- a/exchanges/huobihadax/huobihadax_websocket.go +++ /dev/null @@ -1,475 +0,0 @@ -package huobihadax - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "github.com/gorilla/websocket" - "github.com/thrasher-corp/gocryptotrader/common" - "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" - "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" - "github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler" - log "github.com/thrasher-corp/gocryptotrader/logger" -) - -// WS URL values -const ( - HuobiHadaxSocketIOAddress = "wss://api.hadax.com/ws" - wsMarketKline = "market.%s.kline.1min" - wsMarketDepth = "market.%s.depth.step0" - wsMarketTrade = "market.%s.trade.detail" - - wsAccountsOrdersBaseURL = "wss://api.huobi.pro" - wsAccountsOrdersEndPoint = "/ws/v1" - wsAccountsList = "accounts.list" - wsOrdersList = "orders.list" - wsOrdersDetail = "orders.detail" - wsAccountsOrdersURL = wsAccountsOrdersBaseURL + wsAccountsOrdersEndPoint - wsAccountListEndpoint = wsAccountsOrdersEndPoint + "/" + wsAccountsList - wsOrdersListEndpoint = wsAccountsOrdersEndPoint + "/" + wsOrdersList - wsOrdersDetailEndpoint = wsAccountsOrdersEndPoint + "/" + wsOrdersDetail - - wsDateTimeFormatting = "2006-01-02T15:04:05" - - signatureMethod = "HmacSHA256" - signatureVersion = "2" - requestOp = "req" - authOp = "auth" - - loginDelay = 50 * time.Millisecond - rateLimit = 20 -) - -// Instantiates a communications channel between websocket connections -var comms = make(chan WsMessage, 1) - -// WsConnect initiates a new websocket connection -func (h *HUOBIHADAX) WsConnect() error { - if !h.Websocket.IsEnabled() || !h.IsEnabled() { - return errors.New(wshandler.WebsocketNotEnabled) - } - var dialer websocket.Dialer - err := h.wsDial(&dialer) - if err != nil { - return err - } - err = h.wsAuthenticatedDial(&dialer) - if err != nil { - log.Errorf("%v - authenticated dial failed: %v", h.Name, err) - } - err = h.wsLogin() - if err != nil { - log.Errorf("%v - authentication failed: %v", h.Name, err) - } - go h.WsHandleData() - h.GenerateDefaultSubscriptions() - - return nil -} - -func (h *HUOBIHADAX) wsDial(dialer *websocket.Dialer) error { - err := h.WebsocketConn.Dial(dialer, http.Header{}) - if err != nil { - return err - } - go h.wsMultiConnectionFunnel(h.WebsocketConn, HuobiHadaxSocketIOAddress) - return nil -} - -func (h *HUOBIHADAX) wsAuthenticatedDial(dialer *websocket.Dialer) error { - if !h.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { - return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", h.Name) - } - err := h.AuthenticatedWebsocketConn.Dial(dialer, http.Header{}) - if err != nil { - return err - } - go h.wsMultiConnectionFunnel(h.AuthenticatedWebsocketConn, wsAccountsOrdersURL) - return nil -} - -// wsMultiConnectionFunnel manages data from multiple endpoints and passes it to a channel -func (h *HUOBIHADAX) wsMultiConnectionFunnel(ws *wshandler.WebsocketConnection, url string) { - h.Websocket.Wg.Add(1) - defer h.Websocket.Wg.Done() - for { - select { - case <-h.Websocket.ShutdownC: - return - default: - resp, err := ws.ReadMessage() - if err != nil { - h.Websocket.DataHandler <- err - return - } - h.Websocket.TrafficAlert <- struct{}{} - comms <- WsMessage{Raw: resp.Raw, URL: url} - } - } -} - -// WsHandleData handles data read from the websocket connection -func (h *HUOBIHADAX) WsHandleData() { - h.Websocket.Wg.Add(1) - defer h.Websocket.Wg.Done() - for { - select { - case <-h.Websocket.ShutdownC: - return - case resp := <-comms: - if h.Verbose { - log.Debugf("%v: %v: %v", h.Name, resp.URL, string(resp.Raw)) - } - switch resp.URL { - case HuobiHadaxSocketIOAddress: - h.wsHandleMarketData(resp) - case wsAccountsOrdersURL: - h.wsHandleAuthenticatedData(resp) - } - } - } -} - -func (h *HUOBIHADAX) wsHandleAuthenticatedData(resp WsMessage) { - var init WsAuthenticatedDataResponse - err := common.JSONDecode(resp.Raw, &init) - if err != nil { - h.Websocket.DataHandler <- err - return - } - if init.Ping != 0 { - err = h.WebsocketConn.SendMessage(WsPong{Pong: init.Ping}) - if err != nil { - log.Error(err) - } - return - } - if init.ErrorMessage == "api-signature-not-valid" { - h.Websocket.SetCanUseAuthenticatedEndpoints(false) - } - if init.Op == "sub" { - if h.Verbose { - log.Debugf("%v: %v: Successfully subscribed to %v", h.Name, resp.URL, init.Topic) - } - return - } - if init.ClientID > 0 { - h.AuthenticatedWebsocketConn.AddResponseWithID(init.ClientID, resp.Raw) - return - } - - switch { - case strings.EqualFold(init.Op, authOp): - h.Websocket.SetCanUseAuthenticatedEndpoints(true) - var response WsAuthenticatedDataResponse - err := common.JSONDecode(resp.Raw, &response) - if err != nil { - h.Websocket.DataHandler <- err - } - h.Websocket.DataHandler <- response - case strings.EqualFold(init.Topic, "accounts"): - var response WsAuthenticatedAccountsResponse - err := common.JSONDecode(resp.Raw, &response) - if err != nil { - h.Websocket.DataHandler <- err - } - h.Websocket.DataHandler <- response - case common.StringContains(init.Topic, "orders") && - common.StringContains(init.Topic, "update"): - var response WsAuthenticatedOrdersUpdateResponse - err := common.JSONDecode(resp.Raw, &response) - if err != nil { - h.Websocket.DataHandler <- err - } - h.Websocket.DataHandler <- response - case common.StringContains(init.Topic, "orders"): - var response WsAuthenticatedOrdersResponse - err := common.JSONDecode(resp.Raw, &response) - if err != nil { - h.Websocket.DataHandler <- err - } - h.Websocket.DataHandler <- response - } -} - -func (h *HUOBIHADAX) wsHandleMarketData(resp WsMessage) { - var init WsResponse - err := common.JSONDecode(resp.Raw, &init) - if err != nil { - h.Websocket.DataHandler <- err - return - } - if init.Status == "error" { - h.Websocket.DataHandler <- fmt.Errorf("%v %v Websocket error %s %s", - h.Name, - resp.URL, - init.ErrorCode, - init.ErrorMessage) - return - } - if init.Subscribed != "" { - return - } - if init.Ping != 0 { - err = h.WebsocketConn.SendMessage(WsPong{Pong: init.Ping}) - if err != nil { - log.Error(err) - } - return - } - - switch { - case common.StringContains(init.Channel, "depth"): - var depth WsDepth - err := common.JSONDecode(resp.Raw, &depth) - if err != nil { - h.Websocket.DataHandler <- err - return - } - data := common.SplitStrings(depth.Channel, ".") - h.WsProcessOrderbook(&depth, data[1]) - case common.StringContains(init.Channel, "kline"): - var kline WsKline - err := common.JSONDecode(resp.Raw, &kline) - if err != nil { - h.Websocket.DataHandler <- err - return - } - data := common.SplitStrings(kline.Channel, ".") - h.Websocket.DataHandler <- wshandler.KlineData{ - Timestamp: time.Unix(0, kline.Timestamp), - Exchange: h.GetName(), - AssetType: orderbook.Spot, - Pair: currency.NewPairFromString(data[1]), - OpenPrice: kline.Tick.Open, - ClosePrice: kline.Tick.Close, - HighPrice: kline.Tick.High, - LowPrice: kline.Tick.Low, - Volume: kline.Tick.Volume, - } - case common.StringContains(init.Channel, "trade"): - var trade WsTrade - err := common.JSONDecode(resp.Raw, &trade) - if err != nil { - h.Websocket.DataHandler <- err - return - } - data := common.SplitStrings(trade.Channel, ".") - h.Websocket.DataHandler <- wshandler.TradeData{ - Exchange: h.GetName(), - AssetType: orderbook.Spot, - CurrencyPair: currency.NewPairFromString(data[1]), - Timestamp: time.Unix(0, trade.Tick.Timestamp), - } - } -} - -// WsProcessOrderbook processes new orderbook data -func (h *HUOBIHADAX) WsProcessOrderbook(update *WsDepth, symbol string) error { - p := currency.NewPairFromString(symbol) - var bids, asks []orderbook.Item - for i := 0; i < len(update.Tick.Bids); i++ { - bidLevel := update.Tick.Bids[i].([]interface{}) - bids = append(bids, orderbook.Item{Price: bidLevel[0].(float64), - Amount: bidLevel[0].(float64)}) - } - for i := 0; i < len(update.Tick.Asks); i++ { - askLevel := update.Tick.Asks[i].([]interface{}) - asks = append(asks, orderbook.Item{Price: askLevel[0].(float64), - Amount: askLevel[0].(float64)}) - } - var newOrderBook orderbook.Base - newOrderBook.Asks = asks - newOrderBook.Bids = bids - newOrderBook.Pair = p - err := h.Websocket.Orderbook.LoadSnapshot(&newOrderBook, true) - if err != nil { - return err - } - h.Websocket.DataHandler <- wshandler.WebsocketOrderbookUpdate{ - Pair: p, - Exchange: h.GetName(), - Asset: orderbook.Spot, - } - - return nil -} - -// GenerateDefaultSubscriptions Adds default subscriptions to websocket to be handled by ManageSubscriptions() -func (h *HUOBIHADAX) GenerateDefaultSubscriptions() { - var channels = []string{wsMarketKline, wsMarketDepth, wsMarketTrade} - var subscriptions []wshandler.WebsocketChannelSubscription - if h.Websocket.CanUseAuthenticatedEndpoints() { - channels = append(channels, "orders.%v", "orders.%v.update") - subscriptions = append(subscriptions, wshandler.WebsocketChannelSubscription{ - Channel: "accounts", - }) - } - enabledCurrencies := h.GetEnabledCurrencies() - for i := range channels { - for j := range enabledCurrencies { - enabledCurrencies[j].Delimiter = "" - channel := fmt.Sprintf(channels[i], enabledCurrencies[j].Lower().String()) - subscriptions = append(subscriptions, wshandler.WebsocketChannelSubscription{ - Channel: channel, - Currency: enabledCurrencies[j], - }) - } - } - h.Websocket.SubscribeToChannels(subscriptions) -} - -// Subscribe sends a websocket message to receive data from the channel -func (h *HUOBIHADAX) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscription) error { - if common.StringContains(channelToSubscribe.Channel, "orders.") || - common.StringContains(channelToSubscribe.Channel, "accounts") { - return h.wsAuthenticatedSubscribe("sub", wsAccountsOrdersEndPoint+channelToSubscribe.Channel, channelToSubscribe.Channel) - } - return h.WebsocketConn.SendMessage(WsRequest{Subscribe: channelToSubscribe.Channel}) -} - -// Unsubscribe sends a websocket message to stop receiving data from the channel -func (h *HUOBIHADAX) Unsubscribe(channelToSubscribe wshandler.WebsocketChannelSubscription) error { - if common.StringContains(channelToSubscribe.Channel, "orders.") || - common.StringContains(channelToSubscribe.Channel, "accounts") { - return h.wsAuthenticatedSubscribe("unsub", wsAccountsOrdersEndPoint+channelToSubscribe.Channel, channelToSubscribe.Channel) - } - return h.WebsocketConn.SendMessage(WsRequest{Unsubscribe: channelToSubscribe.Channel}) -} - -func (h *HUOBIHADAX) wsLogin() error { - if !h.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { - return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", h.Name) - } - h.Websocket.SetCanUseAuthenticatedEndpoints(true) - timestamp := time.Now().UTC().Format(wsDateTimeFormatting) - request := WsAuthenticationRequest{ - Op: authOp, - AccessKeyID: h.APIKey, - SignatureMethod: signatureMethod, - SignatureVersion: signatureVersion, - Timestamp: timestamp, - } - hmac := h.wsGenerateSignature(timestamp, wsAccountsOrdersEndPoint) - request.Signature = common.Base64Encode(hmac) - err := h.AuthenticatedWebsocketConn.SendMessage(request) - if err != nil { - h.Websocket.SetCanUseAuthenticatedEndpoints(false) - return err - } - - time.Sleep(loginDelay) - return nil -} - -func (h *HUOBIHADAX) wsGenerateSignature(timestamp, endpoint string) []byte { - values := url.Values{} - values.Set("AccessKeyId", h.APIKey) - values.Set("SignatureMethod", signatureMethod) - values.Set("SignatureVersion", signatureVersion) - values.Set("Timestamp", timestamp) - host := "api.huobi.pro" - payload := fmt.Sprintf("%s\n%s\n%s\n%s", - "GET", host, endpoint, values.Encode()) - return common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret)) -} - -func (h *HUOBIHADAX) wsAuthenticatedSubscribe(operation, endpoint, topic string) error { - timestamp := time.Now().UTC().Format(wsDateTimeFormatting) - request := WsAuthenticatedSubscriptionRequest{ - Op: operation, - AccessKeyID: h.APIKey, - SignatureMethod: signatureMethod, - SignatureVersion: signatureVersion, - Timestamp: timestamp, - Topic: topic, - } - hmac := h.wsGenerateSignature(timestamp, endpoint) - request.Signature = common.Base64Encode(hmac) - return h.AuthenticatedWebsocketConn.SendMessage(request) -} - -func (h *HUOBIHADAX) wsGetAccountsList(pair currency.Pair) (*WsAuthenticatedAccountsListResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated cannot get accounts list", h.Name) - } - timestamp := time.Now().UTC().Format(wsDateTimeFormatting) - request := WsAuthenticatedAccountsListRequest{ - Op: requestOp, - AccessKeyID: h.APIKey, - SignatureMethod: signatureMethod, - SignatureVersion: signatureVersion, - Timestamp: timestamp, - Topic: wsAccountsList, - Symbol: pair, - } - hmac := h.wsGenerateSignature(timestamp, wsAccountListEndpoint) - request.Signature = common.Base64Encode(hmac) - request.ClientID = h.AuthenticatedWebsocketConn.GenerateMessageID(true) - resp, err := h.AuthenticatedWebsocketConn.SendMessageReturnResponse(request.ClientID, request) - if err != nil { - return nil, err - } - var response WsAuthenticatedAccountsListResponse - err = common.JSONDecode(resp, &response) - return &response, err -} - -func (h *HUOBIHADAX) wsGetOrdersList(accountID int64, pair currency.Pair) (*WsAuthenticatedOrdersResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated cannot get orders list", h.Name) - } - timestamp := time.Now().UTC().Format(wsDateTimeFormatting) - request := WsAuthenticatedOrdersListRequest{ - Op: requestOp, - AccessKeyID: h.APIKey, - SignatureMethod: signatureMethod, - SignatureVersion: signatureVersion, - Timestamp: timestamp, - Topic: wsOrdersList, - AccountID: accountID, - Symbol: pair.Lower(), - States: "submitted,partial-filled", - } - hmac := h.wsGenerateSignature(timestamp, wsOrdersListEndpoint) - request.Signature = common.Base64Encode(hmac) - request.ClientID = h.AuthenticatedWebsocketConn.GenerateMessageID(true) - resp, err := h.AuthenticatedWebsocketConn.SendMessageReturnResponse(request.ClientID, request) - if err != nil { - return nil, err - } - var response WsAuthenticatedOrdersResponse - err = common.JSONDecode(resp, &response) - return &response, err -} - -func (h *HUOBIHADAX) wsGetOrderDetails(orderID string) (*WsAuthenticatedOrderDetailResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated cannot get order details", h.Name) - } - timestamp := time.Now().UTC().Format(wsDateTimeFormatting) - request := WsAuthenticatedOrderDetailsRequest{ - Op: requestOp, - AccessKeyID: h.APIKey, - SignatureMethod: signatureMethod, - SignatureVersion: signatureVersion, - Timestamp: timestamp, - Topic: wsOrdersDetail, - OrderID: orderID, - } - hmac := h.wsGenerateSignature(timestamp, wsOrdersDetailEndpoint) - request.Signature = common.Base64Encode(hmac) - request.ClientID = h.AuthenticatedWebsocketConn.GenerateMessageID(true) - resp, err := h.AuthenticatedWebsocketConn.SendMessageReturnResponse(request.ClientID, request) - if err != nil { - return nil, err - } - var response WsAuthenticatedOrderDetailResponse - err = common.JSONDecode(resp, &response) - return &response, err -} diff --git a/exchanges/huobihadax/huobihadax_wrapper.go b/exchanges/huobihadax/huobihadax_wrapper.go deleted file mode 100644 index 37c883f1..00000000 --- a/exchanges/huobihadax/huobihadax_wrapper.go +++ /dev/null @@ -1,475 +0,0 @@ -package huobihadax - -import ( - "errors" - "fmt" - "strconv" - "strings" - "sync" - "time" - - "github.com/thrasher-corp/gocryptotrader/common" - "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" - "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" - "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" - "github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler" - log "github.com/thrasher-corp/gocryptotrader/logger" -) - -// Start starts the OKEX go routine -func (h *HUOBIHADAX) Start(wg *sync.WaitGroup) { - wg.Add(1) - go func() { - h.Run() - wg.Done() - }() -} - -// Run implements the OKEX wrapper -func (h *HUOBIHADAX) Run() { - if h.Verbose { - log.Debugf("%s Websocket: %s. (url: %s).\n", h.GetName(), common.IsEnabled(h.Websocket.IsEnabled()), h.WebsocketURL) - log.Debugf("%s polling delay: %ds.\n", h.GetName(), h.RESTPollingDelay) - log.Debugf("%s %d currencies enabled: %s.\n", h.GetName(), len(h.EnabledPairs), h.EnabledPairs) - } - - exchangeProducts, err := h.GetSymbols() - if err != nil { - log.Debugf("%s Failed to get available symbols.\n", h.GetName()) - } else { - var currencies currency.Pairs - for x := range exchangeProducts { - currencies = append(currencies, - currency.NewPairWithDelimiter(exchangeProducts[x].BaseCurrency, - exchangeProducts[x].QuoteCurrency, - "-")) - } - - err = h.UpdateCurrencies(currencies, false, false) - if err != nil { - log.Debugf("%s Failed to update available currencies.\n", h.GetName()) - } - } -} - -// UpdateTicker updates and returns the ticker for a currency pair -func (h *HUOBIHADAX) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) { - var tickerPrice ticker.Price - tick, err := h.GetMarketDetailMerged(exchange.FormatExchangeCurrency(h.Name, p).String()) - if err != nil { - return tickerPrice, err - } - - tickerPrice.Pair = p - tickerPrice.Low = tick.Low - tickerPrice.Last = tick.Close - tickerPrice.Volume = tick.Volume - tickerPrice.High = tick.High - - if len(tick.Ask) > 0 { - tickerPrice.Ask = tick.Ask[0] - } - - if len(tick.Bid) > 0 { - tickerPrice.Bid = tick.Bid[0] - } - - err = ticker.ProcessTicker(h.GetName(), &tickerPrice, assetType) - if err != nil { - return tickerPrice, err - } - - return ticker.GetTicker(h.Name, p, assetType) -} - -// GetTickerPrice returns the ticker for a currency pair -func (h *HUOBIHADAX) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) { - tickerNew, err := ticker.GetTicker(h.GetName(), p, assetType) - if err != nil { - return h.UpdateTicker(p, assetType) - } - return tickerNew, nil -} - -// GetOrderbookEx returns orderbook base on the currency pair -func (h *HUOBIHADAX) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) { - ob, err := orderbook.Get(h.GetName(), p, assetType) - if err != nil { - return h.UpdateOrderbook(p, assetType) - } - return ob, nil -} - -// UpdateOrderbook updates and returns the orderbook for a currency pair -func (h *HUOBIHADAX) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) { - var orderBook orderbook.Base - orderbookNew, err := h.GetDepth(exchange.FormatExchangeCurrency(h.Name, p).String(), "step1") - if err != nil { - return orderBook, err - } - - for x := range orderbookNew.Bids { - data := orderbookNew.Bids[x] - orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data[1], Price: data[0]}) - } - - for x := range orderbookNew.Asks { - data := orderbookNew.Asks[x] - orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data[1], Price: data[0]}) - } - - orderBook.Pair = p - orderBook.ExchangeName = h.GetName() - orderBook.AssetType = assetType - - err = orderBook.Process() - if err != nil { - return orderBook, err - } - - return orderbook.Get(h.Name, p, assetType) -} - -// GetAccountID returns the account info -func (h *HUOBIHADAX) GetAccountID() ([]Account, error) { - acc, err := h.GetAccounts() - if err != nil { - return nil, err - } - - if len(acc) < 1 { - return nil, errors.New("no account returned") - } - - return acc, nil -} - -// GetAccountInfo retrieves balances for all enabled currencies for the -// HUOBIHADAX exchange -func (h *HUOBIHADAX) GetAccountInfo() (exchange.AccountInfo, error) { - var info exchange.AccountInfo - info.Exchange = h.GetName() - - accounts, err := h.GetAccountID() - if err != nil { - return info, err - } - - for _, account := range accounts { - var acc exchange.Account - - acc.ID = strconv.FormatInt(account.ID, 10) - - balances, err := h.GetAccountBalance(acc.ID) - if err != nil { - return info, err - } - - var currencyDetails []exchange.AccountCurrencyInfo - for _, balance := range balances { - var frozen bool - if balance.Type == "frozen" { - frozen = true - } - - var updated bool - for i := range currencyDetails { - if currencyDetails[i].CurrencyName == currency.NewCode(balance.Currency) { - if frozen { - currencyDetails[i].Hold = balance.Balance - } else { - currencyDetails[i].TotalValue = balance.Balance - } - updated = true - } - } - - if updated { - continue - } - - if frozen { - currencyDetails = append(currencyDetails, - exchange.AccountCurrencyInfo{ - CurrencyName: currency.NewCode(balance.Currency), - Hold: balance.Balance, - }) - } else { - currencyDetails = append(currencyDetails, - exchange.AccountCurrencyInfo{ - CurrencyName: currency.NewCode(balance.Currency), - TotalValue: balance.Balance, - }) - } - } - - acc.Currencies = currencyDetails - info.Accounts = append(info.Accounts, acc) - } - - return info, nil -} - -// GetFundingHistory returns funding history, deposits and -// withdrawals -func (h *HUOBIHADAX) GetFundingHistory() ([]exchange.FundHistory, error) { - var fundHistory []exchange.FundHistory - return fundHistory, common.ErrFunctionNotSupported -} - -// GetExchangeHistory returns historic trade data since exchange opening. -func (h *HUOBIHADAX) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) { - var resp []exchange.TradeHistory - - return resp, common.ErrNotYetImplemented -} - -// SubmitOrder submits a new order -func (h *HUOBIHADAX) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) { - var submitOrderResponse exchange.SubmitOrderResponse - accountID, err := strconv.ParseInt(clientID, 0, 64) - if err != nil { - return submitOrderResponse, err - } - - var formattedType SpotNewOrderRequestParamsType - var params = SpotNewOrderRequestParams{ - Amount: amount, - Source: "api", - Symbol: common.StringToLower(p.String()), - AccountID: int(accountID), - } - - switch { - case side == exchange.BuyOrderSide && orderType == exchange.MarketOrderType: - formattedType = SpotNewOrderRequestTypeBuyMarket - case side == exchange.SellOrderSide && orderType == exchange.MarketOrderType: - formattedType = SpotNewOrderRequestTypeSellMarket - case side == exchange.BuyOrderSide && orderType == exchange.LimitOrderType: - formattedType = SpotNewOrderRequestTypeBuyLimit - params.Price = price - case side == exchange.SellOrderSide && orderType == exchange.LimitOrderType: - formattedType = SpotNewOrderRequestTypeSellLimit - params.Price = price - default: - return submitOrderResponse, errors.New("unsupported order type") - } - - params.Type = formattedType - - response, err := h.SpotNewOrder(params) - - if response > 0 { - submitOrderResponse.OrderID = fmt.Sprintf("%v", response) - } - - if err == nil { - submitOrderResponse.IsOrderPlaced = true - } - - return submitOrderResponse, err -} - -// ModifyOrder will allow of changing orderbook placement and limit to -// market conversion -func (h *HUOBIHADAX) ModifyOrder(action *exchange.ModifyOrder) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// CancelOrder cancels an order by its corresponding ID number -func (h *HUOBIHADAX) CancelOrder(order *exchange.OrderCancellation) error { - orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) - - if err != nil { - return err - } - - _, err = h.CancelExistingOrder(orderIDInt) - - return err -} - -// CancelAllOrders cancels all orders associated with a currency pair -func (h *HUOBIHADAX) CancelAllOrders(orderCancellation *exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) { - var cancelAllOrdersResponse exchange.CancelAllOrdersResponse - for _, currency := range h.GetEnabledCurrencies() { - resp, err := h.CancelOpenOrdersBatch(orderCancellation.AccountID, exchange.FormatExchangeCurrency(h.Name, currency).String()) - if err != nil { - return cancelAllOrdersResponse, err - } - - if resp.Data.FailedCount > 0 { - return cancelAllOrdersResponse, fmt.Errorf("%v orders failed to cancel", resp.Data.FailedCount) - } - - if resp.Status == "error" { - return cancelAllOrdersResponse, errors.New(resp.ErrorMessage) - } - } - - return cancelAllOrdersResponse, nil -} - -// GetOrderInfo returns information on a current open order -func (h *HUOBIHADAX) GetOrderInfo(orderID string) (exchange.OrderDetail, error) { - var orderDetail exchange.OrderDetail - return orderDetail, common.ErrNotYetImplemented -} - -// GetDepositAddress returns a deposit address for a specified currency -func (h *HUOBIHADAX) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is -// submitted -func (h *HUOBIHADAX) WithdrawCryptocurrencyFunds(withdrawRequest *exchange.WithdrawRequest) (string, error) { - resp, err := h.Withdraw(withdrawRequest.Currency, withdrawRequest.Address, withdrawRequest.AddressTag, withdrawRequest.Amount, withdrawRequest.FeeAmount) - return fmt.Sprintf("%v", resp), err -} - -// WithdrawFiatFunds returns a withdrawal ID when a -// withdrawal is submitted -func (h *HUOBIHADAX) WithdrawFiatFunds(withdrawRequest *exchange.WithdrawRequest) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a -// withdrawal is submitted -func (h *HUOBIHADAX) WithdrawFiatFundsToInternationalBank(withdrawRequest *exchange.WithdrawRequest) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// GetWebsocket returns a pointer to the exchange websocket -func (h *HUOBIHADAX) GetWebsocket() (*wshandler.Websocket, error) { - return h.Websocket, nil -} - -// GetFeeByType returns an estimate of fee based on type of transaction -func (h *HUOBIHADAX) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { - if (h.APIKey == "" || h.APISecret == "") && // Todo check connection status - feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { - feeBuilder.FeeType = exchange.OfflineTradeFee - } - return h.GetFee(feeBuilder) -} - -// GetActiveOrders retrieves any orders that are active/open -func (h *HUOBIHADAX) GetActiveOrders(getOrdersRequest *exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) == 0 { - return nil, errors.New("currency must be supplied") - } - - side := "" - if getOrdersRequest.OrderSide == exchange.AnyOrderSide || getOrdersRequest.OrderSide == "" { - side = "" - } else if getOrdersRequest.OrderSide == exchange.SellOrderSide { - side = strings.ToLower(string(getOrdersRequest.OrderSide)) - } - - var allOrders []OrderInfo - for _, currency := range getOrdersRequest.Currencies { - resp, err := h.GetOpenOrders(h.ClientID, - currency.Lower().String(), - side, - 500) - if err != nil { - return nil, err - } - allOrders = append(allOrders, resp...) - } - - var orders []exchange.OrderDetail - for i := range allOrders { - symbol := currency.NewPairDelimiter(allOrders[i].Symbol, - h.ConfigCurrencyPairFormat.Delimiter) - orderDate := time.Unix(0, allOrders[i].CreatedAt*int64(time.Millisecond)) - - orders = append(orders, exchange.OrderDetail{ - ID: fmt.Sprintf("%v", allOrders[i].ID), - Exchange: h.Name, - Amount: allOrders[i].Amount, - Price: allOrders[i].Price, - OrderDate: orderDate, - ExecutedAmount: allOrders[i].FilledAmount, - RemainingAmount: (allOrders[i].Amount - allOrders[i].FilledAmount), - CurrencyPair: symbol, - }) - } - - exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, - getOrdersRequest.EndTicks) - - return orders, nil -} - -// GetOrderHistory retrieves account order information -// Can Limit response to specific order status -func (h *HUOBIHADAX) GetOrderHistory(getOrdersRequest *exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) == 0 { - return nil, errors.New("currency must be supplied") - } - - states := "partial-canceled,filled,canceled" - var allOrders []OrderInfo - for _, currency := range getOrdersRequest.Currencies { - resp, err := h.GetOrders(currency.Lower().String(), - "", - "", - "", - states, - "", - "", - "") - if err != nil { - return nil, err - } - allOrders = append(allOrders, resp...) - } - - var orders []exchange.OrderDetail - for i := range allOrders { - symbol := currency.NewPairDelimiter(allOrders[i].Symbol, - h.ConfigCurrencyPairFormat.Delimiter) - orderDate := time.Unix(0, allOrders[i].CreatedAt*int64(time.Millisecond)) - - orders = append(orders, exchange.OrderDetail{ - ID: fmt.Sprintf("%v", allOrders[i].ID), - Exchange: h.Name, - Amount: allOrders[i].Amount, - Price: allOrders[i].Price, - OrderDate: orderDate, - CurrencyPair: symbol, - }) - } - - exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, - getOrdersRequest.EndTicks) - - return orders, nil -} - -// SubscribeToWebsocketChannels appends to ChannelsToSubscribe -// which lets websocket.manageSubscriptions handle subscribing -func (h *HUOBIHADAX) SubscribeToWebsocketChannels(channels []wshandler.WebsocketChannelSubscription) error { - h.Websocket.SubscribeToChannels(channels) - return nil -} - -// UnsubscribeToWebsocketChannels removes from ChannelsToSubscribe -// which lets websocket.manageSubscriptions handle unsubscribing -func (h *HUOBIHADAX) UnsubscribeToWebsocketChannels(channels []wshandler.WebsocketChannelSubscription) error { - h.Websocket.RemoveSubscribedChannels(channels) - return nil -} - -// GetSubscriptions returns a copied list of subscriptions -func (h *HUOBIHADAX) GetSubscriptions() ([]wshandler.WebsocketChannelSubscription, error) { - return h.Websocket.GetSubscriptions(), nil -} - -// AuthenticateWebsocket sends an authentication message to the websocket -func (h *HUOBIHADAX) AuthenticateWebsocket() error { - return h.wsLogin() -} diff --git a/testdata/configtest.json b/testdata/configtest.json index 4eb05b5f..0677a111 100644 --- a/testdata/configtest.json +++ b/testdata/configtest.json @@ -945,52 +945,6 @@ } ] }, - { - "name": "HuobiHadax", - "enabled": true, - "verbose": false, - "websocket": false, - "useSandbox": false, - "restPollingDelay": 10, - "httpTimeout": 15000000000, - "websocketResponseCheckTimeout": 30000000, - "websocketResponseMaxLimit": 7000000000, - "websocketOrderbookBufferLimit": 5, - "httpUserAgent": "", - "httpDebugging": false, - "authenticatedApiSupport": false, - "authenticatedWebsocketApiSupport": false, - "apiKey": "Key", - "apiSecret": "Secret", - "apiAuthPemKey": "-----BEGIN EC PRIVATE KEY-----\nJUSTADUMMY\n-----END EC PRIVATE KEY-----\n", - "apiUrl": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API", - "apiUrlSecondary": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API", - "proxyAddress": "", - "websocketUrl": "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API", - "availablePairs": "TOS-ETH,XMX-ETH,MAN-ETH,MEX-BTC,AE-BTC,DATX-BTC,HPT-HT,PNT-ETH,NCC-BTC,SHE-BTC,18C-ETH,BUT-ETH,DAC-BTC,TRIO-BTC,CNN-BTC,LXT-BTC,PC-BTC,UIP-BTC,EKT-ETH,SEELE-BTC,GSC-ETH,CNN-ETH,UIP-ETH,LYM-BTC,CVCOIN-BTC,SEXC-ETH,KCASH-HT,RCCC-ETH,REN-BTC,ZJLT-ETH,GTC-BTC,AAC-BTC,PC-ETH,KCASH-BTC,BUT-BTC,MUSK-BTC,PORTAL-ETH,UUU-BTC,TOS-BTC,GET-ETH,SSP-BTC,AAC-ETH,SEXC-BTC,MT-ETH,MT-HT,EGCC-ETH,CDC-ETH,GTC-ETH,CDC-BTC,HPT-BTC,RTE-ETH,FAIR-ETH,REN-ETH,FAIR-BTC,RTE-BTC,FTI-ETH,PORTAL-BTC,LXT-ETH,KCASH-ETH,EGCC-BTC,18C-BTC,UUU-ETH,NCC-ETH,MT-BTC,BKBT-ETH,GET-BTC,DAC-ETH,MUSK-ETH,SSP-ETH,SEELE-ETH,MEX-ETH,MAN-BTC,HPT-USDT,IDT-ETH,AE-ETH,PNT-BTC,RCCC-BTC,ZJLT-BTC,DATX-ETH,IDT-BTC,GSC-BTC,GVE-BTC,LYM-ETH,XMX-BTC,CVCOIN-ETH,EKT-BTC,GVE-ETH,YCC-ETH,HOT-ETH,TRIO-ETH,INC-ETH,UC-ETH,BCV-BTC,INC-BTC,SHE-ETH,UC-BTC,BKBT-BTC,BCV-ETH,YCC-BTC,HOT-BTC,FTI-BTC,IIC-ETH,IIC-BTC", - "enabledPairs": "HOT-BTC", - "baseCurrencies": "USD", - "assetTypes": "SPOT", - "supportsAutoPairUpdates": true, - "configCurrencyPairFormat": { - "uppercase": true, - "delimiter": "-" - }, - "requestCurrencyPairFormat": { - "uppercase": false - }, - "bankAccounts": [ - { - "bankName": "", - "bankAddress": "", - "accountName": "", - "accountNumber": "", - "swiftCode": "", - "iban": "", - "supportedCurrencies": "" - } - ] - }, { "name": "ITBIT", "enabled": true, diff --git a/tools/documentation/documentation.go b/tools/documentation/documentation.go index 458e8226..db794179 100644 --- a/tools/documentation/documentation.go +++ b/tools/documentation/documentation.go @@ -60,7 +60,6 @@ const ( gemini = "..%s..%sexchanges%sgemini%s" hitbtc = "..%s..%sexchanges%shitbtc%s" huobi = "..%s..%sexchanges%shuobi%s" - huobihadax = "..%s..%sexchanges%shuobihadax%s" itbit = "..%s..%sexchanges%sitbit%s" kraken = "..%s..%sexchanges%skraken%s" lakebtc = "..%s..%sexchanges%slakebtc%s" @@ -230,7 +229,6 @@ func addPaths() { codebasePaths["exchanges gemini"] = fmt.Sprintf(gemini, path, path, path, path) codebasePaths["exchanges hitbtc"] = fmt.Sprintf(hitbtc, path, path, path, path) codebasePaths["exchanges huobi"] = fmt.Sprintf(huobi, path, path, path, path) - codebasePaths["exchanges huobihadax"] = fmt.Sprintf(huobihadax, path, path, path, path) codebasePaths["exchanges itbit"] = fmt.Sprintf(itbit, path, path, path, path) codebasePaths["exchanges kraken"] = fmt.Sprintf(kraken, path, path, path, path) codebasePaths["exchanges lakebtc"] = fmt.Sprintf(lakebtc, path, path, path, path) diff --git a/tools/documentation/exchanges_templates/huobihadax.tmpl b/tools/documentation/exchanges_templates/huobihadax.tmpl deleted file mode 100644 index e0c5a594..00000000 --- a/tools/documentation/exchanges_templates/huobihadax.tmpl +++ /dev/null @@ -1,105 +0,0 @@ -{{define "exchanges huobihadax" -}} -{{template "header" .}} -## HuobiHadax Exchange - -### Current Features - -+ REST functions - -### How to enable - -+ [Enable via configuration](https://github.com/thrasher-corp/gocryptotrader/tree/master/config#enable-exchange-via-config-example) - -+ Individual package example below: - -```go - // Exchanges will be abstracted out in further updates and examples will be - // supplied then -``` - -### How to do REST public/private calls - -+ If enabled via "configuration".json file the exchange will be added to the -IBotExchange array in the ```go var bot Bot``` and you will only be able to use -the wrapper interface functions for accessing exchange data. View routines.go -for an example of integration usage with GoCryptoTrader. Rudimentary example -below: - -main.go -```go -var h exchange.IBotExchange - -for i := range bot.exchanges { - if bot.exchanges[i].GetName() == "HuobiHadax" { - h = bot.exchanges[i] - } -} - -// Public calls - wrapper functions - -// Fetches current ticker information -tick, err := h.GetTickerPrice() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := h.GetOrderbookEx() -if err != nil { - // Handle error -} - -// Private calls - wrapper functions - make sure your APIKEY and APISECRET are -// set and AuthenticatedAPISupport is set to true - -// Fetches current account information -accountInfo, err := h.GetAccountInfo() -if err != nil { - // Handle error -} -``` - -+ If enabled via individually importing package, rudimentary example below: - -```go -// Public calls - -// Fetches current ticker information -ticker, err := h.GetTicker() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := h.GetOrderBook() -if err != nil { - // Handle error -} - -// Private calls - make sure your APIKEY and APISECRET are set and -// AuthenticatedAPISupport is set to true - -// GetUserInfo returns account info -accountInfo, err := h.GetUserInfo(...) -if err != nil { - // Handle error -} - -// Submits an order and the exchange and returns its tradeID -tradeID, err := h.Trade(...) -if err != nil { - // Handle error -} -``` - -### How to do LongPolling public/private calls - -```go - // Exchanges will be abstracted out in further updates and examples will be - // supplied then -``` - -### Please click GoDocs chevron above to view current GoDoc information for this package -{{template "contributions"}} -{{template "donations"}} -{{end}} diff --git a/tools/documentation/root_templates/root_readme.tmpl b/tools/documentation/root_templates/root_readme.tmpl index 59ff13e2..92c1c039 100644 --- a/tools/documentation/root_templates/root_readme.tmpl +++ b/tools/documentation/root_templates/root_readme.tmpl @@ -37,7 +37,6 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader | Gemini | Yes | Yes | No | | HitBTC | Yes | Yes | No | | Huobi.Pro | Yes | Yes | NA | -| Huobi.Hadax | Yes | Yes | NA | | ItBit | Yes | NA | No | | Kraken | Yes | Yes | NA | | Lbank | Yes | No | NA |