engine/exchange manager: Add support for custom exchanges (#749)

* engine: Setup exchange manager earlier

So it's available for applications before starting.

* engine: Add a custom exchange builder interface

Allows applications that import GCT as a lib to build new
custom exchanges without further modifications.
This commit is contained in:
Luis Rascão
2021-08-17 05:03:05 +01:00
committed by GitHub
parent 736c92a99b
commit 96669e29cf
4 changed files with 329 additions and 1 deletions

View File

@@ -105,6 +105,8 @@ func NewFromSettings(settings *Settings, flagSet map[string]bool) (*Engine, erro
return nil, fmt.Errorf("failed to create script manager. Err: %s", err)
}
b.ExchangeManager = SetupExchangeManager()
validateSettings(&b, settings, flagSet)
return &b, nil
@@ -363,7 +365,6 @@ func (bot *Engine) Start() error {
bot.Config.PurgeExchangeAPICredentials()
}
bot.ExchangeManager = SetupExchangeManager()
gctlog.Debugln(gctlog.Global, "Setting up exchanges..")
err = bot.SetupExchanges()
if err != nil {

View File

@@ -45,10 +45,17 @@ var (
ErrExchangeFailedToLoad = errors.New("exchange failed to load")
)
// CustomExchangeBuilder interface allows external applications to create
// custom/unsupported exchanges that satisfy the IBotExchange interface.
type CustomExchangeBuilder interface {
NewExchangeByName(name string) (exchange.IBotExchange, error)
}
// ExchangeManager manages what exchanges are loaded
type ExchangeManager struct {
m sync.Mutex
exchanges map[string]exchange.IBotExchange
Builder CustomExchangeBuilder
}
// SetupExchangeManager creates a new exchange manager
@@ -183,6 +190,9 @@ func (m *ExchangeManager) NewExchangeByName(name string) (exchange.IBotExchange,
case "zb":
exch = new(zb.ZB)
default:
if m.Builder != nil {
return m.Builder.NewExchangeByName(nameLower)
}
return nil, fmt.Errorf("%s, %w", nameLower, ErrExchangeNotFound)
}

View File

@@ -1,10 +1,13 @@
package engine
import (
"fmt"
"strings"
"testing"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/bitfinex"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
)
func TestSetupExchangeManager(t *testing.T) {
@@ -79,3 +82,34 @@ func TestNewExchangeByName(t *testing.T) {
}
}
}
type ExchangeBuilder struct{}
func (n ExchangeBuilder) NewExchangeByName(name string) (exchange.IBotExchange, error) {
var exch exchange.IBotExchange
switch name {
case "customex":
exch = new(sharedtestvalues.CustomEx)
default:
return nil, fmt.Errorf("%s, %w", name, ErrExchangeNotFound)
}
return exch, nil
}
func TestNewCustomExchangeByName(t *testing.T) {
m := SetupExchangeManager()
m.Builder = ExchangeBuilder{}
name := "customex"
exch, err := m.NewExchangeByName(name)
if err != nil {
t.Fatal(err)
}
if err == nil {
exch.SetDefaults()
if !strings.EqualFold(exch.GetName(), name) {
t.Error("did not load expected exchange")
}
}
}