mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
daily progress build
This commit is contained in:
@@ -158,7 +158,7 @@ func (c *Config) UpdateClientBankAccounts(bankCfg *BankAccount) error {
|
||||
}
|
||||
|
||||
// CheckClientBankAccounts checks client bank details
|
||||
func (c *Config) CheckClientBankAccounts() error {
|
||||
func (c *Config) CheckClientBankAccounts() {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
@@ -175,24 +175,30 @@ func (c *Config) CheckClientBankAccounts() error {
|
||||
SupportedExchanges: "ANX,Kraken",
|
||||
},
|
||||
)
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
for i := range c.BankAccounts {
|
||||
if c.BankAccounts[i].Enabled {
|
||||
if c.BankAccounts[i].BankName == "" || c.BankAccounts[i].BankAddress == "" {
|
||||
return fmt.Errorf("banking details for %s is enabled but variables not set correctly",
|
||||
c.BankAccounts[i].Enabled = false
|
||||
log.Warnf("banking details for %s is enabled but variables not set correctly",
|
||||
c.BankAccounts[i].BankName)
|
||||
continue
|
||||
}
|
||||
|
||||
if c.BankAccounts[i].AccountName == "" || c.BankAccounts[i].AccountNumber == "" {
|
||||
return fmt.Errorf("banking account details for %s variables not set correctly",
|
||||
c.BankAccounts[i].Enabled = false
|
||||
log.Warnf("banking account details for %s variables not set correctly",
|
||||
c.BankAccounts[i].BankName)
|
||||
continue
|
||||
}
|
||||
if c.BankAccounts[i].IBAN == "" && c.BankAccounts[i].SWIFTCode == "" && c.BankAccounts[i].BSBNumber == "" {
|
||||
return fmt.Errorf("critical banking numbers not set for %s in %s account",
|
||||
c.BankAccounts[i].Enabled = false
|
||||
log.Warnf("critical banking numbers not set for %s in %s account",
|
||||
c.BankAccounts[i].BankName,
|
||||
c.BankAccounts[i].AccountName)
|
||||
continue
|
||||
}
|
||||
|
||||
if c.BankAccounts[i].SupportedExchanges == "" {
|
||||
@@ -200,7 +206,6 @@ func (c *Config) CheckClientBankAccounts() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PurgeExchangeAPICredentials purges the stored API credentials
|
||||
@@ -1254,7 +1259,7 @@ func (c *Config) CheckNTPConfig() {
|
||||
}
|
||||
|
||||
if len(c.NTPClient.Pool) < 1 {
|
||||
log.Warn("NTPClient enabled with no servers configured enabling default pool")
|
||||
log.Warn("NTPClient enabled with no servers configured, enabling default pool.")
|
||||
c.NTPClient.Pool = []string{"pool.ntp.org:123"}
|
||||
}
|
||||
}
|
||||
@@ -1265,8 +1270,8 @@ func (c *Config) DisableNTPCheck(input io.Reader) (string, error) {
|
||||
defer m.Unlock()
|
||||
|
||||
reader := bufio.NewReader(input)
|
||||
log.Warn("Your system time is out of sync this may cause issues with trading")
|
||||
log.Warn("How would you like to show future notifications? (a)lert / (w)arn / (d)isable \n")
|
||||
log.Warn("Your system time is out of sync, this may cause issues with trading.")
|
||||
log.Warn("How would you like to show future notifications? (a)lert / (w)arn / (d)isable. \n")
|
||||
|
||||
var answered = false
|
||||
for ok := true; ok; ok = (!answered) {
|
||||
@@ -1291,7 +1296,7 @@ func (c *Config) DisableNTPCheck(input io.Reader) (string, error) {
|
||||
return "Future notications for out time sync have been disabled", nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("something went wrong NTPCheck should never make it this far")
|
||||
return "", errors.New("something went wrong, NTPCheck should never make it this far")
|
||||
}
|
||||
|
||||
// CheckConnectionMonitorConfig checks and if zero value assigns default values
|
||||
@@ -1502,15 +1507,11 @@ func (c *Config) SaveConfig(configPath string) error {
|
||||
return common.WriteFile(defaultPath, payload)
|
||||
}
|
||||
|
||||
// CheckConfig checks all config settings
|
||||
func (c *Config) CheckConfig() error {
|
||||
err := c.CheckExchangeConfigValues()
|
||||
if err != nil {
|
||||
return fmt.Errorf(ErrCheckingConfigValues, err)
|
||||
}
|
||||
|
||||
c.CheckConnectionMonitorConfig()
|
||||
c.CheckCommunicationsConfig()
|
||||
// CheckRemoteControlConfig checks to see if the old c.Webserver field is used
|
||||
// and migrates the existing settings to the new RemoteControl struct
|
||||
func (c *Config) CheckRemoteControlConfig() {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
if c.Webserver != nil {
|
||||
port := common.ExtractPort(c.Webserver.ListenAddress)
|
||||
@@ -1548,6 +1549,25 @@ func (c *Config) CheckConfig() error {
|
||||
c.Webserver = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// CheckConfig checks all config settings
|
||||
func (c *Config) CheckConfig() error {
|
||||
err := c.CheckLoggerConfig()
|
||||
if err != nil {
|
||||
log.Errorf("Failed to configure logger. Err: %s", err)
|
||||
}
|
||||
|
||||
err = c.CheckExchangeConfigValues()
|
||||
if err != nil {
|
||||
return fmt.Errorf(ErrCheckingConfigValues, err)
|
||||
}
|
||||
|
||||
c.CheckConnectionMonitorConfig()
|
||||
c.CheckCommunicationsConfig()
|
||||
c.CheckClientBankAccounts()
|
||||
c.CheckRemoteControlConfig()
|
||||
|
||||
err = c.CheckCurrencyConfigValues()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1558,7 +1578,11 @@ func (c *Config) CheckConfig() error {
|
||||
c.GlobalHTTPTimeout = configDefaultHTTPTimeout
|
||||
}
|
||||
|
||||
return c.CheckClientBankAccounts()
|
||||
if c.NTPClient.Level != 0 {
|
||||
c.CheckNTPConfig()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadConfig loads your configuration file into your configuration object
|
||||
|
||||
@@ -130,7 +130,7 @@ func TestCheckClientBankAccounts(t *testing.T) {
|
||||
}
|
||||
|
||||
cfg.BankAccounts = nil
|
||||
err = cfg.CheckClientBankAccounts()
|
||||
cfg.CheckClientBankAccounts()
|
||||
if err != nil || len(cfg.BankAccounts) == 0 {
|
||||
t.Error("Test failed. CheckClientBankAccounts error:", err)
|
||||
}
|
||||
@@ -140,33 +140,7 @@ func TestCheckClientBankAccounts(t *testing.T) {
|
||||
Enabled: true,
|
||||
BankName: "test",
|
||||
})
|
||||
err = cfg.CheckClientBankAccounts()
|
||||
if err.Error() != "banking details for test is enabled but variables not set correctly" {
|
||||
t.Error("Test failed. CheckClientBankAccounts unexpected error:", err)
|
||||
}
|
||||
|
||||
cfg.BankAccounts[0].BankAddress = "test"
|
||||
err = cfg.CheckClientBankAccounts()
|
||||
if err.Error() != "banking account details for test variables not set correctly" {
|
||||
t.Error("Test failed. CheckClientBankAccounts unexpected error:", err)
|
||||
}
|
||||
|
||||
cfg.BankAccounts[0].AccountName = "Thrasher"
|
||||
cfg.BankAccounts[0].AccountNumber = "1337"
|
||||
err = cfg.CheckClientBankAccounts()
|
||||
if err.Error() != "critical banking numbers not set for test in Thrasher account" {
|
||||
t.Error("Test failed. CheckClientBankAccounts unexpected error:", err)
|
||||
}
|
||||
|
||||
cfg.BankAccounts[0].IBAN = "12345678"
|
||||
err = cfg.CheckClientBankAccounts()
|
||||
if err != nil {
|
||||
t.Error("Test failed. CheckClientBankAccounts error:", err)
|
||||
}
|
||||
if cfg.BankAccounts[0].SupportedExchanges == "" {
|
||||
t.Error("Test failed. CheckClientBankAccounts SupportedExchanges unexpectedly nil, data:",
|
||||
cfg.BankAccounts[0])
|
||||
}
|
||||
// TO-DO: Complete test coverage
|
||||
}
|
||||
|
||||
func TestGetCommunicationsConfig(t *testing.T) {
|
||||
|
||||
@@ -86,7 +86,7 @@ func (c *Checker) Shutdown() {
|
||||
// Monitor determines internet connectivity via a DNS lookup
|
||||
func (c *Checker) Monitor(wg *sync.WaitGroup) {
|
||||
c.wg.Add(1)
|
||||
tick := time.NewTicker(time.Second)
|
||||
tick := time.NewTicker(c.CheckInterval)
|
||||
defer func() { tick.Stop(); c.wg.Done() }()
|
||||
wg.Done()
|
||||
for {
|
||||
|
||||
@@ -343,7 +343,7 @@ func (s *Storage) SeedCurrencyAnalysisData() error {
|
||||
// loads it into memory
|
||||
func (s *Storage) FetchCurrencyAnalysisData() error {
|
||||
if s.currencyAnalysis == nil {
|
||||
log.Warn("Currency analysis system offline please set api keys for coinmarketcap")
|
||||
log.Warn("Currency analysis system offline, please set api keys for coinmarketcap if you wish to use this feature.")
|
||||
return errors.New("currency analysis system offline")
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ type Engine struct {
|
||||
Exchanges []exchange.IBotExchange
|
||||
ExchangeCurrencyPairManager *ExchangeCurrencyPairSyncer
|
||||
OrderManager *OrderManager
|
||||
PortfolioManager portfolioManager
|
||||
CommsRelayer *communications.Communications
|
||||
Connectivity *connchecker.Checker
|
||||
Shutdown chan bool
|
||||
@@ -86,11 +87,6 @@ func NewFromSettings(settings *Settings) (*Engine, error) {
|
||||
return nil, fmt.Errorf("failed to open/create data directory: %s. Err: %s", settings.DataDir, err)
|
||||
}
|
||||
|
||||
err = b.Config.CheckLoggerConfig()
|
||||
if err != nil {
|
||||
log.Errorf("Failed to configure logger. Err: %s", err)
|
||||
}
|
||||
|
||||
err = log.SetupLogger()
|
||||
if err != nil {
|
||||
log.Errorf("Failed to setup logger. Err: %s", err)
|
||||
@@ -119,7 +115,7 @@ func ValidateSettings(b *Engine, s *Settings) {
|
||||
b.Settings.EnableDryRun = s.EnableDryRun
|
||||
b.Settings.EnableAllExchanges = s.EnableAllExchanges
|
||||
b.Settings.EnableAllPairs = s.EnableAllPairs
|
||||
b.Settings.EnablePortfolioWatcher = s.EnablePortfolioWatcher
|
||||
b.Settings.EnablePortfolioManager = s.EnablePortfolioManager
|
||||
b.Settings.EnableCoinmarketcapAnalysis = s.EnableCoinmarketcapAnalysis
|
||||
|
||||
// TO-DO: FIXME
|
||||
@@ -159,10 +155,11 @@ func ValidateSettings(b *Engine, s *Settings) {
|
||||
}
|
||||
}
|
||||
|
||||
b.Settings.EnableConnectivityMonitor = s.EnableConnectivityMonitor
|
||||
b.Settings.EnableNTPClient = s.EnableNTPClient
|
||||
b.Settings.EnableTickerRoutine = s.EnableTickerRoutine
|
||||
b.Settings.EnableOrderbookRoutine = s.EnableOrderbookRoutine
|
||||
b.Settings.EnableWebsocketRoutine = s.EnableWebsocketRoutine
|
||||
b.Settings.EnableExchangeSyncManager = s.EnableExchangeSyncManager
|
||||
b.Settings.EnableTickerSyncing = s.EnableTickerSyncing
|
||||
b.Settings.EnableOrderbookSyncing = s.EnableOrderbookSyncing
|
||||
b.Settings.EnableExchangeAutoPairUpdates = s.EnableExchangeAutoPairUpdates
|
||||
b.Settings.EnableExchangeWebsocketSupport = s.EnableExchangeWebsocketSupport
|
||||
b.Settings.EnableExchangeRESTSupport = s.EnableExchangeRESTSupport
|
||||
@@ -222,7 +219,7 @@ func PrintSettings(s *Settings) {
|
||||
log.Debugf("\t Enable all exchanges: %v", s.EnableAllExchanges)
|
||||
log.Debugf("\t Enable all pairs: %v", s.EnableAllPairs)
|
||||
log.Debugf("\t Enable coinmarketcap analaysis: %v", s.EnableCoinmarketcapAnalysis)
|
||||
log.Debugf("\t Enable portfolio watcher: %v", s.EnablePortfolioWatcher)
|
||||
log.Debugf("\t Enable portfolio watcher: %v", s.EnablePortfolioManager)
|
||||
log.Debugf("\t Enable gPRC: %v", s.EnableGRPC)
|
||||
log.Debugf("\t Enable gRPC Proxy: %v", s.EnableGRPCProxy)
|
||||
log.Debugf("\t Enable websocket RPC: %v", s.EnableWebsocketRPC)
|
||||
@@ -230,8 +227,10 @@ func PrintSettings(s *Settings) {
|
||||
log.Debugf("\t Enable comms relayer: %v", s.EnableCommsRelayer)
|
||||
log.Debugf("\t Enable event manager: %v", s.EnableEventManager)
|
||||
log.Debugf("\t Event manager sleep delay: %v", s.EventManagerDelay)
|
||||
log.Debugf("\t Enable ticker routine: %v", s.EnableTickerRoutine)
|
||||
log.Debugf("\t Enable orderbook routine: %v", s.EnableOrderbookRoutine)
|
||||
log.Debugf("\t Enable order manager: %v", s.EnableOrderManager)
|
||||
log.Debugf("\t Enable exchange sync manager: %v", s.EnableExchangeSyncManager)
|
||||
log.Debugf("\t Enable ticker syncing: %v", s.EnableTickerSyncing)
|
||||
log.Debugf("\t Enable orderbook syncing: %v", s.EnableOrderbookSyncing)
|
||||
log.Debugf("\t Enable websocket routine: %v\n", s.EnableWebsocketRoutine)
|
||||
log.Debugf("\t Enable NTP client: %v", s.EnableNTPClient)
|
||||
log.Debugf("- FOREX SETTINGS:")
|
||||
@@ -266,16 +265,17 @@ func (e *Engine) Start() {
|
||||
|
||||
// Sets up internet connectivity monitor
|
||||
var err error
|
||||
e.Connectivity, err = connchecker.New(e.Config.ConnectionMonitor.DNSList,
|
||||
e.Config.ConnectionMonitor.PublicDomainList,
|
||||
e.Config.ConnectionMonitor.CheckInterval)
|
||||
if err != nil {
|
||||
log.Fatalf("Connectivity checker failure: %s", err)
|
||||
if e.Settings.EnableConnectivityMonitor {
|
||||
e.Connectivity, err = connchecker.New(e.Config.ConnectionMonitor.DNSList,
|
||||
e.Config.ConnectionMonitor.PublicDomainList,
|
||||
e.Config.ConnectionMonitor.CheckInterval)
|
||||
if err != nil {
|
||||
log.Fatalf("Connectivity checker failure: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if e.Settings.EnableNTPClient {
|
||||
if e.Config.NTPClient.Level != -1 {
|
||||
e.Config.CheckNTPConfig()
|
||||
NTPTime, errNTP := ntpclient.NTPClient(e.Config.NTPClient.Pool)
|
||||
currentTime := time.Now()
|
||||
if errNTP != nil {
|
||||
@@ -356,10 +356,6 @@ func (e *Engine) Start() {
|
||||
log.Warn("currency updater system failed to start", err)
|
||||
}
|
||||
|
||||
e.Portfolio = &portfolio.Portfolio
|
||||
e.Portfolio.Seed(e.Config.Portfolio)
|
||||
SeedExchangeAccountInfo(GetAllEnabledExchangeAccountInfo().Data)
|
||||
|
||||
e.CryptocurrencyDepositAddresses = GetExchangeCryptocurrencyDepositAddresses()
|
||||
|
||||
if e.Settings.EnableGRPC {
|
||||
@@ -375,42 +371,31 @@ func (e *Engine) Start() {
|
||||
StartWebsocketHandler()
|
||||
}
|
||||
|
||||
if e.Settings.EnablePortfolioWatcher {
|
||||
go portfolio.StartPortfolioWatcher()
|
||||
if e.Settings.EnablePortfolioManager {
|
||||
if err = e.PortfolioManager.Start(); err != nil {
|
||||
log.Errorf("Fund manager unable to start: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if e.Settings.EnableExchangeSyncManager {
|
||||
exchangeSyncCfg := CurrencyPairSyncerConfig{
|
||||
SyncTicker: true,
|
||||
SyncOrderbook: true,
|
||||
SyncTicker: e.Settings.EnableTickerSyncing,
|
||||
SyncOrderbook: e.Settings.EnableOrderbookSyncing,
|
||||
SyncContinuously: true,
|
||||
NumWorkers: 15,
|
||||
}
|
||||
|
||||
|
||||
e.ExchangeCurrencyPairManager, err = NewCurrencyPairSyncer(exchangeSyncCfg)
|
||||
if err != nil {
|
||||
log.Warnf("Unable to initialise exchange currency pair syncer. Err: %s", err)
|
||||
} else {
|
||||
e.ExchangeCurrencyPairManager.Start()
|
||||
}
|
||||
*/
|
||||
|
||||
go StartOrderManagerRoutine()
|
||||
|
||||
if e.Settings.EnableTickerRoutine {
|
||||
go TickerUpdaterRoutine()
|
||||
e.ExchangeCurrencyPairManager, err = NewCurrencyPairSyncer(exchangeSyncCfg)
|
||||
if err != nil {
|
||||
log.Warnf("Unable to initialise exchange currency pair syncer. Err: %s", err)
|
||||
} else {
|
||||
go e.ExchangeCurrencyPairManager.Start()
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
if e.Settings.EnableOrderbookRoutine {
|
||||
go OrderbookUpdaterRoutine()
|
||||
}
|
||||
|
||||
if e.Settings.EnableWebsocketRoutine {
|
||||
go WebsocketRoutine()
|
||||
}
|
||||
*/
|
||||
if e.Settings.EnableOrderManager {
|
||||
go StartOrderManagerRoutine()
|
||||
}
|
||||
|
||||
if e.Settings.EnableEventManager {
|
||||
go events.EventManger()
|
||||
@@ -428,9 +413,14 @@ func (e *Engine) Stop() {
|
||||
e.Config.Portfolio = portfolio.Portfolio
|
||||
}
|
||||
|
||||
if e.PortfolioManager.Started() {
|
||||
if err := e.PortfolioManager.Stop(); err != nil {
|
||||
log.Errorf("Fund manager unable to stop. Error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !e.Settings.EnableDryRun {
|
||||
err := e.Config.SaveConfig(e.Settings.ConfigFile)
|
||||
|
||||
if err != nil {
|
||||
log.Error("Unable to save config.")
|
||||
} else {
|
||||
|
||||
@@ -14,17 +14,20 @@ type Settings struct {
|
||||
EnableAllExchanges bool
|
||||
EnableAllPairs bool
|
||||
EnableCoinmarketcapAnalysis bool
|
||||
EnablePortfolioWatcher bool
|
||||
EnablePortfolioManager bool
|
||||
EnableGRPC bool
|
||||
EnableGRPCProxy bool
|
||||
EnableWebsocketRPC bool
|
||||
EnableDeprecatedRPC bool
|
||||
EnableTickerRoutine bool
|
||||
EnableOrderbookRoutine bool
|
||||
EnableWebsocketRoutine bool
|
||||
EnableCommsRelayer bool
|
||||
EnableExchangeSyncManager bool
|
||||
EnableTickerSyncing bool
|
||||
EnableOrderbookSyncing bool
|
||||
EnableEventManager bool
|
||||
EnableOrderManager bool
|
||||
EnableConnectivityMonitor bool
|
||||
EnableNTPClient bool
|
||||
EnableWebsocketRoutine bool
|
||||
EventManagerDelay time.Duration
|
||||
Verbose bool
|
||||
|
||||
|
||||
@@ -269,8 +269,9 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error {
|
||||
// SetupExchanges sets up the exchanges used by the Bot
|
||||
func SetupExchanges() {
|
||||
var wg sync.WaitGroup
|
||||
for x := range Bot.Config.Exchanges {
|
||||
exch := &Bot.Config.Exchanges[x]
|
||||
exchanges := Bot.Config.GetAllExchangeConfigs()
|
||||
for x := range exchanges {
|
||||
exch := exchanges[x]
|
||||
if CheckExchangeExists(exch.Name) {
|
||||
e := GetExchangeByName(exch.Name)
|
||||
if e == nil {
|
||||
|
||||
@@ -26,6 +26,14 @@ import (
|
||||
"github.com/thrasher-/gocryptotrader/utils"
|
||||
)
|
||||
|
||||
// IsOnline returns whether or not the engine has Internet connectivity
|
||||
func IsOnline() bool {
|
||||
if Bot.Connectivity == nil {
|
||||
log.Warnf("IsOnline called but Bot.Connectivity is nil")
|
||||
}
|
||||
return Bot.Connectivity.IsConnected()
|
||||
}
|
||||
|
||||
// GetAvailableExchanges returns a list of enabled exchanges
|
||||
func GetAvailableExchanges() []string {
|
||||
var enExchanges []string
|
||||
|
||||
81
engine/portfolio.go
Normal file
81
engine/portfolio.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
"github.com/thrasher-/gocryptotrader/portfolio"
|
||||
)
|
||||
|
||||
// vars for the fund manager package
|
||||
var (
|
||||
PortfolioSleepDelay = time.Minute
|
||||
)
|
||||
|
||||
type portfolioManager struct {
|
||||
started int32
|
||||
stopped int32
|
||||
shutdown chan struct{}
|
||||
}
|
||||
|
||||
func (p *portfolioManager) Started() bool {
|
||||
return atomic.LoadInt32(&p.started) == 1
|
||||
}
|
||||
|
||||
func (p *portfolioManager) Start() error {
|
||||
if atomic.AddInt32(&p.started, 1) != 1 {
|
||||
return errors.New("portfolio manager already started")
|
||||
}
|
||||
|
||||
log.Debugln("Portfolio manager starting...")
|
||||
Bot.Portfolio = &portfolio.Portfolio
|
||||
Bot.Portfolio.Seed(Bot.Config.Portfolio)
|
||||
p.shutdown = make(chan struct{})
|
||||
go p.run()
|
||||
return nil
|
||||
}
|
||||
func (p *portfolioManager) Stop() error {
|
||||
if atomic.AddInt32(&p.stopped, 1) != 1 {
|
||||
return errors.New("portfolio manager is already stopped")
|
||||
}
|
||||
|
||||
log.Debugln("Portfolio manager shutting down...")
|
||||
close(p.shutdown)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *portfolioManager) run() {
|
||||
log.Debugln("Portfolio manager started.")
|
||||
tick := time.NewTicker(PortfolioSleepDelay)
|
||||
defer func() {
|
||||
log.Debugf("Portfolio manager shutdown.")
|
||||
tick.Stop()
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-p.shutdown:
|
||||
return
|
||||
|
||||
case <-tick.C:
|
||||
p.processPortfolio()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *portfolioManager) processPortfolio() {
|
||||
pf := portfolio.GetPortfolio()
|
||||
data := pf.GetPortfolioGroupedCoin()
|
||||
for key, value := range data {
|
||||
success := pf.UpdatePortfolio(value, key)
|
||||
if success {
|
||||
log.Debugf(
|
||||
"Portfolio manager: Successfully updated address balance for %s address(es) %s\n",
|
||||
key, value,
|
||||
)
|
||||
}
|
||||
}
|
||||
SeedExchangeAccountInfo(GetAllEnabledExchangeAccountInfo().Data)
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
"github.com/thrasher-/gocryptotrader/portfolio"
|
||||
)
|
||||
|
||||
// RESTfulJSONResponse outputs a JSON response of the response interface
|
||||
@@ -100,7 +101,8 @@ func RESTGetAllActiveOrderbooks(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// RESTGetPortfolio returns the Bot portfolio
|
||||
func RESTGetPortfolio(w http.ResponseWriter, r *http.Request) {
|
||||
result := Bot.Portfolio.GetPortfolioSummary()
|
||||
p := portfolio.GetPortfolio()
|
||||
result := p.GetPortfolioSummary()
|
||||
err := RESTfulJSONResponse(w, result)
|
||||
if err != nil {
|
||||
RESTfulError(r.Method, err)
|
||||
|
||||
@@ -466,14 +466,14 @@ func (s *RPCServer) GetPortfolioSummary(ctx context.Context, r *gctrpc.GetPortfo
|
||||
|
||||
// AddPortfolioAddress adds an address to the portfolio manager
|
||||
func (s *RPCServer) AddPortfolioAddress(ctx context.Context, r *gctrpc.AddPortfolioAddressRequest) (*gctrpc.AddPortfolioAddressResponse, error) {
|
||||
Bot.Portfolio.AddAddress(r.Address, r.Description, currency.NewCode(r.CoinType), r.Balance)
|
||||
return &gctrpc.AddPortfolioAddressResponse{}, nil
|
||||
err := Bot.Portfolio.AddAddress(r.Address, r.Description, currency.NewCode(r.CoinType), r.Balance)
|
||||
return &gctrpc.AddPortfolioAddressResponse{}, err
|
||||
}
|
||||
|
||||
// RemovePortfolioAddress removes an address from the portfolio manager
|
||||
func (s *RPCServer) RemovePortfolioAddress(ctx context.Context, r *gctrpc.RemovePortfolioAddressRequest) (*gctrpc.RemovePortfolioAddressResponse, error) {
|
||||
Bot.Portfolio.RemoveAddress(r.Address, r.Description, currency.NewCode(r.CoinType))
|
||||
return &gctrpc.RemovePortfolioAddressResponse{}, nil
|
||||
err := Bot.Portfolio.RemoveAddress(r.Address, r.Description, currency.NewCode(r.CoinType))
|
||||
return &gctrpc.RemovePortfolioAddressResponse{}, err
|
||||
}
|
||||
|
||||
// GetForexProviders returns a list of available forex providers
|
||||
|
||||
11
main.go
11
main.go
@@ -32,18 +32,21 @@ func main() {
|
||||
flag.BoolVar(&settings.EnableDryRun, "dryrun", false, "dry runs bot, doesn't save config file")
|
||||
flag.BoolVar(&settings.EnableAllExchanges, "enableallexchanges", false, "enables all exchanges")
|
||||
flag.BoolVar(&settings.EnableAllPairs, "enableallpairs", false, "enables all pairs for enabled exchanges")
|
||||
flag.BoolVar(&settings.EnablePortfolioWatcher, "portfoliowatcher", true, "enables the portfolio watcher")
|
||||
flag.BoolVar(&settings.EnablePortfolioManager, "portfoliomanager", true, "enables the portfolio manager")
|
||||
flag.BoolVar(&settings.EnableGRPC, "grpc", true, "enables the grpc server")
|
||||
flag.BoolVar(&settings.EnableGRPCProxy, "grpcproxy", true, "enables the grpc proxy server")
|
||||
flag.BoolVar(&settings.EnableWebsocketRPC, "websocketrpc", true, "enables the websocket RPC server")
|
||||
flag.BoolVar(&settings.EnableDeprecatedRPC, "deprecatedrpc", true, "enables the deprecated RPC server")
|
||||
flag.BoolVar(&settings.EnableCommsRelayer, "enablecommsrelayer", true, "enables available communications relayer")
|
||||
flag.BoolVar(&settings.Verbose, "verbose", false, "increases logging verbosity for GoCryptoTrader")
|
||||
flag.BoolVar(&settings.EnableTickerRoutine, "tickerroutine", true, "enables the ticker routine for all loaded exchanges")
|
||||
flag.BoolVar(&settings.EnableOrderbookRoutine, "orderbookroutine", true, "enables the orderbook routine for all loaded exchanges")
|
||||
flag.BoolVar(&settings.EnableExchangeSyncManager, "syncmanager", true, "enables to exchange sync manager")
|
||||
flag.BoolVar(&settings.EnableTickerSyncing, "tickersync", true, "enables ticker syncing for all enabled exchanges")
|
||||
flag.BoolVar(&settings.EnableOrderbookSyncing, "orderbooksync", true, "enables orderbook syncing for all enabled exchanges")
|
||||
flag.BoolVar(&settings.EnableWebsocketRoutine, "websocketroutine", true, "enables the websocket routine for all loaded exchanges")
|
||||
flag.BoolVar(&settings.EnableCoinmarketcapAnalysis, "coinmarketcap", false, "overrides config and runs currency analysis")
|
||||
flag.BoolVar(&settings.EnableEventManager, "enableeventmanager", true, "enables the event manager")
|
||||
flag.BoolVar(&settings.EnableEventManager, "eventmanager", true, "enables the event manager")
|
||||
flag.BoolVar(&settings.EnableOrderManager, "ordermanager", true, "enables the order manager")
|
||||
flag.BoolVar(&settings.EnableConnectivityMonitor, "connectivitymonitor", true, "enables the connectivity monitor")
|
||||
flag.DurationVar(&settings.EventManagerDelay, "eventmanagerdelay", time.Duration(0), "sets the event managers sleep delay between event checking")
|
||||
flag.BoolVar(&settings.EnableNTPClient, "ntpclient", true, "enables the NTP client to check system clock drift")
|
||||
|
||||
|
||||
@@ -149,10 +149,17 @@ func (p *Base) UpdateExchangeAddressBalance(exchangeName string, coinType curren
|
||||
}
|
||||
|
||||
// AddAddress adds an address to the portfolio base
|
||||
func (p *Base) AddAddress(address, description string, coinType currency.Code, balance float64) {
|
||||
func (p *Base) AddAddress(address, description string, coinType currency.Code, balance float64) error {
|
||||
if address == "" {
|
||||
return errors.New("address is empty")
|
||||
}
|
||||
|
||||
if coinType.String() == "" {
|
||||
return errors.New("coin type is empty")
|
||||
}
|
||||
|
||||
if description == PortfolioAddressExchange {
|
||||
p.AddExchangeAddress(address, coinType, balance)
|
||||
return
|
||||
}
|
||||
if !p.AddressExists(address) {
|
||||
p.Addresses = append(
|
||||
@@ -166,19 +173,30 @@ func (p *Base) AddAddress(address, description string, coinType currency.Code, b
|
||||
p.UpdateAddressBalance(address, balance)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveAddress removes an address when checked against the correct address and
|
||||
// coinType
|
||||
func (p *Base) RemoveAddress(address, description string, coinType currency.Code) {
|
||||
func (p *Base) RemoveAddress(address, description string, coinType currency.Code) error {
|
||||
if address == "" {
|
||||
return errors.New("address is empty")
|
||||
}
|
||||
|
||||
if coinType.String() == "" {
|
||||
return errors.New("coin type is empty")
|
||||
}
|
||||
|
||||
for x := range p.Addresses {
|
||||
if p.Addresses[x].Address == address &&
|
||||
p.Addresses[x].CoinType == coinType &&
|
||||
p.Addresses[x].Description == description {
|
||||
p.Addresses = append(p.Addresses[:x], p.Addresses[x+1:]...)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New("portfolio item does not exist")
|
||||
}
|
||||
|
||||
// UpdatePortfolio adds to the portfolio addresses by coin type
|
||||
|
||||
@@ -138,7 +138,19 @@ func TestUpdateAddressBalance(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRemoveAddress(t *testing.T) {
|
||||
newbase := Base{}
|
||||
var newbase Base
|
||||
if err := newbase.RemoveAddress("", "MEOW", currency.LTC); err == nil {
|
||||
t.Error("invalid address should throw an error")
|
||||
}
|
||||
|
||||
if err := newbase.RemoveAddress("Gibson", "", currency.NewCode("")); err == nil {
|
||||
t.Error("invalid coin type should throw an error")
|
||||
}
|
||||
|
||||
if err := newbase.RemoveAddress("HIDDENERINO", "MEOW", currency.LTC); err == nil {
|
||||
t.Error("non-existent address should throw an error")
|
||||
}
|
||||
|
||||
newbase.AddAddress("someaddr",
|
||||
currency.LTC.String(),
|
||||
currency.NewCode("LTCWALLETTEST"),
|
||||
@@ -187,12 +199,36 @@ func TestUpdateExchangeAddressBalance(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAddAddress(t *testing.T) {
|
||||
newbase := Base{}
|
||||
var newbase Base
|
||||
if err := newbase.AddAddress("", "MEOW", currency.LTC, 1); err == nil {
|
||||
t.Error("invalid address should throw an error")
|
||||
}
|
||||
|
||||
if err := newbase.AddAddress("Gibson", "", currency.NewCode(""), 1); err == nil {
|
||||
t.Error("invalid coin type should throw an error")
|
||||
}
|
||||
|
||||
// test adding an exchange address
|
||||
err := newbase.AddAddress("COINUT", PortfolioAddressExchange, currency.LTC, 0)
|
||||
if err != nil {
|
||||
t.Errorf("failed to add address: %v", err)
|
||||
}
|
||||
|
||||
// add a test portfolio address and amount
|
||||
newbase.AddAddress("Gibson",
|
||||
currency.LTC.String(),
|
||||
currency.NewCode("LTCWALLETTEST"),
|
||||
0.02)
|
||||
|
||||
// test updating the balance and make sure it's reflected
|
||||
newbase.AddAddress("Gibson", currency.LTC.String(),
|
||||
currency.NewCode("LTCWALLETTEST"), 0.05)
|
||||
b, _ := newbase.GetAddressBalance("Gibson", "LTC",
|
||||
currency.NewCode("LTCWALLETTEST"))
|
||||
if b != 0.05 {
|
||||
t.Error("invalid portfolio amount")
|
||||
}
|
||||
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.Seed(newbase)
|
||||
if !portfolio.AddressExists("Gibson") {
|
||||
|
||||
Reference in New Issue
Block a user