Binance: Add crypto/flexible loan endpoints (#1331)

* Binance: Add crypto/flexible loan endpoints

* Address nitters

* Address shazbert's nitters
This commit is contained in:
Adrian Gallagher
2023-09-01 16:46:53 +10:00
committed by GitHub
parent 6ab4c27d1c
commit 578dd0bafe
4 changed files with 1056 additions and 3 deletions

View File

@@ -79,9 +79,43 @@ const (
withdrawHistory = "/sapi/v1/capital/withdraw/history"
depositAddress = "/sapi/v1/capital/deposit/address"
// Crypto loan endpoints
loanIncomeHistory = "/sapi/v1/loan/income"
loanBorrow = "/sapi/v1/loan/borrow"
loanBorrowHistory = "/sapi/v1/loan/borrow/history"
loanOngoingOrders = "/sapi/v1/loan/ongoing/orders"
loanRepay = "/sapi/v1/loan/repay"
loanRepaymentHistory = "/sapi/v1/loan/repay/history"
loanAdjustLTV = "/sapi/v1/loan/adjust/ltv"
loanLTVAdjustmentHistory = "/sapi/v1/loan/ltv/adjustment/history"
loanableAssetsData = "/sapi/v1/loan/loanable/data"
loanCollateralAssetsData = "/sapi/v1/loan/collateral/data"
loanCheckCollateralRepayRate = "/sapi/v1/loan/repay/collateral/rate"
loanCustomiseMarginCall = "/sapi/v1/loan/customize/margin_call"
// Flexible loan endpoints
flexibleLoanBorrow = "/sapi/v1/loan/flexible/borrow"
flexibleLoanOngoingOrders = "/sapi/v1/loan/flexible/ongoing/orders"
flexibleLoanBorrowHistory = "/sapi/v1/loan/flexible/borrow/history"
flexibleLoanRepay = "/sapi/v1/loan/flexible/repay"
flexibleLoanRepayHistory = "/sapi/v1/loan/flexible/repay/history"
flexibleLoanAdjustLTV = "/sapi/v1/loan/flexible/adjust/ltv"
flexibleLoanLTVHistory = "/sapi/v1/loan/flexible/ltv/adjustment/history"
flexibleLoanAssetsData = "/sapi/v1/loan/flexible/loanable/data"
flexibleLoanCollateralAssetsData = "/sapi/v1/loan/flexible/collateral/data"
defaultRecvWindow = 5 * time.Second
)
var (
errLoanCoinMustBeSet = errors.New("loan coin must bet set")
errLoanTermMustBeSet = errors.New("loan term must be set")
errCollateralCoinMustBeSet = errors.New("collateral coin must be set")
errOrderIDMustBeSet = errors.New("orderID must be set")
errAmountMustBeSet = errors.New("amount must not be <= 0")
errEitherLoanOrCollateralAmountsMustBeSet = errors.New("either loan or collateral amounts must be set")
)
// GetUndocumentedInterestHistory gets interest history for currency/currencies provided
func (b *Binance) GetUndocumentedInterestHistory(ctx context.Context) (MarginInfoData, error) {
var resp MarginInfoData
@@ -1267,3 +1301,475 @@ func (b *Binance) FetchSpotExchangeLimits(ctx context.Context) ([]order.MinMaxLe
}
return limits, nil
}
// CryptoLoanIncomeHistory returns crypto loan income history
func (b *Binance) CryptoLoanIncomeHistory(ctx context.Context, curr currency.Code, loanType string, startTime, endTime time.Time, limit int64) ([]CryptoLoansIncomeHistory, error) {
params := url.Values{}
if !curr.IsEmpty() {
params.Set("asset", curr.String())
}
if loanType != "" {
params.Set("type", loanType)
}
if !startTime.IsZero() {
params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10))
}
if !endTime.IsZero() {
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp []CryptoLoansIncomeHistory
return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanIncomeHistory, params, spotDefaultRate, &resp)
}
// CryptoLoanBorrow borrows crypto
func (b *Binance) CryptoLoanBorrow(ctx context.Context, loanCoin currency.Code, loanAmount float64, collateralCoin currency.Code, collateralAmount float64, loanTerm int64) ([]CryptoLoanBorrow, error) {
if loanCoin.IsEmpty() {
return nil, errLoanCoinMustBeSet
}
if collateralCoin.IsEmpty() {
return nil, errCollateralCoinMustBeSet
}
if loanTerm <= 0 {
return nil, errLoanTermMustBeSet
}
if loanAmount == 0 && collateralAmount == 0 {
return nil, errEitherLoanOrCollateralAmountsMustBeSet
}
params := url.Values{}
params.Set("loanCoin", loanCoin.String())
if loanAmount != 0 {
params.Set("loanAmount", strconv.FormatFloat(loanAmount, 'f', -1, 64))
}
params.Set("collateralCoin", collateralCoin.String())
if collateralAmount != 0 {
params.Set("collateralAmount", strconv.FormatFloat(collateralAmount, 'f', -1, 64))
}
params.Set("loanTerm", strconv.FormatInt(loanTerm, 10))
var resp []CryptoLoanBorrow
return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanBorrow, params, spotDefaultRate, &resp)
}
// CryptoLoanBorrowHistory gets loan borrow history
func (b *Binance) CryptoLoanBorrowHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*LoanBorrowHistory, error) {
params := url.Values{}
if orderID != 0 {
params.Set("orderId", strconv.FormatInt(orderID, 10))
}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if !startTime.IsZero() {
params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10))
}
if !endTime.IsZero() {
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp LoanBorrowHistory
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanBorrowHistory, params, spotDefaultRate, &resp)
}
// CryptoLoanOngoingOrders obtains ongoing loan orders
func (b *Binance) CryptoLoanOngoingOrders(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, current, limit int64) (*CryptoLoanOngoingOrder, error) {
params := url.Values{}
if orderID != 0 {
params.Set("orderId", strconv.FormatInt(orderID, 10))
}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp CryptoLoanOngoingOrder
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanOngoingOrders, params, spotDefaultRate, &resp)
}
// CryptoLoanRepay repays a crypto loan
func (b *Binance) CryptoLoanRepay(ctx context.Context, orderID int64, amount float64, repayType int64, collateralReturn bool) ([]CryptoLoanRepay, error) {
if orderID <= 0 {
return nil, errOrderIDMustBeSet
}
if amount <= 0 {
return nil, errAmountMustBeSet
}
params := url.Values{}
params.Set("orderId", strconv.FormatInt(orderID, 10))
params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
if repayType != 0 {
params.Set("type", strconv.FormatInt(repayType, 10))
}
params.Set("collateralReturn", strconv.FormatBool(collateralReturn))
var resp []CryptoLoanRepay
return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanRepay, params, spotDefaultRate, &resp)
}
// CryptoLoanRepaymentHistory gets the crypto loan repayment history
func (b *Binance) CryptoLoanRepaymentHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*CryptoLoanRepayHistory, error) {
params := url.Values{}
if orderID != 0 {
params.Set("orderId", strconv.FormatInt(orderID, 10))
}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if !startTime.IsZero() {
params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10))
}
if !endTime.IsZero() {
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp CryptoLoanRepayHistory
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanRepaymentHistory, params, spotDefaultRate, &resp)
}
// CryptoLoanAdjustLTV adjusts the LTV of a crypto loan
func (b *Binance) CryptoLoanAdjustLTV(ctx context.Context, orderID int64, reduce bool, amount float64) (*CryptoLoanAdjustLTV, error) {
if orderID <= 0 {
return nil, errOrderIDMustBeSet
}
if amount <= 0 {
return nil, errAmountMustBeSet
}
params := url.Values{}
params.Set("orderId", strconv.FormatInt(orderID, 10))
params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
direction := "ADDITIONAL"
if reduce {
direction = "REDUCED"
}
params.Set("direction", direction)
var resp CryptoLoanAdjustLTV
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanAdjustLTV, params, spotDefaultRate, &resp)
}
// CryptoLoanLTVAdjustmentHistory gets the crypto loan LTV adjustment history
func (b *Binance) CryptoLoanLTVAdjustmentHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*CryptoLoanLTVAdjustmentHistory, error) {
params := url.Values{}
if orderID != 0 {
params.Set("orderId", strconv.FormatInt(orderID, 10))
}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if !startTime.IsZero() {
params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10))
}
if !endTime.IsZero() {
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp CryptoLoanLTVAdjustmentHistory
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanLTVAdjustmentHistory, params, spotDefaultRate, &resp)
}
// CryptoLoanAssetsData gets the loanable assets data
func (b *Binance) CryptoLoanAssetsData(ctx context.Context, loanCoin currency.Code, vipLevel int64) (*LoanableAssetsData, error) {
params := url.Values{}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if vipLevel != 0 {
params.Set("vipLevel", strconv.FormatInt(vipLevel, 10))
}
var resp LoanableAssetsData
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanableAssetsData, params, spotDefaultRate, &resp)
}
// CryptoLoanCollateralAssetsData gets the collateral assets data
func (b *Binance) CryptoLoanCollateralAssetsData(ctx context.Context, collateralCoin currency.Code, vipLevel int64) (*CollateralAssetData, error) {
params := url.Values{}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if vipLevel != 0 {
params.Set("vipLevel", strconv.FormatInt(vipLevel, 10))
}
var resp CollateralAssetData
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanCollateralAssetsData, params, spotDefaultRate, &resp)
}
// CryptoLoanCheckCollateralRepayRate checks the collateral repay rate
func (b *Binance) CryptoLoanCheckCollateralRepayRate(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64) (*CollateralRepayRate, error) {
if loanCoin.IsEmpty() {
return nil, errLoanCoinMustBeSet
}
if collateralCoin.IsEmpty() {
return nil, errCollateralCoinMustBeSet
}
if amount <= 0 {
return nil, errAmountMustBeSet
}
params := url.Values{}
params.Set("loanCoin", loanCoin.String())
params.Set("collateralCoin", collateralCoin.String())
params.Set("repayAmount", strconv.FormatFloat(amount, 'f', -1, 64))
var resp CollateralRepayRate
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanCheckCollateralRepayRate, params, spotDefaultRate, &resp)
}
// CryptoLoanCustomiseMarginCall customises a loan's margin call
func (b *Binance) CryptoLoanCustomiseMarginCall(ctx context.Context, orderID int64, collateralCoin currency.Code, marginCallValue float64) (*CustomiseMarginCall, error) {
if marginCallValue <= 0 {
return nil, errors.New("marginCallValue must not be <= 0")
}
params := url.Values{}
if orderID != 0 {
params.Set("orderId", strconv.FormatInt(orderID, 10))
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
params.Set("marginCall", strconv.FormatFloat(marginCallValue, 'f', -1, 64))
var resp CustomiseMarginCall
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanCustomiseMarginCall, params, spotDefaultRate, &resp)
}
// FlexibleLoanBorrow creates a flexible loan
func (b *Binance) FlexibleLoanBorrow(ctx context.Context, loanCoin, collateralCoin currency.Code, loanAmount, collateralAmount float64) (*FlexibleLoanBorrow, error) {
if loanCoin.IsEmpty() {
return nil, errLoanCoinMustBeSet
}
if collateralCoin.IsEmpty() {
return nil, errCollateralCoinMustBeSet
}
if loanAmount == 0 && collateralAmount == 0 {
return nil, errEitherLoanOrCollateralAmountsMustBeSet
}
params := url.Values{}
params.Set("loanCoin", loanCoin.String())
if loanAmount != 0 {
params.Set("loanAmount", strconv.FormatFloat(loanAmount, 'f', -1, 64))
}
params.Set("collateralCoin", collateralCoin.String())
if collateralAmount != 0 {
params.Set("collateralAmount", strconv.FormatFloat(collateralAmount, 'f', -1, 64))
}
var resp FlexibleLoanBorrow
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanBorrow, params, spotDefaultRate, &resp)
}
// FlexibleLoanOngoingOrders gets the flexible loan ongoing orders
func (b *Binance) FlexibleLoanOngoingOrders(ctx context.Context, loanCoin, collateralCoin currency.Code, current, limit int64) (*FlexibleLoanOngoingOrder, error) {
params := url.Values{}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp FlexibleLoanOngoingOrder
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanOngoingOrders, params, spotDefaultRate, &resp)
}
// FlexibleLoanBorrowHistory gets the flexible loan borrow history
func (b *Binance) FlexibleLoanBorrowHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanBorrowHistory, error) {
params := url.Values{}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if !startTime.IsZero() {
params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10))
}
if !endTime.IsZero() {
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp FlexibleLoanBorrowHistory
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanBorrowHistory, params, spotDefaultRate, &resp)
}
// FlexibleLoanRepay repays a flexible loan
func (b *Binance) FlexibleLoanRepay(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64, collateralReturn, fullRepayment bool) (*FlexibleLoanRepay, error) {
if loanCoin.IsEmpty() {
return nil, errLoanCoinMustBeSet
}
if collateralCoin.IsEmpty() {
return nil, errCollateralCoinMustBeSet
}
if amount <= 0 {
return nil, errAmountMustBeSet
}
params := url.Values{}
params.Set("loanCoin", loanCoin.String())
params.Set("collateralCoin", collateralCoin.String())
params.Set("repayAmount", strconv.FormatFloat(amount, 'f', -1, 64))
params.Set("collateralReturn", strconv.FormatBool(collateralReturn))
if fullRepayment {
params.Set("fullRepayment", "true")
}
var resp FlexibleLoanRepay
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanRepay, params, spotDefaultRate, &resp)
}
// FlexibleLoanRepayHistory gets the flexible loan repayment history
func (b *Binance) FlexibleLoanRepayHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanRepayHistory, error) {
params := url.Values{}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if !startTime.IsZero() {
params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10))
}
if !endTime.IsZero() {
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp FlexibleLoanRepayHistory
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanRepayHistory, params, spotDefaultRate, &resp)
}
// FlexibleLoanAdjustLTV adjusts the LTV of a flexible loan
func (b *Binance) FlexibleLoanAdjustLTV(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64, reduce bool) (*FlexibleLoanAdjustLTV, error) {
if loanCoin.IsEmpty() {
return nil, errLoanCoinMustBeSet
}
if collateralCoin.IsEmpty() {
return nil, errCollateralCoinMustBeSet
}
if amount <= 0 {
return nil, errAmountMustBeSet
}
direction := "ADDITIONAL"
if reduce {
direction = "REDUCED"
}
params := url.Values{}
params.Set("loanCoin", loanCoin.String())
params.Set("collateralCoin", collateralCoin.String())
params.Set("adjustmentAmount", strconv.FormatFloat(amount, 'f', -1, 64))
params.Set("direction", direction)
var resp FlexibleLoanAdjustLTV
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanAdjustLTV, params, spotDefaultRate, &resp)
}
// FlexibleLoanLTVAdjustmentHistory gets the flexible loan LTV adjustment history
func (b *Binance) FlexibleLoanLTVAdjustmentHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanLTVAdjustmentHistory, error) {
params := url.Values{}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
if !startTime.IsZero() {
params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10))
}
if !endTime.IsZero() {
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if current != 0 {
params.Set("current", strconv.FormatInt(current, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp FlexibleLoanLTVAdjustmentHistory
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanLTVHistory, params, spotDefaultRate, &resp)
}
// FlexibleLoanAssetsData gets the flexible loan assets data
func (b *Binance) FlexibleLoanAssetsData(ctx context.Context, loanCoin currency.Code) (*FlexibleLoanAssetsData, error) {
params := url.Values{}
if !loanCoin.IsEmpty() {
params.Set("loanCoin", loanCoin.String())
}
var resp FlexibleLoanAssetsData
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanAssetsData, params, spotDefaultRate, &resp)
}
// FlexibleCollateralAssetsData gets the flexible loan collateral assets data
func (b *Binance) FlexibleCollateralAssetsData(ctx context.Context, collateralCoin currency.Code) (*FlexibleCollateralAssetsData, error) {
params := url.Values{}
if !collateralCoin.IsEmpty() {
params.Set("collateralCoin", collateralCoin.String())
}
var resp FlexibleCollateralAssetsData
return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanCollateralAssetsData, params, spotDefaultRate, &resp)
}

View File

@@ -2938,3 +2938,240 @@ func TestGetUserMarginInterestHistory(t *testing.T) {
t.Error(err)
}
}
func TestGetCryptoLoansIncomeHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanIncomeHistory(context.Background(), currency.USDT, "", time.Time{}, time.Time{}, 100); err != nil {
t.Error(err)
}
}
func TestCryptoLoanBorrow(t *testing.T) {
t.Parallel()
if _, err := b.CryptoLoanBorrow(context.Background(), currency.EMPTYCODE, 1000, currency.BTC, 1, 7); !errors.Is(err, errLoanCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errLoanCoinMustBeSet)
}
if _, err := b.CryptoLoanBorrow(context.Background(), currency.USDT, 1000, currency.EMPTYCODE, 1, 7); !errors.Is(err, errCollateralCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errCollateralCoinMustBeSet)
}
if _, err := b.CryptoLoanBorrow(context.Background(), currency.USDT, 0, currency.BTC, 1, 0); !errors.Is(err, errLoanTermMustBeSet) {
t.Errorf("received %v, expected %v", err, errLoanTermMustBeSet)
}
if _, err := b.CryptoLoanBorrow(context.Background(), currency.USDT, 0, currency.BTC, 0, 7); !errors.Is(err, errEitherLoanOrCollateralAmountsMustBeSet) {
t.Errorf("received %v, expected %v", err, errEitherLoanOrCollateralAmountsMustBeSet)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
if _, err := b.CryptoLoanBorrow(context.Background(), currency.USDT, 1000, currency.BTC, 1, 7); err != nil {
t.Error(err)
}
}
func TestCryptoLoanBorrowHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanBorrowHistory(context.Background(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil {
t.Error(err)
}
}
func TestCryptoLoanOngoingOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanOngoingOrders(context.Background(), 0, currency.USDT, currency.BTC, 0, 0); err != nil {
t.Error(err)
}
}
func TestCryptoLoanRepay(t *testing.T) {
t.Parallel()
if _, err := b.CryptoLoanRepay(context.Background(), 0, 1000, 1, false); !errors.Is(err, errOrderIDMustBeSet) {
t.Errorf("received %v, expected %v", err, errOrderIDMustBeSet)
}
if _, err := b.CryptoLoanRepay(context.Background(), 42069, 0, 1, false); !errors.Is(err, errAmountMustBeSet) {
t.Errorf("received %v, expected %v", err, errAmountMustBeSet)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
if _, err := b.CryptoLoanRepay(context.Background(), 42069, 1000, 1, false); err != nil {
t.Error(err)
}
}
func TestCryptoLoanRepaymentHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanRepaymentHistory(context.Background(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil {
t.Error(err)
}
}
func TestCryptoLoanAdjustLTV(t *testing.T) {
t.Parallel()
if _, err := b.CryptoLoanAdjustLTV(context.Background(), 0, true, 1); !errors.Is(err, errOrderIDMustBeSet) {
t.Errorf("received %v, expected %v", err, errOrderIDMustBeSet)
}
if _, err := b.CryptoLoanAdjustLTV(context.Background(), 42069, true, 0); !errors.Is(err, errAmountMustBeSet) {
t.Errorf("received %v, expected %v", err, errAmountMustBeSet)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
if _, err := b.CryptoLoanAdjustLTV(context.Background(), 42069, true, 1); err != nil {
t.Error(err)
}
}
func TestCryptoLoanLTVAdjustmentHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanLTVAdjustmentHistory(context.Background(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil {
t.Error(err)
}
}
func TestCryptoLoanAssetsData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanAssetsData(context.Background(), currency.EMPTYCODE, 0); err != nil {
t.Error(err)
}
}
func TestCryptoLoanCollateralAssetsData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanCollateralAssetsData(context.Background(), currency.EMPTYCODE, 0); err != nil {
t.Error(err)
}
}
func TestCryptoLoanCheckCollateralRepayRate(t *testing.T) {
t.Parallel()
if _, err := b.CryptoLoanCheckCollateralRepayRate(context.Background(), currency.EMPTYCODE, currency.BNB, 69); !errors.Is(err, errLoanCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errLoanCoinMustBeSet)
}
if _, err := b.CryptoLoanCheckCollateralRepayRate(context.Background(), currency.BUSD, currency.EMPTYCODE, 69); !errors.Is(err, errCollateralCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errCollateralCoinMustBeSet)
}
if _, err := b.CryptoLoanCheckCollateralRepayRate(context.Background(), currency.BUSD, currency.BNB, 0); !errors.Is(err, errAmountMustBeSet) {
t.Errorf("received %v, expected %v", err, errAmountMustBeSet)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.CryptoLoanCheckCollateralRepayRate(context.Background(), currency.BUSD, currency.BNB, 69); err != nil {
t.Error(err)
}
}
func TestCryptoLoanCustomiseMarginCall(t *testing.T) {
t.Parallel()
if _, err := b.CryptoLoanCustomiseMarginCall(context.Background(), 0, currency.BTC, 0); err == nil {
t.Error("expected an error")
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
if _, err := b.CryptoLoanCustomiseMarginCall(context.Background(), 1337, currency.BTC, .70); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanBorrow(t *testing.T) {
t.Parallel()
if _, err := b.FlexibleLoanBorrow(context.Background(), currency.EMPTYCODE, currency.USDC, 1, 0); !errors.Is(err, errLoanCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errLoanCoinMustBeSet)
}
if _, err := b.FlexibleLoanBorrow(context.Background(), currency.ATOM, currency.EMPTYCODE, 1, 0); !errors.Is(err, errCollateralCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errCollateralCoinMustBeSet)
}
if _, err := b.FlexibleLoanBorrow(context.Background(), currency.ATOM, currency.USDC, 0, 0); !errors.Is(err, errEitherLoanOrCollateralAmountsMustBeSet) {
t.Errorf("received %v, expected %v", err, errEitherLoanOrCollateralAmountsMustBeSet)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
if _, err := b.FlexibleLoanBorrow(context.Background(), currency.ATOM, currency.USDC, 1, 0); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanOngoingOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.FlexibleLoanOngoingOrders(context.Background(), currency.EMPTYCODE, currency.EMPTYCODE, 0, 0); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanBorrowHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.FlexibleLoanBorrowHistory(context.Background(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanRepay(t *testing.T) {
t.Parallel()
if _, err := b.FlexibleLoanRepay(context.Background(), currency.EMPTYCODE, currency.BTC, 1, false, false); !errors.Is(err, errLoanCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errLoanCoinMustBeSet)
}
if _, err := b.FlexibleLoanRepay(context.Background(), currency.USDT, currency.EMPTYCODE, 1, false, false); !errors.Is(err, errCollateralCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errCollateralCoinMustBeSet)
}
if _, err := b.FlexibleLoanRepay(context.Background(), currency.USDT, currency.BTC, 0, false, false); !errors.Is(err, errAmountMustBeSet) {
t.Errorf("received %v, expected %v", err, errAmountMustBeSet)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
if _, err := b.FlexibleLoanRepay(context.Background(), currency.ATOM, currency.USDC, 1, false, false); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanRepayHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.FlexibleLoanRepayHistory(context.Background(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanAdjustLTV(t *testing.T) {
t.Parallel()
if _, err := b.FlexibleLoanAdjustLTV(context.Background(), currency.EMPTYCODE, currency.BTC, 1, true); !errors.Is(err, errLoanCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errLoanCoinMustBeSet)
}
if _, err := b.FlexibleLoanAdjustLTV(context.Background(), currency.USDT, currency.EMPTYCODE, 1, true); !errors.Is(err, errCollateralCoinMustBeSet) {
t.Errorf("received %v, expected %v", err, errCollateralCoinMustBeSet)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
if _, err := b.FlexibleLoanAdjustLTV(context.Background(), currency.USDT, currency.BTC, 1, true); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanLTVAdjustmentHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.FlexibleLoanLTVAdjustmentHistory(context.Background(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil {
t.Error(err)
}
}
func TestFlexibleLoanAssetsData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.FlexibleLoanAssetsData(context.Background(), currency.EMPTYCODE); err != nil {
t.Error(err)
}
}
func TestFlexibleCollateralAssetsData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
if _, err := b.FlexibleCollateralAssetsData(context.Background(), currency.EMPTYCODE); err != nil {
t.Error(err)
}
}

View File

@@ -937,3 +937,300 @@ type UserMarginInterestHistory struct {
Type string `json:"type"`
IsolatedSymbol string `json:"isolatedSymbol"`
}
// CryptoLoansIncomeHistory stores crypto loan income history data
type CryptoLoansIncomeHistory struct {
Asset currency.Code `json:"asset"`
Type string `json:"type"`
Amount float64 `json:"amount,string"`
TransactionID int64 `json:"tranId"`
}
// CryptoLoanBorrow stores crypto loan borrow data
type CryptoLoanBorrow struct {
LoanCoin currency.Code `json:"loanCoin"`
Amount float64 `json:"amount,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
CollateralAmount float64 `json:"collateralAmount,string"`
HourlyInterestRate float64 `json:"hourlyInterestRate,string"`
OrderID int64 `json:"orderId,string"`
}
// LoanBorrowHistoryItem stores loan borrow history item data
type LoanBorrowHistoryItem struct {
OrderID int64 `json:"orderId"`
LoanCoin currency.Code `json:"loanCoin"`
InitialLoanAmount float64 `json:"initialLoanAmount,string"`
HourlyInterestRate float64 `json:"hourlyInterestRate,string"`
LoanTerm int64 `json:"loanTerm,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
InitialCollateralAmount float64 `json:"initialCollateralAmount,string"`
BorrowTime binanceTime `json:"borrowTime"`
Status string `json:"status"`
}
// LoanBorrowHistory stores loan borrow history data
type LoanBorrowHistory struct {
Rows []LoanBorrowHistoryItem `json:"rows"`
Total int64 `json:"total"`
}
// CryptoLoanOngoingOrderItem stores crypto loan ongoing order item data
type CryptoLoanOngoingOrderItem struct {
OrderID int64 `json:"orderId"`
LoanCoin currency.Code `json:"loanCoin"`
TotalDebt float64 `json:"totalDebt,string"`
ResidualInterest float64 `json:"residualInterest,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
CollateralAmount float64 `json:"collateralAmount,string"`
CurrentLTV float64 `json:"currentLTV,string"`
ExpirationTime binanceTime `json:"expirationTime"`
}
// CryptoLoanOngoingOrder stores crypto loan ongoing order data
type CryptoLoanOngoingOrder struct {
Rows []CryptoLoanOngoingOrderItem `json:"rows"`
Total int64 `json:"total"`
}
// CryptoLoanRepay stores crypto loan repayment data
type CryptoLoanRepay struct {
LoanCoin currency.Code `json:"loanCoin"`
RemainingPrincipal float64 `json:"remainingPrincipal,string"`
RemainingInterest float64 `json:"remainingInterest,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
RemainingCollateral float64 `json:"remainingCollateral,string"`
CurrentLTV float64 `json:"currentLTV,string"`
RepayStatus string `json:"repayStatus"`
}
// CryptoLoanRepayHistoryItem stores crypto loan repayment history item data
type CryptoLoanRepayHistoryItem struct {
LoanCoin currency.Code `json:"loanCoin"`
RepayAmount float64 `json:"repayAmount,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
CollateralUsed float64 `json:"collateralUsed,string"`
CollateralReturn float64 `json:"collateralReturn,string"`
RepayType string `json:"repayType"`
RepayTime binanceTime `json:"repayTime"`
OrderID int64 `json:"orderId"`
}
// CryptoLoanRepayHistory stores crypto loan repayment history data
type CryptoLoanRepayHistory struct {
Rows []CryptoLoanRepayHistoryItem `json:"rows"`
Total int64 `json:"total"`
}
// CryptoLoanAdjustLTV stores crypto loan LTV adjustment data
type CryptoLoanAdjustLTV struct {
LoanCoin currency.Code `json:"loanCoin"`
CollateralCoin currency.Code `json:"collateralCoin"`
Direction string `json:"direction"`
Amount float64 `json:"amount,string"`
CurrentLTV float64 `json:"currentLTV,string"`
}
// CryptoLoanLTVAdjustmentItem stores crypto loan LTV adjustment item data
type CryptoLoanLTVAdjustmentItem struct {
LoanCoin currency.Code `json:"loanCoin"`
CollateralCoin currency.Code `json:"collateralCoin"`
Direction string `json:"direction"`
Amount float64 `json:"amount,string"`
PreviousLTV float64 `json:"preLTV,string"`
AfterLTV float64 `json:"afterLTV,string"`
AdjustTime binanceTime `json:"adjustTime"`
OrderID int64 `json:"orderId"`
}
// CryptoLoanLTVAdjustmentHistory stores crypto loan LTV adjustment history data
type CryptoLoanLTVAdjustmentHistory struct {
Rows []CryptoLoanLTVAdjustmentItem `json:"rows"`
Total int64 `json:"total"`
}
// LoanableAssetItem stores loanable asset item data
type LoanableAssetItem struct {
LoanCoin currency.Code `json:"loanCoin"`
SevenDayHourlyInterestRate float64 `json:"_7dHourlyInterestRate,string"`
SevenDayDailyInterestRate float64 `json:"_7dDailyInterestRate,string"`
FourteenDayHourlyInterest float64 `json:"_14dHourlyInterestRate,string"`
FourteenDayDailyInterest float64 `json:"_14dDailyInterestRate,string"`
ThirtyDayHourlyInterest float64 `json:"_30dHourlyInterestRate,string"`
ThirtyDayDailyInterest float64 `json:"_30dDailyInterestRate,string"`
NinetyDayHourlyInterest float64 `json:"_90dHourlyInterestRate,string"`
NinetyDayDailyInterest float64 `json:"_90dDailyInterestRate,string"`
OneHundredAndEightyDayHourlyInterest float64 `json:"_180dHourlyInterestRate,string"`
OneHundredAndEightyDayDailyInterest float64 `json:"_180dDailyInterestRate,string"`
MinimumLimit float64 `json:"minLimit,string"`
MaximumLimit float64 `json:"maxLimit,string"`
VIPLevel int64 `json:"vipLevel"`
}
// LoanableAssetsData stores loanable assets data
type LoanableAssetsData struct {
Rows []LoanableAssetItem `json:"rows"`
Total int64 `json:"total"`
}
// CollateralAssetItem stores collateral asset item data
type CollateralAssetItem struct {
CollateralCoin currency.Code `json:"collateralCoin"`
InitialLTV float64 `json:"initialLTV,string"`
MarginCallLTV float64 `json:"marginCallLTV,string"`
LiquidationLTV float64 `json:"liquidationLTV,string"`
MaxLimit float64 `json:"maxLimit,string"`
VIPLevel int64 `json:"vipLevel"`
}
// CollateralAssetData stores collateral asset data
type CollateralAssetData struct {
Rows []CollateralAssetItem `json:"rows"`
Total int64 `json:"total"`
}
// CollateralRepayRate stores collateral repayment rate data
type CollateralRepayRate struct {
LoanCoin currency.Code `json:"loanCoin"`
CollateralCoin currency.Code `json:"collateralCoin"`
RepayAmount float64 `json:"repayAmount,string"`
Rate float64 `json:"rate,string"`
}
// CustomiseMarginCallItem stores customise margin call item data
type CustomiseMarginCallItem struct {
OrderID int64 `json:"orderId"`
CollateralCoin currency.Code `json:"collateralCoin"`
PreMarginCall float64 `json:"preMarginCall,string"`
AfterMarginCall float64 `json:"afterMarginCall,string"`
CustomiseTime binanceTime `json:"customizeTime"`
}
// CustomiseMarginCall stores customise margin call data
type CustomiseMarginCall struct {
Rows []CustomiseMarginCallItem `json:"rows"`
Total int64 `json:"total"`
}
// FlexibleLoanBorrow stores a flexible loan borrow
type FlexibleLoanBorrow struct {
LoanCoin currency.Code `json:"loanCoin"`
LoanAmount float64 `json:"loanAmount,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
CollateralAmount float64 `json:"collateralAmount,string"`
Status string `json:"status"`
}
// FlexibleLoanOngoingOrderItem stores a flexible loan ongoing order item
type FlexibleLoanOngoingOrderItem struct {
LoanCoin currency.Code `json:"loanCoin"`
TotalDebt float64 `json:"totalDebt,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
CollateralAmount float64 `json:"collateralAmount,string"`
CurrentLTV float64 `json:"currentLTV,string"`
}
// FlexibleLoanOngoingOrder stores flexible loan ongoing orders
type FlexibleLoanOngoingOrder struct {
Rows []FlexibleLoanOngoingOrderItem `json:"rows"`
Total int64 `json:"total"`
}
// FlexibleLoanBorrowHistoryItem stores a flexible loan borrow history item
type FlexibleLoanBorrowHistoryItem struct {
LoanCoin currency.Code `json:"loanCoin"`
InitialLoanAmount float64 `json:"initialLoanAmount,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
InitialCollateralAmount float64 `json:"initialCollateralAmount,string"`
BorrowTime binanceTime `json:"borrowTime"`
Status string `json:"status"`
}
// FlexibleLoanBorrowHistory stores flexible loan borrow history
type FlexibleLoanBorrowHistory struct {
Rows []FlexibleLoanBorrowHistoryItem `json:"rows"`
Total int64 `json:"total"`
}
// FlexibleLoanRepay stores a flexible loan repayment
type FlexibleLoanRepay struct {
LoanCoin currency.Code `json:"loanCoin"`
CollateralCoin currency.Code `json:"collateralCoin"`
RemainingDebt float64 `json:"remainingDebt,string"`
RemainingCollateral float64 `json:"remainingCollateral,string"`
FullRepayment bool `json:"fullRepayment"`
CurrentLTV float64 `json:"currentLTV,string"`
RepayStatus string `json:"repayStatus"`
}
// FlexibleLoanRepayHistoryItem stores a flexible loan repayment history item
type FlexibleLoanRepayHistoryItem struct {
LoanCoin currency.Code `json:"loanCoin"`
RepayAmount float64 `json:"repayAmount,string"`
CollateralCoin currency.Code `json:"collateralCoin"`
CollateralReturn float64 `json:"collateralReturn,string"`
RepayStatus string `json:"repayStatus"`
RepayTime binanceTime `json:"repayTime"`
}
// FlexibleLoanRepayHistory stores flexible loan repayment history
type FlexibleLoanRepayHistory struct {
Rows []FlexibleLoanRepayHistoryItem `json:"rows"`
Total int64 `json:"total"`
}
// FlexibleLoanAdjustLTV stores a flexible loan LTV adjustment
type FlexibleLoanAdjustLTV struct {
LoanCoin currency.Code `json:"loanCoin"`
CollateralCoin currency.Code `json:"collateralCoin"`
Direction string `json:"direction"`
Amount float64 `json:"amount,string"` // docs error: API actually returns "amount" instead of "adjustedAmount"
CurrentLTV float64 `json:"currentLTV,string"`
Status string `json:"status"`
}
// FlexibleLoanLTVAdjustmentHistoryItem stores a flexible loan LTV adjustment history item
type FlexibleLoanLTVAdjustmentHistoryItem struct {
LoanCoin currency.Code `json:"loanCoin"`
CollateralCoin currency.Code `json:"collateralCoin"`
Direction string `json:"direction"`
CollateralAmount float64 `json:"collateralAmount,string"`
PreviousLTV float64 `json:"preLTV,string"`
AfterLTV float64 `json:"afterLTV,string"`
AdjustTime binanceTime `json:"adjustTime"`
}
// FlexibleLoanLTVAdjustmentHistory stores flexible loan LTV adjustment history
type FlexibleLoanLTVAdjustmentHistory struct {
Rows []FlexibleLoanLTVAdjustmentHistoryItem `json:"rows"`
Total int64 `json:"total"`
}
// FlexibleLoanAssetsDataItem stores a flexible loan asset data item
type FlexibleLoanAssetsDataItem struct {
LoanCoin currency.Code `json:"loanCoin"`
FlexibleInterestRate float64 `json:"flexibleInterestRate,string"`
FlexibleMinLimit float64 `json:"flexibleMinLimit,string"`
FlexibleMaxLimit float64 `json:"flexibleMaxLimit,string"`
}
// FlexibleLoanAssetsData stores flexible loan asset data
type FlexibleLoanAssetsData struct {
Rows []FlexibleLoanAssetsDataItem `json:"rows"`
Total int64 `json:"total"`
}
// FlexibleCollateralAssetsDataItem stores a flexible collateral asset data item
type FlexibleCollateralAssetsDataItem struct {
CollateralCoin currency.Code `json:"collateralCoin"`
InitialLTV float64 `json:"initialLTV,string"`
MarginCallLTV float64 `json:"marginCallLTV,string"`
LiquidationLTV float64 `json:"liquidationLTV,string"`
MaxLimit float64 `json:"maxLimit,string"`
}
// FlexibleCollateralAssetsData stores flexible collateral asset data
type FlexibleCollateralAssetsData struct {
Rows []FlexibleCollateralAssetsDataItem `json:"rows"`
Total int64 `json:"total"`
}

View File

@@ -2,6 +2,7 @@ package binance
import (
"encoding/json"
"errors"
"strconv"
"time"
)
@@ -10,11 +11,23 @@ import (
type binanceTime time.Time
func (t *binanceTime) UnmarshalJSON(data []byte) error {
var timestamp int64
if err := json.Unmarshal(data, &timestamp); err != nil {
var result interface{}
if err := json.Unmarshal(data, &result); err != nil {
return err
}
*t = binanceTime(time.UnixMilli(timestamp))
switch v := result.(type) {
case string:
timestamp, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return err
}
*t = binanceTime(time.UnixMilli(timestamp))
case float64:
*t = binanceTime(time.UnixMilli(int64(v)))
default:
return errors.New("invalid time format received")
}
return nil
}