mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-16 23:16:48 +00:00
bitmex: normalize account info currencies (#799)
* bitmex: normalize account info currencies Bitmex has an interesting way of returning BTC balances, it returns them as XBt and denominated in Satoshis instead. Normalize that still in the bitmex wrapper by performing the conversion and returning the normal use BTC currency. * Change NW contract to NQ Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
@@ -93,6 +93,8 @@ const (
|
||||
bitmexEndpointUserWalletSummary = "/user/walletSummary"
|
||||
bitmexEndpointUserRequestWithdraw = "/user/requestWithdrawal"
|
||||
|
||||
constSatoshiBTC = 1e-08
|
||||
|
||||
// ContractPerpetual perpetual contract type
|
||||
ContractPerpetual = iota
|
||||
// ContractFutures futures contract type
|
||||
@@ -772,10 +774,21 @@ func (b *Bitmex) UserRequestWithdrawal(ctx context.Context, params UserRequestWi
|
||||
func (b *Bitmex) GetWalletInfo(ctx context.Context, currency string) (WalletInfo, error) {
|
||||
var info WalletInfo
|
||||
|
||||
return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet,
|
||||
if err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet,
|
||||
bitmexEndpointUserWallet,
|
||||
UserCurrencyParams{Currency: currency},
|
||||
&info)
|
||||
&info); err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// Bitmex has an "interesting" of dealing with currencies,
|
||||
// for instance XBt is actually BTC but in Satoshi units,
|
||||
// for sanity purposes apply here a conversion to normalize
|
||||
// this
|
||||
// avoid a copy here since this is a big struct
|
||||
normalizeWalletInfo(&info)
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// GetWalletHistory returns user wallet history transaction data
|
||||
@@ -908,7 +921,7 @@ func (b *Bitmex) CaptureError(resp, reType interface{}) error {
|
||||
}
|
||||
|
||||
err = json.Unmarshal(marshalled, &Error)
|
||||
if err == nil {
|
||||
if err == nil && Error.Error.Name != "" {
|
||||
return fmt.Errorf("bitmex error %s: %s",
|
||||
Error.Error.Name,
|
||||
Error.Error.Message)
|
||||
@@ -947,3 +960,13 @@ func calculateTradingFee(purchasePrice, amount float64, isMaker bool) float64 {
|
||||
|
||||
return fee * purchasePrice * amount
|
||||
}
|
||||
|
||||
// normalizeWalletInfo converts any non-standard currencies (eg. XBt -> BTC)
|
||||
func normalizeWalletInfo(w *WalletInfo) {
|
||||
if w.Currency != "XBt" {
|
||||
return
|
||||
}
|
||||
|
||||
w.Currency = "BTC"
|
||||
w.Amount *= constSatoshiBTC
|
||||
}
|
||||
|
||||
@@ -163,8 +163,8 @@ func TestGetTrollboxChannels(t *testing.T) {
|
||||
func TestGetTrollboxConnectedUsers(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetTrollboxConnectedUsers(context.Background())
|
||||
if err == nil {
|
||||
t.Error("GetTrollboxConnectedUsers() Expected error")
|
||||
if err != nil {
|
||||
t.Error("GetTrollboxConnectedUsers() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,8 +231,8 @@ func TestGetActiveAndIndexInstruments(t *testing.T) {
|
||||
func TestGetActiveIntervals(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetActiveIntervals(context.Background())
|
||||
if err == nil {
|
||||
t.Error("GetActiveIntervals() Expected error")
|
||||
if err != nil {
|
||||
t.Error("GetActiveIntervals() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,13 +731,23 @@ func TestGetAccountInfo(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := b.UpdateAccountInfo(context.Background(), asset.Spot)
|
||||
if err != nil {
|
||||
t.Error("GetAccountInfo() error", err)
|
||||
t.Error("GetAccountInfo(spot) error", err)
|
||||
}
|
||||
|
||||
_, err = b.UpdateAccountInfo(context.Background(), asset.Futures)
|
||||
if err != nil {
|
||||
t.Error("GetAccountInfo(futures) error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := b.UpdateAccountInfo(context.Background(), asset.Spot)
|
||||
if err == nil {
|
||||
t.Error("GetAccountInfo() error")
|
||||
}
|
||||
|
||||
_, err = b.UpdateAccountInfo(context.Background(), asset.Futures)
|
||||
if err == nil {
|
||||
t.Error("GetAccountInfo(futures) error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1134,3 +1144,20 @@ func TestUpdateTickers(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyNormalization(t *testing.T) {
|
||||
w := &WalletInfo{
|
||||
Currency: "XBt",
|
||||
Amount: 1e+08,
|
||||
}
|
||||
|
||||
normalizeWalletInfo(w)
|
||||
|
||||
if w.Currency != "BTC" {
|
||||
t.Errorf("currency mismatch, expected BTC, got %s", w.Currency)
|
||||
}
|
||||
|
||||
if w.Amount != 1.0 {
|
||||
t.Errorf("amount mismatch, expected 1.0, got %f", w.Amount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,7 +649,7 @@ type MinWithdrawalFee struct {
|
||||
type WalletInfo struct {
|
||||
Account int64 `json:"account"`
|
||||
Addr string `json:"addr"`
|
||||
Amount int64 `json:"amount"`
|
||||
Amount float64 `json:"amount"`
|
||||
ConfirmedDebit int64 `json:"confirmedDebit"`
|
||||
Currency string `json:"currency"`
|
||||
DeltaAmount int64 `json:"deltaAmount"`
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -179,6 +180,7 @@ func (b *Bitmex) Setup(exch *config.ExchangeConfig) error {
|
||||
return b.Websocket.SetupNewConnection(stream.ConnectionSetup{
|
||||
ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout,
|
||||
ResponseMaxLimit: exch.WebsocketResponseMaxLimit,
|
||||
URL: bitmexWSURL,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -415,27 +417,36 @@ func (b *Bitmex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType
|
||||
func (b *Bitmex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) {
|
||||
var info account.Holdings
|
||||
|
||||
bal, err := b.GetAllUserMargin(ctx)
|
||||
userMargins, err := b.GetAllUserMargin(ctx)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// Need to update to add Margin/Liquidity availibilty
|
||||
var accountID string
|
||||
var balances []account.Balance
|
||||
for i := range bal {
|
||||
// Need to update to add Margin/Liquidity availability
|
||||
for i := range userMargins {
|
||||
accountID = strconv.FormatInt(userMargins[i].Account, 10)
|
||||
|
||||
wallet, err := b.GetWalletInfo(ctx, userMargins[i].Currency)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
balances = append(balances, account.Balance{
|
||||
CurrencyName: currency.NewCode(bal[i].Currency),
|
||||
TotalValue: float64(bal[i].WalletBalance),
|
||||
CurrencyName: currency.NewCode(wallet.Currency),
|
||||
TotalValue: wallet.Amount,
|
||||
})
|
||||
}
|
||||
|
||||
info.Accounts = append(info.Accounts,
|
||||
account.SubAccount{
|
||||
ID: accountID,
|
||||
Currencies: balances,
|
||||
})
|
||||
info.Exchange = b.Name
|
||||
info.Accounts = append(info.Accounts, account.SubAccount{
|
||||
Currencies: balances,
|
||||
})
|
||||
|
||||
err = account.Process(&info)
|
||||
if err != nil {
|
||||
if err := account.Process(&info); err != nil {
|
||||
return account.Holdings{}, err
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ func TestFLastTradeData(t *testing.T) {
|
||||
|
||||
func TestFRequestPublicBatchTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
cp, err := currency.NewPairFromString("BTC_NW")
|
||||
cp, err := currency.NewPairFromString("BTC_NQ")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -211,7 +211,7 @@ func TestFQueryTieredAdjustmentFactor(t *testing.T) {
|
||||
func TestFQueryHisOpenInterest(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.FQueryHisOpenInterest(context.Background(),
|
||||
"BTC", "next_week", "60min", "cont", 3)
|
||||
"BTC", "next_quarter", "60min", "cont", 3)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user