Bybit: Fix UpdateAccountInfo coin balance issue, improve GetWalletBalance and enhance test coverage (#1588)

* Bybit: Fix UpdateAccountInfo and enhance GetWalletBalance

* Update struct field and comments
This commit is contained in:
Adrian Gallagher
2024-07-29 12:36:10 +10:00
committed by GitHub
parent d1e36691b3
commit ba3dcc8e25
8 changed files with 308 additions and 214 deletions

View File

@@ -10,95 +10,60 @@ import (
"os"
"testing"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
gctlog "github.com/thrasher-corp/gocryptotrader/log"
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
)
var mockTests = false
func TestMain(m *testing.M) {
b.SetDefaults()
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
b = new(Bybit)
if err := testexch.Setup(b); err != nil {
log.Fatal(err)
}
exchCfg, err := cfg.GetExchangeConfig("Bybit")
if err != nil {
log.Fatal(err)
if apiKey != "" && apiSecret != "" {
b.API.AuthenticatedSupport = true
b.API.AuthenticatedWebsocketSupport = true
b.SetCredentials(apiKey, apiSecret, "", "", "", "")
b.Websocket.SetCanUseAuthenticatedEndpoints(true)
}
exchCfg.API.Credentials.Key = apiKey
exchCfg.API.Credentials.Secret = apiSecret
exchCfg.API.AuthenticatedSupport = true
exchCfg.API.AuthenticatedWebsocketSupport = true
b.Websocket = sharedtestvalues.NewTestWebsocket()
err = b.Setup(exchCfg)
if err != nil {
log.Fatal(err)
}
err = instantiateTradablePairs()
if err != nil {
log.Fatalf("%s %v", b.Name, err)
}
err = b.RetrieveAndSetAccountType(context.Background())
if err != nil {
gctlog.Errorf(gctlog.ExchangeSys, "RetrieveAndSetAccountType: %v", err)
if b.API.AuthenticatedSupport {
if err := b.RetrieveAndSetAccountType(context.Background()); err != nil {
log.Printf("%s unable to RetrieveAndSetAccountType: %v", b.Name, err)
}
}
instantiateTradablePairs()
os.Exit(m.Run())
}
func instantiateTradablePairs() error {
func instantiateTradablePairs() {
handleError := func(msg string, err error) {
if err != nil {
log.Fatalf("Bybit %s: %v", msg, err)
}
}
err := b.UpdateTradablePairs(context.Background(), true)
if err != nil {
return err
handleError("unable to UpdateTradablePairs", err)
setTradablePair := func(assetType asset.Item, p *currency.Pair) {
tradables, err := b.GetEnabledPairs(assetType)
handleError("unable to GetEnabledPairs", err)
format, err := b.GetPairFormat(assetType, true)
handleError("unable to GetPairFormat", err)
*p = tradables[0].Format(format)
}
tradables, err := b.GetEnabledPairs(asset.Spot)
if err != nil {
return err
}
format, err := b.GetPairFormat(asset.Spot, true)
if err != nil {
return err
}
spotTradablePair = tradables[0].Format(format)
tradables, err = b.GetEnabledPairs(asset.USDTMarginedFutures)
if err != nil {
return err
}
format, err = b.GetPairFormat(asset.USDTMarginedFutures, true)
if err != nil {
return err
}
usdtMarginedTradablePair = tradables[0].Format(format)
tradables, err = b.GetEnabledPairs(asset.USDCMarginedFutures)
if err != nil {
return err
}
format, err = b.GetPairFormat(asset.USDCMarginedFutures, true)
if err != nil {
return err
}
usdcMarginedTradablePair = tradables[0].Format(format)
tradables, err = b.GetEnabledPairs(asset.CoinMarginedFutures)
if err != nil {
return err
}
format, err = b.GetPairFormat(asset.CoinMarginedFutures, true)
if err != nil {
return err
}
inverseTradablePair = tradables[0].Format(format)
tradables, err = b.GetEnabledPairs(asset.Options)
if err != nil {
return err
}
format, err = b.GetPairFormat(asset.Options, true)
if err != nil {
return err
}
optionsTradablePair = tradables[0].Format(format)
return nil
setTradablePair(asset.Spot, &spotTradablePair)
setTradablePair(asset.USDTMarginedFutures, &usdtMarginedTradablePair)
setTradablePair(asset.USDCMarginedFutures, &usdcMarginedTradablePair)
setTradablePair(asset.CoinMarginedFutures, &inverseTradablePair)
setTradablePair(asset.Options, &optionsTradablePair)
}

View File

@@ -10,95 +10,50 @@ import (
"os"
"testing"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/mock"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
)
const mockfile = "../../testdata/http_mock/bybit/bybit.json"
var mockTests = true
func TestMain(m *testing.M) {
b.SetDefaults()
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
b = new(Bybit)
if err := testexch.Setup(b); err != nil {
log.Fatal(err)
}
bybitConfig, err := cfg.GetExchangeConfig("Bybit")
if err != nil {
log.Fatal("Bybit Setup() init error", err)
b.SetCredentials("mock", "tester", "", "", "", "") // Hack for UpdateAccountInfo test
if err := testexch.MockHTTPInstance(b); err != nil {
log.Fatal(err)
}
b.SkipAuthCheck = true
bybitConfig.API.Credentials.Key = apiKey
bybitConfig.API.Credentials.Secret = apiSecret
bybitConfig.API.AuthenticatedSupport = true
bybitConfig.API.AuthenticatedWebsocketSupport = true
b.Websocket = sharedtestvalues.NewTestWebsocket()
err = b.Setup(bybitConfig)
if err != nil {
log.Fatal("Bybit setup error", err)
if err := b.UpdateTradablePairs(context.Background(), true); err != nil {
log.Fatalf("Bybit unable to UpdateTradablePairs: %s", err)
}
serverDetails, newClient, err := mock.NewVCRServer(mockfile)
if err != nil {
log.Fatalf("Mock server error %s", err)
}
err = b.SetHTTPClient(newClient)
if err != nil {
log.Fatalf("Mock server error %s", err)
}
endpointMap := b.API.Endpoints.GetURLMap()
for k := range endpointMap {
err = b.API.Endpoints.SetRunning(k, serverDetails)
if err != nil {
log.Fatal(err)
setEnabledPair := func(assetType asset.Item, pair currency.Pair) {
okay, err := b.IsPairEnabled(pair, assetType)
if !okay || err != nil {
err = b.CurrencyPairs.EnablePair(assetType, pair)
if err != nil {
log.Fatal(err)
}
}
}
err = b.UpdateTradablePairs(context.Background(), true)
if err != nil {
log.Fatal("Bybit setup error", err)
}
spotTradablePair = currency.Pair{Base: currency.BTC, Quote: currency.USDT}
okay, err := b.IsPairEnabled(spotTradablePair, asset.Spot)
if !okay || err != nil {
err = b.CurrencyPairs.EnablePair(asset.Spot, spotTradablePair)
if err != nil {
log.Fatal(err)
}
}
usdtMarginedTradablePair = currency.Pair{Base: currency.NewCode("10000LADYS"), Quote: currency.USDT}
if okay, err = b.IsPairEnabled(usdtMarginedTradablePair, asset.USDTMarginedFutures); !okay || err != nil {
err = b.CurrencyPairs.EnablePair(asset.USDTMarginedFutures, usdtMarginedTradablePair)
if err != nil {
log.Fatal(err)
}
}
usdcMarginedTradablePair = currency.Pair{Base: currency.ETH, Quote: currency.PERP}
if okay, err = b.IsPairEnabled(usdcMarginedTradablePair, asset.USDCMarginedFutures); !okay || err != nil {
err = b.CurrencyPairs.EnablePair(asset.USDCMarginedFutures, usdcMarginedTradablePair)
if err != nil {
log.Fatal(err)
}
}
inverseTradablePair = currency.Pair{Base: currency.ADA, Quote: currency.USD}
if okay, err = b.IsPairEnabled(inverseTradablePair, asset.CoinMarginedFutures); !okay || err != nil {
err = b.CurrencyPairs.EnablePair(asset.CoinMarginedFutures, inverseTradablePair)
if err != nil {
log.Fatal(err)
}
}
optionsTradablePair = currency.Pair{Base: currency.BTC, Delimiter: currency.DashDelimiter, Quote: currency.NewCode("29DEC23-80000-C")}
if okay, err = b.IsPairEnabled(optionsTradablePair, asset.Options); !okay || err != nil {
err = b.CurrencyPairs.EnablePair(asset.Options, optionsTradablePair)
if err != nil {
log.Fatal(err)
}
}
setEnabledPair(asset.Spot, spotTradablePair)
setEnabledPair(asset.USDTMarginedFutures, usdtMarginedTradablePair)
setEnabledPair(asset.USDCMarginedFutures, usdcMarginedTradablePair)
setEnabledPair(asset.CoinMarginedFutures, inverseTradablePair)
setEnabledPair(asset.Options, optionsTradablePair)
os.Exit(m.Run())
}

View File

@@ -26,6 +26,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
"github.com/thrasher-corp/gocryptotrader/types"
)
// Please supply your own keys here to do authenticated endpoint testing
@@ -1662,9 +1663,87 @@ func TestGetWalletBalance(t *testing.T) {
if !mockTests {
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
}
_, err := b.GetWalletBalance(context.Background(), "UNIFIED", "")
if err != nil {
t.Fatal(err)
r, err := b.GetWalletBalance(context.Background(), "UNIFIED", "")
require.NoError(t, err, "GetWalletBalance should not error")
require.NotNil(t, r, "GetWalletBalance should return a result")
if mockTests {
require.Len(t, r.List, 1, "GetWalletBalance should return a single list result")
assert.Equal(t, types.Number(0.1997), r.List[0].AccountIMRate, "AccountIMRate should match")
assert.Equal(t, types.Number(0.4996), r.List[0].AccountLTV, "AccountLTV should match")
assert.Equal(t, types.Number(0.0399), r.List[0].AccountMMRate, "AccountMMRate should match")
assert.Equal(t, "UNIFIED", r.List[0].AccountType, "AccountType should match")
assert.Equal(t, types.Number(24616.49915805), r.List[0].TotalAvailableBalance, "TotalAvailableBalance should match")
assert.Equal(t, types.Number(41445.9203332), r.List[0].TotalEquity, "TotalEquity should match")
assert.Equal(t, types.Number(6144.46796478), r.List[0].TotalInitialMargin, "TotalInitialMargin should match")
assert.Equal(t, types.Number(1228.89359295), r.List[0].TotalMaintenanceMargin, "TotalMaintenanceMargin should match")
assert.Equal(t, types.Number(30760.96712284), r.List[0].TotalMarginBalance, "TotalMarginBalance should match")
assert.Equal(t, types.Number(0.0), r.List[0].TotalPerpUPL, "TotalPerpUPL should match")
assert.Equal(t, types.Number(30760.96712284), r.List[0].TotalWalletBalance, "TotalWalletBalance should match")
require.Len(t, r.List[0].Coin, 3, "GetWalletBalance should return 3 coins")
for x := range r.List[0].Coin {
switch x {
case 0:
assert.Equal(t, types.Number(0.21976631), r.List[0].Coin[x].AccruedInterest, "AccruedInterest should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].AvailableToBorrow, "AvailableToBorrow should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].AvailableToWithdraw, "AvailableToWithdraw should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].Bonus, "Bonus should match")
assert.Equal(t, types.Number(30723.630216383711792744), r.List[0].Coin[x].BorrowAmount, "BorrowAmount should match")
assert.Equal(t, currency.USDC, r.List[0].Coin[x].Coin, "Coin should match")
assert.True(t, r.List[0].Coin[x].CollateralSwitch, "CollateralSwitch should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].CumulativeRealisedPNL, "CumulativeRealisedPNL should match")
assert.Equal(t, types.Number(-30723.63021638), r.List[0].Coin[x].Equity, "Equity should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].Locked, "Locked should match")
assert.True(t, r.List[0].Coin[x].MarginCollateral, "MarginCollateral should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].SpotHedgingQuantity, "SpotHedgingQuantity should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalOrderIM, "TotalOrderIM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalPositionIM, "TotalPositionIM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalPositionMM, "TotalPositionMM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].UnrealisedPNL, "UnrealisedPNL should match")
assert.Equal(t, types.Number(-30722.33982391), r.List[0].Coin[x].USDValue, "USDValue should match")
assert.Equal(t, types.Number(-30723.63021638), r.List[0].Coin[x].WalletBalance, "WalletBalance should match")
case 1:
assert.Equal(t, types.Number(0), r.List[0].Coin[x].AccruedInterest, "AccruedInterest should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].AvailableToBorrow, "AvailableToBorrow should match")
assert.Equal(t, types.Number(1005.79191187), r.List[0].Coin[x].AvailableToWithdraw, "AvailableToWithdraw should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].Bonus, "Bonus should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].BorrowAmount, "BorrowAmount should match")
assert.Equal(t, currency.AVAX, r.List[0].Coin[x].Coin, "Coin should match")
assert.True(t, r.List[0].Coin[x].CollateralSwitch, "CollateralSwitch should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].CumulativeRealisedPNL, "CumulativeRealisedPNL should match")
assert.Equal(t, types.Number(2473.9), r.List[0].Coin[x].Equity, "Equity should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].Locked, "Locked should match")
assert.True(t, r.List[0].Coin[x].MarginCollateral, "MarginCollateral should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].SpotHedgingQuantity, "SpotHedgingQuantity should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalOrderIM, "TotalOrderIM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalPositionIM, "TotalPositionIM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalPositionMM, "TotalPositionMM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].UnrealisedPNL, "UnrealisedPNL should match")
assert.Equal(t, types.Number(71233.0214024), r.List[0].Coin[x].USDValue, "USDValue should match")
assert.Equal(t, types.Number(2473.9), r.List[0].Coin[x].WalletBalance, "WalletBalance should match")
case 2:
assert.Equal(t, types.Number(0), r.List[0].Coin[x].AccruedInterest, "AccruedInterest should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].AvailableToBorrow, "AvailableToBorrow should match")
assert.Equal(t, types.Number(935.1415), r.List[0].Coin[x].AvailableToWithdraw, "AvailableToWithdraw should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].Bonus, "Bonus should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].BorrowAmount, "BorrowAmount should match")
assert.Equal(t, currency.USDT, r.List[0].Coin[x].Coin, "Coin should match")
assert.True(t, r.List[0].Coin[x].CollateralSwitch, "CollateralSwitch should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].CumulativeRealisedPNL, "CumulativeRealisedPNL should match")
assert.Equal(t, types.Number(935.1415), r.List[0].Coin[x].Equity, "Equity should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].Locked, "Locked should match")
assert.True(t, r.List[0].Coin[x].MarginCollateral, "MarginCollateral should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].SpotHedgingQuantity, "SpotHedgingQuantity should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalOrderIM, "TotalOrderIM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalPositionIM, "TotalPositionIM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].TotalPositionMM, "TotalPositionMM should match")
assert.Equal(t, types.Number(0), r.List[0].Coin[x].UnrealisedPNL, "UnrealisedPNL should match")
assert.Equal(t, types.Number(935.23875471), r.List[0].Coin[x].USDValue, "USDValue should match")
assert.Equal(t, types.Number(935.1415), r.List[0].Coin[x].WalletBalance, "WalletBalance should match")
}
}
}
}
@@ -2896,13 +2975,40 @@ func TestGetBrokerEarning(t *testing.T) {
func TestUpdateAccountInfo(t *testing.T) {
t.Parallel()
if mockTests {
t.Skip(skipAuthenticatedFunctionsForMockTesting)
if !mockTests {
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
_, err := b.UpdateAccountInfo(context.Background(), asset.Spot)
if err != nil {
t.Error(err)
r, err := b.UpdateAccountInfo(context.Background(), asset.Spot)
require.NoError(t, err, "UpdateAccountInfo should not error")
require.NotEmpty(t, r, "UpdateAccountInfo should return account info")
if mockTests {
require.Len(t, r.Accounts, 1, "Accounts should have 1 item")
require.Len(t, r.Accounts[0].Currencies, 3, "Accounts currencies should have 3 currency items")
for x := range r.Accounts[0].Currencies {
switch x {
case 0:
assert.Equal(t, currency.USDC, r.Accounts[0].Currencies[x].Currency, "Currency should be USDC")
assert.Equal(t, -30723.63021638, r.Accounts[0].Currencies[x].Total, "Total amount should match")
assert.Equal(t, -30723.63021638, r.Accounts[0].Currencies[x].Hold, "Hold amount should match")
assert.Equal(t, 30723.630216383714, r.Accounts[0].Currencies[x].Borrowed, "Borrowed amount should match")
assert.Equal(t, 0.0, r.Accounts[0].Currencies[x].Free, "Free amount should match")
case 1:
assert.Equal(t, currency.AVAX, r.Accounts[0].Currencies[x].Currency, "Currency should be AVAX")
assert.Equal(t, 2473.9, r.Accounts[0].Currencies[x].Total, "Total amount should match")
assert.Equal(t, 1468.10808813, r.Accounts[0].Currencies[x].Hold, "Hold amount should match")
assert.Equal(t, 0.0, r.Accounts[0].Currencies[x].Borrowed, "Borrowed amount should match")
assert.Equal(t, 1005.79191187, r.Accounts[0].Currencies[x].Free, "Free amount should match")
case 2:
assert.Equal(t, currency.USDT, r.Accounts[0].Currencies[x].Currency, "Currency should be USDT")
assert.Equal(t, 935.1415, r.Accounts[0].Currencies[x].Total, "Total amount should match")
assert.Equal(t, 0.0, r.Accounts[0].Currencies[x].Borrowed, "Borrowed amount should match")
assert.Equal(t, 0.0, r.Accounts[0].Currencies[x].Hold, "Hold amount should match")
assert.Equal(t, 935.1415, r.Accounts[0].Currencies[x].Free, "Free amount should match")
}
}
}
}

View File

@@ -881,27 +881,30 @@ type WalletBalance struct {
AccountType string `json:"accountType"`
TotalAvailableBalance types.Number `json:"totalAvailableBalance"`
AccountMMRate types.Number `json:"accountMMRate"`
TotalPerpUPL string `json:"totalPerpUPL"`
TotalPerpUPL types.Number `json:"totalPerpUPL"`
TotalWalletBalance types.Number `json:"totalWalletBalance"`
AccountLTV string `json:"accountLTV"` // Account LTV: account total borrowed size / (account total equity + account total borrowed size).
AccountLTV types.Number `json:"accountLTV"` // Account LTV: account total borrowed size / (account total equity + account total borrowed size).
TotalMaintenanceMargin types.Number `json:"totalMaintenanceMargin"`
SpotHedgingQuantity types.Number `json:"spotHedgingQty"`
Coin []struct {
AvailableToBorrow types.Number `json:"availableToBorrow"`
Bonus types.Number `json:"bonus"`
AccruedInterest string `json:"accruedInterest"`
AvailableToWithdraw types.Number `json:"availableToWithdraw"`
AvailableBalanceForSpot types.Number `json:"free"`
TotalOrderIM string `json:"totalOrderIM"`
Equity types.Number `json:"equity"`
TotalPositionMM string `json:"totalPositionMM"`
USDValue types.Number `json:"usdValue"`
UnrealisedPnl types.Number `json:"unrealisedPnl"`
BorrowAmount types.Number `json:"borrowAmount"`
TotalPositionIM string `json:"totalPositionIM"`
WalletBalance types.Number `json:"walletBalance"`
CumulativeRealisedPnl types.Number `json:"cumRealisedPnl"`
Coin string `json:"coin"`
AvailableToBorrow types.Number `json:"availableToBorrow"`
Bonus types.Number `json:"bonus"`
AccruedInterest types.Number `json:"accruedInterest"`
AvailableToWithdraw types.Number `json:"availableToWithdraw"`
AvailableBalanceForSpot types.Number `json:"free"`
TotalOrderIM types.Number `json:"totalOrderIM"`
Equity types.Number `json:"equity"`
Locked types.Number `json:"locked"`
MarginCollateral bool `json:"marginCollateral"`
SpotHedgingQuantity types.Number `json:"spotHedgingQty"`
TotalPositionMM types.Number `json:"totalPositionMM"`
USDValue types.Number `json:"usdValue"`
UnrealisedPNL types.Number `json:"unrealisedPnl"`
BorrowAmount types.Number `json:"borrowAmount"`
TotalPositionIM types.Number `json:"totalPositionIM"`
WalletBalance types.Number `json:"walletBalance"`
CumulativeRealisedPNL types.Number `json:"cumRealisedPnl"`
Coin currency.Code `json:"coin"`
CollateralSwitch bool `json:"collateralSwitch"`
} `json:"coin"`
} `json:"list"`
}

View File

@@ -588,8 +588,8 @@ func (by *Bybit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a
for i := range balances.List {
for c := range balances.List[i].Coin {
balance := account.Balance{
Currency: currency.NewCode(balances.List[i].Coin[c].Coin),
Total: balances.List[i].TotalWalletBalance.Float64(),
Currency: balances.List[i].Coin[c].Coin,
Total: balances.List[i].Coin[c].WalletBalance.Float64(),
Free: balances.List[i].Coin[c].AvailableToWithdraw.Float64(),
Borrowed: balances.List[i].Coin[c].BorrowAmount.Float64(),
Hold: balances.List[i].Coin[c].WalletBalance.Float64() - balances.List[i].Coin[c].AvailableToWithdraw.Float64(),

View File

@@ -1811,25 +1811,86 @@
"result": {
"list": [
{
"accountIMRate": "0",
"accountLTV": "0",
"accountMMRate": "0",
"accountIMRate": "0.1997",
"accountLTV": "0.4996",
"accountMMRate": "0.0399",
"accountType": "UNIFIED",
"coin": [],
"totalAvailableBalance": "0",
"totalEquity": "0",
"totalInitialMargin": "0",
"totalMaintenanceMargin": "0",
"totalMarginBalance": "0",
"coin": [
{
"accruedInterest": "0.21976631",
"availableToBorrow": "",
"availableToWithdraw": "0",
"bonus": "0",
"borrowAmount": "30723.630216383711792744",
"coin": "USDC",
"collateralSwitch": true,
"cumRealisedPnl": "0",
"equity": "-30723.63021638",
"locked": "0",
"marginCollateral": true,
"spotHedgingQty": "0",
"totalOrderIM": "0",
"totalPositionIM": "0",
"totalPositionMM": "0",
"unrealisedPnl": "0",
"usdValue": "-30722.33982391",
"walletBalance": "-30723.63021638"
},
{
"accruedInterest": "0",
"availableToBorrow": "",
"availableToWithdraw": "1005.79191187",
"bonus": "0",
"borrowAmount": "0.000000000000000000",
"coin": "AVAX",
"collateralSwitch": true,
"cumRealisedPnl": "0",
"equity": "2473.9",
"locked": "0",
"marginCollateral": true,
"spotHedgingQty": "0",
"totalOrderIM": "0",
"totalPositionIM": "0",
"totalPositionMM": "0",
"unrealisedPnl": "0",
"usdValue": "71233.0214024",
"walletBalance": "2473.9"
},
{
"accruedInterest": "0",
"availableToBorrow": "",
"availableToWithdraw": "935.1415",
"bonus": "0",
"borrowAmount": "0.000000000000000000",
"coin": "USDT",
"collateralSwitch": true,
"cumRealisedPnl": "0",
"equity": "935.1415",
"locked": "0",
"marginCollateral": true,
"spotHedgingQty": "0",
"totalOrderIM": "0",
"totalPositionIM": "0",
"totalPositionMM": "0",
"unrealisedPnl": "0",
"usdValue": "935.23875471",
"walletBalance": "935.1415"
}
],
"totalAvailableBalance": "24616.49915805",
"totalEquity": "41445.9203332",
"totalInitialMargin": "6144.46796478",
"totalMaintenanceMargin": "1228.89359295",
"totalMarginBalance": "30760.96712284",
"totalPerpUPL": "0",
"totalWalletBalance": "0"
"totalWalletBalance": "30760.96712284"
}
]
},
"retCode": 0,
"retExtInfo": null,
"retMsg": "OK",
"time": 1700070952044
"time": 1721787898879
},
"queryString": "accountType=UNIFIED",
"bodyParams": "",
@@ -1838,16 +1899,16 @@
"application/x-www-form-urlencoded"
],
"X-Bapi-Api-Key": [
"sample-api-key"
""
],
"X-Bapi-Recv-Window": [
"5000"
],
"X-Bapi-Sign": [
"f12f7832a3c3c6694723a3c9bf700d4a3c3adc63c55ea7fbcbf475d31c6bc178"
"38803d2c41e425da75a8f5e3d066b156db29fe3c2721c508ec2e5ba15605cd3d"
],
"X-Bapi-Timestamp": [
"1700070951671"
"1721787898234"
]
}
}
@@ -480818,21 +480879,21 @@
"data": {
"result": {
"affiliateID": 0,
"apiKey": "oiqQ8ZEaoYKi4168He",
"createdAt": "2023-11-14T00:51:32Z",
"deadlineDay": 90,
"expiredAt": "2024-03-05T19:53:24Z",
"id": "27838971",
"apiKey": "",
"createdAt": "2024-07-24T02:00:03Z",
"deadlineDay": -2,
"expiredAt": "1970-01-01T00:00:00Z",
"id": "13333337",
"inviterID": 0,
"ips": [
"*"
],
"isMaster": true,
"isMaster": false,
"kycLevel": "LEVEL_DEFAULT",
"kycRegion": "",
"mktMakerLevel": "0",
"note": "Sam",
"parentUid": "0",
"note": "bob",
"parentUid": "13333337",
"permissions": {
"Affiliate": [],
"BlockTrade": [],
@@ -480840,18 +480901,14 @@
"Order",
"Position"
],
"CopyTrading": [
"CopyTrading"
],
"CopyTrading": [],
"Derivatives": [
"DerivativesTrade"
],
"Exchange": [
"ExchangeHistory"
],
"NFT": [
"NFTQueryProductList"
],
"NFT": [],
"Options": [
"OptionsTrade"
],
@@ -480860,7 +480917,7 @@
],
"Wallet": [
"AccountTransfer",
"SubMemberTransfer"
"SubMemberTransferList"
]
},
"readOnly": 0,
@@ -480868,14 +480925,14 @@
"secret": "",
"type": 1,
"unified": 0,
"userID": 47232796,
"userID": 13333337,
"uta": 1,
"vipLevel": "No VIP"
"vipLevel": "VIP-1"
},
"retCode": 0,
"retExtInfo": null,
"retMsg": "",
"time": 1701806080769
"time": 1721787897656
},
"queryString": "",
"bodyParams": "",
@@ -480884,16 +480941,16 @@
"application/x-www-form-urlencoded"
],
"X-Bapi-Api-Key": [
"oiqQ8ZEaoYKi4168He"
""
],
"X-Bapi-Recv-Window": [
"5000"
],
"X-Bapi-Sign": [
"953dd7a49c5146312fd1b355f91b162685c102021e14daa9fbce6e77a7b8e731"
"109ad5e4bd903b32fa4a8b1149107153ac7ffdcb8bc30e4c0c0a936f8edb4910"
],
"X-Bapi-Timestamp": [
"1701806080338"
"1721787896811"
]
}
}

View File

@@ -414,17 +414,23 @@ var m sync.Mutex
var set bool
var exclusionFile = DefaultDirectory + "exclusion.json"
var defaultExcludedHeaders = []string{"Key",
var defaultExcludedHeaders = []string{
"Key",
"X-Mbx-Apikey",
"Rest-Key",
"Apiauth-Key"}
var defaultExcludedVariables = []string{"bsb",
"Apiauth-Key",
"X-Bapi-Api-Key",
}
var defaultExcludedVariables = []string{
"bsb",
"user",
"name",
"real_name",
"receiver_name",
"account_number",
"username"}
"username",
"apiKey",
}
// Exclusion defines a list of items to be excluded from the main mock output
// this attempts a catch all approach and needs to be updated per exchange basis

View File

@@ -4,7 +4,8 @@
"X-Mbx-Apikey",
"Rest-Key",
"Apiauth-Key",
"X-Gemini-Apikey"
"X-Gemini-Apikey",
"X-Bapi-Api-Key"
],
"variables": [
"bsb",
@@ -14,6 +15,7 @@
"receiver_name",
"account_number",
"username",
"login"
"login",
"apiKey"
]
}