engine: Adds shutdown method to exchange manager and unload all exchanges when engine is stopped (#1112)

* engine: shutdown and unload exchange when engine is stopped

* linter: fixes

* engine/exchMan: add nil check

* engine/exchanges: add shutdown method to exchanges, rm len check lock not needed, expanded code coverage, address some nits

* exchMan: report all failed shutdowns across exchanges, implement timer and monitoring routines.

* exchMan: improve shutdown sequence and aloc.

* further improvement

* exchman: log from warn to error

* websockconnection: Suppress error return when closure is caused by library

* linter: fix

* fix racies

* add note on why not parallel tests

* glorious: nits

* spelling kween

* thrasher: nits

* engine: change print of setting using reflection, I keep forgetting to implement this so program around forgetfulness

* engine/exchange_management: remove wait group and just rely on intermediary lock

* glorious: nits

* Update common/common.go

Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>

* Update main.go

Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>

---------

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
Ryan O'Hara-Reid
2023-04-05 13:07:35 +10:00
committed by GitHub
parent 4a50a72e4a
commit d23898e63a
35 changed files with 803 additions and 356 deletions

View File

@@ -190,13 +190,16 @@ func TestIsWebsocketServerRunning(t *testing.T) {
}
func TestGetAllActiveOrderbooks(t *testing.T) {
man := SetupExchangeManager()
man := NewExchangeManager()
bs, err := man.NewExchangeByName("Bitstamp")
if err != nil {
t.Fatal(err)
}
bs.SetDefaults()
man.Add(bs)
err = man.Add(bs)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
resp := getAllActiveOrderbooks(man)
if resp == nil {
t.Error("expected not nil")
@@ -205,13 +208,16 @@ func TestGetAllActiveOrderbooks(t *testing.T) {
func TestGetAllActiveTickers(t *testing.T) {
t.Parallel()
man := SetupExchangeManager()
man := NewExchangeManager()
bs, err := man.NewExchangeByName("Bitstamp")
if err != nil {
t.Fatal(err)
}
bs.SetDefaults()
man.Add(bs)
err = man.Add(bs)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
resp := getAllActiveTickers(man)
if resp == nil {
t.Error("expected not nil")
@@ -220,13 +226,16 @@ func TestGetAllActiveTickers(t *testing.T) {
func TestGetAllActiveAccounts(t *testing.T) {
t.Parallel()
man := SetupExchangeManager()
man := NewExchangeManager()
bs, err := man.NewExchangeByName("Bitstamp")
if err != nil {
t.Fatal(err)
}
bs.SetDefaults()
man.Add(bs)
err = man.Add(bs)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
resp := getAllActiveAccounts(man)
if resp == nil {
t.Error("expected not nil")

View File

@@ -31,17 +31,17 @@ func TestSetupDataHistoryManager(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, errNilConfig)
}
_, err = SetupDataHistoryManager(SetupExchangeManager(), nil, nil)
_, err = SetupDataHistoryManager(NewExchangeManager(), nil, nil)
if !errors.Is(err, errNilDatabaseConnectionManager) {
t.Errorf("error '%v', expected '%v'", err, errNilDatabaseConnectionManager)
}
_, err = SetupDataHistoryManager(SetupExchangeManager(), &DatabaseConnectionManager{}, nil)
_, err = SetupDataHistoryManager(NewExchangeManager(), &DatabaseConnectionManager{}, nil)
if !errors.Is(err, errNilConfig) {
t.Errorf("error '%v', expected '%v'", err, errNilConfig)
}
_, err = SetupDataHistoryManager(SetupExchangeManager(), &DatabaseConnectionManager{}, &config.DataHistoryManager{})
_, err = SetupDataHistoryManager(NewExchangeManager(), &DatabaseConnectionManager{}, &config.DataHistoryManager{})
if !errors.Is(err, database.ErrNilInstance) {
t.Errorf("error '%v', expected '%v'", err, database.ErrNilInstance)
}
@@ -60,7 +60,7 @@ func TestSetupDataHistoryManager(t *testing.T) {
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
m, err := SetupDataHistoryManager(SetupExchangeManager(), dbCM, &config.DataHistoryManager{})
m, err := SetupDataHistoryManager(NewExchangeManager(), dbCM, &config.DataHistoryManager{})
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -655,7 +655,7 @@ func TestCompareJobsToData(t *testing.T) {
}
}
func TestRunJob(t *testing.T) {
func TestRunJob(t *testing.T) { //nolint:tparallel // There is a race condition caused by the DataHistoryJob and it's a big change to fix.
t.Parallel()
tt := time.Now().Truncate(kline.OneHour.Duration())
testCases := []*DataHistoryJob{
@@ -731,7 +731,6 @@ func TestRunJob(t *testing.T) {
for x := range testCases {
test := testCases[x]
t.Run(test.Nickname, func(t *testing.T) {
t.Parallel()
err := m.UpsertJob(test, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -912,7 +911,7 @@ func TestConverters(t *testing.T) {
// test helper functions
func createDHM(t *testing.T) (*DataHistoryManager, *datahistoryjob.DataHistoryJob) {
t.Helper()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Fatalf("error '%v', expected '%v'", err, nil)
@@ -926,7 +925,10 @@ func createDHM(t *testing.T) (*DataHistoryManager, *datahistoryjob.DataHistoryJo
Available: currency.Pairs{cp, cp2},
Enabled: currency.Pairs{cp, cp2},
AssetEnabled: convert.BoolPtr(true)}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
exch2, err := em.NewExchangeByName("Binance")
if !errors.Is(err, nil) {
@@ -943,7 +945,11 @@ func createDHM(t *testing.T) (*DataHistoryManager, *datahistoryjob.DataHistoryJo
RequestFormat: &currency.PairFormat{Uppercase: true},
}
em.Add(exch2)
err = em.Add(exch2)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
j := &datahistoryjob.DataHistoryJob{
ID: jobID,
Nickname: "datahistoryjob",
@@ -968,16 +974,14 @@ func createDHM(t *testing.T) (*DataHistoryManager, *datahistoryjob.DataHistoryJo
}
m := &DataHistoryManager{
databaseConnectionInstance: &dataBaseConnection{},
jobDB: dataHistoryJobService{
job: j,
},
jobResultDB: dataHistoryJobResultService{},
started: 1,
exchangeManager: em,
candleLoader: dataHistoryCandleLoader,
interval: time.NewTicker(time.Minute),
verbose: true,
maxResultInsertions: defaultMaxResultInsertions,
jobDB: &dataHistoryJobService{job: j},
jobResultDB: dataHistoryJobResultService{},
started: 1,
exchangeManager: em,
candleLoader: dataHistoryCandleLoader,
interval: time.NewTicker(time.Minute),
verbose: true,
maxResultInsertions: defaultMaxResultInsertions,
}
return m, j
}
@@ -1017,7 +1021,7 @@ func TestProcessCandleData(t *testing.T) {
t.Errorf("received %v expected %v", err, ErrExchangeNotFound)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -1073,7 +1077,7 @@ func TestProcessTradeData(t *testing.T) {
t.Errorf("received %v expected %v", err, ErrExchangeNotFound)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -1192,7 +1196,7 @@ func TestValidateCandles(t *testing.T) {
t.Errorf("received %v expected %v", err, ErrExchangeNotFound)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)

View File

@@ -7,6 +7,7 @@ import (
"log"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"sync"
@@ -114,7 +115,7 @@ func NewFromSettings(settings *Settings, flagSet map[string]bool) (*Engine, erro
return nil, fmt.Errorf("failed to create script manager. Err: %w", err)
}
b.ExchangeManager = SetupExchangeManager()
b.ExchangeManager = NewExchangeManager()
validateSettings(&b, settings, flagSet)
@@ -263,76 +264,31 @@ func validateSettings(b *Engine, s *Settings, flagSet FlagSet) {
}
}
// PrintSettings returns the engine settings
func PrintSettings(s *Settings) {
// PrintLoadedSettings logs loaded settings.
func (s *Settings) PrintLoadedSettings() {
if s == nil {
return
}
gctlog.Debugln(gctlog.Global)
gctlog.Debugf(gctlog.Global, "ENGINE SETTINGS")
gctlog.Debugf(gctlog.Global, "- CORE SETTINGS:")
gctlog.Debugf(gctlog.Global, "\t Verbose mode: %v", s.Verbose)
gctlog.Debugf(gctlog.Global, "\t Enable dry run mode: %v", s.EnableDryRun)
gctlog.Debugf(gctlog.Global, "\t Enable all exchanges: %v", s.EnableAllExchanges)
gctlog.Debugf(gctlog.Global, "\t Enable all pairs: %v", s.EnableAllPairs)
gctlog.Debugf(gctlog.Global, "\t Enable CoinMarketCap analysis: %v", s.EnableCoinmarketcapAnalysis)
gctlog.Debugf(gctlog.Global, "\t Enable portfolio manager: %v", s.EnablePortfolioManager)
gctlog.Debugf(gctlog.Global, "\t Enable data history manager: %v", s.EnableDataHistoryManager)
gctlog.Debugf(gctlog.Global, "\t Enable currency state manager: %v", s.EnableCurrencyStateManager)
gctlog.Debugf(gctlog.Global, "\t Portfolio manager sleep delay: %v\n", s.PortfolioManagerDelay)
gctlog.Debugf(gctlog.Global, "\t Enable gPRC: %v", s.EnableGRPC)
gctlog.Debugf(gctlog.Global, "\t Enable gRPC Proxy: %v", s.EnableGRPCProxy)
gctlog.Debugf(gctlog.Global, "\t Enable gRPC shutdown of bot instance: %v", s.EnableGRPCShutdown)
gctlog.Debugf(gctlog.Global, "\t Enable websocket RPC: %v", s.EnableWebsocketRPC)
gctlog.Debugf(gctlog.Global, "\t Enable deprecated RPC: %v", s.EnableDeprecatedRPC)
gctlog.Debugf(gctlog.Global, "\t Enable comms relayer: %v", s.EnableCommsRelayer)
gctlog.Debugf(gctlog.Global, "\t Enable event manager: %v", s.EnableEventManager)
gctlog.Debugf(gctlog.Global, "\t Event manager sleep delay: %v", s.EventManagerDelay)
gctlog.Debugf(gctlog.Global, "\t Enable order manager: %v", s.EnableOrderManager)
gctlog.Debugf(gctlog.Global, "\t Enable exchange sync manager: %v", s.EnableExchangeSyncManager)
gctlog.Debugf(gctlog.Global, "\t Enable deposit address manager: %v\n", s.EnableDepositAddressManager)
gctlog.Debugf(gctlog.Global, "\t Enable websocket routine: %v\n", s.EnableWebsocketRoutine)
gctlog.Debugf(gctlog.Global, "\t Enable NTP client: %v", s.EnableNTPClient)
gctlog.Debugf(gctlog.Global, "\t Enable Database manager: %v", s.EnableDatabaseManager)
gctlog.Debugf(gctlog.Global, "\t Enable dispatcher: %v", s.EnableDispatcher)
gctlog.Debugf(gctlog.Global, "\t Dispatch package max worker amount: %d", s.DispatchMaxWorkerAmount)
gctlog.Debugf(gctlog.Global, "\t Dispatch package jobs limit: %d", s.DispatchJobsLimit)
gctlog.Debugf(gctlog.Global, "\t Futures PNL tracking: %v", s.EnableFuturesTracking)
gctlog.Debugf(gctlog.Global, "- EXCHANGE SYNCER SETTINGS:\n")
gctlog.Debugf(gctlog.Global, "\t Exchange sync continuously: %v\n", s.SyncContinuously)
gctlog.Debugf(gctlog.Global, "\t Exchange sync workers count: %v\n", s.SyncWorkersCount)
gctlog.Debugf(gctlog.Global, "\t Enable ticker syncing: %v\n", s.EnableTickerSyncing)
gctlog.Debugf(gctlog.Global, "\t Enable orderbook syncing: %v\n", s.EnableOrderbookSyncing)
gctlog.Debugf(gctlog.Global, "\t Enable trade syncing: %v\n", s.EnableTradeSyncing)
gctlog.Debugf(gctlog.Global, "\t Exchange REST sync timeout: %v\n", s.SyncTimeoutREST)
gctlog.Debugf(gctlog.Global, "\t Exchange Websocket sync timeout: %v\n", s.SyncTimeoutWebsocket)
gctlog.Debugf(gctlog.Global, "- FOREX SETTINGS:")
gctlog.Debugf(gctlog.Global, "\t Enable Currency Converter: %v", s.EnableCurrencyConverter)
gctlog.Debugf(gctlog.Global, "\t Enable Currency Layer: %v", s.EnableCurrencyLayer)
gctlog.Debugf(gctlog.Global, "\t Enable ExchangeRatesAPI.io: %v", s.EnableExchangeRates)
gctlog.Debugf(gctlog.Global, "\t Enable Fixer: %v", s.EnableFixer)
gctlog.Debugf(gctlog.Global, "\t Enable OpenExchangeRates: %v", s.EnableOpenExchangeRates)
gctlog.Debugf(gctlog.Global, "\t Enable ExchangeRateHost: %v", s.EnableExchangeRateHost)
gctlog.Debugf(gctlog.Global, "- EXCHANGE SETTINGS:")
gctlog.Debugf(gctlog.Global, "\t Enable exchange auto pair updates: %v", s.EnableExchangeAutoPairUpdates)
gctlog.Debugf(gctlog.Global, "\t Disable all exchange auto pair updates: %v", s.DisableExchangeAutoPairUpdates)
gctlog.Debugf(gctlog.Global, "\t Enable exchange websocket support: %v", s.EnableExchangeWebsocketSupport)
gctlog.Debugf(gctlog.Global, "\t Enable exchange verbose mode: %v", s.EnableExchangeVerbose)
gctlog.Debugf(gctlog.Global, "\t Enable exchange HTTP rate limiter: %v", s.EnableExchangeHTTPRateLimiter)
gctlog.Debugf(gctlog.Global, "\t Enable exchange HTTP debugging: %v", s.EnableExchangeHTTPDebugging)
gctlog.Debugf(gctlog.Global, "\t Max HTTP request jobs: %v", s.MaxHTTPRequestJobsLimit)
gctlog.Debugf(gctlog.Global, "\t HTTP request max retry attempts: %v", s.RequestMaxRetryAttempts)
gctlog.Debugf(gctlog.Global, "\t Trade buffer processing interval: %v", s.TradeBufferProcessingInterval)
gctlog.Debugf(gctlog.Global, "\t Alert communications channel pre-allocation buffer size: %v", s.AlertSystemPreAllocationCommsBuffer)
gctlog.Debugf(gctlog.Global, "\t HTTP timeout: %v", s.HTTPTimeout)
gctlog.Debugf(gctlog.Global, "\t HTTP user agent: %v", s.HTTPUserAgent)
gctlog.Debugf(gctlog.Global, "- GCTSCRIPT SETTINGS: ")
gctlog.Debugf(gctlog.Global, "\t Enable GCTScript manager: %v", s.EnableGCTScriptManager)
gctlog.Debugf(gctlog.Global, "\t GCTScript max virtual machines: %v", s.MaxVirtualMachines)
gctlog.Debugf(gctlog.Global, "- WITHDRAW SETTINGS: ")
gctlog.Debugf(gctlog.Global, "\t Withdraw Cache size: %v", s.WithdrawCacheSize)
gctlog.Debugf(gctlog.Global, "- COMMON SETTINGS:")
gctlog.Debugf(gctlog.Global, "\t Global HTTP timeout: %v", s.GlobalHTTPTimeout)
gctlog.Debugf(gctlog.Global, "\t Global HTTP user agent: %v", s.GlobalHTTPUserAgent)
gctlog.Debugf(gctlog.Global, "\t Global HTTP proxy: %v", s.GlobalHTTPProxy)
settings := reflect.ValueOf(*s)
for x := 0; x < settings.NumField(); x++ {
field := settings.Field(x)
if field.Kind() != reflect.Struct {
continue
}
fieldName := field.Type().Name()
gctlog.Debugln(gctlog.Global, "- "+common.AddPaddingOnUpperCase(fieldName)+":")
for y := 0; y < field.NumField(); y++ {
indvSetting := field.Field(y)
indvName := field.Type().Field(y).Name
if indvSetting.Kind() == reflect.String && indvSetting.IsZero() {
indvSetting = reflect.ValueOf("Undefined")
}
gctlog.Debugln(gctlog.Global, "\t", common.AddPaddingOnUpperCase(indvName)+":", indvSetting)
}
}
gctlog.Debugln(gctlog.Global)
}
@@ -713,12 +669,18 @@ func (bot *Engine) Stop() {
}
}
if err := currency.ShutdownStorageUpdater(); err != nil {
err := bot.ExchangeManager.Shutdown(bot.Settings.ExchangeShutdownTimeout)
if err != nil {
gctlog.Errorf(gctlog.Global, "Exchange manager unable to stop. Error: %v", err)
}
err = currency.ShutdownStorageUpdater()
if err != nil {
gctlog.Errorf(gctlog.Global, "ExchangeSettings storage system. Error: %v", err)
}
if !bot.Settings.EnableDryRun {
err := bot.Config.SaveConfigToFile(bot.Settings.ConfigFile)
err = bot.Config.SaveConfigToFile(bot.Settings.ConfigFile)
if err != nil {
gctlog.Errorln(gctlog.Global, "Unable to save config.")
} else {
@@ -860,7 +822,11 @@ func (bot *Engine) LoadExchange(name string, wg *sync.WaitGroup) error {
return err
}
bot.ExchangeManager.Add(exch)
err = bot.ExchangeManager.Add(exch)
if err != nil {
return err
}
base := exch.GetBase()
if base.API.AuthenticatedSupport ||
base.API.AuthenticatedWebsocketSupport {

View File

@@ -32,7 +32,7 @@ func TestLoadConfigWithSettings(t *testing.T) {
name: "test file",
settings: &Settings{
ConfigFile: config.TestFile,
EnableDryRun: true,
CoreSettings: CoreSettings{EnableDryRun: true},
},
want: &empty,
wantErr: false,
@@ -43,7 +43,7 @@ func TestLoadConfigWithSettings(t *testing.T) {
settings: &Settings{
ConfigFile: config.TestFile,
DataDir: somePath,
EnableDryRun: true,
CoreSettings: CoreSettings{EnableDryRun: true},
},
want: &somePath,
wantErr: false,
@@ -79,7 +79,7 @@ func TestStartStopDoesNotCausePanic(t *testing.T) {
tempDir := t.TempDir()
botOne, err := NewFromSettings(&Settings{
ConfigFile: config.TestFile,
EnableDryRun: true,
CoreSettings: CoreSettings{EnableDryRun: true},
DataDir: tempDir,
}, nil)
if err != nil {
@@ -110,7 +110,7 @@ func TestStartStopTwoDoesNotCausePanic(t *testing.T) {
tempDir2 := t.TempDir()
botOne, err := NewFromSettings(&Settings{
ConfigFile: config.TestFile,
EnableDryRun: true,
CoreSettings: CoreSettings{EnableDryRun: true},
DataDir: tempDir,
}, nil)
if err != nil {
@@ -120,7 +120,7 @@ func TestStartStopTwoDoesNotCausePanic(t *testing.T) {
botTwo, err := NewFromSettings(&Settings{
ConfigFile: config.TestFile,
EnableDryRun: true,
CoreSettings: CoreSettings{EnableDryRun: true},
DataDir: tempDir2,
}, nil)
if err != nil {
@@ -146,14 +146,17 @@ func TestGetExchangeByName(t *testing.T) {
t.Errorf("received: %v expected: %v", err, ErrNilSubsystem)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Fatalf("received '%v' expected '%v'", err, nil)
}
exch.SetDefaults()
exch.SetEnabled(true)
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
e := &Engine{ExchangeManager: em}
if !exch.IsEnabled() {
@@ -180,14 +183,17 @@ func TestGetExchangeByName(t *testing.T) {
func TestUnloadExchange(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Fatalf("received '%v' expected '%v'", err, nil)
}
exch.SetDefaults()
exch.SetEnabled(true)
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
e := &Engine{ExchangeManager: em,
Config: &config.Config{Exchanges: []config.Exchange{{Name: testExchange}}},
}
@@ -203,15 +209,15 @@ func TestUnloadExchange(t *testing.T) {
}
err = e.UnloadExchange(testExchange)
if !errors.Is(err, ErrNoExchangesLoaded) {
t.Errorf("error '%v', expected '%v'", err, ErrNoExchangesLoaded)
if !errors.Is(err, ErrExchangeNotFound) {
t.Errorf("error '%v', expected '%v'", err, ErrExchangeNotFound)
}
}
func TestDryRunParamInteraction(t *testing.T) {
t.Parallel()
bot := &Engine{
ExchangeManager: SetupExchangeManager(),
ExchangeManager: NewExchangeManager(),
Settings: Settings{},
Config: &config.Config{
Exchanges: []config.Exchange{
@@ -323,3 +329,12 @@ func TestSetDefaultWebsocketDataHandler(t *testing.T) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
}
func TestSettingsPrint(t *testing.T) {
t.Parallel()
var s *Settings
s.PrintLoadedSettings()
s = &Settings{}
s.PrintLoadedSettings()
}

View File

@@ -5,7 +5,11 @@ import (
"time"
)
// Settings stores engine params
// Settings stores engine params. Please define a settings struct for automatic
// display of instance settings. For example, if you define a struct named
// ManagerSettings, it will be displayed as a subheading "Manager Settings"
// and individual field names such as 'EnableManager' will be displayed
// as "Enable Manager: true/false".
type Settings struct {
ConfigFile string
DataDir string
@@ -14,7 +18,19 @@ type Settings struct {
GoMaxProcs int
CheckParamInteraction bool
// Core Settings
CoreSettings
ExchangeSyncerSettings
ForexSettings
ExchangeTuningSettings
GCTScriptSettings
WithdrawSettings
// Main shutdown channel
Shutdown chan struct{}
}
// CoreSettings defines settings related to core engine operations
type CoreSettings struct {
EnableDryRun bool
EnableAllExchanges bool
EnableAllPairs bool
@@ -41,8 +57,13 @@ type Settings struct {
EventManagerDelay time.Duration
EnableFuturesTracking bool
Verbose bool
EnableDispatcher bool
DispatchMaxWorkerAmount int
DispatchJobsLimit int
}
// Exchange syncer settings
// ExchangeSyncerSettings defines settings for the exchange pair synchronisation
type ExchangeSyncerSettings struct {
EnableTickerSyncing bool
EnableOrderbookSyncing bool
EnableTradeSyncing bool
@@ -50,16 +71,20 @@ type Settings struct {
SyncContinuously bool
SyncTimeoutREST time.Duration
SyncTimeoutWebsocket time.Duration
}
// Forex settings
// ForexSettings defines settings related to the foreign exchange services
type ForexSettings struct {
EnableCurrencyConverter bool
EnableCurrencyLayer bool
EnableExchangeRates bool
EnableFixer bool
EnableOpenExchangeRates bool
EnableExchangeRateHost bool
}
// Exchange tuning settings
// ExchangeTuningSettings defines settings related to an exchange
type ExchangeTuningSettings struct {
EnableExchangeHTTPRateLimiter bool
EnableExchangeHTTPDebugging bool
EnableExchangeVerbose bool
@@ -72,30 +97,23 @@ type Settings struct {
TradeBufferProcessingInterval time.Duration
RequestMaxRetryAttempts int
AlertSystemPreAllocationCommsBuffer int // See exchanges/alert.go
ExchangeShutdownTimeout time.Duration
HTTPTimeout time.Duration
HTTPUserAgent string
HTTPProxy string
GlobalHTTPTimeout time.Duration
GlobalHTTPUserAgent string
GlobalHTTPProxy string
}
// Global HTTP related settings
GlobalHTTPTimeout time.Duration
GlobalHTTPUserAgent string
GlobalHTTPProxy string
// Exchange HTTP related settings
HTTPTimeout time.Duration
HTTPUserAgent string
HTTPProxy string
// Dispatch system settings
EnableDispatcher bool
DispatchMaxWorkerAmount int
DispatchJobsLimit int
// GCTscript settings
// GCTScriptSettings defines settings related to the GCTScript virtual machine
type GCTScriptSettings struct {
MaxVirtualMachines uint
}
// Withdraw settings
// WithdrawSettings defines settings related to Withdrawing cryptocurrency
type WithdrawSettings struct {
WithdrawCacheSize uint64
// Main shutdown channel
Shutdown chan struct{}
}
const (

View File

@@ -107,7 +107,7 @@ func TestEventManagerStop(t *testing.T) {
func TestEventManagerAdd(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
m, err := setupEventManager(&CommunicationManager{}, em, 0, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -129,7 +129,10 @@ func TestEventManagerAdd(t *testing.T) {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
_, err = m.Add(testExchange, "", EventConditionParams{}, currency.NewPair(currency.BTC, currency.USDC), asset.Spot, "")
if !errors.Is(err, errInvalidItem) {
t.Errorf("error '%v', expected '%v'", err, errInvalidItem)
@@ -159,7 +162,7 @@ func TestEventManagerAdd(t *testing.T) {
func TestEventManagerRemove(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
m, err := setupEventManager(&CommunicationManager{}, em, 0, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -185,7 +188,10 @@ func TestEventManagerRemove(t *testing.T) {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
id, err := m.Add(testExchange, ItemPrice, cond, currency.NewPair(currency.BTC, currency.USDC), asset.Spot, action)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -198,7 +204,7 @@ func TestEventManagerRemove(t *testing.T) {
func TestGetEventCounter(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
m, err := setupEventManager(&CommunicationManager{}, em, 0, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -226,7 +232,10 @@ func TestGetEventCounter(t *testing.T) {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
_, err = m.Add(testExchange, ItemPrice, cond, currency.NewPair(currency.BTC, currency.USDC), asset.Spot, action)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -239,7 +248,7 @@ func TestGetEventCounter(t *testing.T) {
}
func TestCheckEventCondition(t *testing.T) {
em := SetupExchangeManager()
em := NewExchangeManager()
m, err := setupEventManager(&CommunicationManager{}, em, 0, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -272,7 +281,10 @@ func TestCheckEventCondition(t *testing.T) {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
_, err = m.Add(testExchange, ItemPrice, cond, currency.NewPair(currency.BTC, currency.USD), asset.Spot, action)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"strings"
"sync"
"time"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/binance"
@@ -43,6 +44,9 @@ var (
ErrExchangeAlreadyLoaded = errors.New("exchange already loaded")
ErrExchangeFailedToLoad = errors.New("exchange failed to load")
ErrExchangeNameIsEmpty = errors.New("exchange name is empty")
errExchangeIsNil = errors.New("exchange is nil")
errExchangeAlreadyLoaded = errors.New("exchange already loaded")
)
// CustomExchangeBuilder interface allows external applications to create
@@ -53,26 +57,34 @@ type CustomExchangeBuilder interface {
// ExchangeManager manages what exchanges are loaded
type ExchangeManager struct {
m sync.Mutex
mtx sync.Mutex
exchanges map[string]exchange.IBotExchange
Builder CustomExchangeBuilder
}
// SetupExchangeManager creates a new exchange manager
func SetupExchangeManager() *ExchangeManager {
// NewExchangeManager creates a new exchange manager
func NewExchangeManager() *ExchangeManager {
return &ExchangeManager{
exchanges: make(map[string]exchange.IBotExchange),
}
}
// Add adds or replaces an exchange
func (m *ExchangeManager) Add(exch exchange.IBotExchange) {
if exch == nil {
return
// Add adds an exchange
func (m *ExchangeManager) Add(exch exchange.IBotExchange) error {
if m == nil {
return fmt.Errorf("exchange manager: %w", ErrNilSubsystem)
}
if exch == nil {
return fmt.Errorf("exchange manager: %w", errExchangeIsNil)
}
m.mtx.Lock()
defer m.mtx.Unlock()
_, ok := m.exchanges[strings.ToLower(exch.GetName())]
if ok {
return fmt.Errorf("exchange manager: %s %w", exch.GetName(), errExchangeAlreadyLoaded)
}
m.m.Lock()
m.exchanges[strings.ToLower(exch.GetName())] = exch
m.m.Unlock()
return nil
}
// GetExchanges returns all stored exchanges
@@ -80,32 +92,37 @@ func (m *ExchangeManager) GetExchanges() ([]exchange.IBotExchange, error) {
if m == nil {
return nil, fmt.Errorf("exchange manager: %w", ErrNilSubsystem)
}
m.m.Lock()
defer m.m.Unlock()
m.mtx.Lock()
defer m.mtx.Unlock()
exchs := make([]exchange.IBotExchange, 0, len(m.exchanges))
for _, x := range m.exchanges {
exchs = append(exchs, x)
for _, exch := range m.exchanges {
exchs = append(exchs, exch)
}
return exchs, nil
}
// RemoveExchange removes an exchange from the manager
func (m *ExchangeManager) RemoveExchange(exchName string) error {
if m.Len() == 0 {
return ErrNoExchangesLoaded
func (m *ExchangeManager) RemoveExchange(exchangeName string) error {
if m == nil {
return fmt.Errorf("exchange manager: %w", ErrNilSubsystem)
}
exch, err := m.GetExchangeByName(exchName)
if exchangeName == "" {
return fmt.Errorf("exchange manager: %w", ErrExchangeNameIsEmpty)
}
m.mtx.Lock()
defer m.mtx.Unlock()
exch, ok := m.exchanges[strings.ToLower(exchangeName)]
if !ok {
return fmt.Errorf("exchange manager: %s %w", exchangeName, ErrExchangeNotFound)
}
err := exch.Shutdown()
if err != nil {
return err
return fmt.Errorf("exchange manager: %w", err)
}
m.m.Lock()
defer m.m.Unlock()
err = exch.GetBase().Requester.Shutdown()
if err != nil {
return err
}
delete(m.exchanges, strings.ToLower(exchName))
log.Infof(log.ExchangeSys, "%s exchange unloaded successfully.\n", exchName)
delete(m.exchanges, strings.ToLower(exchangeName))
log.Infof(log.ExchangeSys, "%s exchange unloaded successfully.\n", exchangeName)
return nil
}
@@ -117,33 +134,27 @@ func (m *ExchangeManager) GetExchangeByName(exchangeName string) (exchange.IBotE
if exchangeName == "" {
return nil, fmt.Errorf("exchange manager: %w", ErrExchangeNameIsEmpty)
}
m.m.Lock()
defer m.m.Unlock()
m.mtx.Lock()
defer m.mtx.Unlock()
exch, ok := m.exchanges[strings.ToLower(exchangeName)]
if !ok {
return nil, fmt.Errorf("%s %w", exchangeName, ErrExchangeNotFound)
return nil, fmt.Errorf("exchange manager: %s %w", exchangeName, ErrExchangeNotFound)
}
return exch, nil
}
// Len says how many exchanges are loaded
func (m *ExchangeManager) Len() int {
m.m.Lock()
defer m.m.Unlock()
return len(m.exchanges)
}
// NewExchangeByName helps create a new exchange to be loaded
func (m *ExchangeManager) NewExchangeByName(name string) (exchange.IBotExchange, error) {
if m == nil {
return nil, fmt.Errorf("exchange manager %w", ErrNilSubsystem)
}
nameLower := strings.ToLower(name)
if exch, _ := m.GetExchangeByName(nameLower); exch != nil {
return nil, fmt.Errorf("%s %w", name, ErrExchangeAlreadyLoaded)
_, err := m.GetExchangeByName(nameLower)
if err != nil && !errors.Is(err, ErrExchangeNotFound) {
return nil, fmt.Errorf("exchange manager: %s %w", name, err)
}
if err == nil {
return nil, fmt.Errorf("exchange manager: %s %w", name, ErrExchangeAlreadyLoaded)
}
var exch exchange.IBotExchange
var exch exchange.IBotExchange
switch nameLower {
case "binanceus":
exch = new(binanceus.Binanceus)
@@ -201,7 +212,66 @@ func (m *ExchangeManager) NewExchangeByName(name string) (exchange.IBotExchange,
if m.Builder != nil {
return m.Builder.NewExchangeByName(nameLower)
}
return nil, fmt.Errorf("%s, %w", nameLower, ErrExchangeNotFound)
return nil, fmt.Errorf("exchange manager: %s, %w", nameLower, ErrExchangeNotFound)
}
return exch, nil
}
// Shutdown shuts down all exchanges and unloads them
func (m *ExchangeManager) Shutdown(shutdownTimeout time.Duration) error {
if m == nil {
return fmt.Errorf("exchange manager: %w", ErrNilSubsystem)
}
if shutdownTimeout < 0 {
shutdownTimeout = 0
}
var lockout sync.Mutex
timer := time.NewTimer(shutdownTimeout)
var wg sync.WaitGroup
m.mtx.Lock()
defer m.mtx.Unlock()
lockout.Lock()
for _, exch := range m.exchanges {
wg.Add(1)
go func(wg *sync.WaitGroup, mtx *sync.Mutex, exch exchange.IBotExchange) {
err := exch.Shutdown()
if err != nil {
log.Errorf(log.ExchangeSys, "%s failed to shutdown %v.\n", exch.GetName(), err)
} else {
mtx.Lock()
delete(m.exchanges, strings.ToLower(exch.GetName()))
mtx.Unlock()
}
wg.Done()
}(&wg, &lockout, exch)
}
lockout.Unlock()
ch := make(chan struct{})
go func(wg *sync.WaitGroup, finish chan<- struct{}) {
wg.Wait()
finish <- struct{}{}
}(&wg, ch)
select {
case <-timer.C:
// Possible deadlock in a number of operating exchanges.
lockout.Lock()
for name := range m.exchanges {
log.Warnf(log.ExchangeSys, "%s has failed to shutdown within %s, please review.\n", name, shutdownTimeout)
}
lockout.Unlock()
case <-ch:
// Every exchange has finished their shutdown call.
lockout.Lock()
for name := range m.exchanges {
log.Errorf(log.ExchangeSys, "%s has failed to shutdown due to error, please review.\n", name)
}
lockout.Unlock()
}
return nil
}

View File

@@ -11,9 +11,15 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
)
func TestSetupExchangeManager(t *testing.T) {
type broken struct {
bitfinex.Bitfinex
}
func (b *broken) Shutdown() error { return errExpectedTestError }
func TestNewExchangeManager(t *testing.T) {
t.Parallel()
m := SetupExchangeManager()
m := NewExchangeManager()
if m == nil { //nolint:staticcheck,nolintlint // SA5011 Ignore the nil warnings
t.Fatalf("unexpected response")
}
@@ -24,10 +30,27 @@ func TestSetupExchangeManager(t *testing.T) {
func TestExchangeManagerAdd(t *testing.T) {
t.Parallel()
m := SetupExchangeManager()
var m *ExchangeManager
err := m.Add(nil)
if !errors.Is(err, ErrNilSubsystem) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrNilSubsystem)
}
m = NewExchangeManager()
err = m.Add(nil)
if !errors.Is(err, errExchangeIsNil) {
t.Fatalf("received: '%v' but expected: '%v'", err, errExchangeIsNil)
}
b := new(bitfinex.Bitfinex)
b.SetDefaults()
m.Add(b)
err = m.Add(b)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
err = m.Add(b)
if !errors.Is(err, errExchangeAlreadyLoaded) {
t.Fatalf("received: '%v' but expected: '%v'", err, errExchangeAlreadyLoaded)
}
exchanges, err := m.GetExchanges()
if err != nil {
t.Error("no exchange manager found")
@@ -39,7 +62,13 @@ func TestExchangeManagerAdd(t *testing.T) {
func TestExchangeManagerGetExchanges(t *testing.T) {
t.Parallel()
m := SetupExchangeManager()
var m *ExchangeManager
_, err := m.GetExchanges()
if !errors.Is(err, ErrNilSubsystem) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrNilSubsystem)
}
m = NewExchangeManager()
exchanges, err := m.GetExchanges()
if err != nil {
t.Error("no exchange manager found")
@@ -49,7 +78,10 @@ func TestExchangeManagerGetExchanges(t *testing.T) {
}
b := new(bitfinex.Bitfinex)
b.SetDefaults()
m.Add(b)
err = m.Add(b)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
exchanges, err = m.GetExchanges()
if err != nil {
t.Error("no exchange manager found")
@@ -61,30 +93,76 @@ func TestExchangeManagerGetExchanges(t *testing.T) {
func TestExchangeManagerRemoveExchange(t *testing.T) {
t.Parallel()
m := SetupExchangeManager()
if err := m.RemoveExchange("Bitfinex"); err != ErrNoExchangesLoaded {
t.Error("no exchanges should be loaded")
var m *ExchangeManager
err := m.RemoveExchange("")
if !errors.Is(err, ErrNilSubsystem) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrNilSubsystem)
}
m = NewExchangeManager()
err = m.RemoveExchange("")
if !errors.Is(err, ErrExchangeNameIsEmpty) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrExchangeNameIsEmpty)
}
err = m.RemoveExchange("Bitfinex")
if !errors.Is(err, ErrExchangeNotFound) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrExchangeNotFound)
}
b := new(bitfinex.Bitfinex)
b.SetDefaults()
m.Add(b)
err := m.RemoveExchange("Bitstamp")
err = m.Add(b)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
err = m.RemoveExchange("Bitstamp")
if !errors.Is(err, ErrExchangeNotFound) {
t.Errorf("received: %v but expected: %v", err, ErrExchangeNotFound)
}
if err := m.RemoveExchange("BiTFiNeX"); err != nil {
t.Error("exchange should have been removed")
err = m.RemoveExchange("BiTFiNeX")
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
if m.Len() != 0 {
if len(m.exchanges) != 0 {
t.Error("exchange manager len should be 0")
}
brokenExch := &broken{}
brokenExch.SetDefaults()
err = m.Add(brokenExch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
err = m.RemoveExchange("BiTFiNeX")
if !errors.Is(err, errExpectedTestError) {
t.Fatalf("received: '%v' but expected: '%v'", err, errExpectedTestError)
}
}
func TestNewExchangeByName(t *testing.T) {
m := SetupExchangeManager()
var m *ExchangeManager
_, err := m.NewExchangeByName("")
if !errors.Is(err, ErrNilSubsystem) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrNilSubsystem)
}
m = NewExchangeManager()
_, err = m.NewExchangeByName("")
if !errors.Is(err, ErrExchangeNameIsEmpty) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrExchangeNameIsEmpty)
}
exchanges := []string{"binanceus", "binance", "bitfinex", "bitflyer", "bithumb", "bitmex", "bitstamp", "bittrex", "btc markets", "btse", "bybit", "coinut", "exmo", "coinbasepro", "gateio", "gemini", "hitbtc", "huobi", "itbit", "kraken", "lbank", "okcoin international", "okx", "poloniex", "yobit", "zb", "fake"}
for i := range exchanges {
exch, err := m.NewExchangeByName(exchanges[i])
var exch exchange.IBotExchange
exch, err = m.NewExchangeByName(exchanges[i])
if err != nil && exchanges[i] != "fake" {
t.Fatal(err)
}
@@ -95,6 +173,19 @@ func TestNewExchangeByName(t *testing.T) {
}
}
}
load := &bitfinex.Bitfinex{}
load.SetDefaults()
err = m.Add(load)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
_, err = m.NewExchangeByName("bitfinex")
if !errors.Is(err, ErrExchangeAlreadyLoaded) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrExchangeAlreadyLoaded)
}
}
type ExchangeBuilder struct{}
@@ -113,7 +204,7 @@ func (n ExchangeBuilder) NewExchangeByName(name string) (exchange.IBotExchange,
}
func TestNewCustomExchangeByName(t *testing.T) {
m := SetupExchangeManager()
m := NewExchangeManager()
m.Builder = ExchangeBuilder{}
name := "customex"
exch, err := m.NewExchangeByName(name)
@@ -127,3 +218,31 @@ func TestNewCustomExchangeByName(t *testing.T) {
}
}
}
func TestExchangeManagerShutdown(t *testing.T) {
t.Parallel()
var m *ExchangeManager
err := m.Shutdown(-1)
if !errors.Is(err, ErrNilSubsystem) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrNilSubsystem)
}
m = NewExchangeManager()
err = m.Shutdown(-1)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
brokenExch := &broken{}
brokenExch.SetDefaults()
err = m.Add(brokenExch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
err = m.Shutdown(-1)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
}

View File

@@ -59,7 +59,7 @@ func CreateTestBot(t *testing.T) *Engine {
},
}
bot := &Engine{
ExchangeManager: SetupExchangeManager(),
ExchangeManager: NewExchangeManager(),
Config: &config.Config{Exchanges: []config.Exchange{
{
Name: testExchange,
@@ -1057,7 +1057,7 @@ func createDepositEngine(opts *fakeDepositExchangeOpts) *Engine {
ps.Available = nil
}
return &Engine{
Settings: Settings{Verbose: true},
Settings: Settings{CoreSettings: CoreSettings{Verbose: true}},
Config: &config.Config{
Exchanges: []config.Exchange{
{
@@ -1189,7 +1189,10 @@ func TestGetExchangeNames(t *testing.T) {
}
if exch != nil {
exch.SetDefaults()
bot.ExchangeManager.Add(exch)
err = bot.ExchangeManager.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
}
}
if e := bot.GetExchangeNames(false); len(e) != len(bot.Config.Exchanges) {

View File

@@ -160,24 +160,24 @@ func TestSetupOrderManager(t *testing.T) {
if !errors.Is(err, errNilExchangeManager) {
t.Errorf("error '%v', expected '%v'", err, errNilExchangeManager)
}
_, err = SetupOrderManager(SetupExchangeManager(), nil, nil, false, false, 0)
_, err = SetupOrderManager(NewExchangeManager(), nil, nil, false, false, 0)
if !errors.Is(err, errNilCommunicationsManager) {
t.Errorf("error '%v', expected '%v'", err, errNilCommunicationsManager)
}
_, err = SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, nil, false, false, 0)
_, err = SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, nil, false, false, 0)
if !errors.Is(err, errNilWaitGroup) {
t.Errorf("error '%v', expected '%v'", err, errNilWaitGroup)
}
var wg sync.WaitGroup
_, err = SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
_, err = SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
_, err = SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, &wg, false, true, 0)
_, err = SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, &wg, false, true, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
_, err = SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, &wg, false, true, 1337)
_, err = SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, &wg, false, true, 1337)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -190,7 +190,7 @@ func TestOrderManagerStart(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
}
var wg sync.WaitGroup
m, err = SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
m, err = SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -211,7 +211,7 @@ func TestOrderManagerIsRunning(t *testing.T) {
}
var wg sync.WaitGroup
m, err := SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
m, err := SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -236,7 +236,7 @@ func TestOrderManagerStop(t *testing.T) {
}
var wg sync.WaitGroup
m, err = SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
m, err = SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, &wg, false, false, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -258,7 +258,7 @@ func TestOrderManagerStop(t *testing.T) {
func OrdersSetup(t *testing.T) *OrderManager {
t.Helper()
var wg sync.WaitGroup
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -277,7 +277,10 @@ func OrdersSetup(t *testing.T) *OrderManager {
fakeExchange := omfExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
m, err := SetupOrderManager(em, &CommunicationManager{}, &wg, false, false, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -733,7 +736,7 @@ func TestOrderManager_Modify(t *testing.T) {
func TestProcessOrders(t *testing.T) {
var wg sync.WaitGroup
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -742,7 +745,10 @@ func TestProcessOrders(t *testing.T) {
fakeExchange := omfExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
m, err := SetupOrderManager(em, &CommunicationManager{}, &wg, false, false, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -1305,13 +1311,16 @@ func TestSubmitFakeOrder(t *testing.T) {
ord.Side = order.Buy
ord.Type = order.Market
ord.Amount = 1337
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
o.orderStore.exchangeManager = em
resp, err = ord.DeriveSubmitResponse("1234")
@@ -1436,7 +1445,7 @@ func TestOrderManagerAdd(t *testing.T) {
func TestGetAllOpenFuturesPositions(t *testing.T) {
t.Parallel()
wg := &sync.WaitGroup{}
o, err := SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, wg, false, false, time.Hour)
o, err := SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, wg, false, false, time.Hour)
if !errors.Is(err, nil) {
t.Errorf("received '%v', expected '%v'", err, nil)
}
@@ -1464,7 +1473,7 @@ func TestGetAllOpenFuturesPositions(t *testing.T) {
func TestGetOpenFuturesPosition(t *testing.T) {
t.Parallel()
wg := &sync.WaitGroup{}
o, err := SetupOrderManager(SetupExchangeManager(), &CommunicationManager{}, wg, false, false, time.Hour)
o, err := SetupOrderManager(NewExchangeManager(), &CommunicationManager{}, wg, false, false, time.Hour)
if !errors.Is(err, nil) {
t.Errorf("received '%v', expected '%v'", err, nil)
}
@@ -1481,7 +1490,7 @@ func TestGetOpenFuturesPosition(t *testing.T) {
t.Errorf("received '%v', expected '%v'", err, order.ErrNotFuturesAsset)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -1508,7 +1517,10 @@ func TestGetOpenFuturesPosition(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
o, err = SetupOrderManager(em, &CommunicationManager{}, wg, false, true, time.Hour)
if !errors.Is(err, nil) {
t.Errorf("received '%v', expected '%v'", err, nil)
@@ -1557,7 +1569,7 @@ func TestProcessFuturesPositions(t *testing.T) {
if !errors.Is(err, errFuturesTrackingDisabled) {
t.Errorf("received '%v', expected '%v'", err, errFuturesTrackingDisabled)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -1594,7 +1606,10 @@ func TestProcessFuturesPositions(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
o, err = SetupOrderManager(em, &CommunicationManager{}, &wg, false, true, time.Hour)
if !errors.Is(err, nil) {

View File

@@ -12,7 +12,7 @@ func TestSetupPortfolioManager(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, errNilExchangeManager)
}
m, err := setupPortfolioManager(SetupExchangeManager(), 0, nil)
m, err := setupPortfolioManager(NewExchangeManager(), 0, nil)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -27,7 +27,7 @@ func TestIsPortfolioManagerRunning(t *testing.T) {
t.Error("expected false")
}
m, err := setupPortfolioManager(SetupExchangeManager(), 0, nil)
m, err := setupPortfolioManager(NewExchangeManager(), 0, nil)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -52,7 +52,7 @@ func TestPortfolioManagerStart(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
}
m, err = setupPortfolioManager(SetupExchangeManager(), 0, nil)
m, err = setupPortfolioManager(NewExchangeManager(), 0, nil)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -81,7 +81,7 @@ func TestPortfolioManagerStop(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
}
m, err = setupPortfolioManager(SetupExchangeManager(), 0, nil)
m, err = setupPortfolioManager(NewExchangeManager(), 0, nil)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -101,13 +101,16 @@ func TestPortfolioManagerStop(t *testing.T) {
}
func TestProcessPortfolio(t *testing.T) {
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("Bitstamp")
if !errors.Is(err, nil) {
t.Fatalf("error '%v', expected '%v'", err, nil)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
m, err := setupPortfolioManager(em, 0, nil)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)

View File

@@ -390,7 +390,7 @@ func RPCTestSetup(t *testing.T) *Engine {
})
engerino.Config = &config.Config{}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -405,7 +405,10 @@ func RPCTestSetup(t *testing.T) *Engine {
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
exch, err = em.NewExchangeByName("Binance")
if err != nil {
@@ -421,7 +424,10 @@ func RPCTestSetup(t *testing.T) *Engine {
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
engerino.ExchangeManager = em
engerino.Config.Database = dbConf
@@ -1048,7 +1054,7 @@ func TestFindMissingSavedCandleIntervals(t *testing.T) {
func TestSetExchangeTradeProcessing(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -1058,7 +1064,10 @@ func TestSetExchangeTradeProcessing(t *testing.T) {
b.Config = &config.Exchange{
Features: &config.FeaturesConfig{Enabled: config.FeaturesEnabledConfig{SaveTradeData: false}},
}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
_, err = s.SetExchangeTradeProcessing(context.Background(), &gctrpc.SetExchangeTradeProcessingRequest{Exchange: testExchange, Status: true})
if err != nil {
@@ -1166,7 +1175,7 @@ func TestGetHistoricTrades(t *testing.T) {
func TestGetAccountInfo(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -1181,7 +1190,10 @@ func TestGetAccountInfo(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
_, err = s.GetAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{Exchange: fakeExchangeName, AssetType: asset.Spot.String()})
if !errors.Is(err, nil) {
@@ -1191,7 +1203,7 @@ func TestGetAccountInfo(t *testing.T) {
func TestUpdateAccountInfo(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -1206,7 +1218,10 @@ func TestUpdateAccountInfo(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
_, err = s.GetAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{Exchange: fakeExchangeName, AssetType: asset.Spot.String()})
@@ -1232,7 +1247,7 @@ func TestGetOrders(t *testing.T) {
t.Parallel()
exchName := "Binance"
engerino := &Engine{}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(exchName)
if err != nil {
t.Fatal(err)
@@ -1247,7 +1262,10 @@ func TestGetOrders(t *testing.T) {
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
om, err := SetupOrderManager(em, engerino.CommunicationsManager, &wg, false, false, 0)
if !errors.Is(err, nil) {
@@ -1339,7 +1357,7 @@ func TestGetOrder(t *testing.T) {
t.Parallel()
exchName := "Binance"
engerino := &Engine{}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(exchName)
if err != nil {
t.Fatal(err)
@@ -1354,7 +1372,10 @@ func TestGetOrder(t *testing.T) {
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
om, err := SetupOrderManager(em, engerino.CommunicationsManager, &wg, false, false, 0)
if !errors.Is(err, nil) {
@@ -1588,7 +1609,7 @@ func TestParseEvents(t *testing.T) {
func TestRPCServerUpsertDataHistoryJob(t *testing.T) {
t.Parallel()
m, _ := createDHM(t)
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -1601,7 +1622,10 @@ func TestRPCServerUpsertDataHistoryJob(t *testing.T) {
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true)}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{dataHistoryManager: m, ExchangeManager: em}}
_, err = s.UpsertDataHistoryJob(context.Background(), nil)
if !errors.Is(err, errNilRequestData) {
@@ -1872,7 +1896,7 @@ func TestGetDataHistoryJobSummary(t *testing.T) {
func TestGetManagedOrders(t *testing.T) {
exchName := "Binance"
engerino := &Engine{}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(exchName)
if err != nil {
t.Fatal(err)
@@ -1887,7 +1911,10 @@ func TestGetManagedOrders(t *testing.T) {
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
om, err := SetupOrderManager(em, engerino.CommunicationsManager, &wg, false, false, 0)
if !errors.Is(err, nil) {
@@ -2168,7 +2195,7 @@ func TestCurrencyStateTrading(t *testing.T) {
func TestCurrencyStateTradingPair(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -2192,7 +2219,10 @@ func TestCurrencyStateTradingPair(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em,
currencyStateManager: &CurrencyStateManager{started: 1, iExchangeManager: em}}}
@@ -2209,7 +2239,7 @@ func TestCurrencyStateTradingPair(t *testing.T) {
func TestGetFuturesPositions(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -2243,7 +2273,10 @@ func TestGetFuturesPositions(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
om, err := SetupOrderManager(em, &CommunicationManager{}, &wg, false, false, time.Hour)
if !errors.Is(err, nil) {
@@ -2345,7 +2378,7 @@ func TestGetFuturesPositions(t *testing.T) {
func TestGetCollateral(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -2375,7 +2408,10 @@ func TestGetCollateral(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{
Engine: &Engine{
ExchangeManager: em,
@@ -2466,7 +2502,7 @@ func TestShutdown(t *testing.T) {
func TestGetTechnicalAnalysis(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -2495,7 +2531,10 @@ func TestGetTechnicalAnalysis(t *testing.T) {
}
b.Features.Enabled.Kline.Intervals = kline.DeployExchangeIntervals(kline.OneDay)
em.Add(fExchange{IBotExchange: exch})
err = em.Add(fExchange{IBotExchange: exch})
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{
Engine: &Engine{
ExchangeManager: em,
@@ -2735,7 +2774,7 @@ func TestGetTechnicalAnalysis(t *testing.T) {
func TestGetMarginRatesHistory(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
@@ -2759,7 +2798,10 @@ func TestGetMarginRatesHistory(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{
Engine: &Engine{
ExchangeManager: em,
@@ -2874,7 +2916,7 @@ func TestGetMarginRatesHistory(t *testing.T) {
func TestGetFundingRates(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -2907,7 +2949,10 @@ func TestGetFundingRates(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
om, err := SetupOrderManager(em, &CommunicationManager{}, &wg, false, false, time.Hour)
if !errors.Is(err, nil) {
@@ -2966,7 +3011,7 @@ func TestGetFundingRates(t *testing.T) {
func TestGetManagedPosition(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -3003,7 +3048,10 @@ func TestGetManagedPosition(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
om, err := SetupOrderManager(em, &CommunicationManager{}, &wg, false, false, time.Hour)
if !errors.Is(err, nil) {
@@ -3105,7 +3153,7 @@ func TestGetManagedPosition(t *testing.T) {
func TestGetAllManagedPositions(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -3142,7 +3190,10 @@ func TestGetAllManagedPositions(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var wg sync.WaitGroup
om, err := SetupOrderManager(em, &CommunicationManager{}, &wg, false, false, time.Hour)
if !errors.Is(err, nil) {
@@ -3212,7 +3263,7 @@ func TestGetAllManagedPositions(t *testing.T) {
func TestGetOrderbookMovement(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -3239,7 +3290,10 @@ func TestGetOrderbookMovement(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
@@ -3319,7 +3373,7 @@ func TestGetOrderbookMovement(t *testing.T) {
func TestGetOrderbookAmountByNominal(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -3346,7 +3400,10 @@ func TestGetOrderbookAmountByNominal(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
@@ -3419,7 +3476,7 @@ func TestGetOrderbookAmountByNominal(t *testing.T) {
func TestGetOrderbookAmountByImpact(t *testing.T) {
t.Parallel()
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("binance")
if err != nil {
t.Fatal(err)
@@ -3446,7 +3503,10 @@ func TestGetOrderbookAmountByImpact(t *testing.T) {
fakeExchange := fExchange{
IBotExchange: exch,
}
em.Add(fakeExchange)
err = em.Add(fakeExchange)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em}}

View File

@@ -64,13 +64,16 @@ func TestSyncManagerStart(t *testing.T) {
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("Bitstamp")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
m.exchangeManager = em
m.config.SynchronizeContinuously = true
err = m.Start()
@@ -98,13 +101,16 @@ func TestSyncManagerStop(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
}
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("Bitstamp")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
m, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: &currency.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -146,13 +152,16 @@ func TestPrintTickerSummary(t *testing.T) {
var m *syncManager
m.PrintTickerSummary(&ticker.Price{}, "REST", nil)
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("Bitstamp")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
m, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: &currency.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -185,13 +194,16 @@ func TestPrintOrderbookSummary(t *testing.T) {
var m *syncManager
m.PrintOrderbookSummary(nil, "REST", nil)
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName("Bitstamp")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
m, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: &currency.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)

View File

@@ -19,26 +19,26 @@ func TestWebsocketRoutineManagerSetup(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, errNilExchangeManager)
}
_, err = setupWebsocketRoutineManager(SetupExchangeManager(), nil, nil, nil, false)
_, err = setupWebsocketRoutineManager(NewExchangeManager(), nil, nil, nil, false)
if !errors.Is(err, errNilOrderManager) {
t.Errorf("error '%v', expected '%v'", err, errNilOrderManager)
}
_, err = setupWebsocketRoutineManager(SetupExchangeManager(), &OrderManager{}, nil, nil, false)
_, err = setupWebsocketRoutineManager(NewExchangeManager(), &OrderManager{}, nil, nil, false)
if !errors.Is(err, errNilCurrencyPairSyncer) {
t.Errorf("error '%v', expected '%v'", err, errNilCurrencyPairSyncer)
}
_, err = setupWebsocketRoutineManager(SetupExchangeManager(), &OrderManager{}, &syncManager{}, nil, false)
_, err = setupWebsocketRoutineManager(NewExchangeManager(), &OrderManager{}, &syncManager{}, nil, false)
if !errors.Is(err, errNilCurrencyConfig) {
t.Errorf("error '%v', expected '%v'", err, errNilCurrencyConfig)
}
_, err = setupWebsocketRoutineManager(SetupExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{}, true)
_, err = setupWebsocketRoutineManager(NewExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{}, true)
if !errors.Is(err, errNilCurrencyPairFormat) {
t.Errorf("error '%v', expected '%v'", err, errNilCurrencyPairFormat)
}
m, err := setupWebsocketRoutineManager(SetupExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{CurrencyPairFormat: &currency.PairFormat{}}, false)
m, err := setupWebsocketRoutineManager(NewExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{CurrencyPairFormat: &currency.PairFormat{}}, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -57,7 +57,7 @@ func TestWebsocketRoutineManagerStart(t *testing.T) {
Uppercase: false,
Delimiter: "-",
}}
m, err = setupWebsocketRoutineManager(SetupExchangeManager(), &OrderManager{}, &syncManager{}, cfg, true)
m, err = setupWebsocketRoutineManager(NewExchangeManager(), &OrderManager{}, &syncManager{}, cfg, true)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -77,7 +77,7 @@ func TestWebsocketRoutineManagerIsRunning(t *testing.T) {
t.Error("expected false")
}
m, err := setupWebsocketRoutineManager(SetupExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{CurrencyPairFormat: &currency.PairFormat{}}, false)
m, err := setupWebsocketRoutineManager(NewExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{CurrencyPairFormat: &currency.PairFormat{}}, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -101,7 +101,7 @@ func TestWebsocketRoutineManagerStop(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
}
m, err = setupWebsocketRoutineManager(SetupExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{CurrencyPairFormat: &currency.PairFormat{}}, false)
m, err = setupWebsocketRoutineManager(NewExchangeManager(), &OrderManager{}, &syncManager{}, &currency.Config{CurrencyPairFormat: &currency.PairFormat{}}, false)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
@@ -123,14 +123,16 @@ func TestWebsocketRoutineManagerStop(t *testing.T) {
func TestWebsocketRoutineManagerHandleData(t *testing.T) {
var exchName = "Bitstamp"
var wg sync.WaitGroup
em := SetupExchangeManager()
em := NewExchangeManager()
exch, err := em.NewExchangeByName(exchName)
if !errors.Is(err, nil) {
t.Fatalf("error '%v', expected '%v'", err, nil)
}
exch.SetDefaults()
em.Add(exch)
err = em.Add(exch)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
om, err := SetupOrderManager(em, &CommunicationManager{}, &wg, false, false, 0)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)

View File

@@ -22,7 +22,7 @@ const (
func withdrawManagerTestHelper(t *testing.T) (*ExchangeManager, *portfolioManager) {
t.Helper()
em := SetupExchangeManager()
em := NewExchangeManager()
b := new(bybit.Bybit)
b.SetDefaults()
cfg, err := b.GetDefaultConfig(context.Background())
@@ -33,7 +33,10 @@ func withdrawManagerTestHelper(t *testing.T) (*ExchangeManager, *portfolioManage
if err != nil {
t.Fatal(err)
}
em.Add(b)
err = em.Add(b)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
pm, err := setupPortfolioManager(em, 0, &portfolio.Base{Addresses: []portfolio.Address{}})
if err != nil {
t.Fatal(err)