Feature: Add support to check whether an exchange supports automatic 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
This commit is contained in:
Adrian Gallagher
2018-03-27 12:53:46 +11:00
parent 2d0cb20c69
commit 52dfddbb18
31 changed files with 390 additions and 30 deletions

View File

@@ -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

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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()
}
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -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
@@ -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)
}
}
}

View File

@@ -60,6 +60,8 @@ type Base struct {
AvailablePairs []string
EnabledPairs []string
AssetTypes []string
PairsLastUpdated int64
SupportsAutoPairUpdating bool
WebsocketURL string
APIUrl string
RequestCurrencyPairFormat config.CurrencyPairFormatConfig
@@ -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,

View File

@@ -2,6 +2,7 @@ package exchange
import (
"testing"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
@@ -9,6 +10,105 @@ import (
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
func TestSetAutoPairDefaults(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults failed to load config file. Error: %s", err)
}
b := Base{
Name: "TESTNAME",
SupportsAutoPairUpdating: true,
}
err = b.SetAutoPairDefaults()
if err == nil {
t.Fatal("Test failed. TestSetAutoPairDefaults returned nil error for a non-existent exchange")
}
b.Name = "Bitstamp"
err = b.SetAutoPairDefaults()
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults. Error %s", err)
}
exch, err := cfg.GetExchangeConfig(b.Name)
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults load config failed. Error %s", err)
}
if !exch.SupportsAutoPairUpdates {
t.Fatalf("Test failed. TestSetAutoPairDefaults Incorrect value")
}
if exch.PairsLastUpdated != 0 {
t.Fatalf("Test failed. TestSetAutoPairDefaults Incorrect value")
}
exch.SupportsAutoPairUpdates = false
err = cfg.UpdateExchangeConfig(exch)
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults update config failed. Error %s", err)
}
exch, err = cfg.GetExchangeConfig(b.Name)
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults load config failed. Error %s", err)
}
if exch.SupportsAutoPairUpdates != false {
t.Fatal("Test failed. TestSetAutoPairDefaults Incorrect value")
}
err = b.SetAutoPairDefaults()
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults. Error %s", err)
}
exch, err = cfg.GetExchangeConfig(b.Name)
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults load config failed. Error %s", err)
}
if exch.SupportsAutoPairUpdates == false {
t.Fatal("Test failed. TestSetAutoPairDefaults Incorrect value")
}
b.SupportsAutoPairUpdating = false
err = b.SetAutoPairDefaults()
if err != nil {
t.Fatalf("Test failed. TestSetAutoPairDefaults. Error %s", err)
}
if b.PairsLastUpdated == 0 {
t.Fatal("Test failed. TestSetAutoPairDefaults Incorrect value")
}
}
func TestSupportsAutoPairUpdates(t *testing.T) {
b := Base{
Name: "TESTNAME",
SupportsAutoPairUpdating: false,
}
if b.SupportsAutoPairUpdates() {
t.Fatal("Test failed. TestSupportsAutoPairUpdates Incorrect value")
}
}
func TestGetLastPairsUpdateTime(t *testing.T) {
testTime := time.Now().Unix()
b := Base{
Name: "TESTNAME",
PairsLastUpdated: testTime,
}
if b.GetLastPairsUpdateTime() != testTime {
t.Fatal("Test failed. TestGetLastPairsUpdateTim Incorrect value")
}
}
func TestSetAssetTypes(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)

View File

@@ -61,6 +61,7 @@ func (e *EXMO) SetDefaults() {
e.ConfigCurrencyPairFormat.Delimiter = "_"
e.ConfigCurrencyPairFormat.Uppercase = true
e.AssetTypes = []string{ticker.Spot}
e.SupportsAutoPairUpdating = true
}
// Setup takes in the supplied exchange configuration details and sets params
@@ -85,6 +86,10 @@ func (e *EXMO) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = e.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -70,6 +70,7 @@ func (g *GDAX) SetDefaults() {
g.ConfigCurrencyPairFormat.Uppercase = true
g.AssetTypes = []string{ticker.Spot}
g.APIUrl = gdaxAPIURL
g.SupportsAutoPairUpdating = true
}
// Setup initialises the exchange parameters with the current configuration
@@ -97,6 +98,10 @@ func (g *GDAX) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = g.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -109,6 +109,7 @@ func (g *Gemini) SetDefaults() {
g.ConfigCurrencyPairFormat.Delimiter = ""
g.ConfigCurrencyPairFormat.Uppercase = true
g.AssetTypes = []string{ticker.Spot}
g.SupportsAutoPairUpdating = true
}
// Setup sets exchange configuration parameters
@@ -138,6 +139,10 @@ func (g *Gemini) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = g.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -59,6 +59,7 @@ func (p *HitBTC) SetDefaults() {
p.ConfigCurrencyPairFormat.Delimiter = "-"
p.ConfigCurrencyPairFormat.Uppercase = true
p.AssetTypes = []string{ticker.Spot}
p.SupportsAutoPairUpdating = true
}
// Setup sets user exchange configuration settings
@@ -83,6 +84,10 @@ func (p *HitBTC) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = p.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -65,6 +65,7 @@ func (h *HUOBI) SetDefaults() {
h.ConfigCurrencyPairFormat.Delimiter = "-"
h.ConfigCurrencyPairFormat.Uppercase = true
h.AssetTypes = []string{ticker.Spot}
h.SupportsAutoPairUpdating = true
}
// Setup sets user configuration
@@ -89,6 +90,10 @@ func (h *HUOBI) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = h.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -49,6 +49,7 @@ func (i *ItBit) SetDefaults() {
i.ConfigCurrencyPairFormat.Delimiter = ""
i.ConfigCurrencyPairFormat.Uppercase = true
i.AssetTypes = []string{ticker.Spot}
i.SupportsAutoPairUpdating = false
}
// Setup sets the exchange parameters from exchange config
@@ -73,6 +74,10 @@ func (i *ItBit) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = i.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -63,6 +63,7 @@ func (k *Kraken) SetDefaults() {
k.ConfigCurrencyPairFormat.Delimiter = "-"
k.ConfigCurrencyPairFormat.Uppercase = true
k.AssetTypes = []string{ticker.Spot}
k.SupportsAutoPairUpdating = true
}
// Setup sets current exchange configuration
@@ -87,6 +88,10 @@ func (k *Kraken) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = k.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -50,6 +50,7 @@ func (l *LakeBTC) SetDefaults() {
l.ConfigCurrencyPairFormat.Delimiter = ""
l.ConfigCurrencyPairFormat.Uppercase = true
l.AssetTypes = []string{ticker.Spot}
l.SupportsAutoPairUpdating = false
}
// Setup sets exchange configuration profile
@@ -74,6 +75,10 @@ func (l *LakeBTC) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = l.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -55,6 +55,7 @@ func (l *Liqui) SetDefaults() {
l.ConfigCurrencyPairFormat.Delimiter = "_"
l.ConfigCurrencyPairFormat.Uppercase = true
l.AssetTypes = []string{ticker.Spot}
l.SupportsAutoPairUpdating = true
}
// Setup sets exchange configuration parameters for liqui
@@ -79,6 +80,10 @@ func (l *Liqui) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = l.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -118,6 +118,7 @@ func (l *LocalBitcoins) SetDefaults() {
l.RequestCurrencyPairFormat.Uppercase = true
l.ConfigCurrencyPairFormat.Delimiter = ""
l.ConfigCurrencyPairFormat.Uppercase = true
l.SupportsAutoPairUpdating = false
}
// Setup sets exchange configuration parameters
@@ -138,6 +139,10 @@ func (l *LocalBitcoins) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = l.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -98,6 +98,7 @@ func (o *OKCoin) SetDefaults() {
o.RESTPollingDelay = 10
o.FuturesValues = []string{"this_week", "next_week", "quarter"}
o.AssetTypes = []string{ticker.Spot}
o.SupportsAutoPairUpdating = false
if okcoinDefaultsSet {
o.AssetTypes = append(o.AssetTypes, o.FuturesValues...)
@@ -136,6 +137,10 @@ func (o *OKCoin) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = o.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -97,6 +97,7 @@ func (o *OKEX) SetDefaults() {
o.RequestCurrencyPairFormat.Uppercase = false
o.ConfigCurrencyPairFormat.Delimiter = "_"
o.ConfigCurrencyPairFormat.Uppercase = false
o.SupportsAutoPairUpdating = false
}
// Setup method sets current configuration details if enabled
@@ -121,6 +122,10 @@ func (o *OKEX) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = o.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -66,6 +66,7 @@ func (p *Poloniex) SetDefaults() {
p.ConfigCurrencyPairFormat.Delimiter = "_"
p.ConfigCurrencyPairFormat.Uppercase = true
p.AssetTypes = []string{ticker.Spot}
p.SupportsAutoPairUpdating = true
}
// Setup sets user exchange configuration settings
@@ -90,6 +91,10 @@ func (p *Poloniex) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = p.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -58,6 +58,7 @@ func (w *WEX) SetDefaults() {
w.ConfigCurrencyPairFormat.Delimiter = ""
w.ConfigCurrencyPairFormat.Uppercase = true
w.AssetTypes = []string{ticker.Spot}
w.SupportsAutoPairUpdating = false
}
// Setup sets exchange configuration parameters for WEX
@@ -82,6 +83,10 @@ func (w *WEX) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = w.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}

View File

@@ -58,6 +58,7 @@ func (y *Yobit) SetDefaults() {
y.ConfigCurrencyPairFormat.Delimiter = "_"
y.ConfigCurrencyPairFormat.Uppercase = true
y.AssetTypes = []string{ticker.Spot}
y.SupportsAutoPairUpdating = false
}
// Setup sets exchange configuration parameters for Yobit
@@ -82,6 +83,10 @@ func (y *Yobit) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = y.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
}
}