diff --git a/common/common.go b/common/common.go index dd2da2ed..8efb23e3 100644 --- a/common/common.go +++ b/common/common.go @@ -139,12 +139,22 @@ func StringContains(input, substring string) bool { return strings.Contains(input, substring) } -// DataContains checks the substring array with an input and returns a bool -func DataContains(haystack []string, needle string) bool { +// StringDataContains checks the substring array with an input and returns a bool +func StringDataContains(haystack []string, needle string) bool { data := strings.Join(haystack, ",") return strings.Contains(data, needle) } +// StringDataCompare data checks the substring array with an input and returns a bool +func StringDataCompare(haystack []string, needle string) bool { + for x := range haystack { + if haystack[x] == needle { + return true + } + } + return false +} + // JoinStrings joins an array together with the required separator and returns // it as a string func JoinStrings(input []string, separator string) string { diff --git a/common/common_test.go b/common/common_test.go index 78e49c6a..dd1ccd49 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -243,19 +243,38 @@ func TestStringContains(t *testing.T) { } } -func TestDataContains(t *testing.T) { +func TestStringDataContains(t *testing.T) { t.Parallel() - originalHaystack := []string{"hello", "world", "data", "Contains", "string"} - originalNeedle := "world" + originalHaystack := []string{"hello", "world", "USDT", "Contains", "string"} + originalNeedle := "USD" anotherNeedle := "thing" expectedOutput := true expectedOutputTwo := false - actualResult := DataContains(originalHaystack, originalNeedle) + actualResult := StringDataContains(originalHaystack, originalNeedle) if actualResult != expectedOutput { t.Errorf("Test failed. Expected '%v'. Actual '%v'", expectedOutput, actualResult) } - actualResult = DataContains(originalHaystack, anotherNeedle) + actualResult = StringDataContains(originalHaystack, anotherNeedle) + if actualResult != expectedOutputTwo { + t.Errorf("Test failed. Expected '%v'. Actual '%v'", + expectedOutput, actualResult) + } +} + +func TestStringDataCompare(t *testing.T) { + t.Parallel() + originalHaystack := []string{"hello", "WoRld", "USDT", "Contains", "string"} + originalNeedle := "WoRld" + anotherNeedle := "USD" + expectedOutput := true + expectedOutputTwo := false + actualResult := StringDataCompare(originalHaystack, originalNeedle) + if actualResult != expectedOutput { + t.Errorf("Test failed. Expected '%v'. Actual '%v'", + expectedOutput, actualResult) + } + actualResult = StringDataCompare(originalHaystack, anotherNeedle) if actualResult != expectedOutputTwo { t.Errorf("Test failed. Expected '%v'. Actual '%v'", expectedOutput, actualResult) diff --git a/config/config.go b/config/config.go index ab8e2790..e3d3162f 100644 --- a/config/config.go +++ b/config/config.go @@ -338,8 +338,8 @@ func (c *Config) RetrieveConfigCurrencyPairs(enabledOnly bool) error { baseCurrencies := common.SplitStrings(c.Exchanges[x].BaseCurrencies, ",") for y := range baseCurrencies { - if !common.DataContains(fiatCurrencies, baseCurrencies[y]) { - fiatCurrencies = append(fiatCurrencies, baseCurrencies[y]) + if !common.StringDataCompare(fiatCurrencies, common.StringToUpper(baseCurrencies[y])) { + fiatCurrencies = append(fiatCurrencies, common.StringToUpper(baseCurrencies[y])) } } } @@ -358,26 +358,20 @@ func (c *Config) RetrieveConfigCurrencyPairs(enabledOnly bool) error { } for y := range pairs { - if !common.DataContains(fiatCurrencies, pairs[y].FirstCurrency.String()) && - !common.DataContains(cryptoCurrencies, pairs[y].FirstCurrency.String()) { - cryptoCurrencies = append(cryptoCurrencies, pairs[y].FirstCurrency.String()) + if !common.StringDataCompare(fiatCurrencies, pairs[y].FirstCurrency.Upper().String()) && + !common.StringDataCompare(cryptoCurrencies, pairs[y].FirstCurrency.Upper().String()) { + cryptoCurrencies = append(cryptoCurrencies, pairs[y].FirstCurrency.Upper().String()) } - if !common.DataContains(fiatCurrencies, pairs[y].SecondCurrency.String()) && - !common.DataContains(cryptoCurrencies, pairs[y].SecondCurrency.String()) { - cryptoCurrencies = append(cryptoCurrencies, pairs[y].SecondCurrency.String()) + if !common.StringDataCompare(fiatCurrencies, pairs[y].SecondCurrency.Upper().String()) && + !common.StringDataCompare(cryptoCurrencies, pairs[y].SecondCurrency.Upper().String()) { + cryptoCurrencies = append(cryptoCurrencies, pairs[y].SecondCurrency.Upper().String()) } } } currency.Update(fiatCurrencies, false) currency.Update(cryptoCurrencies, true) - - for x := range currency.BaseCurrencies { - if currency.BaseCurrencies[x] == "RUR" { - currency.BaseCurrencies[x] = "RUB" - } - } return nil } diff --git a/config/config_test.go b/config/config_test.go index cbf0ebbf..40a0896e 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -95,7 +95,7 @@ func TestGetEnabledExchanges(t *testing.T) { ) } - if !common.DataContains(exchanges, "Bitfinex") { + if !common.StringDataCompare(exchanges, "Bitfinex") { t.Error( "Test failed. TestGetEnabledExchanges. Expected exchange Bitfinex not found", ) diff --git a/currency/currency.go b/currency/currency.go index 0c1798ba..21a3c5e8 100644 --- a/currency/currency.go +++ b/currency/currency.go @@ -9,6 +9,7 @@ import ( "time" "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/currency/pair" ) // Rate holds the current exchange rates for the currency pair. @@ -104,14 +105,14 @@ func GetProvider() string { // FIAT currency func IsDefaultCurrency(currency string) bool { defaultCurrencies := common.SplitStrings(DefaultCurrencies, ",") - return common.DataContains(defaultCurrencies, common.StringToUpper(currency)) + return common.StringDataCompare(defaultCurrencies, common.StringToUpper(currency)) } // IsDefaultCryptocurrency checks if the currency passed in matches the default // CRYPTO currency func IsDefaultCryptocurrency(currency string) bool { cryptoCurrencies := common.SplitStrings(DefaultCryptoCurrencies, ",") - return common.DataContains(cryptoCurrencies, common.StringToUpper(currency)) + return common.StringDataCompare(cryptoCurrencies, common.StringToUpper(currency)) } // IsFiatCurrency checks if the currency passed is an enabled FIAT currency @@ -120,7 +121,7 @@ func IsFiatCurrency(currency string) bool { log.Println("IsFiatCurrency: BaseCurrencies string variable not populated") return false } - return common.DataContains(BaseCurrencies, common.StringToUpper(currency)) + return common.StringDataCompare(BaseCurrencies, common.StringToUpper(currency)) } // IsCryptocurrency checks if the currency passed is an enabled CRYPTO currency. @@ -131,19 +132,30 @@ func IsCryptocurrency(currency string) bool { ) return false } - return common.DataContains(CryptoCurrencies, common.StringToUpper(currency)) + return common.StringDataCompare(CryptoCurrencies, common.StringToUpper(currency)) +} + +// IsCryptoPair checks to see if the pair is a crypto pair. For example, BTCLTC +func IsCryptoPair(p pair.CurrencyPair) bool { + return IsCryptocurrency(p.FirstCurrency.String()) && IsCryptocurrency(p.SecondCurrency.String()) +} + +// IsCryptoFiatPair checks to see if the pair is a crypto fiat pair. For example, BTCUSD +func IsCryptoFiatPair(p pair.CurrencyPair) bool { + return IsCryptocurrency(p.FirstCurrency.String()) && !IsCryptocurrency(p.SecondCurrency.String()) || + !IsCryptocurrency(p.FirstCurrency.String()) && IsCryptocurrency(p.SecondCurrency.String()) } // Update updates the local crypto currency or base currency store func Update(input []string, cryptos bool) { for x := range input { if cryptos { - if !common.DataContains(CryptoCurrencies, input[x]) { - CryptoCurrencies = append(CryptoCurrencies, input[x]) + if !common.StringDataCompare(CryptoCurrencies, input[x]) { + CryptoCurrencies = append(CryptoCurrencies, common.StringToUpper(input[x])) } } else { - if !common.DataContains(BaseCurrencies, input[x]) { - BaseCurrencies = append(BaseCurrencies, input[x]) + if !common.StringDataCompare(BaseCurrencies, input[x]) { + BaseCurrencies = append(BaseCurrencies, common.StringToUpper(input[x])) } } } @@ -190,6 +202,14 @@ func ConvertCurrency(amount float64, from, to string) (float64, error) { return amount, nil } + if from == "RUR" { + from = "RUB" + } + + if to == "RUR" { + to = "RUB" + } + if YahooEnabled { currency := from + to _, ok := CurrencyStore[currency] diff --git a/currency/currency_test.go b/currency/currency_test.go index f25333a7..119bb776 100644 --- a/currency/currency_test.go +++ b/currency/currency_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/currency/pair" ) func TestSetProvider(t *testing.T) { @@ -164,6 +165,40 @@ func TestIsCryptocurrency(t *testing.T) { } } +func TestIsCryptoPair(t *testing.T) { + if IsCryptocurrency("") { + t.Error("Test failed. TestIsCryptocurrency returned true on an empty string") + } + + CryptoCurrencies = []string{"BTC", "LTC", "DASH"} + BaseCurrencies = []string{"USD"} + + if !IsCryptoPair(pair.NewCurrencyPair("BTC", "LTC")) { + t.Error("Test Failed. TestIsCryptoPair. Expected true result") + } + + if IsCryptoPair(pair.NewCurrencyPair("BTC", "USD")) { + t.Error("Test Failed. TestIsCryptoPair. Expected false result") + } +} + +func TestIsCryptoFiatPair(t *testing.T) { + if IsCryptocurrency("") { + t.Error("Test failed. TestIsCryptocurrency returned true on an empty string") + } + + CryptoCurrencies = []string{"BTC", "LTC", "DASH"} + BaseCurrencies = []string{"USD"} + + if !IsCryptoFiatPair(pair.NewCurrencyPair("BTC", "USD")) { + t.Error("Test Failed. TestIsCryptoPair. Expected true result") + } + + if IsCryptoFiatPair(pair.NewCurrencyPair("BTC", "LTC")) { + t.Error("Test Failed. TestIsCryptoPair. Expected false result") + } +} + func TestUpdate(t *testing.T) { CryptoCurrencies = []string{"BTC", "LTC", "DASH"} BaseCurrencies = []string{"USD", "AUD"} diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index db83e1db..94736ed5 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -462,7 +462,7 @@ func (b *Binance) SendAuthHTTPRequest(method, path string, params url.Values, re // CheckLimit checks value against a variable list func (b *Binance) CheckLimit(limit int64) error { - if !common.DataContains(b.validLimits, strconv.FormatInt(limit, 10)) { + if !common.StringDataCompare(b.validLimits, strconv.FormatInt(limit, 10)) { return errors.New("Incorrect limit values - valid values are 5, 10, 20, 50, 100, 500, 1000") } return nil @@ -470,7 +470,7 @@ func (b *Binance) CheckLimit(limit int64) error { // CheckSymbol checks value against a variable list func (b *Binance) CheckSymbol(symbol string) error { - if !common.DataContains(b.AvailablePairs, symbol) { + if !common.StringDataCompare(b.AvailablePairs, symbol) { return errors.New("Incorrect symbol values - please check available pairs in configuration") } return nil @@ -478,7 +478,7 @@ func (b *Binance) CheckSymbol(symbol string) error { // CheckIntervals checks value against a variable list func (b *Binance) CheckIntervals(interval string) error { - if !common.DataContains(b.validIntervals, interval) { + if !common.StringDataCompare(b.validIntervals, interval) { return errors.New(`Incorrect interval values - valid values are "1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","1d","3d","1w","1M"`) } return nil diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index f81f439c..f62dcd99 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -160,7 +160,7 @@ func TestGetSymbols(t *testing.T) { if len(expectedCurrencies) <= len(symbols) { for _, explicitSymbol := range expectedCurrencies { - if common.DataContains(expectedCurrencies, explicitSymbol) { + if common.StringDataCompare(expectedCurrencies, explicitSymbol) { break } else { t.Error("BitfinexGetSymbols currency mismatch with: ", explicitSymbol) diff --git a/exchanges/bittrex/bittrex_wrapper.go b/exchanges/bittrex/bittrex_wrapper.go index 5dadd2ae..0d81f84d 100644 --- a/exchanges/bittrex/bittrex_wrapper.go +++ b/exchanges/bittrex/bittrex_wrapper.go @@ -27,7 +27,7 @@ func (b *Bittrex) Run() { log.Printf("%s Failed to get available symbols.\n", b.GetName()) } else { forceUpgrade := false - if !common.DataContains(b.EnabledPairs, "-") || !common.DataContains(b.AvailablePairs, "-") { + if !common.StringDataContains(b.EnabledPairs, "-") || !common.StringDataContains(b.AvailablePairs, "-") { forceUpgrade = true } var currencies []string diff --git a/exchanges/btcc/btcc_wrapper.go b/exchanges/btcc/btcc_wrapper.go index 344ac902..2702c4ff 100644 --- a/exchanges/btcc/btcc_wrapper.go +++ b/exchanges/btcc/btcc_wrapper.go @@ -28,7 +28,7 @@ func (b *BTCC) Run() { go b.WebsocketClient() } - if common.DataContains(b.EnabledPairs, "CNY") || common.DataContains(b.AvailablePairs, "CNY") || common.DataContains(b.BaseCurrencies, "CNY") { + if common.StringDataContains(b.EnabledPairs, "CNY") || common.StringDataContains(b.AvailablePairs, "CNY") || common.StringDataContains(b.BaseCurrencies, "CNY") { log.Println("WARNING: BTCC only supports BTCUSD now, upgrading available, enabled and base currencies to BTCUSD/USD") pairs := []string{"BTCUSD"} cfg := config.GetConfig() diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index d6dde298..091ddc72 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -23,7 +23,7 @@ func (b *BTCMarkets) Run() { log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) } - if !common.DataContains(b.EnabledPairs, "AUD") || !common.DataContains(b.EnabledPairs, "AUD") { + if !common.StringDataContains(b.EnabledPairs, "AUD") || !common.StringDataContains(b.EnabledPairs, "AUD") { enabledPairs := []string{} for x := range b.EnabledPairs { enabledPairs = append(enabledPairs, b.EnabledPairs[x]+"AUD") diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index 495465a6..8563682b 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -56,7 +56,7 @@ func TestSetAssetTypes(t *testing.T) { t.Fatalf("Test failed. TestSetAssetTypes. Error %s", err) } - if !common.DataContains(b.AssetTypes, ticker.Spot) { + if !common.StringDataCompare(b.AssetTypes, ticker.Spot) { t.Fatal("Test failed. TestSetAssetTypes assetTypes is not set") } } @@ -73,7 +73,7 @@ func TestGetExchangeAssetTypes(t *testing.T) { t.Fatal("Test failed. Unable to obtain Bitfinex asset types") } - if !common.DataContains(result, ticker.Spot) { + if !common.StringDataCompare(result, ticker.Spot) { t.Fatal("Test failed. Bitfinex does not contain default asset type 'SPOT'") } diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index 0f0e0fb1..cd4b4b02 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -32,7 +32,7 @@ func (p *HitBTC) Run() { log.Printf("%s Failed to get available symbols.\n", p.GetName()) } else { forceUpgrade := false - if !common.DataContains(p.EnabledPairs, "-") || !common.DataContains(p.AvailablePairs, "-") { + if !common.StringDataContains(p.EnabledPairs, "-") || !common.StringDataContains(p.AvailablePairs, "-") { forceUpgrade = true } var currencies []string diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index 2783a928..f36257f1 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -33,11 +33,11 @@ func (h *HUOBI) Run() { log.Printf("%s Failed to get available symbols.\n", h.GetName()) } else { forceUpgrade := false - if common.DataContains(h.EnabledPairs, "CNY") || common.DataContains(h.AvailablePairs, "CNY") { + if common.StringDataContains(h.EnabledPairs, "CNY") || common.StringDataContains(h.AvailablePairs, "CNY") { forceUpgrade = true } - if common.DataContains(h.BaseCurrencies, "CNY") { + if common.StringDataContains(h.BaseCurrencies, "CNY") { cfg := config.GetConfig() exchCfg, err := cfg.GetExchangeConfig(h.Name) if err != nil { diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index 7f287249..c67b5472 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -30,7 +30,7 @@ func (k *Kraken) Run() { log.Printf("%s Failed to get available symbols.\n", k.GetName()) } else { forceUpgrade := false - if !common.DataContains(k.EnabledPairs, "-") || !common.DataContains(k.AvailablePairs, "-") { + if !common.StringDataContains(k.EnabledPairs, "-") || !common.StringDataContains(k.AvailablePairs, "-") { forceUpgrade = true } diff --git a/exchanges/localbitcoins/localbitcoins_wrapper.go b/exchanges/localbitcoins/localbitcoins_wrapper.go index 41ec78de..034c296f 100644 --- a/exchanges/localbitcoins/localbitcoins_wrapper.go +++ b/exchanges/localbitcoins/localbitcoins_wrapper.go @@ -70,12 +70,12 @@ func (l *LocalBitcoins) UpdateOrderbook(p pair.CurrencyPair, assetType string) ( for x := range orderbookNew.Bids { data := orderbookNew.Bids[x] - orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data.Amount, Price: data.Price}) + orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data.Amount / data.Price, Price: data.Price}) } for x := range orderbookNew.Asks { data := orderbookNew.Asks[x] - orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Amount, Price: data.Price}) + orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Amount / data.Price, Price: data.Price}) } orderbook.ProcessOrderbook(l.GetName(), p, orderBook, assetType) diff --git a/exchanges/okex/okex.go b/exchanges/okex/okex.go index d509ac93..cbf4d1f8 100644 --- a/exchanges/okex/okex.go +++ b/exchanges/okex/okex.go @@ -971,7 +971,7 @@ func (o *OKEX) SetCheckVarDefaults() { // CheckContractPosition checks to see if the string is a valid position for okex func (o *OKEX) CheckContractPosition(position string) error { - if !common.DataContains(o.ContractPosition, position) { + if !common.StringDataCompare(o.ContractPosition, position) { return errors.New("invalid position string - e.g. 1 = open long position, 2 = open short position, 3 = liquidate long position, 4 = liquidate short position") } return nil @@ -979,7 +979,7 @@ func (o *OKEX) CheckContractPosition(position string) error { // CheckSymbol checks to see if the string is a valid symbol for okex func (o *OKEX) CheckSymbol(symbol string) error { - if !common.DataContains(o.CurrencyPairs, symbol) { + if !common.StringDataCompare(o.CurrencyPairs, symbol) { return errors.New("invalid symbol string") } return nil @@ -987,7 +987,7 @@ func (o *OKEX) CheckSymbol(symbol string) error { // CheckContractType checks to see if the string is a correct asset func (o *OKEX) CheckContractType(contractType string) error { - if !common.DataContains(o.ContractTypes, contractType) { + if !common.StringDataCompare(o.ContractTypes, contractType) { return errors.New("invalid contract type string") } return nil @@ -995,7 +995,7 @@ func (o *OKEX) CheckContractType(contractType string) error { // CheckType checks to see if the string is a correct type func (o *OKEX) CheckType(typeInput string) error { - if !common.DataContains(o.Types, typeInput) { + if !common.StringDataCompare(o.Types, typeInput) { return errors.New("invalid type string") } return nil diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index e737c8a4..3a0fae85 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -32,7 +32,7 @@ func (p *Poloniex) Run() { log.Printf("%s Failed to get available symbols.\n", p.GetName()) } else { forceUpdate := false - if common.DataContains(p.AvailablePairs, "BTC_USDT") { + if common.StringDataCompare(p.AvailablePairs, "BTC_USDT") { log.Printf("%s contains invalid pair, forcing upgrade of available currencies.\n", p.GetName()) forceUpdate = true diff --git a/portfolio/portfolio.go b/portfolio/portfolio.go index 7c670508..cd87bf6f 100644 --- a/portfolio/portfolio.go +++ b/portfolio/portfolio.go @@ -441,7 +441,7 @@ func (p *Base) GetPortfolioSummary() Summary { var portfolioExchanges []string for _, x := range p.Addresses { if x.Description == PortfolioAddressExchange { - if !common.DataContains(portfolioExchanges, x.Address) { + if !common.StringDataCompare(portfolioExchanges, x.Address) { portfolioExchanges = append(portfolioExchanges, x.Address) } }