Skip to content

Commit

Permalink
add updatedAt for account balance
Browse files Browse the repository at this point in the history
Signed-off-by: Ye Sijun <[email protected]>
  • Loading branch information
junnplus committed Mar 6, 2025
1 parent 7fa2592 commit 1130a05
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 deletions.
20 changes: 15 additions & 5 deletions exchanges/account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var (
errBalanceIsNil = errors.New("balance is nil")
errNoCredentialBalances = errors.New("no balances associated with credentials")
errCredentialsAreNil = errors.New("credentials are nil")
errOutOfSequence = errors.New("out of sequence")
)

// CollectBalances converts a map of sub-account balances into a slice
Expand Down Expand Up @@ -103,7 +104,7 @@ func GetHoldings(exch string, creds *Credentials, assetType asset.Item) (Holding
return Holdings{}, fmt.Errorf("%s %s %s %w %w", exch, creds, assetType, errNoCredentialBalances, ErrExchangeHoldingsNotFound)
}

var currencyBalances = make([]Balance, 0, len(subAccountHoldings))
currencyBalances := make([]Balance, 0, len(subAccountHoldings))
cpy := *creds
for mapKey, assetHoldings := range subAccountHoldings {
if mapKey.Asset != assetType {
Expand Down Expand Up @@ -254,7 +255,7 @@ func (s *Service) Update(incoming *Holdings, creds *Credentials) error {
Asset: incoming.Accounts[x].AssetType,
}] = bal
}
bal.load(incoming.Accounts[x].Currencies[y])
bal.load(&incoming.Accounts[x].Currencies[y])

Check failure on line 258 in exchanges/account/account.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `bal.load` is not checked (errcheck)
}
}

Expand All @@ -268,22 +269,31 @@ func (s *Service) Update(incoming *Holdings, creds *Credentials) error {

// load checks to see if there is a change from incoming balance, if there is a
// change it will change then alert external routines.
func (b *ProtectedBalance) load(change Balance) {
func (b *ProtectedBalance) load(change *Balance) error {
b.m.Lock()
defer b.m.Unlock()
if change == nil {
return fmt.Errorf("%w for '%T'", common.ErrNilPointer, change)
}
if !b.updatedAt.IsZero() && !b.updatedAt.Before(change.UpdatedAt) {
return errOutOfSequence
}
if b.total == change.Total &&
b.hold == change.Hold &&
b.free == change.Free &&
b.availableWithoutBorrow == change.AvailableWithoutBorrow &&
b.borrowed == change.Borrowed {
return
b.borrowed == change.Borrowed &&
b.updatedAt.Equal(change.UpdatedAt) {
return nil
}
b.total = change.Total
b.hold = change.Hold
b.free = change.Free
b.availableWithoutBorrow = change.AvailableWithoutBorrow
b.borrowed = change.Borrowed
b.updatedAt = change.UpdatedAt
b.notice.Alert()
return nil
}

// Wait waits for a change in amounts for an asset type. This will pause
Expand Down
32 changes: 28 additions & 4 deletions exchanges/account/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ func TestGetHoldings(t *testing.T) {
Accounts: []SubAccount{
{
ID: "1337",
}},
},
},
}, happyCredentials)
assert.ErrorIs(t, err, asset.ErrNotSupported)

Expand All @@ -106,7 +107,8 @@ func TestGetHoldings(t *testing.T) {
Hold: 20,
},
},
}},
},
},
}, happyCredentials)
assert.NoError(t, err)

Expand All @@ -124,7 +126,8 @@ func TestGetHoldings(t *testing.T) {
Hold: 20,
},
},
}},
},
},
}, happyCredentials)
assert.NoError(t, err)

Expand Down Expand Up @@ -292,8 +295,13 @@ func TestBalanceInternalWait(t *testing.T) {
func TestBalanceInternalLoad(t *testing.T) {
t.Parallel()
bi := &ProtectedBalance{}
bi.load(Balance{Total: 1, Hold: 2, Free: 3, AvailableWithoutBorrow: 4, Borrowed: 5})
err := bi.load(&Balance{Total: 1, Hold: 2, Free: 3, AvailableWithoutBorrow: 4, Borrowed: 5})
assert.NoError(t, err, "should have been loaded")

bi.m.Lock()
if !bi.updatedAt.IsZero() {
t.Fatal("unexpected value")
}
if bi.total != 1 {
t.Fatal("unexpected value")
}
Expand All @@ -314,6 +322,22 @@ func TestBalanceInternalLoad(t *testing.T) {
if bi.GetFree() != 3 {
t.Fatal("unexpected value")
}

err = bi.load(&Balance{Total: 1, Hold: 2, Free: 3, AvailableWithoutBorrow: 4, Borrowed: 5})
assert.NoError(t, err, "should have been loaded")

now := time.Now()
err = bi.load(&Balance{UpdatedAt: now, Total: 1, Hold: 2, Free: 3, AvailableWithoutBorrow: 4, Borrowed: 5})
assert.NoError(t, err, "should have been loaded")

err = bi.load(&Balance{UpdatedAt: now, Total: 2, Hold: 3, Free: 4, AvailableWithoutBorrow: 5, Borrowed: 6})
assert.Error(t, err, "should have not been loaded")

err = bi.load(&Balance{Total: 2, Hold: 3, Free: 4, AvailableWithoutBorrow: 5, Borrowed: 6})
assert.Error(t, err, "should have not been loaded")

err = bi.load(&Balance{UpdatedAt: now.Add(time.Second), Total: 2, Hold: 3, Free: 4, AvailableWithoutBorrow: 5, Borrowed: 6})
assert.NoError(t, err, "should have been loaded")
}

func TestGetFree(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions exchanges/account/account_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package account
import (
"errors"
"sync"
"time"

"github.com/gofrs/uuid"
"github.com/thrasher-corp/gocryptotrader/common/key"
Expand Down Expand Up @@ -59,6 +60,7 @@ type Balance struct {
Free float64
AvailableWithoutBorrow float64
Borrowed float64
UpdatedAt time.Time
}

// Change defines incoming balance change on currency holdings
Expand All @@ -78,6 +80,7 @@ type ProtectedBalance struct {
availableWithoutBorrow float64
borrowed float64
m sync.Mutex
updatedAt time.Time

// notice alerts for when the balance changes for strategy inspection and
// usage.
Expand Down

0 comments on commit 1130a05

Please sign in to comment.