mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-01 15:10:44 +00:00
Engine: Protocol Features, coverage, types, BTC markets websocket (#368)
* Attempts to update orderbook so it doesn't need to sort * Reverts the ws ob stuff. Gets rid of sorting because it happens later. Adds some exchange features * update existing feature lists. Expands list definition to match my emotions * Adds bithumb bitmex and bitstamp. adds a couple more types * Features for you, features for me, features for bittrex, btcmarkets, btse, coinbasepro, coinut, exmo, gateio and gemini * Features for hitbtc, huobi, itbit, kraken, lakebtc, lbank, localbitcoins, okcoin, okex, poloniex, yobit, zb * Who can forget good old alphapoint? * Adds btcmarksets websocket :glitch_crab: fixes alphapoint features * Adds extra data not in the documentation :/ * Replaces websocket features by using protocol features. However, it breaks it due to import cycles. I'm not sure what I'll do just yet * Removes import cycle via duplicate structs. * Increases coverage of config with `TestCheckCurrencyConfigValues`. Moves all currency pair package types into their own files or places it at the bottom of files if necessary * Increase coverage in code.go * One way of determining a test has failed, is when to it fails. Removed redundant explanation * Increases code coverage of conversion * Lint fixes * Fixes orderbook tests * Re-adds sorting because its important to still have the internal pre-processed orderbook to be representative of a real orderbook * Secret lints that did not show up via Windows linting * Adds protocol package to contain exchange features * Fixes protocol implementation * Fixes ws tests * Addresses the following: Removes st-st-stutters in config types, changes GetAvailableForexProviders -> GetSupportedForexProviders, removes errors from tests where error is nil, removes orderbook setup when not necessary, removes import newlines, removes false bools from declaration, changes should of to should have * imports and casing * Fixes two more nil error checks
This commit is contained in:
145
config/config.go
145
config/config.go
@@ -13,7 +13,6 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
@@ -27,67 +26,6 @@ import (
|
||||
log "github.com/thrasher-corp/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// Constants declared here are filename strings and test strings
|
||||
const (
|
||||
FXProviderFixer = "fixer"
|
||||
EncryptedConfigFile = "config.dat"
|
||||
ConfigFile = "config.json"
|
||||
ConfigTestFile = "../testdata/configtest.json"
|
||||
configFileEncryptionPrompt = 0
|
||||
configFileEncryptionEnabled = 1
|
||||
configFileEncryptionDisabled = -1
|
||||
configPairsLastUpdatedWarningThreshold = 30 // 30 days
|
||||
configDefaultHTTPTimeout = time.Second * 15
|
||||
configDefaultWebsocketResponseCheckTimeout = time.Millisecond * 30
|
||||
configDefaultWebsocketResponseMaxLimit = time.Second * 7
|
||||
configDefaultWebsocketOrderbookBufferLimit = 5
|
||||
configDefaultWebsocketTrafficTimeout = time.Second * 30
|
||||
configMaxAuthFailures = 3
|
||||
defaultNTPAllowedDifference = 50000000
|
||||
defaultNTPAllowedNegativeDifference = 50000000
|
||||
|
||||
DefaultAPIKey = "Key"
|
||||
DefaultAPISecret = "Secret"
|
||||
DefaultAPIClientID = "ClientID"
|
||||
)
|
||||
|
||||
// Constants here hold some messages
|
||||
const (
|
||||
ErrExchangeNameEmpty = "exchange #%d name is empty"
|
||||
ErrExchangeAvailablePairsEmpty = "exchange %s available pairs is empty"
|
||||
ErrExchangeEnabledPairsEmpty = "exchange %s enabled pairs is empty"
|
||||
ErrExchangeBaseCurrenciesEmpty = "exchange %s base currencies is empty"
|
||||
ErrExchangeNotFound = "exchange %s not found"
|
||||
ErrNoEnabledExchanges = "no exchanges enabled"
|
||||
ErrCryptocurrenciesEmpty = "cryptocurrencies variable is empty"
|
||||
ErrFailureOpeningConfig = "fatal error opening %s file. Error: %s"
|
||||
ErrCheckingConfigValues = "fatal error checking config values. Error: %s"
|
||||
ErrSavingConfigBytesMismatch = "config file %q bytes comparison doesn't match, read %s expected %s"
|
||||
WarningWebserverCredentialValuesEmpty = "webserver support disabled due to empty Username/Password values"
|
||||
WarningWebserverListenAddressInvalid = "webserver support disabled due to invalid listen address"
|
||||
WarningExchangeAuthAPIDefaultOrEmptyValues = "exchange %s authenticated API support disabled due to default/empty APIKey/Secret/ClientID values"
|
||||
WarningPairsLastUpdatedThresholdExceeded = "exchange %s last manual update of available currency pairs has exceeded %d days. Manual update required!"
|
||||
)
|
||||
|
||||
// Constants here define unset default values displayed in the config.json
|
||||
// file
|
||||
const (
|
||||
APIURLNonDefaultMessage = "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API"
|
||||
WebsocketURLNonDefaultMessage = "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API"
|
||||
DefaultUnsetAPIKey = "Key"
|
||||
DefaultUnsetAPISecret = "Secret"
|
||||
DefaultUnsetAccountPlan = "accountPlan"
|
||||
DefaultForexProviderExchangeRatesAPI = "ExchangeRates"
|
||||
)
|
||||
|
||||
// Variables here are used for configuration
|
||||
var (
|
||||
Cfg Config
|
||||
IsInitialSetup bool
|
||||
testBypass bool
|
||||
m sync.Mutex
|
||||
)
|
||||
|
||||
// GetCurrencyConfig returns currency configurations
|
||||
func (c *Config) GetCurrencyConfig() CurrencyConfig {
|
||||
return c.Currency
|
||||
@@ -982,14 +920,14 @@ func (c *Config) CheckExchangeConfigValues() error {
|
||||
}
|
||||
if !c.Exchanges[i].Features.Supports.RESTCapabilities.AutoPairUpdates && !c.Exchanges[i].Features.Supports.WebsocketCapabilities.AutoPairUpdates {
|
||||
lastUpdated := convert.UnixTimestampToTime(c.Exchanges[i].CurrencyPairs.LastUpdated)
|
||||
lastUpdated = lastUpdated.AddDate(0, 0, configPairsLastUpdatedWarningThreshold)
|
||||
lastUpdated = lastUpdated.AddDate(0, 0, pairsLastUpdatedWarningThreshold)
|
||||
if lastUpdated.Unix() <= time.Now().Unix() {
|
||||
log.Warnf(log.ExchangeSys, WarningPairsLastUpdatedThresholdExceeded, c.Exchanges[i].Name, configPairsLastUpdatedWarningThreshold)
|
||||
log.Warnf(log.ExchangeSys, WarningPairsLastUpdatedThresholdExceeded, c.Exchanges[i].Name, pairsLastUpdatedWarningThreshold)
|
||||
}
|
||||
}
|
||||
if c.Exchanges[i].HTTPTimeout <= 0 {
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s HTTP Timeout value not set, defaulting to %v.\n", c.Exchanges[i].Name, configDefaultHTTPTimeout)
|
||||
c.Exchanges[i].HTTPTimeout = configDefaultHTTPTimeout
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s HTTP Timeout value not set, defaulting to %v.\n", c.Exchanges[i].Name, defaultHTTPTimeout)
|
||||
c.Exchanges[i].HTTPTimeout = defaultHTTPTimeout
|
||||
}
|
||||
|
||||
if c.Exchanges[i].HTTPRateLimiter != nil {
|
||||
@@ -1016,24 +954,24 @@ func (c *Config) CheckExchangeConfigValues() error {
|
||||
|
||||
if c.Exchanges[i].WebsocketResponseCheckTimeout <= 0 {
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s Websocket response check timeout value not set, defaulting to %v.",
|
||||
c.Exchanges[i].Name, configDefaultWebsocketResponseCheckTimeout)
|
||||
c.Exchanges[i].WebsocketResponseCheckTimeout = configDefaultWebsocketResponseCheckTimeout
|
||||
c.Exchanges[i].Name, defaultWebsocketResponseCheckTimeout)
|
||||
c.Exchanges[i].WebsocketResponseCheckTimeout = defaultWebsocketResponseCheckTimeout
|
||||
}
|
||||
|
||||
if c.Exchanges[i].WebsocketResponseMaxLimit <= 0 {
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s Websocket response max limit value not set, defaulting to %v.",
|
||||
c.Exchanges[i].Name, configDefaultWebsocketResponseMaxLimit)
|
||||
c.Exchanges[i].WebsocketResponseMaxLimit = configDefaultWebsocketResponseMaxLimit
|
||||
c.Exchanges[i].Name, defaultWebsocketResponseMaxLimit)
|
||||
c.Exchanges[i].WebsocketResponseMaxLimit = defaultWebsocketResponseMaxLimit
|
||||
}
|
||||
if c.Exchanges[i].WebsocketTrafficTimeout <= 0 {
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s Websocket response traffic timeout value not set, defaulting to %v.",
|
||||
c.Exchanges[i].Name, configDefaultWebsocketTrafficTimeout)
|
||||
c.Exchanges[i].WebsocketTrafficTimeout = configDefaultWebsocketTrafficTimeout
|
||||
c.Exchanges[i].Name, defaultWebsocketTrafficTimeout)
|
||||
c.Exchanges[i].WebsocketTrafficTimeout = defaultWebsocketTrafficTimeout
|
||||
}
|
||||
if c.Exchanges[i].WebsocketOrderbookBufferLimit <= 0 {
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s Websocket orderbook buffer limit value not set, defaulting to %v.",
|
||||
c.Exchanges[i].Name, configDefaultWebsocketOrderbookBufferLimit)
|
||||
c.Exchanges[i].WebsocketOrderbookBufferLimit = configDefaultWebsocketOrderbookBufferLimit
|
||||
c.Exchanges[i].Name, defaultWebsocketOrderbookBufferLimit)
|
||||
c.Exchanges[i].WebsocketOrderbookBufferLimit = defaultWebsocketOrderbookBufferLimit
|
||||
}
|
||||
err := c.CheckPairConsistency(c.Exchanges[i].Name)
|
||||
if err != nil {
|
||||
@@ -1065,10 +1003,7 @@ func (c *Config) CheckExchangeConfigValues() error {
|
||||
|
||||
// CheckCurrencyConfigValues checks to see if the currency config values are correct or not
|
||||
func (c *Config) CheckCurrencyConfigValues() error {
|
||||
fxProviders := forexprovider.GetAvailableForexProviders()
|
||||
if len(fxProviders) == 0 {
|
||||
return errors.New("no forex providers available")
|
||||
}
|
||||
fxProviders := forexprovider.GetSupportedForexProviders()
|
||||
|
||||
if len(fxProviders) != len(c.Currency.ForexProviders) {
|
||||
for x := range fxProviders {
|
||||
@@ -1088,27 +1023,25 @@ func (c *Config) CheckCurrencyConfigValues() error {
|
||||
count := 0
|
||||
for i := range c.Currency.ForexProviders {
|
||||
if c.Currency.ForexProviders[i].Enabled {
|
||||
if c.Currency.ForexProviders[i].APIKey == DefaultUnsetAPIKey && c.Currency.ForexProviders[i].Name != DefaultForexProviderExchangeRatesAPI {
|
||||
if c.Currency.ForexProviders[i].Name == "CurrencyConverter" &&
|
||||
c.Currency.ForexProviders[i].PrimaryProvider &&
|
||||
(c.Currency.ForexProviders[i].APIKey == "" ||
|
||||
c.Currency.ForexProviders[i].APIKey == DefaultUnsetAPIKey) {
|
||||
log.Warnln(log.Global, "CurrencyConverter forex provider no longer supports unset API key requests. Switching to ExchangeRates FX provider..")
|
||||
c.Currency.ForexProviders[i].Enabled = false
|
||||
c.Currency.ForexProviders[i].PrimaryProvider = false
|
||||
c.Currency.ForexProviders[i].APIKey = DefaultUnsetAPIKey
|
||||
c.Currency.ForexProviders[i].APIKeyLvl = -1
|
||||
continue
|
||||
}
|
||||
if c.Currency.ForexProviders[i].APIKey == DefaultUnsetAPIKey &&
|
||||
c.Currency.ForexProviders[i].Name != DefaultForexProviderExchangeRatesAPI {
|
||||
log.Warnf(log.Global, "%s enabled forex provider API key not set. Please set this in your config.json file\n", c.Currency.ForexProviders[i].Name)
|
||||
c.Currency.ForexProviders[i].Enabled = false
|
||||
c.Currency.ForexProviders[i].PrimaryProvider = false
|
||||
continue
|
||||
}
|
||||
|
||||
if c.Currency.ForexProviders[i].Name == "CurrencyConverter" {
|
||||
if c.Currency.ForexProviders[i].Enabled &&
|
||||
c.Currency.ForexProviders[i].PrimaryProvider &&
|
||||
(c.Currency.ForexProviders[i].APIKey == "" ||
|
||||
c.Currency.ForexProviders[i].APIKey == DefaultUnsetAPIKey) {
|
||||
log.Warnln(log.Global, "CurrencyConverter forex provider no longer supports unset API key requests. Switching to ExchangeRates FX provider..")
|
||||
c.Currency.ForexProviders[i].Enabled = false
|
||||
c.Currency.ForexProviders[i].PrimaryProvider = false
|
||||
c.Currency.ForexProviders[i].APIKey = DefaultUnsetAPIKey
|
||||
c.Currency.ForexProviders[i].APIKeyLvl = -1
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if c.Currency.ForexProviders[i].APIKeyLvl == -1 && c.Currency.ForexProviders[i].Name != DefaultForexProviderExchangeRatesAPI {
|
||||
log.Warnf(log.Global, "%s APIKey Level not set, functions limited. Please set this in your config.json file\n",
|
||||
c.Currency.ForexProviders[i].Name)
|
||||
@@ -1406,7 +1339,7 @@ func GetFilePath(file string) (string, error) {
|
||||
}
|
||||
|
||||
if flag.Lookup("test.v") != nil && !testBypass {
|
||||
return ConfigTestFile, nil
|
||||
return TestFile, nil
|
||||
}
|
||||
|
||||
exePath, err := common.GetExecutablePath()
|
||||
@@ -1415,8 +1348,8 @@ func GetFilePath(file string) (string, error) {
|
||||
}
|
||||
|
||||
oldDirs := []string{
|
||||
filepath.Join(exePath, ConfigFile),
|
||||
filepath.Join(exePath, EncryptedConfigFile),
|
||||
filepath.Join(exePath, File),
|
||||
filepath.Join(exePath, EncryptedFile),
|
||||
}
|
||||
|
||||
newDir := common.GetDefaultDataDir(runtime.GOOS)
|
||||
@@ -1425,8 +1358,8 @@ func GetFilePath(file string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
newDirs := []string{
|
||||
filepath.Join(newDir, ConfigFile),
|
||||
filepath.Join(newDir, EncryptedConfigFile),
|
||||
filepath.Join(newDir, File),
|
||||
filepath.Join(newDir, EncryptedFile),
|
||||
}
|
||||
|
||||
// First upgrade the old dir config file if it exists to the corresponding
|
||||
@@ -1522,23 +1455,23 @@ func (c *Config) ReadConfig(configPath string, dryrun bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.EncryptConfig == configFileEncryptionDisabled {
|
||||
if c.EncryptConfig == fileEncryptionDisabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.EncryptConfig == configFileEncryptionPrompt {
|
||||
if c.EncryptConfig == fileEncryptionPrompt {
|
||||
m.Lock()
|
||||
IsInitialSetup = true
|
||||
m.Unlock()
|
||||
if c.PromptForConfigEncryption(configPath, dryrun) {
|
||||
c.EncryptConfig = configFileEncryptionEnabled
|
||||
c.EncryptConfig = fileEncryptionEnabled
|
||||
return c.SaveConfig(defaultPath, dryrun)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errCounter := 0
|
||||
for {
|
||||
if errCounter >= configMaxAuthFailures {
|
||||
if errCounter >= maxAuthFailures {
|
||||
return errors.New("failed to decrypt config after 3 attempts")
|
||||
}
|
||||
key, err := PromptForConfigKey(IsInitialSetup)
|
||||
@@ -1559,7 +1492,7 @@ func (c *Config) ReadConfig(configPath string, dryrun bool) error {
|
||||
|
||||
err = ConfirmConfigJSON(data, &c)
|
||||
if err != nil {
|
||||
if errCounter < configMaxAuthFailures {
|
||||
if errCounter < maxAuthFailures {
|
||||
log.Error(log.ConfigMgr, "Invalid password.")
|
||||
}
|
||||
errCounter++
|
||||
@@ -1587,7 +1520,7 @@ func (c *Config) SaveConfig(configPath string, dryrun bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.EncryptConfig == configFileEncryptionEnabled {
|
||||
if c.EncryptConfig == fileEncryptionEnabled {
|
||||
var key []byte
|
||||
|
||||
if IsInitialSetup {
|
||||
@@ -1678,8 +1611,8 @@ func (c *Config) CheckConfig() error {
|
||||
}
|
||||
|
||||
if c.GlobalHTTPTimeout <= 0 {
|
||||
log.Warnf(log.ConfigMgr, "Global HTTP Timeout value not set, defaulting to %v.\n", configDefaultHTTPTimeout)
|
||||
c.GlobalHTTPTimeout = configDefaultHTTPTimeout
|
||||
log.Warnf(log.ConfigMgr, "Global HTTP Timeout value not set, defaulting to %v.\n", defaultHTTPTimeout)
|
||||
c.GlobalHTTPTimeout = defaultHTTPTimeout
|
||||
}
|
||||
|
||||
if c.NTPClient.Level != 0 {
|
||||
|
||||
@@ -43,7 +43,7 @@ func (c *Config) PromptForConfigEncryption(configPath string, dryrun bool) bool
|
||||
}
|
||||
|
||||
if !common.YesOrNo(input) {
|
||||
c.EncryptConfig = configFileEncryptionDisabled
|
||||
c.EncryptConfig = fileEncryptionDisabled
|
||||
err := c.SaveConfig(configPath, dryrun)
|
||||
if err != nil {
|
||||
log.Errorf(log.ConfigMgr, "cannot save config %s", err)
|
||||
|
||||
@@ -9,7 +9,7 @@ func TestPromptForConfigEncryption(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if Cfg.PromptForConfigEncryption("", true) {
|
||||
t.Error("Test failed. PromptForConfigEncryption return incorrect bool")
|
||||
t.Error("PromptForConfigEncryption return incorrect bool")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,25 +18,25 @@ func TestPromptForConfigKey(t *testing.T) {
|
||||
|
||||
byteyBite, err := PromptForConfigKey(true)
|
||||
if err == nil && len(byteyBite) > 1 {
|
||||
t.Errorf("Test failed. PromptForConfigKey: %s", err)
|
||||
t.Errorf("PromptForConfigKey: %s", err)
|
||||
}
|
||||
|
||||
_, err = PromptForConfigKey(false)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
t.Error("Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncryptConfigFile(t *testing.T) {
|
||||
_, err := EncryptConfigFile([]byte("test"), nil)
|
||||
if err == nil {
|
||||
t.Fatal("Test failed. Expected different result")
|
||||
t.Fatal("Expected error")
|
||||
}
|
||||
|
||||
sessionDK = []byte("a")
|
||||
_, err = EncryptConfigFile([]byte("test"), nil)
|
||||
if err == nil {
|
||||
t.Fatal("Test failed. Expected different result")
|
||||
t.Fatal("Expected error")
|
||||
}
|
||||
|
||||
sessionDK, err = makeNewSessionDK([]byte("asdf"))
|
||||
@@ -60,17 +60,17 @@ func TestDecryptConfigFile(t *testing.T) {
|
||||
|
||||
_, err = DecryptConfigFile(result, nil)
|
||||
if err == nil {
|
||||
t.Fatal("Test failed. Expected different result")
|
||||
t.Fatal("Expected error")
|
||||
}
|
||||
|
||||
_, err = DecryptConfigFile([]byte("test"), nil)
|
||||
if err == nil {
|
||||
t.Fatal("Test failed. Expected different result")
|
||||
t.Fatal("Expected error")
|
||||
}
|
||||
|
||||
_, err = DecryptConfigFile([]byte("test"), []byte("AAAAAAAAAAAAAAAA"))
|
||||
if err == nil {
|
||||
t.Fatalf("Test failed. Expected %s", errAESBlockSize)
|
||||
t.Fatalf("Expected %s", errAESBlockSize)
|
||||
}
|
||||
|
||||
result, err = EncryptConfigFile([]byte("test"), []byte("key"))
|
||||
@@ -86,14 +86,14 @@ func TestDecryptConfigFile(t *testing.T) {
|
||||
|
||||
func TestConfirmConfigJSON(t *testing.T) {
|
||||
var result interface{}
|
||||
testConfirmJSON, err := ioutil.ReadFile(ConfigTestFile)
|
||||
testConfirmJSON, err := ioutil.ReadFile(TestFile)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed. testConfirmJSON: %s", err)
|
||||
t.Errorf("testConfirmJSON: %s", err)
|
||||
}
|
||||
|
||||
err = ConfirmConfigJSON(testConfirmJSON, &result)
|
||||
if err != nil || result == nil {
|
||||
t.Errorf("Test failed. testConfirmJSON: %s", err)
|
||||
t.Errorf("testConfirmJSON: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func TestConfirmECS(t *testing.T) {
|
||||
|
||||
ECStest := []byte(EncryptConfirmString)
|
||||
if !ConfirmECS(ECStest) {
|
||||
t.Errorf("Test failed. TestConfirmECS: Error finding ECS.")
|
||||
t.Errorf("TestConfirmECS: Error finding ECS.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ func TestRemoveECS(t *testing.T) {
|
||||
isremoved := RemoveECS(ECStest)
|
||||
|
||||
if string(isremoved) != "" {
|
||||
t.Errorf("Test failed. TestConfirmECS: Error ECS not deleted.")
|
||||
t.Errorf("TestConfirmECS: Error ECS not deleted.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,6 @@ func TestMakeNewSessionDK(t *testing.T) {
|
||||
|
||||
_, err := makeNewSessionDK(nil)
|
||||
if err == nil {
|
||||
t.Fatal("Test failed. makeNewSessionDK passed with nil key")
|
||||
t.Fatal("makeNewSessionDK passed with nil key")
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,15 +3,77 @@ package config
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency/forexprovider/base"
|
||||
"github.com/thrasher-corp/gocryptotrader/database"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/protocol"
|
||||
log "github.com/thrasher-corp/gocryptotrader/logger"
|
||||
"github.com/thrasher-corp/gocryptotrader/portfolio"
|
||||
)
|
||||
|
||||
// Constants declared here are filename strings and test strings
|
||||
const (
|
||||
FXProviderFixer = "fixer"
|
||||
EncryptedFile = "config.dat"
|
||||
File = "config.json"
|
||||
TestFile = "../testdata/configtest.json"
|
||||
fileEncryptionPrompt = 0
|
||||
fileEncryptionEnabled = 1
|
||||
fileEncryptionDisabled = -1
|
||||
pairsLastUpdatedWarningThreshold = 30 // 30 days
|
||||
defaultHTTPTimeout = time.Second * 15
|
||||
defaultWebsocketResponseCheckTimeout = time.Millisecond * 30
|
||||
defaultWebsocketResponseMaxLimit = time.Second * 7
|
||||
defaultWebsocketOrderbookBufferLimit = 5
|
||||
defaultWebsocketTrafficTimeout = time.Second * 30
|
||||
maxAuthFailures = 3
|
||||
defaultNTPAllowedDifference = 50000000
|
||||
defaultNTPAllowedNegativeDifference = 50000000
|
||||
DefaultAPIKey = "Key"
|
||||
DefaultAPISecret = "Secret"
|
||||
DefaultAPIClientID = "ClientID"
|
||||
)
|
||||
|
||||
// Constants here hold some messages
|
||||
const (
|
||||
ErrExchangeNameEmpty = "exchange #%d name is empty"
|
||||
ErrExchangeAvailablePairsEmpty = "exchange %s available pairs is empty"
|
||||
ErrExchangeEnabledPairsEmpty = "exchange %s enabled pairs is empty"
|
||||
ErrExchangeBaseCurrenciesEmpty = "exchange %s base currencies is empty"
|
||||
ErrExchangeNotFound = "exchange %s not found"
|
||||
ErrNoEnabledExchanges = "no exchanges enabled"
|
||||
ErrCryptocurrenciesEmpty = "cryptocurrencies variable is empty"
|
||||
ErrFailureOpeningConfig = "fatal error opening %s file. Error: %s"
|
||||
ErrCheckingConfigValues = "fatal error checking config values. Error: %s"
|
||||
ErrSavingConfigBytesMismatch = "config file %q bytes comparison doesn't match, read %s expected %s"
|
||||
WarningWebserverCredentialValuesEmpty = "webserver support disabled due to empty Username/Password values"
|
||||
WarningWebserverListenAddressInvalid = "webserver support disabled due to invalid listen address"
|
||||
WarningExchangeAuthAPIDefaultOrEmptyValues = "exchange %s authenticated API support disabled due to default/empty APIKey/Secret/ClientID values"
|
||||
WarningPairsLastUpdatedThresholdExceeded = "exchange %s last manual update of available currency pairs has exceeded %d days. Manual update required!"
|
||||
)
|
||||
|
||||
// Constants here define unset default values displayed in the config.json
|
||||
// file
|
||||
const (
|
||||
APIURLNonDefaultMessage = "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API"
|
||||
WebsocketURLNonDefaultMessage = "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API"
|
||||
DefaultUnsetAPIKey = "Key"
|
||||
DefaultUnsetAPISecret = "Secret"
|
||||
DefaultUnsetAccountPlan = "accountPlan"
|
||||
DefaultForexProviderExchangeRatesAPI = "ExchangeRates"
|
||||
)
|
||||
|
||||
// Variables here are used for configuration
|
||||
var (
|
||||
Cfg Config
|
||||
IsInitialSetup bool
|
||||
testBypass bool
|
||||
m sync.Mutex
|
||||
)
|
||||
|
||||
// Config is the overarching object that holds all the information for
|
||||
// prestart management of Portfolio, Communications, Webserver and Enabled
|
||||
// Exchanges
|
||||
@@ -313,39 +375,12 @@ type TelegramConfig struct {
|
||||
VerificationToken string `json:"verificationToken"`
|
||||
}
|
||||
|
||||
// ProtocolFeaturesConfig holds all variables for the exchanges supported features
|
||||
// for a protocol (e.g REST or Websocket)
|
||||
type ProtocolFeaturesConfig struct {
|
||||
TickerBatching bool `json:"tickerBatching,omitempty"`
|
||||
AutoPairUpdates bool `json:"autoPairUpdates,omitempty"`
|
||||
AccountBalance bool `json:"accountBalance,omitempty"`
|
||||
CryptoDeposit bool `json:"cryptoDeposit,omitempty"`
|
||||
CryptoWithdrawal uint32 `json:"cryptoWithdrawal,omitempty"`
|
||||
FiatWithdraw bool `json:"fiatWithdraw,omitempty"`
|
||||
GetOrder bool `json:"getOrder,omitempty"`
|
||||
GetOrders bool `json:"getOrders,omitempty"`
|
||||
CancelOrders bool `json:"cancelOrders,omitempty"`
|
||||
CancelOrder bool `json:"cancelOrder,omitempty"`
|
||||
SubmitOrder bool `json:"submitOrder,omitempty"`
|
||||
SubmitOrders bool `json:"submitOrders,omitempty"`
|
||||
ModifyOrder bool `json:"modifyOrder,omitempty"`
|
||||
DepositHistory bool `json:"depositHistory,omitempty"`
|
||||
WithdrawalHistory bool `json:"withdrawalHistory,omitempty"`
|
||||
TradeHistory bool `json:"tradeHistory,omitempty"`
|
||||
UserTradeHistory bool `json:"userTradeHistory,omitempty"`
|
||||
TradeFee bool `json:"tradeFee,omitempty"`
|
||||
FiatDepositFee bool `json:"fiatDepositFee,omitempty"`
|
||||
FiatWithdrawalFee bool `json:"fiatWithdrawalFee,omitempty"`
|
||||
CryptoDepositFee bool `json:"cryptoDepositFee,omitempty"`
|
||||
CryptoWithdrawalFee bool `json:"cryptoWithdrawalFee,omitempty"`
|
||||
}
|
||||
|
||||
// FeaturesSupportedConfig stores the exchanges supported features
|
||||
type FeaturesSupportedConfig struct {
|
||||
REST bool `json:"restAPI"`
|
||||
RESTCapabilities ProtocolFeaturesConfig `json:"restCapabilities,omitempty"`
|
||||
Websocket bool `json:"websocketAPI"`
|
||||
WebsocketCapabilities ProtocolFeaturesConfig `json:"websocketCapabilities,omitempty"`
|
||||
REST bool `json:"restAPI"`
|
||||
RESTCapabilities protocol.Features `json:"restCapabilities,omitempty"`
|
||||
Websocket bool `json:"websocketAPI"`
|
||||
WebsocketCapabilities protocol.Features `json:"websocketCapabilities,omitempty"`
|
||||
}
|
||||
|
||||
// FeaturesEnabledConfig stores the exchanges enabled features
|
||||
|
||||
Reference in New Issue
Block a user