Skip to content

Commit

Permalink
account: segregate holdings by credentials for future multi-key manag…
Browse files Browse the repository at this point in the history
…ement (thrasher-corp#956)

* exchanges/account: shift credentials to account package and segregate funds to keys

* merge: fixes

* linter: fix

* Update exchanges/account/account.go

Co-authored-by: Scott <[email protected]>

* glorious: nits + protection for string panic

* glorious_suggestion: add method for matching keys

* linter: fix tests

* account: add protected method for credentials minimizing access, display full account details to rpc.

* linter: spelling kweeeeeeen

* accounts/portfolio: clean/check portfolio code and quickly check balances from change. Add protected method for future matching.

* accounts: theres no point in pointerising everything

* linter: ok pointerise this then...

* exchanges: fix regression add in little notes.

* glorious: nits

* Update exchanges/account/credentials.go

Co-authored-by: Scott <[email protected]>

* Update exchanges/account/credentials_test.go

Co-authored-by: Scott <[email protected]>

* Update exchanges/account/credentials_test.go

Co-authored-by: Scott <[email protected]>

* glorious: nits

* gloriously: fix glorious glorious test gloriously

Co-authored-by: Ryan O'Hara-Reid <[email protected]>
Co-authored-by: Scott <[email protected]>
  • Loading branch information
3 people authored Jul 21, 2022
1 parent 455738f commit 663e753
Show file tree
Hide file tree
Showing 48 changed files with 1,010 additions and 549 deletions.
10 changes: 10 additions & 0 deletions cmd/exchange_template/wrapper_file.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,16 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateAccountInfo(ctx context.Context, as

// FetchAccountInfo retrieves balances for all enabled currencies
func ({{.Variable}} *{{.CapitalName}}) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) {
// Example implementation below:
// creds, err := {{.Variable}}.GetCredentials(ctx)
// if err != nil {
// return account.Holdings{}, err
// }
// acc, err := account.GetHoldings({{.Variable}}.Name, creds, assetType)
// if err != nil {
// return {{.Variable}}.UpdateAccountInfo(ctx, assetType)
// }
// return acc, nil
return account.Holdings{}, common.ErrNotYetImplemented
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/gctcli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/core"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/gctrpc/auth"
"github.com/thrasher-corp/gocryptotrader/signaler"
"github.com/urfave/cli/v2"
Expand All @@ -28,7 +28,7 @@ var (
pairDelimiter string
certPath string
timeout time.Duration
exchangeCreds exchange.Credentials
exchangeCreds account.Credentials
verbose bool
)

Expand Down
88 changes: 40 additions & 48 deletions engine/portfolio_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ func setupPortfolioManager(e *ExchangeManager, portfolioManagerDelay time.Durati

// IsRunning safely checks whether the subsystem is running
func (m *portfolioManager) IsRunning() bool {
if m == nil {
return false
}
return atomic.LoadInt32(&m.started) == 1
return m != nil && atomic.LoadInt32(&m.started) == 1
}

// Start runs the subsystem
Expand Down Expand Up @@ -160,11 +157,10 @@ func (m *portfolioManager) seedExchangeAccountInfo(accounts []account.Holdings)
return
}
for x := range accounts {
exchangeName := accounts[x].Exchange
var currencies []account.Balance
for y := range accounts[x].Accounts {
next:
for z := range accounts[x].Accounts[y].Currencies {
var update bool
for i := range currencies {
if !accounts[x].Accounts[y].Currencies[z].CurrencyName.Equal(currencies[i].CurrencyName) {
continue
Expand All @@ -174,10 +170,7 @@ func (m *portfolioManager) seedExchangeAccountInfo(accounts []account.Holdings)
currencies[i].AvailableWithoutBorrow += accounts[x].Accounts[y].Currencies[z].AvailableWithoutBorrow
currencies[i].Free += accounts[x].Accounts[y].Currencies[z].Free
currencies[i].Borrowed += accounts[x].Accounts[y].Currencies[z].Borrowed
update = true
}
if update {
continue
continue next
}
currencies = append(currencies, account.Balance{
CurrencyName: accounts[x].Accounts[y].Currencies[z].CurrencyName,
Expand All @@ -190,51 +183,50 @@ func (m *portfolioManager) seedExchangeAccountInfo(accounts []account.Holdings)
}
}

for x := range currencies {
currencyName := currencies[x].CurrencyName
total := currencies[x].Total

if !m.base.ExchangeAddressExists(exchangeName, currencyName) {
if total <= 0 {
for j := range currencies {
if !m.base.ExchangeAddressExists(accounts[x].Exchange, currencies[j].CurrencyName) {
if currencies[j].Total <= 0 {
continue
}

log.Debugf(log.PortfolioMgr, "Portfolio: Adding new exchange address: %s, %s, %f, %s\n",
exchangeName,
currencyName,
total,
accounts[x].Exchange,
currencies[j].CurrencyName,
currencies[j].Total,
portfolio.ExchangeAddress)

m.base.Addresses = append(
m.base.Addresses,
portfolio.Address{Address: exchangeName,
CoinType: currencyName,
Balance: total,
Description: portfolio.ExchangeAddress})
} else {
if total <= 0 {
log.Debugf(log.PortfolioMgr, "Portfolio: Removing %s %s entry.\n",
exchangeName,
currencyName)
m.base.RemoveExchangeAddress(exchangeName, currencyName)
} else {
balance, ok := m.base.GetAddressBalance(exchangeName,
portfolio.ExchangeAddress,
currencyName)
if !ok {
continue
}
m.base.Addresses = append(m.base.Addresses, portfolio.Address{
Address: accounts[x].Exchange,
CoinType: currencies[j].CurrencyName,
Balance: currencies[j].Total,
Description: portfolio.ExchangeAddress,
})
continue
}

if balance != total {
log.Debugf(log.PortfolioMgr, "Portfolio: Updating %s %s entry with balance %f.\n",
exchangeName,
currencyName,
total)
m.base.UpdateExchangeAddressBalance(exchangeName,
currencyName,
total)
}
}
if currencies[j].Total <= 0 {
log.Debugf(log.PortfolioMgr, "Portfolio: Removing %s %s entry.\n",
accounts[x].Exchange,
currencies[j].CurrencyName)
m.base.RemoveExchangeAddress(accounts[x].Exchange, currencies[j].CurrencyName)
continue
}

balance, ok := m.base.GetAddressBalance(accounts[x].Exchange,
portfolio.ExchangeAddress,
currencies[j].CurrencyName)
if !ok {
continue
}

if balance != currencies[j].Total {
log.Debugf(log.PortfolioMgr, "Portfolio: Updating %s %s entry with balance %f.\n",
accounts[x].Exchange,
currencies[j].CurrencyName,
currencies[j].Total)
m.base.UpdateExchangeAddressBalance(accounts[x].Exchange,
currencies[j].CurrencyName,
currencies[j].Total)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions engine/rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (s *RPCServer) authenticateClient(ctx context.Context) (context.Context, er
password != s.Config.RemoteControl.Password {
return ctx, fmt.Errorf("username/password mismatch")
}
ctx, err = exchange.ParseCredentialsMetadata(ctx, md)
ctx, err = account.ParseCredentialsMetadata(ctx, md)
if err != nil {
return ctx, err
}
Expand Down Expand Up @@ -618,7 +618,7 @@ func createAccountInfoRequest(h account.Holdings) (*gctrpc.GetAccountInfoRespons
accounts := make([]*gctrpc.Account, len(h.Accounts))
for x := range h.Accounts {
var a gctrpc.Account
a.Id = h.Accounts[x].ID
a.Id = h.Accounts[x].Credentials.String()
for _, y := range h.Accounts[x].Currencies {
if y.Total == 0 &&
y.Hold == 0 &&
Expand Down
16 changes: 10 additions & 6 deletions engine/rpcserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2198,10 +2198,12 @@ func TestGetFuturesPositions(t *testing.T) {
t.Fatalf("received '%v', expected '%v'", err, exchange.ErrCredentialsAreEmpty)
}

ctx := exchange.DeployCredentialsToContext(context.Background(), &exchange.Credentials{
Key: "wow",
Secret: "super wow",
})
ctx := account.DeployCredentialsToContext(context.Background(),
&account.Credentials{
Key: "wow",
Secret: "super wow",
},
)

_, err = s.GetFuturesPositions(ctx, &gctrpc.GetFuturesPositionsRequest{
Exchange: fakeExchangeName,
Expand Down Expand Up @@ -2312,7 +2314,8 @@ func TestGetCollateral(t *testing.T) {
t.Fatalf("received '%v', expected '%v'", err, exchange.ErrCredentialsAreEmpty)
}

ctx := exchange.DeployCredentialsToContext(context.Background(), &exchange.Credentials{Key: "fakerino", Secret: "supafake"})
ctx := account.DeployCredentialsToContext(context.Background(),
&account.Credentials{Key: "fakerino", Secret: "supafake"})

_, err = s.GetCollateral(ctx, &gctrpc.GetCollateralRequest{
Exchange: fakeExchangeName,
Expand All @@ -2322,7 +2325,8 @@ func TestGetCollateral(t *testing.T) {
t.Fatalf("received '%v', expected '%v'", err, errNoAccountInformation)
}

ctx = exchange.DeployCredentialsToContext(context.Background(), &exchange.Credentials{Key: "fakerino", Secret: "supafake", SubAccount: "1337"})
ctx = account.DeployCredentialsToContext(context.Background(),
&account.Credentials{Key: "fakerino", Secret: "supafake", SubAccount: "1337"})

r, err := s.GetCollateral(ctx, &gctrpc.GetCollateralRequest{
Exchange: fakeExchangeName,
Expand Down
Loading

0 comments on commit 663e753

Please sign in to comment.