Add currency converter provider failover and add config setting

This commit is contained in:
Adrian Gallagher
2017-09-10 16:28:16 +10:00
parent 3ad9c3dfbe
commit 0682dcec88
4 changed files with 168 additions and 65 deletions

View File

@@ -45,6 +45,7 @@ var (
WarningWebserverListenAddressInvalid = "WARNING -- Webserver support disabled due to invalid listen address."
WarningWebserverRootWebFolderNotFound = "WARNING -- Webserver support disabled due to missing web folder."
WarningExchangeAuthAPIDefaultOrEmptyValues = "WARNING -- Exchange %s: Authenticated API support disabled due to default/empty APIKey/Secret/ClientID values."
WarningCurrencyExchangeProvider = "WARNING -- Currency exchange provider invalid valid. Reset to Fixer."
RenamingConfigFile = "Renaming config file %s to %s."
Cfg Config
)
@@ -86,14 +87,15 @@ type CurrencyPairFormatConfig struct {
// Config is the overarching object that holds all the information for
// prestart management of portfolio, SMSGlobal, webserver and enabled exchange
type Config struct {
Name string
EncryptConfig int
Cryptocurrencies string
CurrencyPairFormat *CurrencyPairFormatConfig `json:"CurrencyPairFormat"`
Portfolio portfolio.Base `json:"PortfolioAddresses"`
SMS SMSGlobalConfig `json:"SMSGlobal"`
Webserver WebserverConfig `json:"Webserver"`
Exchanges []ExchangeConfig `json:"Exchanges"`
Name string
EncryptConfig int
Cryptocurrencies string
CurrencyExchangeProvider string
CurrencyPairFormat *CurrencyPairFormatConfig `json:"CurrencyPairFormat"`
Portfolio portfolio.Base `json:"PortfolioAddresses"`
SMS SMSGlobalConfig `json:"SMSGlobal"`
Webserver WebserverConfig `json:"Webserver"`
Exchanges []ExchangeConfig `json:"Exchanges"`
}
// ExchangeConfig holds all the information needed for each enabled Exchange.
@@ -429,6 +431,15 @@ func (c *Config) LoadConfig(configPath string) error {
}
}
if c.CurrencyExchangeProvider == "" {
c.CurrencyExchangeProvider = "fixer"
} else {
if c.CurrencyExchangeProvider != "yahoo" && c.CurrencyExchangeProvider != "fixer" {
log.Println(WarningCurrencyExchangeProvider)
c.CurrencyExchangeProvider = "fixer"
}
}
if c.CurrencyPairFormat == nil {
c.CurrencyPairFormat = &CurrencyPairFormatConfig{
Delimiter: "-",

View File

@@ -68,9 +68,38 @@ var (
ErrCurrencyNotFound = errors.New("unable to find specified currency")
ErrQueryingYahoo = errors.New("unable to query Yahoo currency values")
ErrQueryingYahooZeroCount = errors.New("yahoo returned zero currency data")
YahooEnabled = false
YahooEnabled = true
)
// SetProvider sets the currency exchange service used by the currency
// converter
func SetProvider(yahooEnabled bool) {
if yahooEnabled {
YahooEnabled = true
return
}
YahooEnabled = false
}
// SwapProvider swaps the currency exchange service used by the curency
// converter
func SwapProvider() {
if YahooEnabled {
YahooEnabled = false
return
}
YahooEnabled = true
}
// GetProvider returns the currency exchange service used by the currency
// converter
func GetProvider() string {
if YahooEnabled {
return "yahoo"
}
return "fixer"
}
// IsDefaultCurrency checks if the currency passed in matches the default
// FIAT currency
func IsDefaultCurrency(currency string) bool {

View File

@@ -7,6 +7,65 @@ import (
"github.com/thrasher-/gocryptotrader/common"
)
func TestSetProvider(t *testing.T) {
defaultVal := YahooEnabled
expected := "yahoo"
SetProvider(true)
actual := GetProvider()
if expected != actual {
t.Errorf("Test failed. TestGetProvider expected %s got %s", expected, actual)
}
SetProvider(false)
expected = "fixer"
actual = GetProvider()
if expected != actual {
t.Errorf("Test failed. TestGetProvider expected %s got %s", expected, actual)
}
SetProvider(defaultVal)
}
func TestSwapProvider(t *testing.T) {
defaultVal := YahooEnabled
expected := "fixer"
SetProvider(true)
SwapProvider()
actual := GetProvider()
if expected != actual {
t.Errorf("Test failed. TestGetProvider expected %s got %s", expected, actual)
}
SetProvider(false)
SwapProvider()
expected = "yahoo"
actual = GetProvider()
if expected != actual {
t.Errorf("Test failed. TestGetProvider expected %s got %s", expected, actual)
}
SetProvider(defaultVal)
}
func TestGetProvider(t *testing.T) {
defaultVal := YahooEnabled
SetProvider(true)
expected := "yahoo"
actual := GetProvider()
if expected != actual {
t.Errorf("Test failed. TestGetProvider expected %s got %s", expected, actual)
}
SetProvider(false)
expected = "fixer"
actual = GetProvider()
if expected != actual {
t.Errorf("Test failed. TestGetProvider expected %s got %s", expected, actual)
}
SetProvider(defaultVal)
}
func TestIsDefaultCurrency(t *testing.T) {
t.Parallel()
@@ -264,36 +323,35 @@ func TestCheckAndAddCurrency(t *testing.T) {
}
func TestSeedCurrencyData(t *testing.T) {
if YahooEnabled {
currencyRequestDefault := ""
currencyRequestUSDAUD := "USD,AUD"
currencyRequestObtuse := "WigWham"
SetProvider(true)
currencyRequestDefault := ""
currencyRequestUSDAUD := "USD,AUD"
currencyRequestObtuse := "WigWham"
err := SeedCurrencyData(currencyRequestDefault)
if err != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err, currencyRequestDefault,
)
}
err2 := SeedCurrencyData(currencyRequestUSDAUD)
if err2 != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err2, currencyRequestUSDAUD,
)
}
err3 := SeedCurrencyData(currencyRequestObtuse)
if err3 == nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err3, currencyRequestObtuse,
)
}
err := SeedCurrencyData(currencyRequestDefault)
if err != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err, currencyRequestDefault,
)
}
err2 := SeedCurrencyData(currencyRequestUSDAUD)
if err2 != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err2, currencyRequestUSDAUD,
)
}
err3 := SeedCurrencyData(currencyRequestObtuse)
if err3 == nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err3, currencyRequestObtuse,
)
}
YahooEnabled = false
err := SeedCurrencyData("")
SetProvider(false)
err = SeedCurrencyData("")
if err != nil {
t.Errorf("Test failed. SeedCurrencyData via Fixer. Error: %s", err)
}
@@ -313,30 +371,29 @@ func TestMakecurrencyPairs(t *testing.T) {
}
func TestConvertCurrency(t *testing.T) {
if YahooEnabled {
fiatCurrencies := DefaultCurrencies
for _, currencyFrom := range common.SplitStrings(fiatCurrencies, ",") {
for _, currencyTo := range common.SplitStrings(fiatCurrencies, ",") {
floatyMcfloat, err := ConvertCurrency(1000, currencyFrom, currencyTo)
if err != nil {
t.Errorf(
"Test Failed. ConvertCurrency: Error %s with return: %.2f Currency 1: %s Currency 2: %s",
err, floatyMcfloat, currencyFrom, currencyTo,
)
}
if reflect.TypeOf(floatyMcfloat).String() != "float64" {
t.Error("Test Failed. ConvertCurrency: Error, incorrect return type")
}
if floatyMcfloat <= 0 {
t.Error(
"Test Failed. ConvertCurrency: Error, negative return or a serious issue with current fiat",
)
}
SetProvider(true)
fiatCurrencies := DefaultCurrencies
for _, currencyFrom := range common.SplitStrings(fiatCurrencies, ",") {
for _, currencyTo := range common.SplitStrings(fiatCurrencies, ",") {
floatyMcfloat, err := ConvertCurrency(1000, currencyFrom, currencyTo)
if err != nil {
t.Errorf(
"Test Failed. ConvertCurrency: Error %s with return: %.2f Currency 1: %s Currency 2: %s",
err, floatyMcfloat, currencyFrom, currencyTo,
)
}
if reflect.TypeOf(floatyMcfloat).String() != "float64" {
t.Error("Test Failed. ConvertCurrency: Error, incorrect return type")
}
if floatyMcfloat <= 0 {
t.Error(
"Test Failed. ConvertCurrency: Error, negative return or a serious issue with current fiat",
)
}
}
}
YahooEnabled = false
SetProvider(false)
_, err := ConvertCurrency(1000, "USD", "AUD")
if err != nil {
t.Errorf("Test failed. ConvertCurrency USD -> AUD. Error %s", err)
@@ -383,10 +440,6 @@ func TestFetchFixerCurrencyData(t *testing.T) {
}
func TestFetchYahooCurrencyData(t *testing.T) {
if !YahooEnabled {
return
}
t.Parallel()
var fetchData []string
fiatCurrencies := DefaultCurrencies
@@ -407,10 +460,6 @@ func TestFetchYahooCurrencyData(t *testing.T) {
}
func TestQueryYahooCurrencyValues(t *testing.T) {
if !YahooEnabled {
return
}
err := QueryYahooCurrencyValues(DefaultCurrencies)
if err != nil {
t.Errorf("Test Failed. QueryYahooCurrencyValues: Error, %s", err)

16
main.go
View File

@@ -167,10 +167,24 @@ func main() {
setupBotExchanges()
if bot.config.CurrencyExchangeProvider == "yahoo" {
currency.SetProvider(true)
} else {
currency.SetProvider(false)
}
log.Printf("Using %s as currency exchange provider.", bot.config.CurrencyExchangeProvider)
bot.config.RetrieveConfigCurrencyPairs()
err = currency.SeedCurrencyData(currency.BaseCurrencies)
if err != nil {
log.Fatalf("Fatal error retrieving config currencies. Error: %s", err)
currency.SwapProvider()
log.Printf("'%s' currency exchange provider failed, swapping to %s and testing..",
bot.config.CurrencyExchangeProvider, currency.GetProvider())
err = currency.SeedCurrencyData(currency.BaseCurrencies)
if err != nil {
log.Fatalf("Fatal error retrieving config currencies. Error: %s", err)
}
}
log.Println("Successfully retrieved config currencies.")