From d7368c1a8db22291e1a97784ea0f66685ddbfb46 Mon Sep 17 00:00:00 2001 From: Adrian Gallagher Date: Tue, 5 Feb 2019 11:17:05 +1100 Subject: [PATCH] Remove Liqui exchange from GCT --- README.md | 1 - config/config_test.go | 13 +- config_example.json | 42 -- exchange.go | 3 - exchanges/exchange_test.go | 2 +- exchanges/liqui/README.md | 133 ------ exchanges/liqui/liqui.go | 348 --------------- exchanges/liqui/liqui_test.go | 411 ------------------ exchanges/liqui/liqui_types.go | 225 ---------- exchanges/liqui/liqui_wrapper.go | 307 ------------- testdata/configtest.json | 42 -- tools/documentation/documentation.go | 2 - .../exchanges_templates/liqui.tmpl | 98 ----- .../root_templates/root_readme.tmpl | 1 - 14 files changed, 10 insertions(+), 1618 deletions(-) delete mode 100644 exchanges/liqui/README.md delete mode 100644 exchanges/liqui/liqui.go delete mode 100644 exchanges/liqui/liqui_test.go delete mode 100644 exchanges/liqui/liqui_types.go delete mode 100644 exchanges/liqui/liqui_wrapper.go delete mode 100644 tools/documentation/exchanges_templates/liqui.tmpl diff --git a/README.md b/README.md index 7015a675..072c8898 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,6 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader | ItBit | Yes | NA | No | | Kraken | Yes | NA | NA | | LakeBTC | Yes | No | NA | -| Liqui | Yes | No | NA | | LocalBitcoins | Yes | NA | NA | | OKCoin China | Yes | Yes | No | | OKCoin International | Yes | Yes | No | diff --git a/config/config_test.go b/config/config_test.go index 80c7b365..fe7ef4ef 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -8,6 +8,12 @@ import ( log "github.com/thrasher-/gocryptotrader/logger" ) +const ( + // Default number of enabled exchanges. Modify this whenever an exchange is + // added or removed + defaultEnabledExchanges = 29 +) + func TestGetCurrencyConfig(t *testing.T) { cfg := GetConfig() err := cfg.LoadConfig(ConfigTestFile) @@ -408,7 +414,7 @@ func TestGetEnabledExchanges(t *testing.T) { } exchanges := cfg.GetEnabledExchanges() - if len(exchanges) != 30 { + if len(exchanges) != defaultEnabledExchanges { t.Error( "Test failed. TestGetEnabledExchanges. Enabled exchanges value mismatch", ) @@ -460,7 +466,6 @@ func TestGetDisabledExchanges(t *testing.T) { } func TestCountEnabledExchanges(t *testing.T) { - defaultEnabledExchanges := 30 GetConfigEnabledExchanges := GetConfig() err := GetConfigEnabledExchanges.LoadConfig(ConfigTestFile) if err != nil { @@ -489,7 +494,7 @@ func TestGetConfigCurrencyPairFormat(t *testing.T) { ) } - exchFmt, err := cfg.GetConfigCurrencyPairFormat("Liqui") + exchFmt, err := cfg.GetConfigCurrencyPairFormat("Yobit") if !exchFmt.Uppercase || exchFmt.Delimiter != "_" { t.Errorf( "Test failed. TestGetConfigCurrencyPairFormat. Invalid values", @@ -513,7 +518,7 @@ func TestGetRequestCurrencyPairFormat(t *testing.T) { ) } - exchFmt, err := cfg.GetRequestCurrencyPairFormat("Liqui") + exchFmt, err := cfg.GetRequestCurrencyPairFormat("Bitfinex") if exchFmt.Uppercase || exchFmt.Delimiter != "_" || exchFmt.Separator != "-" { t.Errorf( "Test failed. TestGetRequestCurrencyPairFormat. Invalid values", diff --git a/config_example.json b/config_example.json index 250d4b6e..ba957234 100644 --- a/config_example.json +++ b/config_example.json @@ -986,48 +986,6 @@ } ] }, - { - "name": "Liqui", - "enabled": true, - "verbose": false, - "websocket": false, - "useSandbox": false, - "restPollingDelay": 10, - "httpTimeout": 15000000000, - "httpUserAgent": "", - "authenticatedApiSupport": false, - "apiKey": "Key", - "apiSecret": "Secret", - "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": "ANT_ETH,BNT_ETH,HOT_ETH,OAX_ETH,AST_BTC,SALT_ETH,LTC_BTC,ETH_BTC,GNO_USDT,SAN_ETH,RLC_ETH,STORJ_BTC,WPR_BTC,OMG_ETH,INS_ETH,AION_ETH,PRO_BTC,KNC_USDT,DASH_ETH,SNT_BTC,AION_USDT,ADX_BTC,MANA_ETH,WINGS_BTC,ETH_USDT,GUP_ETH,CVC_USDT,OAX_BTC,AGI_ETH,TTU_ETH,SNT_ETH,TNT_USDT,LTC_USDT,RLC_BTC,TRST_USDT,SNT_USDT,OMG_USDT,BCHABC_USDT,REP_ETH,ADX_USDT,DGD_USDT,GNO_BTC,SNGLS_USDT,AION_BTC,WINGS_ETH,ENJ_ETH,DASH_BTC,WPR_USDT,TRST_BTC,OMG_BTC,TRX_BTC,STORJ_USDT,BMC_USDT,CLN_USDT,IND_BTC,ENG_BTC,AST_ETH,DGD_ETH,LDC_ETH,ENJ_USDT,TNT_ETH,TRX_ETH,DGD_BTC,ENG_ETH,SALT_BTC,CLN_BTC,GNO_ETH,TRST_ETH,ANT_BTC,ANT_USDT,PRO_USDT,GUP_USDT,SNGLS_BTC,MANA_BTC,CVC_BTC,SALT_USDT,BTC_USDT,TNT_BTC,BNT_USDT,PAY_USDT,WINGS_USDT,BMC_BTC,ENG_USDT,GNT_USDT,OAX_USDT,GUP_BTC,GNT_BTC,SRN_ETH,TTU_USDT,GNT_ETH,REP_USDT,RLC_USDT,SAN_BTC,BCHABC_ETH,MANA_USDT,PRO_ETH,TRX_USDT,CLN_ETH,LDC_USDT,AGI_BTC,INS_BTC,STORJ_ETH,PAY_ETH,LDC_BTC,CVC_ETH,INS_USDT,SAN_USDT,ENJ_BTC,AGI_USDT,TTU_BTC,BNT_BTC,IND_ETH,IND_USDT,AST_USDT,WPR_ETH,HOT_BTC,REP_BTC,SNGLS_ETH,ADX_ETH,BMC_ETH,KNC_BTC,DASH_USDT,BCHABC_BTC,KNC_ETH,LTC_ETH,HOT_USDT,PAY_BTC", - "enabledPairs": "ETH_BTC,LTC_BTC,DASH_BTC", - "baseCurrencies": "USD", - "assetTypes": "SPOT", - "supportsAutoPairUpdates": true, - "configCurrencyPairFormat": { - "uppercase": true, - "delimiter": "_" - }, - "requestCurrencyPairFormat": { - "uppercase": false, - "delimiter": "_", - "separator": "-" - }, - "bankAccounts": [ - { - "bankName": "", - "bankAddress": "", - "accountName": "", - "accountNumber": "", - "swiftCode": "", - "iban": "", - "supportedCurrencies": "" - } - ] - }, { "name": "LocalBitcoins", "enabled": true, diff --git a/exchange.go b/exchange.go index 1b3fa467..f3d4355b 100644 --- a/exchange.go +++ b/exchange.go @@ -27,7 +27,6 @@ import ( "github.com/thrasher-/gocryptotrader/exchanges/itbit" "github.com/thrasher-/gocryptotrader/exchanges/kraken" "github.com/thrasher-/gocryptotrader/exchanges/lakebtc" - "github.com/thrasher-/gocryptotrader/exchanges/liqui" "github.com/thrasher-/gocryptotrader/exchanges/localbitcoins" "github.com/thrasher-/gocryptotrader/exchanges/okcoin" "github.com/thrasher-/gocryptotrader/exchanges/okex" @@ -178,8 +177,6 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { exch = new(kraken.Kraken) case "lakebtc": exch = new(lakebtc.LakeBTC) - case "liqui": - exch = new(liqui.Liqui) case "localbitcoins": exch = new(localbitcoins.LocalBitcoins) case "okcoin china": diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index 60d38a48..5dcee734 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -589,7 +589,7 @@ func TestGetAndFormatExchangeCurrencies(t *testing.T) { pairs = append(pairs, pair.NewCurrencyPairDelimiter("BTC_USD", "_")) pairs = append(pairs, pair.NewCurrencyPairDelimiter("LTC_BTC", "_")) - actual, err := GetAndFormatExchangeCurrencies("Liqui", pairs) + actual, err := GetAndFormatExchangeCurrencies("Yobit", pairs) if err != nil { t.Errorf("Test failed - Exchange TestGetAndFormatExchangeCurrencies error %s", err) } diff --git a/exchanges/liqui/README.md b/exchanges/liqui/README.md deleted file mode 100644 index 263c29e7..00000000 --- a/exchanges/liqui/README.md +++ /dev/null @@ -1,133 +0,0 @@ -# GoCryptoTrader package Liqui - - - - -[![Build Status](https://travis-ci.org/thrasher-/gocryptotrader.svg?branch=master)](https://travis-ci.org/thrasher-/gocryptotrader) -[![Software License](https://img.shields.io/badge/License-MIT-orange.svg?style=flat-square)](https://github.com/thrasher-/gocryptotrader/blob/master/LICENSE) -[![GoDoc](https://godoc.org/github.com/thrasher-/gocryptotrader?status.svg)](https://godoc.org/github.com/thrasher-/gocryptotrader/exchanges/liqui) -[![Coverage Status](http://codecov.io/github/thrasher-/gocryptotrader/coverage.svg?branch=master)](http://codecov.io/github/thrasher-/gocryptotrader?branch=master) -[![Go Report Card](https://goreportcard.com/badge/github.com/thrasher-/gocryptotrader)](https://goreportcard.com/report/github.com/thrasher-/gocryptotrader) - - -This liqui 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://gocryptotrader.herokuapp.com/) - -## Liqui Exchange - -### Current Features - -+ REST Support - -### How to enable - -+ [Enable via configuration](https://github.com/thrasher-/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 l exchange.IBotExchange - -for i := range bot.exchanges { - if bot.exchanges[i].GetName() == "Liqui" { - l = bot.exchanges[i] - } -} - -// Public calls - wrapper functions - -// Fetches current ticker information -tick, err := l.GetTickerPrice() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := l.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 := l.GetAccountInfo() -if err != nil { - // Handle error -} -``` - -+ If enabled via individually importing package, rudimentary example below: - -```go -// Public calls - -// Fetches current ticker information -ticker, err := l.GetTicker() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := l.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 := l.GetUserInfo(...) -if err != nil { - // Handle error -} - -// Submits an order and the exchange and returns its tradeID -tradeID, err := l.Trade(...) -if err != nil { - // Handle error -} -``` - -### 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-/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/liqui/liqui.go b/exchanges/liqui/liqui.go deleted file mode 100644 index 9013bdba..00000000 --- a/exchanges/liqui/liqui.go +++ /dev/null @@ -1,348 +0,0 @@ -package liqui - -import ( - "errors" - "fmt" - "net/url" - "strconv" - "strings" - "time" - - "github.com/thrasher-/gocryptotrader/common" - "github.com/thrasher-/gocryptotrader/config" - exchange "github.com/thrasher-/gocryptotrader/exchanges" - "github.com/thrasher-/gocryptotrader/exchanges/request" - "github.com/thrasher-/gocryptotrader/exchanges/ticker" - log "github.com/thrasher-/gocryptotrader/logger" -) - -const ( - liquiAPIPublicURL = "https://api.Liqui.io/api" - liquiAPIPrivateURL = "https://api.Liqui.io/tapi" - liquiAPIPublicVersion = "3" - liquiAPIPrivateVersion = "1" - liquiInfo = "info" - liquiTicker = "ticker" - liquiDepth = "depth" - liquiTrades = "trades" - liquiAccountInfo = "getInfo" - liquiTrade = "Trade" - liquiActiveOrders = "ActiveOrders" - liquiOrderInfo = "OrderInfo" - liquiCancelOrder = "CancelOrder" - liquiTradeHistory = "TradeHistory" - liquiWithdrawCoin = "WithdrawCoin" - - liquiAuthRate = 0 - liquiUnauthRate = 1 -) - -// Liqui is the overarching type across the liqui package -type Liqui struct { - exchange.Base - Ticker map[string]Ticker - Info Info -} - -// SetDefaults sets current default values for liqui -func (l *Liqui) SetDefaults() { - l.Name = "Liqui" - l.Enabled = false - l.Fee = 0.25 - l.Verbose = false - l.RESTPollingDelay = 10 - l.Ticker = make(map[string]Ticker) - l.APIWithdrawPermissions = exchange.WithdrawCryptoWithAPIPermission | - exchange.NoFiatWithdrawals - l.RequestCurrencyPairFormat.Delimiter = "_" - l.RequestCurrencyPairFormat.Uppercase = false - l.RequestCurrencyPairFormat.Separator = "-" - l.ConfigCurrencyPairFormat.Delimiter = "_" - l.ConfigCurrencyPairFormat.Uppercase = true - l.AssetTypes = []string{ticker.Spot} - l.SupportsAutoPairUpdating = true - l.SupportsRESTTickerBatching = true - l.Requester = request.New(l.Name, - request.NewRateLimit(time.Second, liquiAuthRate), - request.NewRateLimit(time.Second, liquiUnauthRate), - common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout)) - l.APIUrlDefault = liquiAPIPublicURL - l.APIUrl = l.APIUrlDefault - l.APIUrlSecondaryDefault = liquiAPIPrivateURL - l.APIUrlSecondary = l.APIUrlSecondaryDefault - l.WebsocketInit() -} - -// Setup sets exchange configuration parameters for liqui -func (l *Liqui) Setup(exch config.ExchangeConfig) { - if !exch.Enabled { - l.SetEnabled(false) - } else { - l.Enabled = true - l.AuthenticatedAPISupport = exch.AuthenticatedAPISupport - l.SetAPIKeys(exch.APIKey, exch.APISecret, "", false) - l.SetHTTPClientTimeout(exch.HTTPTimeout) - l.SetHTTPClientUserAgent(exch.HTTPUserAgent) - l.RESTPollingDelay = exch.RESTPollingDelay - l.Verbose = exch.Verbose - l.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",") - l.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",") - l.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",") - err := l.SetCurrencyPairFormat() - if err != nil { - log.Fatal(err) - } - err = l.SetAssetTypes() - if err != nil { - log.Fatal(err) - } - err = l.SetAutoPairDefaults() - if err != nil { - log.Fatal(err) - } - err = l.SetAPIURL(exch) - if err != nil { - log.Fatal(err) - } - err = l.SetClientProxyAddress(exch.ProxyAddress) - if err != nil { - log.Fatal(err) - } - } -} - -// GetAvailablePairs returns all available pairs -func (l *Liqui) GetAvailablePairs(nonHidden bool) []string { - var pairs []string - for x, y := range l.Info.Pairs { - if nonHidden && y.Hidden == 1 || x == "" { - continue - } - pairs = append(pairs, common.StringToUpper(x)) - } - return pairs -} - -// GetInfo provides all the information about currently active pairs, such as -// the maximum number of digits after the decimal point, the minimum price, the -// maximum price, the minimum transaction size, whether the pair is hidden, the -// commission for each pair. -func (l *Liqui) GetInfo() (Info, error) { - resp := Info{} - req := fmt.Sprintf("%s/%s/%s/", l.APIUrl, liquiAPIPublicVersion, liquiInfo) - - return resp, l.SendHTTPRequest(req, &resp) -} - -// GetTicker returns information about currently active pairs, such as: the -// maximum price, the minimum price, average price, trade volume, trade volume -// in currency, the last trade, Buy and Sell price. All information is provided -// over the past 24 hours. -// -// currencyPair - example "eth_btc" -func (l *Liqui) GetTicker(currencyPair string) (map[string]Ticker, error) { - type Response struct { - Data map[string]Ticker - Success int `json:"success"` - Error string `json:"error"` - } - - response := Response{Data: make(map[string]Ticker)} - req := fmt.Sprintf("%s/%s/%s/%s", l.APIUrl, liquiAPIPublicVersion, liquiTicker, currencyPair) - - return response.Data, l.SendHTTPRequest(req, &response.Data) -} - -// GetDepth information about active orders on the pair. Additionally it accepts -// an optional GET-parameter limit, which indicates how many orders should be -// displayed (150 by default). Is set to less than 2000. -func (l *Liqui) GetDepth(currencyPair string) (Orderbook, error) { - type Response struct { - Data map[string]Orderbook - Success int `json:"success"` - Error string `json:"error"` - } - - response := Response{Data: make(map[string]Orderbook)} - req := fmt.Sprintf("%s/%s/%s/%s", l.APIUrl, liquiAPIPublicVersion, liquiDepth, currencyPair) - - return response.Data[currencyPair], l.SendHTTPRequest(req, &response.Data) -} - -// GetTrades returns information about the last trades. Additionally it accepts -// an optional GET-parameter limit, which indicates how many orders should be -// displayed (150 by default). The maximum allowable value is 2000. -func (l *Liqui) GetTrades(currencyPair string) ([]Trades, error) { - type Response struct { - Data map[string][]Trades - Success int `json:"success"` - Error string `json:"error"` - } - - response := Response{Data: make(map[string][]Trades)} - req := fmt.Sprintf("%s/%s/%s/%s", l.APIUrl, liquiAPIPublicVersion, liquiTrades, currencyPair) - - return response.Data[currencyPair], l.SendHTTPRequest(req, &response.Data) -} - -// GetAccountInformation returns information about the user’s current balance, API-key -// privileges, the number of open orders and Server Time. To use this method you -// need a privilege of the key info. -func (l *Liqui) GetAccountInformation() (AccountInfo, error) { - var result AccountInfo - - return result, - l.SendAuthenticatedHTTPRequest(liquiAccountInfo, url.Values{}, &result) -} - -// Trade creates orders on the exchange. -// to-do: convert orderid to int64 -func (l *Liqui) Trade(pair, orderType string, amount, price float64) (float64, error) { - req := url.Values{} - req.Add("pair", pair) - req.Add("type", orderType) - req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - req.Add("rate", strconv.FormatFloat(price, 'f', -1, 64)) - var result Trade - - err := l.SendAuthenticatedHTTPRequest(liquiTrade, req, &result) - if result.Success == 0 { - return -1, errors.New(result.Error) - } - return result.OrderID, err -} - -// GetOpenOrders returns the list of your active orders. -func (l *Liqui) GetOpenOrders(pair string) (map[string]ActiveOrders, error) { - result := make(map[string]ActiveOrders) - - req := url.Values{} - req.Add("pair", pair) - - return result, l.SendAuthenticatedHTTPRequest(liquiActiveOrders, req, &result) -} - -// GetOrderInfoByID returns the information on particular order. -func (l *Liqui) GetOrderInfoByID(OrderID int64) (map[string]OrderInfo, error) { - result := make(map[string]OrderInfo) - - req := url.Values{} - req.Add("order_id", strconv.FormatInt(OrderID, 10)) - - return result, l.SendAuthenticatedHTTPRequest(liquiOrderInfo, req, &result) -} - -// CancelExistingOrder method is used for order cancelation. -func (l *Liqui) CancelExistingOrder(OrderID int64) error { - req := url.Values{} - req.Add("order_id", strconv.FormatInt(OrderID, 10)) - var result CancelOrder - - err := l.SendAuthenticatedHTTPRequest(liquiCancelOrder, req, &result) - if result.Success == 0 { - return errors.New(result.Error) - } - return err -} - -// GetTradeHistory returns trade history -func (l *Liqui) GetTradeHistory(vals url.Values, pair string) (map[string]TradeHistory, error) { - result := make(map[string]TradeHistory) - - if pair != "" { - vals.Add("pair", pair) - } - - return result, l.SendAuthenticatedHTTPRequest(liquiTradeHistory, vals, &result) -} - -// WithdrawCoins is designed for cryptocurrency withdrawals. -// API mentions that this isn't active now, but will be soon - you must provide the first 8 characters of the key -// in your ticket to support. -func (l *Liqui) WithdrawCoins(coin string, amount float64, address string) (WithdrawCoins, error) { - req := url.Values{} - req.Add("coinName", coin) - req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - req.Add("address", address) - - var result WithdrawCoins - err := l.SendAuthenticatedHTTPRequest(liquiWithdrawCoin, req, &result) - if err != nil { - return WithdrawCoins{}, err - } - if len(result.Error) > 0 { - return result, errors.New(result.Error) - } - - return result, nil -} - -// SendHTTPRequest sends an unauthenticated HTTP request -func (l *Liqui) SendHTTPRequest(path string, result interface{}) error { - return l.SendPayload("GET", path, nil, nil, result, false, l.Verbose) -} - -// SendAuthenticatedHTTPRequest sends an authenticated http request to liqui -func (l *Liqui) SendAuthenticatedHTTPRequest(method string, values url.Values, result interface{}) (err error) { - if !l.AuthenticatedAPISupport { - return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, l.Name) - } - - if l.Nonce.Get() == 0 { - l.Nonce.Set(time.Now().Unix()) - } else { - l.Nonce.Inc() - } - values.Set("nonce", l.Nonce.String()) - values.Set("method", method) - - encoded := values.Encode() - hmac := common.GetHMAC(common.HashSHA512, []byte(encoded), []byte(l.APISecret)) - - if l.Verbose { - log.Debugf("Sending POST request to %s calling method %s with params %s\n", - l.APIUrlSecondary, method, encoded) - } - - headers := make(map[string]string) - headers["Key"] = l.APIKey - headers["Sign"] = common.HexEncodeToString(hmac) - headers["Content-Type"] = "application/x-www-form-urlencoded" - - return l.SendPayload("POST", - l.APIUrlSecondary, headers, - strings.NewReader(encoded), - result, - true, - l.Verbose) -} - -// GetFee returns an estimate of fee based on type of transaction -func (l *Liqui) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { - var fee float64 - switch feeBuilder.FeeType { - case exchange.CryptocurrencyTradeFee: - fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount, feeBuilder.IsMaker) - case exchange.CryptocurrencyWithdrawalFee: - fee = getCryptocurrencyWithdrawalFee(feeBuilder.FirstCurrency) - } - - if fee < 0 { - fee = 0 - } - - return fee, nil -} - -func getCryptocurrencyWithdrawalFee(currency string) float64 { - return WithdrawalFees[currency] -} - -func calculateTradingFee(purchasePrice, amount float64, isMaker bool) (fee float64) { - if isMaker { - fee = 0.001 - } else { - fee = 0.0025 - } - return fee * purchasePrice * amount -} diff --git a/exchanges/liqui/liqui_test.go b/exchanges/liqui/liqui_test.go deleted file mode 100644 index 2081d228..00000000 --- a/exchanges/liqui/liqui_test.go +++ /dev/null @@ -1,411 +0,0 @@ -package liqui - -import ( - "net/url" - "testing" - - "github.com/thrasher-/gocryptotrader/common" - "github.com/thrasher-/gocryptotrader/config" - "github.com/thrasher-/gocryptotrader/currency/pair" - "github.com/thrasher-/gocryptotrader/currency/symbol" - exchange "github.com/thrasher-/gocryptotrader/exchanges" -) - -var l Liqui - -const ( - apiKey = "" - apiSecret = "" - canManipulateRealOrders = false -) - -func TestSetDefaults(t *testing.T) { - l.SetDefaults() -} - -func TestSetup(t *testing.T) { - cfg := config.GetConfig() - cfg.LoadConfig("../../testdata/configtest.json") - liquiConfig, err := cfg.GetExchangeConfig("Liqui") - if err != nil { - t.Error("Test Failed - liqui Setup() init error") - } - liquiConfig.AuthenticatedAPISupport = true - liquiConfig.APIKey = apiKey - liquiConfig.APISecret = apiSecret - - l.Setup(liquiConfig) -} - -func TestGetAvailablePairs(t *testing.T) { - t.Parallel() - v := l.GetAvailablePairs(false) - if len(v) != 0 { - t.Error("Test Failed - liqui GetFee() error") - } -} - -func TestGetInfo(t *testing.T) { - t.Parallel() - _, err := l.GetInfo() - if err != nil { - t.Error("Test Failed - liqui GetInfo() error", err) - } -} - -func TestGetTicker(t *testing.T) { - t.Parallel() - _, err := l.GetTicker("eth_btc") - if err != nil { - t.Error("Test Failed - liqui GetTicker() error", err) - } -} - -func TestGetDepth(t *testing.T) { - t.Parallel() - _, err := l.GetDepth("eth_btc") - if err != nil { - t.Error("Test Failed - liqui GetDepth() error", err) - } -} - -func TestGetTrades(t *testing.T) { - t.Parallel() - _, err := l.GetTrades("eth_btc") - if err != nil { - t.Error("Test Failed - liqui GetTrades() error", err) - } -} - -func TestAuthRequests(t *testing.T) { - if l.APIKey != "" && l.APISecret != "" { - _, err := l.GetAccountInfo() - if err == nil { - t.Error("Test Failed - liqui GetAccountInfo() error", err) - } - - _, err = l.Trade("", "", 0, 1) - if err == nil { - t.Error("Test Failed - liqui Trade() error", err) - } - - _, err = l.GetOpenOrders("eth_btc") - if err == nil { - t.Error("Test Failed - liqui GetActiveOrders() error", err) - } - - _, err = l.GetOrderInfo(1337) - if err == nil { - t.Error("Test Failed - liqui GetOrderInfo() error", err) - } - - err = l.CancelExistingOrder(1337) - if err == nil { - t.Error("Test Failed - liqui CancelExistingOrder() error", err) - } - - _, err = l.GetTradeHistory(url.Values{}, "") - if err == nil { - t.Error("Test Failed - liqui GetTradeHistory() error", err) - } - - _, err = l.WithdrawCoins("btc", 1337, "someaddr") - if err == nil { - t.Error("Test Failed - liqui WithdrawCoins() error", err) - } - } -} - -func TestUpdateTicker(t *testing.T) { - p := pair.NewCurrencyPairDelimiter("ETH_BTC", "_") - _, err := l.UpdateTicker(p, "SPOT") - if err != nil { - t.Error("Test Failed - liqui UpdateTicker() error", err) - } -} - -func TestUpdateOrderbook(t *testing.T) { - p := pair.NewCurrencyPairDelimiter("ETH_BTC", "_") - _, err := l.UpdateOrderbook(p, "SPOT") - if err != nil { - t.Error("Test Failed - liqui UpdateOrderbook() error", err) - } -} - -func setFeeBuilder() exchange.FeeBuilder { - return exchange.FeeBuilder{ - Amount: 1, - Delimiter: "-", - FeeType: exchange.CryptocurrencyTradeFee, - FirstCurrency: symbol.LTC, - SecondCurrency: symbol.BTC, - IsMaker: false, - PurchasePrice: 1, - CurrencyItem: symbol.USD, - BankTransactionType: exchange.WireTransfer, - } -} -func TestGetFee(t *testing.T) { - l.SetDefaults() - var feeBuilder = setFeeBuilder() - // CryptocurrencyTradeFee Basic - if resp, err := l.GetFee(feeBuilder); resp != float64(0.0025) || err != nil { - t.Error(err) - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.0025), resp) - } - - // CryptocurrencyTradeFee High quantity - feeBuilder = setFeeBuilder() - feeBuilder.Amount = 1000 - feeBuilder.PurchasePrice = 1000 - if resp, err := l.GetFee(feeBuilder); resp != float64(2500) || 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 := l.GetFee(feeBuilder); resp != float64(0.001) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.001), resp) - t.Error(err) - } - - // CryptocurrencyTradeFee Negative purchase price - feeBuilder = setFeeBuilder() - feeBuilder.PurchasePrice = -1000 - if resp, err := l.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 := l.GetFee(feeBuilder); resp != float64(0.01) || err != nil { - t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.01), resp) - t.Error(err) - } - - // CryptocurrencyWithdrawalFee Invalid currency - feeBuilder = setFeeBuilder() - feeBuilder.FirstCurrency = "hello" - feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if resp, err := l.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 := l.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 := l.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.CurrencyItem = symbol.USD - if resp, err := l.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) { - l.SetDefaults() - expectedResult := exchange.WithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText - - withdrawPermissions := l.FormatWithdrawPermissions() - - if withdrawPermissions != expectedResult { - t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) - } -} - -func TestGetActiveOrders(t *testing.T) { - l.SetDefaults() - TestSetup(t) - - var getOrdersRequest = exchange.GetOrdersRequest{ - OrderType: exchange.AnyOrderType, - Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USDT)}, - } - - _, err := l.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) { - l.SetDefaults() - TestSetup(t) - - var getOrdersRequest = exchange.GetOrdersRequest{ - OrderType: exchange.AnyOrderType, - } - - _, err := l.GetOrderHistory(getOrdersRequest) - if err != common.ErrFunctionNotSupported { - t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) - } -} - -// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them -// ---------------------------------------------------------------------------------------------------------------------------- -func areTestAPIKeysSet() bool { - if l.APIKey != "" && l.APIKey != "Key" && - l.APISecret != "" && l.APISecret != "Secret" { - return true - } - return false -} - -func TestSubmitOrder(t *testing.T) { - l.SetDefaults() - TestSetup(t) - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - var p = pair.CurrencyPair{ - Delimiter: "", - FirstCurrency: symbol.BTC, - SecondCurrency: symbol.EUR, - } - response, err := l.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi") - 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) { - l.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) - var orderCancellation = exchange.OrderCancellation{ - OrderID: "1", - WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", - AccountID: "1", - CurrencyPair: currencyPair, - } - - err := l.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) { - l.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) - var orderCancellation = exchange.OrderCancellation{ - OrderID: "1", - WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", - AccountID: "1", - CurrencyPair: currencyPair, - } - - resp, err := l.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 TestModifyOrder(t *testing.T) { - _, err := l.ModifyOrder(exchange.ModifyOrder{}) - if err == nil { - t.Error("Test failed - ModifyOrder() error") - } -} - -func TestWithdraw(t *testing.T) { - l.SetDefaults() - TestSetup(t) - var withdrawCryptoRequest = exchange.WithdrawRequest{ - Amount: 100, - Currency: symbol.LTC, - Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", - Description: "WITHDRAW IT ALL", - } - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - _, err := l.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) { - l.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - var withdrawFiatRequest = exchange.WithdrawRequest{} - - _, err := l.WithdrawFiatFunds(withdrawFiatRequest) - if err != common.ErrFunctionNotSupported { - t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) - } -} - -func TestWithdrawInternationalBank(t *testing.T) { - l.SetDefaults() - TestSetup(t) - - if areTestAPIKeysSet() && !canManipulateRealOrders { - t.Skip("API keys set, canManipulateRealOrders false, skipping test") - } - - var withdrawFiatRequest = exchange.WithdrawRequest{} - - _, err := l.WithdrawFiatFundsToInternationalBank(withdrawFiatRequest) - if err != common.ErrFunctionNotSupported { - t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) - } -} diff --git a/exchanges/liqui/liqui_types.go b/exchanges/liqui/liqui_types.go deleted file mode 100644 index 50063627..00000000 --- a/exchanges/liqui/liqui_types.go +++ /dev/null @@ -1,225 +0,0 @@ -package liqui - -import "github.com/thrasher-/gocryptotrader/currency/symbol" - -// Info holds the current pair information as well as server time -type Info struct { - ServerTime int64 `json:"server_time"` - Pairs map[string]PairData `json:"pairs"` - Success int `json:"success"` - Error string `json:"error"` -} - -// PairData is a sub-type for Info -type PairData struct { - DecimalPlaces int `json:"decimal_places"` - MinPrice float64 `json:"min_price"` - MaxPrice float64 `json:"max_price"` - MinAmount float64 `json:"min_amount"` - Hidden int `json:"hidden"` - Fee float64 `json:"fee"` -} - -// Ticker contains ticker information -type Ticker struct { - High float64 - Low float64 - Avg float64 - Vol float64 - VolumeCurrency float64 - Last float64 - Buy float64 - Sell float64 - Updated int64 -} - -// Orderbook references both ask and bid sides -type Orderbook struct { - Asks [][]float64 `json:"asks"` - Bids [][]float64 `json:"bids"` -} - -// Trades contains trade information -type Trades struct { - Type string `json:"type"` - Price float64 `json:"bid"` - Amount float64 `json:"amount"` - TID int64 `json:"tid"` - Timestamp int64 `json:"timestamp"` -} - -// AccountInfo contains full account details information -type AccountInfo struct { - Funds map[string]float64 `json:"funds"` - Rights struct { - Info bool `json:"info"` - Trade bool `json:"trade"` - Withdraw bool `json:"withdraw"` - } `json:"rights"` - ServerTime float64 `json:"server_time"` - TransactionCount int `json:"transaction_count"` - OpenOrders int `json:"open_orders"` - Success int `json:"success"` - Error string `json:"error"` -} - -// ActiveOrders holds active order information -type ActiveOrders struct { - Pair string `json:"pair"` - Type string `json:"sell"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - TimestampCreated float64 `json:"time_created"` - Status int `json:"status"` - Success int `json:"success"` - Error string `json:"error"` -} - -// OrderInfo holds specific order information -type OrderInfo struct { - Pair string `json:"pair"` - Type string `json:"sell"` - StartAmount float64 `json:"start_amount"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - TimestampCreated float64 `json:"time_created"` - Status int `json:"status"` - Success int `json:"success"` - Error string `json:"error"` -} - -// CancelOrder holds cancelled order information -type CancelOrder struct { - OrderID float64 `json:"order_id"` - Funds map[string]float64 `json:"funds"` - Success int `json:"success"` - Error string `json:"error"` -} - -// Trade holds trading information -type Trade struct { - Received float64 `json:"received"` - Remains float64 `json:"remains"` - OrderID float64 `json:"order_id"` - Funds map[string]float64 `json:"funds"` - Success int `json:"success"` - Error string `json:"error"` -} - -// TradeHistory contains trade history data -type TradeHistory struct { - Pair string `json:"pair"` - Type string `json:"type"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - OrderID float64 `json:"order_id"` - MyOrder int `json:"is_your_order"` - Timestamp float64 `json:"timestamp"` - Success int `json:"success"` - Error string `json:"error"` -} - -// Response is a generalized return type -type Response struct { - Return interface{} `json:"return"` - Success int `json:"success"` - Error string `json:"error"` -} - -// WithdrawCoins shows the amount of coins withdrawn from liqui not yet available -type WithdrawCoins struct { - TID int64 `json:"tId"` - AmountSent float64 `json:"amountSent"` - Funds map[string]float64 `json:"funds"` - Success int `json:"success"` - Error string `json:"error"` -} - -// WithdrawalFees the large list of predefined withdrawal fees -// Prone to change -var WithdrawalFees = map[string]float64{ - symbol.ZRX: 5, - symbol.ADX: 10, - symbol.AE: 2, - symbol.AION: 5, - symbol.AST: 25, - symbol.ANT: 2, - symbol.REP: 0.15, - symbol.BNT: 1.5, - symbol.BAT: 20, - symbol.BTC: 0.001, - symbol.BCH: 0.007, - symbol.BMC: 7, - symbol.BCAP: 2, - symbol.TIME: 0.5, - symbol.CVC: 15, - symbol.CFI: 100, - symbol.CLN: 100, - symbol.DASH: 0.003, - symbol.MANA: 40, - symbol.DGD: 0.05, - symbol.DNT: 100, - symbol.EDG: 15, - symbol.ENG: 3, - symbol.ENJ: 50, - symbol.EOS: 0.5, - symbol.ETH: 0.01, - symbol.FIRST: 5, - symbol.GNO: 0.1, - symbol.GNT: 15, - symbol.GOLOS: 0.01, - symbol.GBG: 0.01, - symbol.HMQ: 20, - symbol.ICN: 7, - symbol.RLC: 5, - symbol.INCNT: 1, - symbol.IND: 70, - symbol.INS: 7, - symbol.KNC: 4, - symbol.LDC: 1000, - symbol.LTC: 0.01, - symbol.LUN: 0.5, - symbol.GUP: 40, - symbol.MLN: 0.2, - symbol.MGO: 20, - symbol.MCO: 0.7, - symbol.MYST: 20, - symbol.NEU: 7, - symbol.NET: 10, - symbol.OAX: 10, - symbol.OMG: 0.5, - symbol.PTOY: 50, - symbol.PLU: 0.5, - symbol.PRO: 7, - symbol.QTUM: 0.2, - symbol.QRL: 10, - symbol.REN: 100, - symbol.REQ: 50, - symbol.ROUND: 100, - symbol.SALT: 4, - symbol.SAN: 4, - symbol.SNGLS: 80, - symbol.AGI: 50, - symbol.SRN: 30, - symbol.SNM: 25, - symbol.XID: 50, - symbol.SNT: 50, - symbol.STEEM: 0.01, - symbol.SBD: 0.01, - symbol.STORJ: 7, - symbol.STX: 20, - symbol.TAAS: 2, - symbol.PAY: 5, - symbol.USDT: 20, - symbol.TNT: 100, - symbol.TKN: 5, - symbol.TRX: 100, - symbol.VEN: 3, - symbol.VSL: 30, - symbol.WAVES: 0.01, - symbol.WPR: 100, - symbol.TRST: 100, - symbol.WINGS: 20, - symbol.XXX: 0.01, - symbol.XZC: 0.01, -} diff --git a/exchanges/liqui/liqui_wrapper.go b/exchanges/liqui/liqui_wrapper.go deleted file mode 100644 index 3ff6c157..00000000 --- a/exchanges/liqui/liqui_wrapper.go +++ /dev/null @@ -1,307 +0,0 @@ -package liqui - -import ( - "errors" - "fmt" - "strconv" - "strings" - "sync" - "time" - - "github.com/thrasher-/gocryptotrader/common" - "github.com/thrasher-/gocryptotrader/currency/pair" - exchange "github.com/thrasher-/gocryptotrader/exchanges" - "github.com/thrasher-/gocryptotrader/exchanges/orderbook" - "github.com/thrasher-/gocryptotrader/exchanges/ticker" - log "github.com/thrasher-/gocryptotrader/logger" -) - -// Start starts the Liqui go routine -func (l *Liqui) Start(wg *sync.WaitGroup) { - wg.Add(1) - go func() { - l.Run() - wg.Done() - }() -} - -// Run implements the Liqui wrapper -func (l *Liqui) Run() { - if l.Verbose { - log.Debugf("%s polling delay: %ds.\n", l.GetName(), l.RESTPollingDelay) - log.Debugf("%s %d currencies enabled: %s.\n", l.GetName(), len(l.EnabledPairs), l.EnabledPairs) - } - - var err error - l.Info, err = l.GetInfo() - if err != nil { - log.Errorf("%s Unable to fetch info.\n", l.GetName()) - } else { - exchangeProducts := l.GetAvailablePairs(true) - err = l.UpdateCurrencies(exchangeProducts, false, false) - if err != nil { - log.Errorf("%s Failed to get config.\n", l.GetName()) - } - } -} - -// UpdateTicker updates and returns the ticker for a currency pair -func (l *Liqui) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) { - var tickerPrice ticker.Price - pairsString, err := exchange.GetAndFormatExchangeCurrencies(l.Name, - l.GetEnabledCurrencies()) - if err != nil { - return tickerPrice, err - } - - result, err := l.GetTicker(pairsString.String()) - if err != nil { - return tickerPrice, err - } - - for _, x := range l.GetEnabledCurrencies() { - currency := exchange.FormatExchangeCurrency(l.Name, x).String() - var tp ticker.Price - tp.Pair = x - tp.High = result[currency].High - tp.Last = result[currency].Last - tp.Ask = result[currency].Sell - tp.Bid = result[currency].Buy - tp.Last = result[currency].Last - tp.Low = result[currency].Low - tp.Volume = result[currency].Vol - ticker.ProcessTicker(l.Name, x, tp, assetType) - } - - return ticker.GetTicker(l.Name, p, assetType) -} - -// GetTickerPrice returns the ticker for a currency pair -func (l *Liqui) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) { - tickerNew, err := ticker.GetTicker(l.Name, p, assetType) - if err != nil { - return l.UpdateTicker(p, assetType) - } - return tickerNew, nil -} - -// GetOrderbookEx returns orderbook base on the currency pair -func (l *Liqui) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) { - ob, err := orderbook.GetOrderbook(l.Name, p, assetType) - if err != nil { - return l.UpdateOrderbook(p, assetType) - } - return ob, nil -} - -// UpdateOrderbook updates and returns the orderbook for a currency pair -func (l *Liqui) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) { - var orderBook orderbook.Base - orderbookNew, err := l.GetDepth(exchange.FormatExchangeCurrency(l.Name, p).String()) - 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.ProcessOrderbook(l.Name, p, orderBook, assetType) - return orderbook.GetOrderbook(l.Name, p, assetType) -} - -// GetAccountInfo retrieves balances for all enabled currencies for the -// Liqui exchange -func (l *Liqui) GetAccountInfo() (exchange.AccountInfo, error) { - var response exchange.AccountInfo - response.Exchange = l.GetName() - accountBalance, err := l.GetAccountInformation() - if err != nil { - return response, err - } - - var currencies []exchange.AccountCurrencyInfo - for x, y := range accountBalance.Funds { - var exchangeCurrency exchange.AccountCurrencyInfo - exchangeCurrency.CurrencyName = common.StringToUpper(x) - exchangeCurrency.TotalValue = y - exchangeCurrency.Hold = 0 - currencies = append(currencies, exchangeCurrency) - } - - response.Accounts = append(response.Accounts, exchange.Account{ - Currencies: currencies, - }) - - return response, nil -} - -// GetFundingHistory returns funding history, deposits and -// withdrawals -func (l *Liqui) GetFundingHistory() ([]exchange.FundHistory, error) { - var fundHistory []exchange.FundHistory - return fundHistory, common.ErrFunctionNotSupported -} - -// GetExchangeHistory returns historic trade data since exchange opening. -func (l *Liqui) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) { - var resp []exchange.TradeHistory - - return resp, common.ErrNotYetImplemented -} - -// SubmitOrder submits a new order -func (l *Liqui) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) { - var submitOrderResponse exchange.SubmitOrderResponse - response, err := l.Trade(p.Pair().String(), orderType.ToString(), amount, price) - - 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 (l *Liqui) ModifyOrder(action exchange.ModifyOrder) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// CancelOrder cancels an order by its corresponding ID number -func (l *Liqui) CancelOrder(order exchange.OrderCancellation) error { - orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) - - if err != nil { - return err - } - - return l.CancelExistingOrder(orderIDInt) - -} - -// CancelAllOrders cancels all orders associated with a currency pair -func (l *Liqui) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) { - cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{ - OrderStatus: make(map[string]string), - } - activeOrders, err := l.GetOpenOrders("") - if err != nil { - return cancelAllOrdersResponse, err - } - - for activeOrder := range activeOrders { - orderIDInt, err := strconv.ParseInt(activeOrder, 10, 64) - if err != nil { - return cancelAllOrdersResponse, err - } - - err = l.CancelExistingOrder(orderIDInt) - if err != nil { - cancelAllOrdersResponse.OrderStatus[activeOrder] = err.Error() - } - } - - return cancelAllOrdersResponse, nil -} - -// GetOrderInfo returns information on a current open order -func (l *Liqui) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) { - var orderDetail exchange.OrderDetail - return orderDetail, common.ErrNotYetImplemented -} - -// GetDepositAddress returns a deposit address for a specified currency -func (l *Liqui) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is -// submitted -func (l *Liqui) WithdrawCryptocurrencyFunds(withdrawRequest exchange.WithdrawRequest) (string, error) { - resp, err := l.WithdrawCoins(withdrawRequest.Currency.String(), withdrawRequest.Amount, withdrawRequest.Address) - if err != nil { - return "", err - } - - return fmt.Sprintf("%v", resp.TID), nil -} - -// WithdrawFiatFunds returns a withdrawal ID when a -// withdrawal is submitted -func (l *Liqui) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a -// withdrawal is submitted -func (l *Liqui) WithdrawFiatFundsToInternationalBank(withdrawRequest exchange.WithdrawRequest) (string, error) { - return "", common.ErrFunctionNotSupported -} - -// GetWebsocket returns a pointer to the exchange websocket -func (l *Liqui) GetWebsocket() (*exchange.Websocket, error) { - return nil, common.ErrFunctionNotSupported -} - -// GetFeeByType returns an estimate of fee based on type of transaction -func (l *Liqui) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) { - return l.GetFee(feeBuilder) -} - -// GetWithdrawCapabilities returns the types of withdrawal methods permitted by the exchange -func (l *Liqui) GetWithdrawCapabilities() uint32 { - return l.GetWithdrawPermissions() -} - -// GetActiveOrders retrieves any orders that are active/open -func (l *Liqui) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") - } - - var orders []exchange.OrderDetail - for _, currency := range getOrdersRequest.Currencies { - resp, err := l.GetOpenOrders(exchange.FormatExchangeCurrency(l.Name, currency).String()) - if err != nil { - return nil, err - } - - for ID, order := range resp { - symbol := pair.NewCurrencyPairDelimiter(order.Pair, l.ConfigCurrencyPairFormat.Delimiter) - orderDate := time.Unix(int64(order.TimestampCreated), 0) - side := exchange.OrderSide(strings.ToUpper(order.Type)) - - orders = append(orders, exchange.OrderDetail{ - Amount: order.Amount, - ID: ID, - Price: order.Rate, - OrderSide: side, - OrderDate: orderDate, - Exchange: l.Name, - CurrencyPair: symbol, - }) - } - } - - exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks) - exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide) - - return orders, nil -} - -// GetOrderHistory retrieves account order information -// Can Limit response to specific order status -func (l *Liqui) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - return nil, common.ErrFunctionNotSupported -} diff --git a/testdata/configtest.json b/testdata/configtest.json index bcc054bf..8ed9c789 100644 --- a/testdata/configtest.json +++ b/testdata/configtest.json @@ -998,48 +998,6 @@ } ] }, - { - "name": "Liqui", - "enabled": true, - "verbose": false, - "websocket": false, - "useSandbox": false, - "restPollingDelay": 10, - "httpTimeout": 15000000000, - "httpUserAgent": "", - "authenticatedApiSupport": false, - "apiKey": "Key", - "apiSecret": "Secret", - "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": "BMC_ETH,OAX_BTC,OMG_USDT,DGD_BTC,MANA_USDT,LTC_USDT,TRST_BTC,ETH_USDT,STORJ_BTC,KNC_BTC,STORJ_USDT,GNT_ETH,LTC_ETH,DASH_ETH,AST_BTC,WPR_BTC,PRO_USDT,ANT_USDT,SNGLS_USDT,OAX_ETH,MANA_ETH,IND_USDT,ENG_BTC,DASH_USDT,REP_BTC,BCHABC_ETH,MANA_BTC,WPR_ETH,GNO_ETH,DGD_USDT,BCHABC_BTC,BNT_BTC,HOT_ETH,CLN_USDT,HOT_USDT,GNO_BTC,KNC_ETH,AST_ETH,CLN_BTC,RLC_USDT,GUP_BTC,BNT_ETH,LDC_USDT,GNT_USDT,CVC_USDT,BMC_BTC,WPR_USDT,SALT_BTC,TTU_BTC,ANT_BTC,DGD_ETH,AION_USDT,GUP_USDT,ADX_USDT,AGI_BTC,GNT_BTC,IND_ETH,CLN_ETH,ENG_USDT,PRO_BTC,TRX_BTC,INS_ETH,LDC_ETH,RLC_ETH,SNT_BTC,TNT_ETH,SAN_USDT,PAY_USDT,REP_ETH,SNGLS_ETH,CVC_BTC,IND_BTC,HOT_BTC,LDC_BTC,AION_BTC,SAN_BTC,TNT_BTC,ENG_ETH,WINGS_ETH,SNT_ETH,ENJ_BTC,ENJ_ETH,SALT_USDT,SNT_USDT,WINGS_USDT,ENJ_USDT,SNGLS_BTC,SRN_ETH,BTC_USDT,ADX_ETH,BMC_USDT,TRX_USDT,OMG_BTC,TRST_USDT,TNT_USDT,BNT_USDT,REP_USDT,OMG_ETH,SAN_ETH,ADX_BTC,RLC_BTC,TTU_USDT,ANT_ETH,TRX_ETH,TTU_ETH,INS_USDT,AGI_USDT,GUP_ETH,PAY_ETH,ETH_BTC,KNC_USDT,CVC_ETH,BCHABC_USDT,INS_BTC,TRST_ETH,PAY_BTC,PRO_ETH,LTC_BTC,WINGS_BTC,STORJ_ETH,SALT_ETH,AION_ETH,AST_USDT,GNO_USDT,AGI_ETH,DASH_BTC,OAX_USDT", - "enabledPairs": "ETH_BTC,LTC_BTC,DASH_BTC", - "baseCurrencies": "USD", - "assetTypes": "SPOT", - "supportsAutoPairUpdates": true, - "configCurrencyPairFormat": { - "uppercase": true, - "delimiter": "_" - }, - "requestCurrencyPairFormat": { - "uppercase": false, - "delimiter": "_", - "separator": "-" - }, - "bankAccounts": [ - { - "bankName": "", - "bankAddress": "", - "accountName": "", - "accountNumber": "", - "swiftCode": "", - "iban": "", - "supportedCurrencies": "" - } - ] - }, { "name": "LocalBitcoins", "enabled": true, diff --git a/tools/documentation/documentation.go b/tools/documentation/documentation.go index 9e9dc4ba..37544680 100644 --- a/tools/documentation/documentation.go +++ b/tools/documentation/documentation.go @@ -68,7 +68,6 @@ const ( itbit = "..%s..%sexchanges%sitbit%s" kraken = "..%s..%sexchanges%skraken%s" lakebtc = "..%s..%sexchanges%slakebtc%s" - liqui = "..%s..%sexchanges%sliqui%s" localbitcoins = "..%s..%sexchanges%slocalbitcoins%s" okcoin = "..%s..%sexchanges%sokcoin%s" okex = "..%s..%sexchanges%sokex%s" @@ -243,7 +242,6 @@ func addPaths() { 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) - codebasePaths["exchanges liqui"] = fmt.Sprintf(liqui, path, path, path, path) codebasePaths["exchanges localbitcoins"] = fmt.Sprintf(localbitcoins, path, path, path, path) codebasePaths["exchanges okcoin"] = fmt.Sprintf(okcoin, path, path, path, path) codebasePaths["exchanges okex"] = fmt.Sprintf(okex, path, path, path, path) diff --git a/tools/documentation/exchanges_templates/liqui.tmpl b/tools/documentation/exchanges_templates/liqui.tmpl deleted file mode 100644 index a0b4bd92..00000000 --- a/tools/documentation/exchanges_templates/liqui.tmpl +++ /dev/null @@ -1,98 +0,0 @@ -{{define "exchanges liqui" -}} -{{template "header" .}} -## Liqui Exchange - -### Current Features - -+ REST Support - -### How to enable - -+ [Enable via configuration](https://github.com/thrasher-/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 l exchange.IBotExchange - -for i := range bot.exchanges { - if bot.exchanges[i].GetName() == "Liqui" { - l = bot.exchanges[i] - } -} - -// Public calls - wrapper functions - -// Fetches current ticker information -tick, err := l.GetTickerPrice() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := l.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 := l.GetAccountInfo() -if err != nil { - // Handle error -} -``` - -+ If enabled via individually importing package, rudimentary example below: - -```go -// Public calls - -// Fetches current ticker information -ticker, err := l.GetTicker() -if err != nil { - // Handle error -} - -// Fetches current orderbook information -ob, err := l.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 := l.GetUserInfo(...) -if err != nil { - // Handle error -} - -// Submits an order and the exchange and returns its tradeID -tradeID, err := l.Trade(...) -if err != nil { - // Handle error -} -``` - -### 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 6a6a316e..c364faf2 100644 --- a/tools/documentation/root_templates/root_readme.tmpl +++ b/tools/documentation/root_templates/root_readme.tmpl @@ -41,7 +41,6 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader | ItBit | Yes | NA | No | | Kraken | Yes | NA | NA | | LakeBTC | Yes | No | NA | -| Liqui | Yes | No | NA | | LocalBitcoins | Yes | NA | NA | | OKCoin China | Yes | Yes | No | | OKCoin International | Yes | Yes | No |