Skip to content

Commit

Permalink
Feature: Add support to check whether an exchange supports automatic …
Browse files Browse the repository at this point in the history
…currency pair updates and if they don't, show a warning if the last currency pair update is >= 30 days

Also fix race condition in config get/set functions
  • Loading branch information
thrasher- committed Mar 27, 2018
1 parent 2d0cb20 commit 52dfddb
Show file tree
Hide file tree
Showing 31 changed files with 390 additions and 30 deletions.
31 changes: 23 additions & 8 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"log"
"os"
"strconv"
"sync"
"time"

"github.com/thrasher-/gocryptotrader/common"
Expand All @@ -19,12 +20,13 @@ import (

// Constants declared here are filename strings and test strings
const (
EncryptedConfigFile = "config.dat"
ConfigFile = "config.json"
ConfigTestFile = "../testdata/configtest.json"
configFileEncryptionPrompt = 0
configFileEncryptionEnabled = 1
configFileEncryptionDisabled = -1
EncryptedConfigFile = "config.dat"
ConfigFile = "config.json"
ConfigTestFile = "../testdata/configtest.json"
configFileEncryptionPrompt = 0
configFileEncryptionEnabled = 1
configFileEncryptionDisabled = -1
configPairsLastUpdatedWarningThreshold = 30 // 30 days
)

// Variables here are mainly alerts and a configuration object
Expand All @@ -47,6 +49,7 @@ var (
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."
WarningPairsLastUpdatedThresholdExceeded = "WARNING -- Exchange %s: Last manual update of available currency pairs has exceeded %d days. Manual update required!"
Cfg Config
)

Expand Down Expand Up @@ -95,6 +98,7 @@ type Config struct {
SMS SMSGlobalConfig `json:"SMSGlobal"`
Webserver WebserverConfig `json:"Webserver"`
Exchanges []ExchangeConfig `json:"Exchanges"`
m sync.Mutex
}

// ExchangeConfig holds all the information needed for each enabled Exchange.
Expand All @@ -113,6 +117,8 @@ type ExchangeConfig struct {
EnabledPairs string
BaseCurrencies string
AssetTypes string
SupportsAutoPairUpdates bool
PairsLastUpdated int64 `json:",omitempty"`
ConfigCurrencyPairFormat *CurrencyPairFormatConfig `json:"ConfigCurrencyPairFormat"`
RequestCurrencyPairFormat *CurrencyPairFormatConfig `json:"RequestCurrencyPairFormat"`
}
Expand Down Expand Up @@ -213,6 +219,8 @@ func (c *Config) GetCurrencyPairDisplayConfig() *CurrencyPairFormatConfig {

// GetExchangeConfig returns your exchange configurations by its indivdual name
func (c *Config) GetExchangeConfig(name string) (ExchangeConfig, error) {
c.m.Lock()
defer c.m.Unlock()
for i := range c.Exchanges {
if c.Exchanges[i].Name == name {
return c.Exchanges[i], nil
Expand All @@ -223,6 +231,8 @@ func (c *Config) GetExchangeConfig(name string) (ExchangeConfig, error) {

// UpdateExchangeConfig updates exchange configurations
func (c *Config) UpdateExchangeConfig(e ExchangeConfig) error {
c.m.Lock()
defer c.m.Unlock()
for i := range c.Exchanges {
if c.Exchanges[i].Name == e.Name {
c.Exchanges[i] = e
Expand Down Expand Up @@ -279,15 +289,20 @@ func (c *Config) CheckExchangeConfigValues() error {
if exch.APIKey == "" || exch.APISecret == "" || exch.APIKey == "Key" || exch.APISecret == "Secret" {
c.Exchanges[i].AuthenticatedAPISupport = false
log.Printf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
continue
} else if exch.Name == "ITBIT" || exch.Name == "Bitstamp" || exch.Name == "COINUT" || exch.Name == "GDAX" {
if exch.ClientID == "" || exch.ClientID == "ClientID" {
c.Exchanges[i].AuthenticatedAPISupport = false
log.Printf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
continue
}
}
}
if !exch.SupportsAutoPairUpdates {
lastUpdated := common.UnixTimestampToTime(exch.PairsLastUpdated)
lastUpdated.AddDate(0, 0, configPairsLastUpdatedWarningThreshold)
if lastUpdated.Unix() >= time.Now().Unix() {
log.Printf(WarningPairsLastUpdatedThresholdExceeded, exch.Name, configPairsLastUpdatedWarningThreshold)
}
}
exchanges++
}
}
Expand Down
59 changes: 48 additions & 11 deletions config_example.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions exchanges/alphapoint/alphapoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (a *Alphapoint) SetDefaults() {
a.APIUrl = alphapointDefaultAPIURL
a.WebsocketURL = alphapointDefaultWebsocketURL
a.AssetTypes = []string{ticker.Spot}
a.SupportsAutoPairUpdating = false
}

// GetTicker returns current ticker information from Alphapoint for a selected
Expand Down
5 changes: 5 additions & 0 deletions exchanges/anx/anx.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (a *ANX) SetDefaults() {
a.ConfigCurrencyPairFormat.Uppercase = true
a.ConfigCurrencyPairFormat.Index = "BTC"
a.AssetTypes = []string{ticker.Spot}
a.SupportsAutoPairUpdating = false
}

//Setup is run on startup to setup exchange with config values
Expand All @@ -74,6 +75,10 @@ func (a *ANX) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = a.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/binance/binance.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func (b *Binance) SetDefaults() {
b.ConfigCurrencyPairFormat.Delimiter = "-"
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = true
b.SetValues()
}

Expand All @@ -82,6 +83,10 @@ func (b *Binance) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/bitfinex/bitfinex.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func (b *Bitfinex) SetDefaults() {
b.ConfigCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = true
}

// Setup takes in the supplied exchange configuration details and sets params
Expand All @@ -124,6 +125,10 @@ func (b *Bitfinex) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/bitflyer/bitflyer.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func (b *Bitflyer) SetDefaults() {
b.ConfigCurrencyPairFormat.Delimiter = "_"
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = false
}

// Setup takes in the supplied exchange configuration details and sets params
Expand All @@ -107,6 +108,10 @@ func (b *Bitflyer) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/bithumb/bithumb.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func (b *Bithumb) SetDefaults() {
b.ConfigCurrencyPairFormat.Uppercase = true
b.ConfigCurrencyPairFormat.Index = "KRW"
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = false
}

// Setup takes in the supplied exchange configuration details and sets params
Expand All @@ -88,6 +89,10 @@ func (b *Bithumb) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/bitstamp/bitstamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func (b *Bitstamp) SetDefaults() {
b.ConfigCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = true
}

// Setup sets configuration values to bitstamp
Expand All @@ -91,6 +92,10 @@ func (b *Bitstamp) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/bittrex/bittrex.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func (b *Bittrex) SetDefaults() {
b.ConfigCurrencyPairFormat.Delimiter = "-"
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = true
}

// Setup method sets current configuration details if enabled
Expand All @@ -96,6 +97,10 @@ func (b *Bittrex) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/btcc/btcc.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func (b *BTCC) SetDefaults() {
b.ConfigCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = true
}

// Setup is run on startup to setup exchange with config values
Expand All @@ -85,6 +86,10 @@ func (b *BTCC) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/btcmarkets/btcmarkets.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (b *BTCMarkets) SetDefaults() {
b.ConfigCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = true
}

// Setup takes in an exchange configuration and sets all parameters
Expand All @@ -82,6 +83,10 @@ func (b *BTCMarkets) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = b.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions exchanges/coinut/coinut.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func (c *COINUT) SetDefaults() {
c.ConfigCurrencyPairFormat.Delimiter = ""
c.ConfigCurrencyPairFormat.Uppercase = true
c.AssetTypes = []string{ticker.Spot}
c.SupportsAutoPairUpdating = true
}

// Setup sets the current exchange configuration
Expand All @@ -80,6 +81,10 @@ func (c *COINUT) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = c.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
45 changes: 45 additions & 0 deletions exchanges/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ type Base struct {
AvailablePairs []string
EnabledPairs []string
AssetTypes []string
PairsLastUpdated int64
SupportsAutoPairUpdating bool
WebsocketURL string
APIUrl string
RequestCurrencyPairFormat config.CurrencyPairFormatConfig
Expand All @@ -85,6 +87,49 @@ type IBotExchange interface {
GetAuthenticatedAPISupport() bool
SetCurrencies(pairs []pair.CurrencyPair, enabledPairs bool) error
GetExchangeHistory(pair.CurrencyPair, string) ([]TradeHistory, error)
SupportsAutoPairUpdates() bool
GetLastPairsUpdateTime() int64
}

// SetAutoPairDefaults sets the default values for whether or not the exchange
// supports auto pair updating or not
func (e *Base) SetAutoPairDefaults() error {
cfg := config.GetConfig()
exch, err := cfg.GetExchangeConfig(e.Name)
if err != nil {
return err
}

update := false
if e.SupportsAutoPairUpdating {
if !exch.SupportsAutoPairUpdates {
exch.SupportsAutoPairUpdates = true
update = true
}
} else {
if exch.PairsLastUpdated == 0 {
exch.PairsLastUpdated = time.Now().Unix()
e.PairsLastUpdated = exch.PairsLastUpdated
update = true
}
}

if update {
return cfg.UpdateExchangeConfig(exch)
}
return nil
}

// SupportsAutoPairUpdates returns whether or not the exchange supports
// auto currency pair updating
func (e *Base) SupportsAutoPairUpdates() bool {
return e.SupportsAutoPairUpdating
}

// GetLastPairsUpdateTime returns the unix timestamp of when the exchanges
// currency pairs were last updated
func (e *Base) GetLastPairsUpdateTime() int64 {
return e.PairsLastUpdated
}

// SetAssetTypes checks the exchange asset types (whether it supports SPOT,
Expand Down
Loading

0 comments on commit 52dfddb

Please sign in to comment.