mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
Add dynamic loading/unloading and reloading of exchanges
This commit is contained in:
224
exchange.go
Normal file
224
exchange.go
Normal file
@@ -0,0 +1,224 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/anx"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/bitfinex"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/bitstamp"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/bittrex"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/btcc"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/btcmarkets"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/coinut"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/gdax"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/huobi"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/itbit"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/kraken"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/lakebtc"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/liqui"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/localbitcoins"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/okcoin"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/poloniex"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/wex"
|
||||
)
|
||||
|
||||
// vars related to exchange functions
|
||||
var (
|
||||
ErrNoExchangesLoaded = errors.New("no exchanges have been loaded")
|
||||
ErrExchangeNotFound = errors.New("exchange not found")
|
||||
ErrExchangeAlreadyLoaded = errors.New("exchange already loaded")
|
||||
ErrExchangeFailedToLoad = errors.New("exchange failed to load")
|
||||
)
|
||||
|
||||
// CheckExchangeExists returns true whether or not an exchange has already
|
||||
// been loaded
|
||||
func CheckExchangeExists(exchName string) bool {
|
||||
for x := range bot.exchanges {
|
||||
if common.StringToLower(bot.exchanges[x].GetName()) == common.StringToLower(exchName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetExchangeByName returns an exchange given an exchange name
|
||||
func GetExchangeByName(exchName string) exchange.IBotExchange {
|
||||
for x := range bot.exchanges {
|
||||
if common.StringToLower(bot.exchanges[x].GetName()) == common.StringToLower(exchName) {
|
||||
return bot.exchanges[x]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReloadExchange loads an exchange config by name
|
||||
func ReloadExchange(name string) error {
|
||||
nameLower := common.StringToLower(name)
|
||||
|
||||
if len(bot.exchanges) == 0 {
|
||||
return ErrNoExchangesLoaded
|
||||
}
|
||||
|
||||
if !CheckExchangeExists(nameLower) {
|
||||
return ErrExchangeNotFound
|
||||
}
|
||||
|
||||
exchCfg, err := bot.config.GetExchangeConfig(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e := GetExchangeByName(nameLower)
|
||||
e.Setup(exchCfg)
|
||||
log.Printf("%s exchange reloaded successfully.\n", name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnloadExchange unloads an exchange by
|
||||
func UnloadExchange(name string) error {
|
||||
nameLower := common.StringToLower(name)
|
||||
|
||||
if len(bot.exchanges) == 0 {
|
||||
return ErrNoExchangesLoaded
|
||||
}
|
||||
|
||||
if !CheckExchangeExists(nameLower) {
|
||||
return ErrExchangeNotFound
|
||||
}
|
||||
|
||||
exchCfg, err := bot.config.GetExchangeConfig(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exchCfg.Enabled = false
|
||||
err = bot.config.UpdateExchangeConfig(exchCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for x := range bot.exchanges {
|
||||
if bot.exchanges[x].GetName() == name {
|
||||
bot.exchanges[x].SetEnabled(false)
|
||||
bot.exchanges = append(bot.exchanges[:x], bot.exchanges[x+1:]...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return ErrExchangeNotFound
|
||||
}
|
||||
|
||||
// LoadExchange loads an exchange by name
|
||||
func LoadExchange(name string) error {
|
||||
nameLower := common.StringToLower(name)
|
||||
var exch exchange.IBotExchange
|
||||
|
||||
if len(bot.exchanges) > 0 {
|
||||
if CheckExchangeExists(nameLower) {
|
||||
return ErrExchangeAlreadyLoaded
|
||||
}
|
||||
}
|
||||
|
||||
switch nameLower {
|
||||
case "anx":
|
||||
exch = new(anx.ANX)
|
||||
case "bitfinex":
|
||||
exch = new(bitfinex.Bitfinex)
|
||||
case "bitstamp":
|
||||
exch = new(bitstamp.Bitstamp)
|
||||
case "bittrex":
|
||||
exch = new(bittrex.Bittrex)
|
||||
case "btcc":
|
||||
exch = new(btcc.BTCC)
|
||||
case "btc markets":
|
||||
exch = new(btcmarkets.BTCMarkets)
|
||||
case "coinut":
|
||||
exch = new(coinut.COINUT)
|
||||
case "gdax":
|
||||
exch = new(gdax.GDAX)
|
||||
case "gemini":
|
||||
exch = new(gdax.GDAX)
|
||||
case "huobi":
|
||||
exch = new(huobi.HUOBI)
|
||||
case "itbit":
|
||||
exch = new(itbit.ItBit)
|
||||
case "kraken":
|
||||
exch = new(kraken.Kraken)
|
||||
case "lakebtc":
|
||||
exch = new(lakebtc.LakeBTC)
|
||||
case "liqui":
|
||||
exch = new(liqui.Liqui)
|
||||
case "localbitcoins":
|
||||
exch = new(localbitcoins.LocalBitcoins)
|
||||
case "okcoin china":
|
||||
exch = new(okcoin.OKCoin)
|
||||
case "okcoin international":
|
||||
exch = new(okcoin.OKCoin)
|
||||
case "poloniex":
|
||||
exch = new(poloniex.Poloniex)
|
||||
case "wex":
|
||||
exch = new(wex.WEX)
|
||||
default:
|
||||
return ErrExchangeNotFound
|
||||
}
|
||||
|
||||
if exch == nil {
|
||||
return ErrExchangeFailedToLoad
|
||||
}
|
||||
|
||||
exch.SetDefaults()
|
||||
bot.exchanges = append(bot.exchanges, exch)
|
||||
exchCfg, err := bot.config.GetExchangeConfig(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exchCfg.Enabled = true
|
||||
exch.Setup(exchCfg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupExchanges sets up the exchanges used by the bot
|
||||
func SetupExchanges() {
|
||||
for _, exch := range bot.config.Exchanges {
|
||||
if CheckExchangeExists(exch.Name) {
|
||||
e := GetExchangeByName(exch.Name)
|
||||
if e == nil {
|
||||
log.Println(ErrExchangeNotFound)
|
||||
continue
|
||||
}
|
||||
|
||||
err := ReloadExchange(exch.Name)
|
||||
if err != nil {
|
||||
log.Printf("ReloadExchange %s failed: %s", exch.Name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !e.IsEnabled() {
|
||||
UnloadExchange(exch.Name)
|
||||
continue
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
if !exch.Enabled {
|
||||
log.Printf("%s: Exchange support: Disabled", exch.Name)
|
||||
continue
|
||||
} else {
|
||||
err := LoadExchange(exch.Name)
|
||||
if err != nil {
|
||||
log.Printf("LoadExchange %s failed: %s", exch.Name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
log.Printf(
|
||||
"%s: Exchange support: Enabled (Authenticated API support: %s - Verbose mode: %s).\n",
|
||||
exch.Name,
|
||||
common.IsEnabled(exch.AuthenticatedAPISupport),
|
||||
common.IsEnabled(exch.Verbose),
|
||||
)
|
||||
}
|
||||
}
|
||||
138
exchange_test.go
Normal file
138
exchange_test.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
)
|
||||
|
||||
var testSetup = false
|
||||
|
||||
func SetupTest(t *testing.T) {
|
||||
if !testSetup {
|
||||
bot.config = &config.Cfg
|
||||
err := bot.config.LoadConfig("./testdata/configtest.json")
|
||||
if err != nil {
|
||||
t.Fatalf("Test failed. SetupTest: Failed to load config: %s", err)
|
||||
}
|
||||
testSetup = true
|
||||
}
|
||||
|
||||
if CheckExchangeExists("Bitfinex") {
|
||||
return
|
||||
}
|
||||
err := LoadExchange("Bitfinex")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed. SetupTest: Failed to load exchange: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func CleanupTest(t *testing.T) {
|
||||
if !CheckExchangeExists("Bitfinex") {
|
||||
return
|
||||
}
|
||||
|
||||
err := UnloadExchange("Bitfinex")
|
||||
if err != nil {
|
||||
t.Fatalf("Test failed. CleanupTest: Failed to unload exchange: %s",
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckExchangeExists(t *testing.T) {
|
||||
SetupTest(t)
|
||||
|
||||
if !CheckExchangeExists("Bitfinex") {
|
||||
t.Errorf("Test failed. TestGetExchangeExists: Unable to find exchange")
|
||||
}
|
||||
|
||||
if CheckExchangeExists("Asdsad") {
|
||||
t.Errorf("Test failed. TestGetExchangeExists: Non-existant exchange found")
|
||||
}
|
||||
|
||||
CleanupTest(t)
|
||||
}
|
||||
|
||||
func TestGetExchangeByName(t *testing.T) {
|
||||
SetupTest(t)
|
||||
|
||||
exch := GetExchangeByName("Bitfinex")
|
||||
if exch == nil {
|
||||
t.Errorf("Test failed. TestGetExchangeByName: Failed to get exchange")
|
||||
}
|
||||
|
||||
if !exch.IsEnabled() {
|
||||
t.Errorf("Test failed. TestGetExchangeByName: Unexpected result")
|
||||
}
|
||||
|
||||
exch.SetEnabled(false)
|
||||
bfx := GetExchangeByName("Bitfinex")
|
||||
if bfx.IsEnabled() {
|
||||
t.Errorf("Test failed. TestGetExchangeByName: Unexpected result")
|
||||
}
|
||||
|
||||
if exch.GetName() != "Bitfinex" {
|
||||
t.Errorf("Test failed. TestGetExchangeByName: Unexpected result")
|
||||
}
|
||||
|
||||
exch = GetExchangeByName("Asdasd")
|
||||
if exch != nil {
|
||||
t.Errorf("Test failed. TestGetExchangeByName: Non-existant exchange found")
|
||||
}
|
||||
|
||||
CleanupTest(t)
|
||||
}
|
||||
|
||||
func TestReloadExchange(t *testing.T) {
|
||||
SetupTest(t)
|
||||
|
||||
err := ReloadExchange("asdf")
|
||||
if err != ErrExchangeNotFound {
|
||||
t.Errorf("Test failed. TestReloadExchange: Incorrect result: %s",
|
||||
err)
|
||||
}
|
||||
|
||||
err = ReloadExchange("Bitfinex")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed. TestReloadExchange: Incorrect result: %s",
|
||||
err)
|
||||
}
|
||||
|
||||
CleanupTest(t)
|
||||
|
||||
err = ReloadExchange("asdf")
|
||||
if err != ErrNoExchangesLoaded {
|
||||
t.Errorf("Test failed. TestReloadExchange: Incorrect result: %s",
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnloadExchange(t *testing.T) {
|
||||
SetupTest(t)
|
||||
|
||||
err := UnloadExchange("asdf")
|
||||
if err != ErrExchangeNotFound {
|
||||
t.Errorf("Test failed. TestUnloadExchange: Incorrect result: %s",
|
||||
err)
|
||||
}
|
||||
|
||||
err = UnloadExchange("Bitfinex")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed. TestUnloadExchange: Failed to get exchange. %s",
|
||||
err)
|
||||
}
|
||||
|
||||
err = UnloadExchange("asdf")
|
||||
if err != ErrNoExchangesLoaded {
|
||||
t.Errorf("Test failed. TestUnloadExchange: Incorrect result: %s",
|
||||
err)
|
||||
}
|
||||
|
||||
CleanupTest(t)
|
||||
}
|
||||
|
||||
func TestSetupExchanges(t *testing.T) {
|
||||
SetupTest(t)
|
||||
SetupExchanges()
|
||||
CleanupTest(t)
|
||||
}
|
||||
@@ -64,6 +64,7 @@ type IBotExchange interface {
|
||||
SetDefaults()
|
||||
GetName() string
|
||||
IsEnabled() bool
|
||||
SetEnabled(bool)
|
||||
GetTickerPrice(currency pair.CurrencyPair, assetType string) (ticker.Price, error)
|
||||
UpdateTicker(currency pair.CurrencyPair, assetType string) (ticker.Price, error)
|
||||
GetOrderbookEx(currency pair.CurrencyPair, assetType string) (orderbook.Base, error)
|
||||
|
||||
@@ -96,7 +96,7 @@ func (o *OKCoin) SetDefaults() {
|
||||
o.FuturesValues = []string{"this_week", "next_week", "quarter"}
|
||||
o.AssetTypes = []string{ticker.Spot}
|
||||
|
||||
if !okcoinDefaultsSet {
|
||||
if okcoinDefaultsSet {
|
||||
o.AssetTypes = append(o.AssetTypes, o.FuturesValues...)
|
||||
o.APIUrl = OKCOIN_API_URL
|
||||
o.Name = "OKCOIN International"
|
||||
|
||||
27
helpers.go
27
helpers.go
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/translation"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
@@ -31,25 +30,15 @@ func GetRelatableCurrencies(p pair.CurrencyPair) []pair.CurrencyPair {
|
||||
return pairs
|
||||
}
|
||||
|
||||
// GetExchangeByName returns an exchange given an exchange name
|
||||
func GetExchangeByName(exchName string) exchange.IBotExchange {
|
||||
for x := range bot.exchanges {
|
||||
if common.StringToLower(bot.exchanges[x].GetName()) == common.StringToLower(exchName) {
|
||||
return bot.exchanges[x]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSpecificOrderbook returns a specific orderbook given the currency,
|
||||
// exchangeName and assetType
|
||||
func GetSpecificOrderbook(currency, exchangeName, assetType string) (orderbook.Base, error) {
|
||||
var specificOrderbook orderbook.Base
|
||||
var err error
|
||||
for i := 0; i < len(bot.exchanges); i++ {
|
||||
if bot.exchanges[i] != nil {
|
||||
if bot.exchanges[i].IsEnabled() && bot.exchanges[i].GetName() == exchangeName {
|
||||
specificOrderbook, err = bot.exchanges[i].GetOrderbookEx(
|
||||
for x := range bot.exchanges {
|
||||
if bot.exchanges[x] != nil {
|
||||
if bot.exchanges[x].GetName() == exchangeName {
|
||||
specificOrderbook, err = bot.exchanges[x].GetOrderbookEx(
|
||||
pair.NewCurrencyPairFromString(currency),
|
||||
assetType,
|
||||
)
|
||||
@@ -65,10 +54,10 @@ func GetSpecificOrderbook(currency, exchangeName, assetType string) (orderbook.B
|
||||
func GetSpecificTicker(currency, exchangeName, assetType string) (ticker.Price, error) {
|
||||
var specificTicker ticker.Price
|
||||
var err error
|
||||
for i := 0; i < len(bot.exchanges); i++ {
|
||||
if bot.exchanges[i] != nil {
|
||||
if bot.exchanges[i].IsEnabled() && bot.exchanges[i].GetName() == exchangeName {
|
||||
specificTicker, err = bot.exchanges[i].GetTickerPrice(
|
||||
for x := range bot.exchanges {
|
||||
if bot.exchanges[x] != nil {
|
||||
if bot.exchanges[x].GetName() == exchangeName {
|
||||
specificTicker, err = bot.exchanges[x].GetTickerPrice(
|
||||
pair.NewCurrencyPairFromString(currency),
|
||||
assetType,
|
||||
)
|
||||
|
||||
106
main.go
106
main.go
@@ -14,93 +14,23 @@ import (
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/anx"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/bitfinex"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/bitstamp"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/bittrex"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/btcc"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/btcmarkets"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/coinut"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/gdax"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/gemini"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/huobi"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/itbit"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/kraken"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/lakebtc"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/liqui"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/localbitcoins"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/okcoin"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/poloniex"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/wex"
|
||||
"github.com/thrasher-/gocryptotrader/portfolio"
|
||||
"github.com/thrasher-/gocryptotrader/smsglobal"
|
||||
)
|
||||
|
||||
// ExchangeMain contains all the necessary exchange packages
|
||||
type ExchangeMain struct {
|
||||
anx anx.ANX
|
||||
btcc btcc.BTCC
|
||||
bitstamp bitstamp.Bitstamp
|
||||
bitfinex bitfinex.Bitfinex
|
||||
bittrex bittrex.Bittrex
|
||||
wex wex.WEX
|
||||
btcmarkets btcmarkets.BTCMarkets
|
||||
coinut coinut.COINUT
|
||||
gdax gdax.GDAX
|
||||
gemini gemini.Gemini
|
||||
okcoinChina okcoin.OKCoin
|
||||
okcoinIntl okcoin.OKCoin
|
||||
itbit itbit.ItBit
|
||||
lakebtc lakebtc.LakeBTC
|
||||
liqui liqui.Liqui
|
||||
localbitcoins localbitcoins.LocalBitcoins
|
||||
poloniex poloniex.Poloniex
|
||||
huobi huobi.HUOBI
|
||||
kraken kraken.Kraken
|
||||
}
|
||||
|
||||
// Bot contains configuration, portfolio, exchange & ticker data and is the
|
||||
// overarching type across this code base.
|
||||
type Bot struct {
|
||||
config *config.Config
|
||||
smsglobal *smsglobal.Base
|
||||
portfolio *portfolio.Base
|
||||
exchange ExchangeMain
|
||||
exchanges []exchange.IBotExchange
|
||||
tickers []ticker.Ticker
|
||||
shutdown chan bool
|
||||
configFile string
|
||||
}
|
||||
|
||||
var bot Bot
|
||||
|
||||
func setupBotExchanges() {
|
||||
for _, exch := range bot.config.Exchanges {
|
||||
for i := 0; i < len(bot.exchanges); i++ {
|
||||
if bot.exchanges[i] != nil {
|
||||
if bot.exchanges[i].GetName() == exch.Name {
|
||||
bot.exchanges[i].Setup(exch)
|
||||
if bot.exchanges[i].IsEnabled() {
|
||||
log.Printf(
|
||||
"%s: Exchange support: %s (Authenticated API support: %s - Verbose mode: %s).\n",
|
||||
exch.Name, common.IsEnabled(exch.Enabled),
|
||||
common.IsEnabled(exch.AuthenticatedAPISupport),
|
||||
common.IsEnabled(exch.Verbose),
|
||||
)
|
||||
bot.exchanges[i].Start()
|
||||
} else {
|
||||
log.Printf(
|
||||
"%s: Exchange support: %s\n", exch.Name,
|
||||
common.IsEnabled(exch.Enabled),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
HandleInterrupt()
|
||||
|
||||
@@ -135,42 +65,12 @@ func main() {
|
||||
"Available Exchanges: %d. Enabled Exchanges: %d.\n",
|
||||
len(bot.config.Exchanges), bot.config.GetConfigEnabledExchanges(),
|
||||
)
|
||||
log.Println("Bot Exchange support:")
|
||||
|
||||
bot.exchanges = []exchange.IBotExchange{
|
||||
new(anx.ANX),
|
||||
new(kraken.Kraken),
|
||||
new(btcc.BTCC),
|
||||
new(bitstamp.Bitstamp),
|
||||
new(bitfinex.Bitfinex),
|
||||
new(bittrex.Bittrex),
|
||||
new(wex.WEX),
|
||||
new(btcmarkets.BTCMarkets),
|
||||
new(coinut.COINUT),
|
||||
new(gdax.GDAX),
|
||||
new(gemini.Gemini),
|
||||
new(okcoin.OKCoin),
|
||||
new(okcoin.OKCoin),
|
||||
new(itbit.ItBit),
|
||||
new(lakebtc.LakeBTC),
|
||||
new(liqui.Liqui),
|
||||
new(localbitcoins.LocalBitcoins),
|
||||
new(poloniex.Poloniex),
|
||||
new(huobi.HUOBI),
|
||||
SetupExchanges()
|
||||
if len(bot.exchanges) == 0 {
|
||||
log.Fatalf("No exchanges were able to be loaded. Exiting")
|
||||
}
|
||||
|
||||
for i := 0; i < len(bot.exchanges); i++ {
|
||||
if bot.exchanges[i] != nil {
|
||||
bot.exchanges[i].SetDefaults()
|
||||
log.Printf(
|
||||
"Exchange %s successfully set default settings.\n",
|
||||
bot.exchanges[i].GetName(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
setupBotExchanges()
|
||||
|
||||
if bot.config.CurrencyExchangeProvider == "yahoo" {
|
||||
currency.SetProvider(true)
|
||||
} else {
|
||||
|
||||
@@ -86,6 +86,8 @@ func RESTSaveAllSettings(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
RESTfulError(r.Method, err)
|
||||
}
|
||||
|
||||
SetupExchanges()
|
||||
}
|
||||
|
||||
// RESTGetOrderbook returns orderbook info for a given currency, exchange and
|
||||
|
||||
117
routines.go
117
routines.go
@@ -173,44 +173,47 @@ func relayWebsocketEvent(result interface{}, event, assetType, exchangeName stri
|
||||
}
|
||||
}
|
||||
|
||||
// TickerUpdaterRoutine fetches and updates the ticker for all enabled
|
||||
// currency pairs and exchanges
|
||||
func TickerUpdaterRoutine() {
|
||||
log.Println("Starting ticker updater routine")
|
||||
for {
|
||||
for x := range bot.exchanges {
|
||||
if bot.exchanges[x].IsEnabled() {
|
||||
exchangeName := bot.exchanges[x].GetName()
|
||||
enabledCurrencies := bot.exchanges[x].GetEnabledCurrencies()
|
||||
if bot.exchanges[x] == nil {
|
||||
continue
|
||||
}
|
||||
exchangeName := bot.exchanges[x].GetName()
|
||||
enabledCurrencies := bot.exchanges[x].GetEnabledCurrencies()
|
||||
|
||||
var result ticker.Price
|
||||
var err error
|
||||
var assetTypes []string
|
||||
var result ticker.Price
|
||||
var err error
|
||||
var assetTypes []string
|
||||
|
||||
assetTypes, err = exchange.GetExchangeAssetTypes(exchangeName)
|
||||
if err != nil {
|
||||
log.Printf("failed to get %s exchange asset types. Error: %s",
|
||||
exchangeName, err)
|
||||
}
|
||||
assetTypes, err = exchange.GetExchangeAssetTypes(exchangeName)
|
||||
if err != nil {
|
||||
log.Printf("failed to get %s exchange asset types. Error: %s",
|
||||
exchangeName, err)
|
||||
}
|
||||
|
||||
for y := range enabledCurrencies {
|
||||
currency := enabledCurrencies[y]
|
||||
for y := range enabledCurrencies {
|
||||
currency := enabledCurrencies[y]
|
||||
|
||||
if len(assetTypes) > 1 {
|
||||
for z := range assetTypes {
|
||||
result, err = bot.exchanges[x].UpdateTicker(currency,
|
||||
assetTypes[z])
|
||||
printSummary(result, currency, assetTypes[z], exchangeName, err)
|
||||
if err == nil {
|
||||
relayWebsocketEvent(result, "ticker_update", assetTypes[z], exchangeName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(assetTypes) > 1 {
|
||||
for z := range assetTypes {
|
||||
result, err = bot.exchanges[x].UpdateTicker(currency,
|
||||
assetTypes[0])
|
||||
printSummary(result, currency, assetTypes[0], exchangeName, err)
|
||||
assetTypes[z])
|
||||
printSummary(result, currency, assetTypes[z], exchangeName, err)
|
||||
if err == nil {
|
||||
relayWebsocketEvent(result, "ticker_update", assetTypes[0], exchangeName)
|
||||
relayWebsocketEvent(result, "ticker_update", assetTypes[z], exchangeName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result, err = bot.exchanges[x].UpdateTicker(currency,
|
||||
assetTypes[0])
|
||||
printSummary(result, currency, assetTypes[0], exchangeName, err)
|
||||
if err == nil {
|
||||
relayWebsocketEvent(result, "ticker_update", assetTypes[0], exchangeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,47 +221,51 @@ func TickerUpdaterRoutine() {
|
||||
}
|
||||
}
|
||||
|
||||
// OrderbookUpdaterRoutine fetches and updates the orderbooks for all enabled
|
||||
// currency pairs and exchanges
|
||||
func OrderbookUpdaterRoutine() {
|
||||
log.Println("Starting orderbook updater routine")
|
||||
for {
|
||||
for x := range bot.exchanges {
|
||||
if bot.exchanges[x].IsEnabled() {
|
||||
if bot.exchanges[x].GetName() == "ANX" {
|
||||
continue
|
||||
}
|
||||
if bot.exchanges[x] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
exchangeName := bot.exchanges[x].GetName()
|
||||
enabledCurrencies := bot.exchanges[x].GetEnabledCurrencies()
|
||||
var result orderbook.Base
|
||||
var err error
|
||||
var assetTypes []string
|
||||
if bot.exchanges[x].GetName() == "ANX" {
|
||||
continue
|
||||
}
|
||||
|
||||
assetTypes, err = exchange.GetExchangeAssetTypes(exchangeName)
|
||||
if err != nil {
|
||||
log.Printf("failed to get %s exchange asset types. Error: %s",
|
||||
exchangeName, err)
|
||||
}
|
||||
exchangeName := bot.exchanges[x].GetName()
|
||||
enabledCurrencies := bot.exchanges[x].GetEnabledCurrencies()
|
||||
var result orderbook.Base
|
||||
var err error
|
||||
var assetTypes []string
|
||||
|
||||
for y := range enabledCurrencies {
|
||||
currency := enabledCurrencies[y]
|
||||
assetTypes, err = exchange.GetExchangeAssetTypes(exchangeName)
|
||||
if err != nil {
|
||||
log.Printf("failed to get %s exchange asset types. Error: %s",
|
||||
exchangeName, err)
|
||||
}
|
||||
|
||||
if len(assetTypes) > 1 {
|
||||
for z := range assetTypes {
|
||||
result, err = bot.exchanges[x].UpdateOrderbook(currency,
|
||||
assetTypes[z])
|
||||
printOrderbookSummary(result, currency, assetTypes[z], exchangeName, err)
|
||||
if err == nil {
|
||||
relayWebsocketEvent(result, "orderbook_update", assetTypes[z], exchangeName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for y := range enabledCurrencies {
|
||||
currency := enabledCurrencies[y]
|
||||
|
||||
if len(assetTypes) > 1 {
|
||||
for z := range assetTypes {
|
||||
result, err = bot.exchanges[x].UpdateOrderbook(currency,
|
||||
assetTypes[0])
|
||||
printOrderbookSummary(result, currency, assetTypes[0], exchangeName, err)
|
||||
assetTypes[z])
|
||||
printOrderbookSummary(result, currency, assetTypes[z], exchangeName, err)
|
||||
if err == nil {
|
||||
relayWebsocketEvent(result, "orderbook_update", assetTypes[0], exchangeName)
|
||||
relayWebsocketEvent(result, "orderbook_update", assetTypes[z], exchangeName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result, err = bot.exchanges[x].UpdateOrderbook(currency,
|
||||
assetTypes[0])
|
||||
printOrderbookSummary(result, currency, assetTypes[0], exchangeName, err)
|
||||
if err == nil {
|
||||
relayWebsocketEvent(result, "orderbook_update", assetTypes[0], exchangeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
31
testdata/configtest.json
vendored
31
testdata/configtest.json
vendored
@@ -13,19 +13,19 @@
|
||||
{
|
||||
"Address": "1JCe8z4jJVNXSjohjM4i9Hh813dLCNx2Sy",
|
||||
"CoinType": "BTC",
|
||||
"Balance": 124178.00647714,
|
||||
"Balance": 124178.00354266,
|
||||
"Description": ""
|
||||
},
|
||||
{
|
||||
"Address": "3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v",
|
||||
"CoinType": "BTC",
|
||||
"Balance": 107843.84030984,
|
||||
"Balance": 123439.8370977,
|
||||
"Description": ""
|
||||
},
|
||||
{
|
||||
"Address": "LgY8ahfHRhvjVQC1zJnBhFMG5pCTMuKRqh",
|
||||
"CoinType": "LTC",
|
||||
"Balance": 100000.052,
|
||||
"Balance": 0.03665026,
|
||||
"Description": ""
|
||||
},
|
||||
{
|
||||
@@ -211,6 +211,28 @@
|
||||
"Uppercase": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "COINUT",
|
||||
"Enabled": true,
|
||||
"Verbose": false,
|
||||
"Websocket": false,
|
||||
"UseSandbox": false,
|
||||
"RESTPollingDelay": 10,
|
||||
"AuthenticatedAPISupport": false,
|
||||
"APIKey": "Key",
|
||||
"APISecret": "Secret",
|
||||
"ClientID": "ClientID",
|
||||
"AvailablePairs": "LTCBTC,ETCBTC,ETHBTC",
|
||||
"EnabledPairs": "LTCBTC,ETCBTC,ETHBTC",
|
||||
"BaseCurrencies": "USD",
|
||||
"AssetTypes": "SPOT",
|
||||
"ConfigCurrencyPairFormat": {
|
||||
"Uppercase": true
|
||||
},
|
||||
"RequestCurrencyPairFormat": {
|
||||
"Uppercase": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "GDAX",
|
||||
"Enabled": true,
|
||||
@@ -313,7 +335,8 @@
|
||||
"BaseCurrencies": "EUR,USD,CAD,GBP,JPY",
|
||||
"AssetTypes": "SPOT",
|
||||
"ConfigCurrencyPairFormat": {
|
||||
"Uppercase": true
|
||||
"Uppercase": true,
|
||||
"Delimiter": "-"
|
||||
},
|
||||
"RequestCurrencyPairFormat": {
|
||||
"Uppercase": true,
|
||||
|
||||
@@ -174,7 +174,7 @@ func wsSaveConfig(wsClient *websocket.Conn, data interface{}) error {
|
||||
}
|
||||
}
|
||||
|
||||
setupBotExchanges()
|
||||
SetupExchanges()
|
||||
wsResp.Data = WebsocketResponseSuccess
|
||||
return wsClient.WriteJSON(wsResp)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user