mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
* consolidate type to types package and share across code base * rm convert type and convert codebase * rm irrelavant test cases * Fix tests * glorious nits * Update exchanges/gateio/gateio_types.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * thrasher: nits --------- Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
3480 lines
106 KiB
Go
3480 lines
106 KiB
Go
package binance
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/common/key"
|
|
"github.com/thrasher-corp/gocryptotrader/core"
|
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
|
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/collateral"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/futures"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/margin"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
|
|
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
|
|
testsubs "github.com/thrasher-corp/gocryptotrader/internal/testing/subscriptions"
|
|
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
|
)
|
|
|
|
// Please supply your own keys here for due diligence testing
|
|
const (
|
|
apiKey = ""
|
|
apiSecret = ""
|
|
canManipulateRealOrders = false
|
|
useTestNet = false
|
|
)
|
|
|
|
var (
|
|
b = &Binance{}
|
|
// this pair is used to ensure that endpoints match it correctly
|
|
testPairMapping = currency.NewPair(currency.DOGE, currency.USDT)
|
|
)
|
|
|
|
func setFeeBuilder() *exchange.FeeBuilder {
|
|
return &exchange.FeeBuilder{
|
|
Amount: 1,
|
|
FeeType: exchange.CryptocurrencyTradeFee,
|
|
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
|
PurchasePrice: 1,
|
|
}
|
|
}
|
|
|
|
// getTime returns a static time for mocking endpoints, if mock is not enabled
|
|
// this will default to time now with a window size of 30 days.
|
|
// Mock details are unix seconds; start = 1577836800 and end = 1580515200
|
|
func getTime() (start, end time.Time) {
|
|
if mockTests {
|
|
return time.Unix(1577836800, 0), time.Unix(1580515200, 0)
|
|
}
|
|
|
|
tn := time.Now()
|
|
offset := time.Hour * 24 * 6
|
|
return tn.Add(-offset), tn
|
|
}
|
|
|
|
func TestUServerTime(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UServerTime(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWrapperGetServerTime(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetServerTime(context.Background(), asset.Empty)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
|
|
st, err := b.GetServerTime(context.Background(), asset.Spot)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if st.IsZero() {
|
|
t.Fatal("expected a time")
|
|
}
|
|
|
|
st, err = b.GetServerTime(context.Background(), asset.USDTMarginedFutures)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if st.IsZero() {
|
|
t.Fatal("expected a time")
|
|
}
|
|
|
|
st, err = b.GetServerTime(context.Background(), asset.CoinMarginedFutures)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if st.IsZero() {
|
|
t.Fatal("expected a time")
|
|
}
|
|
}
|
|
|
|
func TestUpdateTicker(t *testing.T) {
|
|
t.Parallel()
|
|
r, err := b.UpdateTicker(context.Background(), testPairMapping, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if r.Pair.Base != currency.DOGE && r.Pair.Quote != currency.USDT {
|
|
t.Error("invalid pair values")
|
|
}
|
|
tradablePairs, err := b.FetchTradablePairs(context.Background(), asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if len(tradablePairs) == 0 {
|
|
t.Fatal("no tradable pairs")
|
|
}
|
|
_, err = b.UpdateTicker(context.Background(), tradablePairs[0], asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
usdtMarginedPairs, err := b.FetchTradablePairs(context.Background(), asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if len(usdtMarginedPairs) == 0 {
|
|
t.Errorf("no pairs are enabled")
|
|
}
|
|
_, err = b.UpdateTicker(context.Background(), usdtMarginedPairs[0], asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateTickers(t *testing.T) {
|
|
err := b.UpdateTickers(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
err = b.UpdateTickers(context.Background(), asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
err = b.UpdateTickers(context.Background(), asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
cp, err := currency.NewPairFromString("BTCUSDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UpdateOrderbook(context.Background(), cp, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UpdateOrderbook(context.Background(), cp, asset.Margin)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UpdateOrderbook(context.Background(), cp, asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
cp2, err := currency.NewPairFromString("BTCUSD_PERP")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UpdateOrderbook(context.Background(), cp2, asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// USDT Margined Futures
|
|
|
|
func TestUExchangeInfo(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UExchangeInfo(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUFuturesOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UFuturesOrderbook(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 1000)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestURecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.URecentTrades(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 1000)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUCompressedTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UCompressedTrades(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.UCompressedTrades(context.Background(), currency.NewPair(currency.LTC, currency.USDT), "", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUKlineData(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UKlineData(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "1d", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.UKlineData(context.Background(), currency.NewPair(currency.LTC, currency.USDT), "5m", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUGetMarkPrice(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UGetMarkPrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UGetMarkPrice(context.Background(), currency.EMPTYPAIR)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUGetFundingHistory(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UGetFundingHistory(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 1, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.UGetFundingHistory(context.Background(), currency.NewPair(currency.LTC, currency.USDT), 1, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestU24HTickerPriceChangeStats(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.U24HTickerPriceChangeStats(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.U24HTickerPriceChangeStats(context.Background(), currency.EMPTYPAIR)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUSymbolPriceTicker(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.USymbolPriceTicker(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.USymbolPriceTicker(context.Background(), currency.EMPTYPAIR)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUSymbolOrderbookTicker(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.USymbolOrderbookTicker(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.USymbolOrderbookTicker(context.Background(), currency.EMPTYPAIR)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUOpenInterest(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UOpenInterest(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUOpenInterestStats(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UOpenInterestStats(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 1, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.UOpenInterestStats(context.Background(), currency.NewPair(currency.LTC, currency.USDT), "1d", 10, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUTopAcccountsLongShortRatio(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UTopAcccountsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 2, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.UTopAcccountsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 2, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUTopPostionsLongShortRatio(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UTopPostionsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 3, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.UTopPostionsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "1d", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUGlobalLongShortRatio(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UGlobalLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 3, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.UGlobalLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "4h", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUTakerBuySellVol(t *testing.T) {
|
|
t.Parallel()
|
|
start, end := getTime()
|
|
_, err := b.UTakerBuySellVol(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 10, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUCompositeIndexInfo(t *testing.T) {
|
|
t.Parallel()
|
|
cp, err := currency.NewPairFromString("DEFI-USDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UCompositeIndexInfo(context.Background(), cp)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UCompositeIndexInfo(context.Background(), currency.EMPTYPAIR)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUFuturesNewOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UFuturesNewOrder(context.Background(),
|
|
&UFuturesNewOrderRequest{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Side: "BUY",
|
|
OrderType: "LIMIT",
|
|
TimeInForce: "GTC",
|
|
Quantity: 1,
|
|
Price: 1,
|
|
},
|
|
)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUPlaceBatchOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
var data []PlaceBatchOrderData
|
|
var tempData PlaceBatchOrderData
|
|
tempData.Symbol = "BTCUSDT"
|
|
tempData.Side = "BUY"
|
|
tempData.OrderType = "LIMIT"
|
|
tempData.Quantity = 4
|
|
tempData.Price = 1
|
|
tempData.TimeInForce = "GTC"
|
|
data = append(data, tempData)
|
|
_, err := b.UPlaceBatchOrders(context.Background(), data)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUGetOrderData(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UGetOrderData(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "123", "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUCancelOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UCancelOrder(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "123", "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUCancelAllOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UCancelAllOpenOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUCancelBatchOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UCancelBatchOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), []string{"123"}, []string{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAutoCancelAllOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UAutoCancelAllOpenOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 30)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUFetchOpenOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UFetchOpenOrder(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "123", "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAllAccountOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UAllAccountOpenOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAllAccountOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UAllAccountOrders(context.Background(), currency.EMPTYPAIR, 0, 0, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UAllAccountOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 0, 5, time.Now().Add(-time.Hour*4), time.Now())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAccountBalanceV2(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UAccountBalanceV2(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAccountInformationV2(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UAccountInformationV2(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUChangeInitialLeverageRequest(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UChangeInitialLeverageRequest(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 2)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUChangeInitialMarginType(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
err := b.UChangeInitialMarginType(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "ISOLATED")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUModifyIsolatedPositionMarginReq(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UModifyIsolatedPositionMarginReq(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "LONG", "add", 5)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUPositionMarginChangeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.UPositionMarginChangeHistory(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "add", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUPositionsInfoV2(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UPositionsInfoV2(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAccountTradesHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UAccountTradesHistory(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAccountIncomeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UAccountIncomeHistory(context.Background(), currency.EMPTYPAIR, "", 5, time.Now().Add(-time.Hour*48), time.Now())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUGetNotionalAndLeverageBrackets(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UGetNotionalAndLeverageBrackets(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUPositionsADLEstimate(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UPositionsADLEstimate(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUAccountForcedOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.UAccountForcedOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "ADL", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// Coin Margined Futures
|
|
|
|
func TestGetFuturesExchangeInfo(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.FuturesExchangeInfo(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesOrderbook(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 1000)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesPublicTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesPublicTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetPastPublicTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetPastPublicTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAggregatedTradesList(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesAggregatedTradesList(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 0, 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetPerpsExchangeInfo(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetPerpMarkets(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetIndexAndMarkPrice(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetIndexAndMarkPrice(context.Background(), "", "BTCUSD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesKlineData(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesKlineData(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
start, end := getTime()
|
|
_, err = b.GetFuturesKlineData(context.Background(), currency.NewPairWithDelimiter("LTCUSD", "PERP", "_"), "5m", 5, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetContinuousKlineData(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetContinuousKlineData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetContinuousKlineData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetIndexPriceKlines(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetIndexPriceKlines(context.Background(), "BTCUSD", "1M", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetIndexPriceKlines(context.Background(), "BTCUSD", "1M", 5, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesSwapTickerChangeStats(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesSwapTickerChangeStats(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetFuturesSwapTickerChangeStats(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetFuturesSwapTickerChangeStats(context.Background(), currency.EMPTYPAIR, "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesGetFundingHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesGetFundingHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.FuturesGetFundingHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 50, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesHistoricalTrades(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetFuturesHistoricalTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 5)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetFuturesHistoricalTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesSymbolPriceTicker(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesSymbolPriceTicker(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesOrderbookTicker(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesOrderbookTicker(context.Background(), currency.EMPTYPAIR, "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetFuturesOrderbookTicker(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestOpenInterest(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.OpenInterest(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOpenInterestStats(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetOpenInterestStats(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetOpenInterestStats(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetTraderFuturesAccountRatio(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetTraderFuturesAccountRatio(context.Background(), "BTCUSD", "5m", 0, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetTraderFuturesAccountRatio(context.Background(), "BTCUSD", "5m", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetTraderFuturesPositionsRatio(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetTraderFuturesPositionsRatio(context.Background(), "BTCUSD", "5m", 0, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetTraderFuturesPositionsRatio(context.Background(), "BTCUSD", "5m", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarketRatio(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetMarketRatio(context.Background(), "BTCUSD", "5m", 0, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetMarketRatio(context.Background(), "BTCUSD", "5m", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesTakerVolume(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesTakerVolume(context.Background(), "BTCUSD", "ALL", "5m", 0, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetFuturesTakerVolume(context.Background(), "BTCUSD", "ALL", "5m", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesBasisData(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesBasisData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
start, end := getTime()
|
|
_, err = b.GetFuturesBasisData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, start, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesNewOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.FuturesNewOrder(
|
|
context.Background(),
|
|
&FuturesNewOrderRequest{
|
|
Symbol: currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"),
|
|
Side: "BUY",
|
|
OrderType: "LIMIT",
|
|
TimeInForce: BinanceRequestParamsTimeGTC,
|
|
Quantity: 1,
|
|
Price: 1,
|
|
},
|
|
)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesBatchOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
var data []PlaceBatchOrderData
|
|
var tempData PlaceBatchOrderData
|
|
tempData.Symbol = "BTCUSD_PERP"
|
|
tempData.Side = "BUY"
|
|
tempData.OrderType = "LIMIT"
|
|
tempData.Quantity = 1
|
|
tempData.Price = 1
|
|
tempData.TimeInForce = "GTC"
|
|
|
|
data = append(data, tempData)
|
|
_, err := b.FuturesBatchOrder(context.Background(), data)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesBatchCancelOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.FuturesBatchCancelOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), []string{"123"}, []string{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesGetOrderData(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesGetOrderData(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "123", "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.FuturesCancelAllOpenOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestAutoCancelAllOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.AutoCancelAllOpenOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 30000)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesOpenOrderData(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesOpenOrderData(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesAllOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetFuturesAllOpenOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAllFuturesOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetAllFuturesOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), currency.EMPTYPAIR, time.Time{}, time.Time{}, 0, 2)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesChangeMarginType(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.FuturesChangeMarginType(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "ISOLATED")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesAccountBalance(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetFuturesAccountBalance(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetFuturesAccountInfo(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesChangeInitialLeverage(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.FuturesChangeInitialLeverage(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestModifyIsolatedPositionMargin(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.ModifyIsolatedPositionMargin(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "BOTH", "add", 5)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesMarginChangeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesMarginChangeHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "add", time.Time{}, time.Time{}, 10)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesPositionsInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesPositionsInfo(context.Background(), "BTCUSD", "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesTradeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesTradeHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", time.Time{}, time.Time{}, 5, 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesIncomeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesIncomeHistory(context.Background(), currency.EMPTYPAIR, "TRANSFER", time.Time{}, time.Time{}, 5)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesForceOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesForceOrders(context.Background(), currency.EMPTYPAIR, "ADL", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUGetNotionalLeverage(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesNotionalBracket(context.Background(), "BTCUSD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.FuturesNotionalBracket(context.Background(), "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFuturesPositionsADLEstimate(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FuturesPositionsADLEstimate(context.Background(), currency.EMPTYPAIR)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarkPriceKline(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetMarkPriceKline(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetExchangeInfo(t *testing.T) {
|
|
t.Parallel()
|
|
info, err := b.GetExchangeInfo(context.Background())
|
|
require.NoError(t, err, "GetExchangeInfo must not error")
|
|
if mockTests {
|
|
exp := time.Date(2024, 5, 10, 6, 8, 1, int(707*time.Millisecond), time.UTC)
|
|
assert.True(t, info.ServerTime.Equal(exp), "expected %v received %v", exp.UTC(), info.ServerTime.UTC())
|
|
} else {
|
|
assert.WithinRange(t, info.ServerTime, time.Now().Add(-24*time.Hour), time.Now().Add(24*time.Hour), "ServerTime should be within a day of now")
|
|
}
|
|
}
|
|
|
|
func TestFetchTradablePairs(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.FetchTradablePairs(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error("Binance FetchTradablePairs(asset asets.AssetType) error", err)
|
|
}
|
|
|
|
_, err = b.FetchTradablePairs(context.Background(), asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.FetchTradablePairs(context.Background(), asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderBook(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetOrderBook(context.Background(),
|
|
OrderBookDataRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 1000,
|
|
})
|
|
|
|
if err != nil {
|
|
t.Error("Binance GetOrderBook() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetMostRecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetMostRecentTrades(context.Background(),
|
|
RecentTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 15,
|
|
})
|
|
|
|
if err != nil {
|
|
t.Error("Binance GetMostRecentTrades() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricalTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetHistoricalTrades(context.Background(), "BTCUSDT", 5, -1)
|
|
if !mockTests && err == nil {
|
|
t.Errorf("Binance GetHistoricalTrades() error: %v", "expected error")
|
|
} else if mockTests && err != nil {
|
|
t.Errorf("Binance GetHistoricalTrades() error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAggregatedTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetAggregatedTrades(context.Background(),
|
|
&AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 5,
|
|
})
|
|
if err != nil {
|
|
t.Error("Binance GetAggregatedTrades() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetSpotKline(t *testing.T) {
|
|
t.Parallel()
|
|
start, end := getTime()
|
|
_, err := b.GetSpotKline(context.Background(),
|
|
&KlinesRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Interval: kline.FiveMin.Short(),
|
|
Limit: 24,
|
|
StartTime: start,
|
|
EndTime: end,
|
|
})
|
|
if err != nil {
|
|
t.Error("Binance GetSpotKline() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAveragePrice(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetAveragePrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error("Binance GetAveragePrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetPriceChangeStats(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetPriceChangeStats(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error("Binance GetPriceChangeStats() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTickers(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetTickers(context.Background())
|
|
if err != nil {
|
|
t.Error("Binance TestGetTickers error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetLatestSpotPrice(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetLatestSpotPrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error("Binance GetLatestSpotPrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetBestPrice(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetBestPrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error("Binance GetBestPrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestQueryOrder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.QueryOrder(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 1337)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("QueryOrder() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("QueryOrder() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock QueryOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.OpenOrders(context.Background(), currency.EMPTYPAIR)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p := currency.NewPair(currency.BTC, currency.USDT)
|
|
_, err = b.OpenOrders(context.Background(), p)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestAllOrders(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.AllOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", "")
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("AllOrders() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("AllOrders() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock AllOrders() error", err)
|
|
}
|
|
}
|
|
|
|
// TestGetFeeByTypeOfflineTradeFee logic test
|
|
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var feeBuilder = setFeeBuilder()
|
|
_, err := b.GetFeeByType(context.Background(), feeBuilder)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) || mockTests {
|
|
if feeBuilder.FeeType != exchange.OfflineTradeFee {
|
|
t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType)
|
|
}
|
|
} else {
|
|
if feeBuilder.FeeType != exchange.CryptocurrencyTradeFee {
|
|
t.Errorf("Expected %v, received %v", exchange.CryptocurrencyTradeFee, feeBuilder.FeeType)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetFee(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var feeBuilder = setFeeBuilder()
|
|
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && mockTests {
|
|
// CryptocurrencyTradeFee Basic
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee High quantity
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.Amount = 1000
|
|
feeBuilder.PurchasePrice = 1000
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee IsMaker
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.IsMaker = true
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee Negative purchase price
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.PurchasePrice = -1000
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// CryptocurrencyWithdrawalFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyDepositFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.CryptocurrencyDepositFee
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// InternationalBankDepositFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
|
feeBuilder.FiatCurrency = currency.HKD
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// InternationalBankWithdrawalFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
|
feeBuilder.FiatCurrency = currency.HKD
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFormatWithdrawPermissions(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText
|
|
withdrawPermissions := b.FormatWithdrawPermissions()
|
|
if withdrawPermissions != expectedResult {
|
|
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveOrders(t *testing.T) {
|
|
t.Parallel()
|
|
pair, err := currency.NewPairFromString("BTC_USDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
var getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
Pairs: currency.Pairs{pair},
|
|
AssetType: asset.Spot,
|
|
Side: order.AnySide,
|
|
}
|
|
|
|
_, err = b.GetActiveOrders(context.Background(), &getOrdersRequest)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("GetActiveOrders() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("GetActiveOrders() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock GetActiveOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderHistory(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
AssetType: asset.Spot,
|
|
Side: order.AnySide,
|
|
}
|
|
|
|
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
if err == nil {
|
|
t.Error("Expected: 'At least one currency is required to fetch order history'. received nil")
|
|
}
|
|
|
|
getOrdersRequest.Pairs = []currency.Pair{
|
|
currency.NewPair(currency.LTC,
|
|
currency.BTC)}
|
|
|
|
_, err = b.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("GetOrderHistory() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("GetOrderHistory() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock GetOrderHistory() error", err)
|
|
}
|
|
}
|
|
|
|
func TestNewOrderTest(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
req := &NewOrderRequest{
|
|
Symbol: currency.NewPair(currency.LTC, currency.BTC),
|
|
Side: order.Buy.String(),
|
|
TradeType: BinanceRequestParamsOrderLimit,
|
|
Price: 0.0025,
|
|
Quantity: 100000,
|
|
TimeInForce: BinanceRequestParamsTimeGTC,
|
|
}
|
|
|
|
err := b.NewOrderTest(context.Background(), req)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("NewOrderTest() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("NewOrderTest() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock NewOrderTest() error", err)
|
|
}
|
|
|
|
req = &NewOrderRequest{
|
|
Symbol: currency.NewPair(currency.LTC, currency.BTC),
|
|
Side: order.Sell.String(),
|
|
TradeType: BinanceRequestParamsOrderMarket,
|
|
Price: 0.0045,
|
|
QuoteOrderQty: 10,
|
|
}
|
|
|
|
err = b.NewOrderTest(context.Background(), req)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("NewOrderTest() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("NewOrderTest() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock NewOrderTest() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricTrades(t *testing.T) {
|
|
t.Parallel()
|
|
p := currency.NewPair(currency.BTC, currency.USDT)
|
|
start := time.Unix(1577977445, 0) // 2020-01-02 15:04:05
|
|
end := start.Add(15 * time.Minute) // 2020-01-02 15:19:05
|
|
result, err := b.GetHistoricTrades(context.Background(), p, asset.Spot, start, end)
|
|
assert.NoError(t, err, "GetHistoricTrades should not error")
|
|
expected := 2134
|
|
if mockTests {
|
|
expected = 1002
|
|
}
|
|
assert.Equal(t, expected, len(result), "GetHistoricTrades should return correct number of entries")
|
|
for _, r := range result {
|
|
if !assert.WithinRange(t, r.Timestamp, start, end, "All trades should be within time range") {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetAggregatedTradesBatched(t *testing.T) {
|
|
t.Parallel()
|
|
currencyPair, err := currency.NewPairFromString("BTCUSDT")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
start, err := time.Parse(time.RFC3339, "2020-01-02T15:04:05Z")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
expectTime, err := time.Parse(time.RFC3339Nano, "2020-01-02T16:19:04.831Z")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
// mock test or live test
|
|
mock bool
|
|
args *AggregatedTradeRequestParams
|
|
numExpected int
|
|
lastExpected time.Time
|
|
}{
|
|
{
|
|
name: "mock batch with timerange",
|
|
mock: true,
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currencyPair,
|
|
StartTime: start,
|
|
EndTime: start.Add(75 * time.Minute),
|
|
},
|
|
numExpected: 1012,
|
|
lastExpected: time.Date(2020, 1, 2, 16, 18, 31, int(919*time.Millisecond), time.UTC),
|
|
},
|
|
{
|
|
name: "batch with timerange",
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currencyPair,
|
|
StartTime: start,
|
|
EndTime: start.Add(75 * time.Minute),
|
|
},
|
|
numExpected: 12130,
|
|
lastExpected: expectTime,
|
|
},
|
|
{
|
|
name: "mock custom limit with start time set, no end time",
|
|
mock: true,
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartTime: start,
|
|
Limit: 1001,
|
|
},
|
|
numExpected: 1001,
|
|
lastExpected: time.Date(2020, 1, 2, 15, 18, 39, int(226*time.Millisecond), time.UTC),
|
|
},
|
|
{
|
|
name: "custom limit with start time set, no end time",
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartTime: time.Date(2020, 11, 18, 23, 0, 28, 921, time.UTC),
|
|
Limit: 1001,
|
|
},
|
|
numExpected: 1001,
|
|
lastExpected: time.Date(2020, 11, 18, 23, 1, 33, int(62*time.Millisecond*10), time.UTC),
|
|
},
|
|
{
|
|
name: "mock recent trades",
|
|
mock: true,
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 3,
|
|
},
|
|
numExpected: 3,
|
|
lastExpected: time.Date(2020, 1, 2, 16, 19, 5, int(200*time.Millisecond), time.UTC),
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
if tt.mock != mockTests {
|
|
t.Skip("mock mismatch, skipping")
|
|
}
|
|
result, err := b.GetAggregatedTrades(context.Background(), tt.args)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if len(result) != tt.numExpected {
|
|
t.Errorf("GetAggregatedTradesBatched() expected %v entries, got %v", tt.numExpected, len(result))
|
|
}
|
|
lastTradeTime := result[len(result)-1].TimeStamp
|
|
if !lastTradeTime.Equal(tt.lastExpected) {
|
|
t.Errorf("last trade expected %v, got %v", tt.lastExpected.UTC(), lastTradeTime.UTC())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetAggregatedTradesErrors(t *testing.T) {
|
|
t.Parallel()
|
|
start, err := time.Parse(time.RFC3339, "2020-01-02T15:04:05Z")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args *AggregatedTradeRequestParams
|
|
}{
|
|
{
|
|
name: "get recent trades does not support custom limit",
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 1001,
|
|
},
|
|
},
|
|
{
|
|
name: "start time and fromId cannot be both set",
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartTime: start,
|
|
EndTime: start.Add(75 * time.Minute),
|
|
FromID: 2,
|
|
},
|
|
},
|
|
{
|
|
name: "can't get most recent 5000 (more than 1000 not allowed)",
|
|
args: &AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 5000,
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetAggregatedTrades(context.Background(), tt.args)
|
|
if err == nil {
|
|
t.Errorf("Binance.GetAggregatedTrades() error = %v, wantErr true", err)
|
|
return
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
|
|
// -----------------------------------------------------------------------------------------------------------------------------
|
|
|
|
func TestSubmitOrder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if !mockTests {
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
}
|
|
|
|
var orderSubmission = &order.Submit{
|
|
Exchange: b.Name,
|
|
Pair: currency.Pair{
|
|
Delimiter: "_",
|
|
Base: currency.LTC,
|
|
Quote: currency.BTC,
|
|
},
|
|
Side: order.Buy,
|
|
Type: order.Limit,
|
|
Price: 1,
|
|
Amount: 1000000000,
|
|
ClientID: "meowOrder",
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
_, err := b.SubmitOrder(context.Background(), orderSubmission)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("SubmitOrder() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("SubmitOrder() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock SubmitOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelExchangeOrder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if !mockTests {
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
}
|
|
var orderCancellation = &order.Cancel{
|
|
OrderID: "1",
|
|
WalletAddress: core.BitcoinDonationAddress,
|
|
AccountID: "1",
|
|
Pair: currency.NewPair(currency.LTC, currency.BTC),
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
err := b.CancelOrder(context.Background(), orderCancellation)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("CancelExchangeOrder() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("CancelExchangeOrder() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock CancelExchangeOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllExchangeOrders(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if !mockTests {
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
}
|
|
var orderCancellation = &order.Cancel{
|
|
OrderID: "1",
|
|
WalletAddress: core.BitcoinDonationAddress,
|
|
AccountID: "1",
|
|
Pair: currency.NewPair(currency.LTC, currency.BTC),
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
_, err := b.CancelAllOrders(context.Background(), orderCancellation)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("CancelAllExchangeOrders() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("CancelAllExchangeOrders() expecting an error when no keys are set")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock CancelAllExchangeOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
items := asset.Items{
|
|
asset.CoinMarginedFutures,
|
|
asset.USDTMarginedFutures,
|
|
asset.Spot,
|
|
asset.Margin,
|
|
}
|
|
for i := range items {
|
|
assetType := items[i]
|
|
t.Run(fmt.Sprintf("Update info of account [%s]", assetType.String()), func(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UpdateAccountInfo(context.Background(), assetType)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWrapperGetActiveOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
p, err := currency.NewPairFromString("EOS-USDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetActiveOrders(context.Background(), &order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
Side: order.AnySide,
|
|
Pairs: currency.Pairs{p},
|
|
AssetType: asset.CoinMarginedFutures,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p2, err := currency.NewPairFromString("BTCUSDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetActiveOrders(context.Background(), &order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
Side: order.AnySide,
|
|
Pairs: currency.Pairs{p2},
|
|
AssetType: asset.USDTMarginedFutures,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWrapperGetOrderHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
p, err := currency.NewPairFromString("EOSUSD_PERP")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetOrderHistory(context.Background(), &order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
Side: order.AnySide,
|
|
FromOrderID: "123",
|
|
Pairs: currency.Pairs{p},
|
|
AssetType: asset.CoinMarginedFutures,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p2, err := currency.NewPairFromString("BTCUSDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetOrderHistory(context.Background(), &order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
Side: order.AnySide,
|
|
FromOrderID: "123",
|
|
Pairs: currency.Pairs{p2},
|
|
AssetType: asset.USDTMarginedFutures,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetOrderHistory(context.Background(), &order.MultiOrderRequest{
|
|
AssetType: asset.USDTMarginedFutures,
|
|
})
|
|
if err == nil {
|
|
t.Errorf("expecting an error since invalid param combination is given. Got err: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
p, err := currency.NewPairFromString("EOS-USDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
fPair, err := b.FormatExchangeCurrency(p, asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = b.CancelOrder(context.Background(), &order.Cancel{
|
|
AssetType: asset.CoinMarginedFutures,
|
|
Pair: fPair,
|
|
OrderID: "1234",
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p2, err := currency.NewPairFromString("BTC-USDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
fpair2, err := b.FormatExchangeCurrency(p2, asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = b.CancelOrder(context.Background(), &order.Cancel{
|
|
AssetType: asset.USDTMarginedFutures,
|
|
Pair: fpair2,
|
|
OrderID: "1234",
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
tradablePairs, err := b.FetchTradablePairs(context.Background(),
|
|
asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if len(tradablePairs) == 0 {
|
|
t.Fatal("no tradable pairs")
|
|
}
|
|
_, err = b.GetOrderInfo(context.Background(),
|
|
"123", tradablePairs[0], asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestModifyOrder(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.ModifyOrder(context.Background(),
|
|
&order.Modify{AssetType: asset.Spot})
|
|
if err == nil {
|
|
t.Error("ModifyOrder() error cannot be nil")
|
|
}
|
|
}
|
|
|
|
func TestGetAllCoinsInfo(t *testing.T) {
|
|
t.Parallel()
|
|
if !mockTests {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
_, err := b.GetAllCoinsInfo(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWithdraw(t *testing.T) {
|
|
t.Parallel()
|
|
if !mockTests {
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
}
|
|
|
|
withdrawCryptoRequest := withdraw.Request{
|
|
Exchange: b.Name,
|
|
Amount: -1,
|
|
Currency: currency.BTC,
|
|
Description: "WITHDRAW IT ALL",
|
|
Crypto: withdraw.CryptoRequest{
|
|
Address: core.BitcoinDonationAddress,
|
|
},
|
|
}
|
|
|
|
_, err := b.WithdrawCryptocurrencyFunds(context.Background(),
|
|
&withdrawCryptoRequest)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("Withdraw() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("Withdraw() expecting an error when no keys are set")
|
|
}
|
|
}
|
|
|
|
func TestDepositHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if !mockTests {
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
}
|
|
_, err := b.DepositHistory(context.Background(), currency.ETH, "", time.Time{}, time.Time{}, 0, 10000)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error(err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("expecting an error when no keys are set")
|
|
}
|
|
}
|
|
|
|
func TestWithdrawHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if !mockTests {
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
}
|
|
_, err := b.GetWithdrawalsHistory(context.Background(), currency.ETH, asset.Spot)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("GetWithdrawalsHistory() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("GetWithdrawalsHistory() expecting an error when no keys are set")
|
|
}
|
|
}
|
|
|
|
func TestWithdrawFiat(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.WithdrawFiatFunds(context.Background(),
|
|
&withdraw.Request{})
|
|
if err != common.ErrFunctionNotSupported {
|
|
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
|
}
|
|
}
|
|
|
|
func TestWithdrawInternationalBank(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.WithdrawFiatFundsToInternationalBank(context.Background(),
|
|
&withdraw.Request{})
|
|
if err != common.ErrFunctionNotSupported {
|
|
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
|
}
|
|
}
|
|
|
|
func TestGetDepositAddress(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetDepositAddress(context.Background(), currency.USDT, "", currency.BNB.String())
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error("GetDepositAddress() error", err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("GetDepositAddress() error cannot be nil")
|
|
case mockTests && err != nil:
|
|
t.Error("Mock GetDepositAddress() error", err)
|
|
}
|
|
}
|
|
|
|
func BenchmarkWsHandleData(bb *testing.B) {
|
|
bb.ReportAllocs()
|
|
ap, err := b.CurrencyPairs.GetPairs(asset.Spot, false)
|
|
require.NoError(bb, err)
|
|
err = b.CurrencyPairs.StorePairs(asset.Spot, ap, true)
|
|
require.NoError(bb, err)
|
|
|
|
data, err := os.ReadFile("testdata/wsHandleData.json")
|
|
require.NoError(bb, err)
|
|
lines := bytes.Split(data, []byte("\n"))
|
|
require.Len(bb, lines, 8)
|
|
go func() {
|
|
for {
|
|
<-b.Websocket.DataHandler
|
|
}
|
|
}()
|
|
bb.ResetTimer()
|
|
for range bb.N {
|
|
for x := range lines {
|
|
assert.NoError(bb, b.wsHandleData(lines[x]))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSubscribe(t *testing.T) {
|
|
t.Parallel()
|
|
b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
require.NoError(t, testexch.Setup(b), "Test instance Setup must not error")
|
|
channels, err := b.generateSubscriptions() // Note: We grab this before it's overwritten by MockWsInstance below
|
|
require.NoError(t, err, "generateSubscriptions must not error")
|
|
if mockTests {
|
|
exp := []string{"btcusdt@depth@100ms", "btcusdt@kline_1m", "btcusdt@ticker", "btcusdt@trade", "dogeusdt@depth@100ms", "dogeusdt@kline_1m", "dogeusdt@ticker", "dogeusdt@trade"}
|
|
mock := func(msg []byte, w *websocket.Conn) error {
|
|
var req WsPayload
|
|
require.NoError(t, json.Unmarshal(msg, &req), "Unmarshal should not error")
|
|
require.ElementsMatch(t, req.Params, exp, "Params should have correct channels")
|
|
return w.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf(`{"result":null,"id":%d}`, req.ID)))
|
|
}
|
|
b = testexch.MockWsInstance[Binance](t, testexch.CurryWsMockUpgrader(t, mock))
|
|
} else {
|
|
testexch.SetupWs(t, b)
|
|
}
|
|
err = b.Subscribe(channels)
|
|
require.NoError(t, err, "Subscribe should not error")
|
|
err = b.Unsubscribe(channels)
|
|
require.NoError(t, err, "Unsubscribe should not error")
|
|
}
|
|
|
|
func TestSubscribeBadResp(t *testing.T) {
|
|
t.Parallel()
|
|
channels := subscription.List{
|
|
{Channel: "moons@ticker"},
|
|
}
|
|
mock := func(msg []byte, w *websocket.Conn) error {
|
|
var req WsPayload
|
|
err := json.Unmarshal(msg, &req)
|
|
require.NoError(t, err, "Unmarshal should not error")
|
|
return w.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf(`{"result":{"error":"carrots"},"id":%d}`, req.ID)))
|
|
}
|
|
b := testexch.MockWsInstance[Binance](t, testexch.CurryWsMockUpgrader(t, mock)) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
err := b.Subscribe(channels)
|
|
assert.ErrorIs(t, err, common.ErrUnknownError, "Subscribe should error correctly")
|
|
assert.ErrorContains(t, err, "carrots", "Subscribe should error containing the carrots")
|
|
}
|
|
|
|
func TestWsTickerUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
pressXToJSON := []byte(`{"stream":"btcusdt@ticker","data":{"e":"24hrTicker","E":1580254809477,"s":"BTCUSDT","p":"420.97000000","P":"4.720","w":"9058.27981278","x":"8917.98000000","c":"9338.96000000","Q":"0.17246300","b":"9338.03000000","B":"0.18234600","a":"9339.70000000","A":"0.14097600","o":"8917.99000000","h":"9373.19000000","l":"8862.40000000","v":"72229.53692000","q":"654275356.16896672","O":1580168409456,"C":1580254809456,"F":235294268,"L":235894703,"n":600436}}`)
|
|
err := b.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsKlineUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
pressXToJSON := []byte(`{"stream":"btcusdt@kline_1m","data":{
|
|
"e": "kline",
|
|
"E": 1234567891,
|
|
"s": "BTCUSDT",
|
|
"k": {
|
|
"t": 1234000001,
|
|
"T": 1234600001,
|
|
"s": "BTCUSDT",
|
|
"i": "1m",
|
|
"f": 100,
|
|
"L": 200,
|
|
"o": "0.0010",
|
|
"c": "0.0020",
|
|
"h": "0.0025",
|
|
"l": "0.0015",
|
|
"v": "1000",
|
|
"n": 100,
|
|
"x": false,
|
|
"q": "1.0000",
|
|
"V": "500",
|
|
"Q": "0.500",
|
|
"B": "123456"
|
|
}
|
|
}}`)
|
|
err := b.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsTradeUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
b.SetSaveTradeDataStatus(true)
|
|
pressXToJSON := []byte(`{"stream":"btcusdt@trade","data":{
|
|
"e": "trade",
|
|
"E": 1234567891,
|
|
"s": "BTCUSDT",
|
|
"t": 12345,
|
|
"p": "0.001",
|
|
"q": "100",
|
|
"b": 88,
|
|
"a": 50,
|
|
"T": 1234567851,
|
|
"m": true,
|
|
"M": true
|
|
}}`)
|
|
err := b.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsDepthUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
require.NoError(t, testexch.Setup(b), "Test instance Setup must not error")
|
|
b.setupOrderbookManager()
|
|
seedLastUpdateID := int64(161)
|
|
book := OrderBook{
|
|
Asks: []OrderbookItem{
|
|
{Price: 6621.80000000, Quantity: 0.00198100},
|
|
{Price: 6622.14000000, Quantity: 4.00000000},
|
|
{Price: 6622.46000000, Quantity: 2.30000000},
|
|
{Price: 6622.47000000, Quantity: 1.18633300},
|
|
{Price: 6622.64000000, Quantity: 4.00000000},
|
|
{Price: 6622.73000000, Quantity: 0.02900000},
|
|
{Price: 6622.76000000, Quantity: 0.12557700},
|
|
{Price: 6622.81000000, Quantity: 2.08994200},
|
|
{Price: 6622.82000000, Quantity: 0.01500000},
|
|
{Price: 6623.17000000, Quantity: 0.16831300},
|
|
},
|
|
Bids: []OrderbookItem{
|
|
{Price: 6621.55000000, Quantity: 0.16356700},
|
|
{Price: 6621.45000000, Quantity: 0.16352600},
|
|
{Price: 6621.41000000, Quantity: 0.86091200},
|
|
{Price: 6621.25000000, Quantity: 0.16914100},
|
|
{Price: 6621.23000000, Quantity: 0.09193600},
|
|
{Price: 6621.22000000, Quantity: 0.00755100},
|
|
{Price: 6621.13000000, Quantity: 0.08432000},
|
|
{Price: 6621.03000000, Quantity: 0.00172000},
|
|
{Price: 6620.94000000, Quantity: 0.30506700},
|
|
{Price: 6620.93000000, Quantity: 0.00200000},
|
|
},
|
|
LastUpdateID: seedLastUpdateID,
|
|
}
|
|
|
|
update1 := []byte(`{"stream":"btcusdt@depth","data":{
|
|
"e": "depthUpdate",
|
|
"E": 1234567881,
|
|
"s": "BTCUSDT",
|
|
"U": 157,
|
|
"u": 160,
|
|
"b": [
|
|
["6621.45", "0.3"]
|
|
],
|
|
"a": [
|
|
["6622.46", "1.5"]
|
|
]
|
|
}}`)
|
|
|
|
p := currency.NewPairWithDelimiter("BTC", "USDT", "-")
|
|
if err := b.SeedLocalCacheWithBook(p, &book); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := b.wsHandleData(update1); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
b.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false
|
|
|
|
ob, err := b.Websocket.Orderbook.GetOrderbook(p, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if exp, got := seedLastUpdateID, ob.LastUpdateID; got != exp {
|
|
t.Fatalf("Unexpected Last update id of orderbook for old update. Exp: %d, got: %d", exp, got)
|
|
}
|
|
if exp, got := 2.3, ob.Asks[2].Amount; got != exp {
|
|
t.Fatalf("Ask altered by outdated update. Exp: %f, got %f", exp, got)
|
|
}
|
|
if exp, got := 0.163526, ob.Bids[1].Amount; got != exp {
|
|
t.Fatalf("Bid altered by outdated update. Exp: %f, got %f", exp, got)
|
|
}
|
|
|
|
update2 := []byte(`{"stream":"btcusdt@depth","data":{
|
|
"e": "depthUpdate",
|
|
"E": 1234567892,
|
|
"s": "BTCUSDT",
|
|
"U": 161,
|
|
"u": 165,
|
|
"b": [
|
|
["6621.45", "0.163526"]
|
|
],
|
|
"a": [
|
|
["6622.46", "2.3"],
|
|
["6622.47", "1.9"]
|
|
]
|
|
}}`)
|
|
|
|
if err = b.wsHandleData(update2); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
ob, err = b.Websocket.Orderbook.GetOrderbook(p, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if exp, got := int64(165), ob.LastUpdateID; got != exp {
|
|
t.Fatalf("Unexpected Last update id of orderbook for new update. Exp: %d, got: %d", exp, got)
|
|
}
|
|
if exp, got := 2.3, ob.Asks[2].Amount; got != exp {
|
|
t.Fatalf("Unexpected Ask amount. Exp: %f, got %f", exp, got)
|
|
}
|
|
if exp, got := 1.9, ob.Asks[3].Amount; got != exp {
|
|
t.Fatalf("Unexpected Ask amount. Exp: %f, got %f", exp, got)
|
|
}
|
|
if exp, got := 0.163526, ob.Bids[1].Amount; got != exp {
|
|
t.Fatalf("Unexpected Bid amount. Exp: %f, got %f", exp, got)
|
|
}
|
|
|
|
// reset order book sync status
|
|
b.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0
|
|
}
|
|
|
|
func TestWsBalanceUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
pressXToJSON := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{
|
|
"e": "balanceUpdate",
|
|
"E": 1573200697110,
|
|
"a": "BTC",
|
|
"d": "100.00000000",
|
|
"T": 1573200697068
|
|
}}`)
|
|
err := b.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsOCO(t *testing.T) {
|
|
t.Parallel()
|
|
pressXToJSON := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{
|
|
"e": "listStatus",
|
|
"E": 1564035303637,
|
|
"s": "ETHBTC",
|
|
"g": 2,
|
|
"c": "OCO",
|
|
"l": "EXEC_STARTED",
|
|
"L": "EXECUTING",
|
|
"r": "NONE",
|
|
"C": "F4QN4G8DlFATFlIUQ0cjdD",
|
|
"T": 1564035303625,
|
|
"O": [
|
|
{
|
|
"s": "ETHBTC",
|
|
"i": 17,
|
|
"c": "AJYsMjErWJesZvqlJCTUgL"
|
|
},
|
|
{
|
|
"s": "ETHBTC",
|
|
"i": 18,
|
|
"c": "bfYPSQdLoqAJeNrOr9adzq"
|
|
}
|
|
]
|
|
}}`)
|
|
err := b.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetWsAuthStreamKey(t *testing.T) {
|
|
key, err := b.GetWsAuthStreamKey(context.Background())
|
|
switch {
|
|
case mockTests && err != nil,
|
|
!mockTests && sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Fatal(err)
|
|
case !mockTests && !sharedtestvalues.AreAPICredentialsSet(b) && err == nil:
|
|
t.Fatal("Expected error")
|
|
}
|
|
|
|
if key == "" && (sharedtestvalues.AreAPICredentialsSet(b) || mockTests) {
|
|
t.Error("Expected key")
|
|
}
|
|
}
|
|
|
|
func TestMaintainWsAuthStreamKey(t *testing.T) {
|
|
err := b.MaintainWsAuthStreamKey(context.Background())
|
|
switch {
|
|
case mockTests && err != nil,
|
|
!mockTests && sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Fatal(err)
|
|
case !mockTests && !sharedtestvalues.AreAPICredentialsSet(b) && err == nil:
|
|
t.Fatal("Expected error")
|
|
}
|
|
}
|
|
|
|
func TestExecutionTypeToOrderStatus(t *testing.T) {
|
|
type TestCases struct {
|
|
Case string
|
|
Result order.Status
|
|
}
|
|
testCases := []TestCases{
|
|
{Case: "NEW", Result: order.New},
|
|
{Case: "PARTIALLY_FILLED", Result: order.PartiallyFilled},
|
|
{Case: "FILLED", Result: order.Filled},
|
|
{Case: "CANCELED", Result: order.Cancelled},
|
|
{Case: "PENDING_CANCEL", Result: order.PendingCancel},
|
|
{Case: "REJECTED", Result: order.Rejected},
|
|
{Case: "EXPIRED", Result: order.Expired},
|
|
{Case: "LOL", Result: order.UnknownStatus},
|
|
}
|
|
for i := range testCases {
|
|
result, _ := stringToOrderStatus(testCases[i].Case)
|
|
if result != testCases[i].Result {
|
|
t.Errorf("Expected: %v, received: %v", testCases[i].Result, result)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandles(t *testing.T) {
|
|
t.Parallel()
|
|
startTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
end := startTime.Add(time.Hour * 24 * 7)
|
|
bAssets := b.GetAssetTypes(false)
|
|
for i := range bAssets {
|
|
cps, err := b.GetAvailablePairs(bAssets[i])
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = b.CurrencyPairs.EnablePair(bAssets[i], cps[0])
|
|
if err != nil && !errors.Is(err, currency.ErrPairAlreadyEnabled) {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = b.GetHistoricCandles(context.Background(), cps[0], bAssets[i], kline.OneDay, startTime, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
pair, err := currency.NewPairFromString("BTC-USDT")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
startTime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
_, err = b.GetHistoricCandles(context.Background(), pair, asset.Spot, kline.Interval(time.Hour*7), startTime, end)
|
|
if !errors.Is(err, kline.ErrRequestExceedsExchangeLimits) {
|
|
t.Fatalf("received: '%v', but expected: '%v'", err, kline.ErrRequestExceedsExchangeLimits)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandlesExtended(t *testing.T) {
|
|
t.Parallel()
|
|
startTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
end := startTime.Add(time.Hour * 24 * 7)
|
|
bAssets := b.GetAssetTypes(false)
|
|
for i := range bAssets {
|
|
cps, err := b.GetAvailablePairs(bAssets[i])
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = b.CurrencyPairs.EnablePair(bAssets[i], cps[0])
|
|
if err != nil && !errors.Is(err, currency.ErrPairAlreadyEnabled) {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = b.GetHistoricCandlesExtended(context.Background(), cps[0], bAssets[i], kline.OneDay, startTime, end)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBinance_FormatExchangeKlineInterval(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
interval kline.Interval
|
|
output string
|
|
}{
|
|
{
|
|
"OneMin",
|
|
kline.OneMin,
|
|
"1m",
|
|
},
|
|
{
|
|
"OneDay",
|
|
kline.OneDay,
|
|
"1d",
|
|
},
|
|
{
|
|
"OneWeek",
|
|
kline.OneWeek,
|
|
"1w",
|
|
},
|
|
{
|
|
"OneMonth",
|
|
kline.OneMonth,
|
|
"1M",
|
|
},
|
|
}
|
|
|
|
for x := range testCases {
|
|
test := testCases[x]
|
|
|
|
t.Run(test.name, func(t *testing.T) {
|
|
ret := b.FormatExchangeKlineInterval(test.interval)
|
|
|
|
if ret != test.output {
|
|
t.Fatalf("unexpected result return expected: %v received: %v", test.output, ret)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetRecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
pair := currency.NewPair(currency.BTC, currency.USDT)
|
|
_, err := b.GetRecentTrades(context.Background(),
|
|
pair, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetRecentTrades(context.Background(),
|
|
pair, asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pair.Base = currency.NewCode("BTCUSD")
|
|
pair.Quote = currency.PERP
|
|
_, err = b.GetRecentTrades(context.Background(),
|
|
pair, asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAvailableTransferChains(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetAvailableTransferChains(context.Background(), currency.BTC)
|
|
switch {
|
|
case sharedtestvalues.AreAPICredentialsSet(b) && err != nil:
|
|
t.Error(err)
|
|
case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests:
|
|
t.Error("error cannot be nil")
|
|
case mockTests && err != nil:
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestSeedLocalCache(t *testing.T) {
|
|
t.Parallel()
|
|
err := b.SeedLocalCache(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestGenerateSubscriptions(t *testing.T) {
|
|
t.Parallel()
|
|
exp := subscription.List{}
|
|
pairs, err := b.GetEnabledPairs(asset.Spot)
|
|
assert.NoError(t, err, "GetEnabledPairs should not error")
|
|
wsFmt := currency.PairFormat{Uppercase: false, Delimiter: ""}
|
|
baseExp := subscription.List{
|
|
{Channel: subscription.CandlesChannel, QualifiedChannel: "kline_1m", Asset: asset.Spot, Interval: kline.OneMin},
|
|
{Channel: subscription.OrderbookChannel, QualifiedChannel: "depth@100ms", Asset: asset.Spot, Interval: kline.HundredMilliseconds},
|
|
{Channel: subscription.TickerChannel, QualifiedChannel: "ticker", Asset: asset.Spot},
|
|
{Channel: subscription.AllTradesChannel, QualifiedChannel: "trade", Asset: asset.Spot},
|
|
}
|
|
for _, p := range pairs {
|
|
for _, baseSub := range baseExp {
|
|
sub := baseSub.Clone()
|
|
sub.Pairs = currency.Pairs{p}
|
|
sub.QualifiedChannel = wsFmt.Format(p) + "@" + sub.QualifiedChannel
|
|
exp = append(exp, sub)
|
|
}
|
|
}
|
|
subs, err := b.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions should not error")
|
|
testsubs.EqualLists(t, exp, subs)
|
|
}
|
|
|
|
// TestFormatChannelInterval exercises formatChannelInterval
|
|
func TestFormatChannelInterval(t *testing.T) {
|
|
t.Parallel()
|
|
assert.Equal(t, "@1000ms", formatChannelInterval(&subscription.Subscription{Channel: subscription.OrderbookChannel, Interval: kline.ThousandMilliseconds}), "1s should format correctly for Orderbook")
|
|
assert.Equal(t, "@1m", formatChannelInterval(&subscription.Subscription{Channel: subscription.OrderbookChannel, Interval: kline.OneMin}), "Orderbook should format correctly")
|
|
assert.Equal(t, "_15m", formatChannelInterval(&subscription.Subscription{Channel: subscription.CandlesChannel, Interval: kline.FifteenMin}), "Candles should format correctly")
|
|
}
|
|
|
|
// TestFormatChannelLevels exercises formatChannelLevels
|
|
func TestFormatChannelLevels(t *testing.T) {
|
|
t.Parallel()
|
|
assert.Equal(t, "10", formatChannelLevels(&subscription.Subscription{Channel: subscription.OrderbookChannel, Levels: 10}), "Levels should format correctly")
|
|
assert.Empty(t, formatChannelLevels(&subscription.Subscription{Channel: subscription.OrderbookChannel, Levels: 0}), "Levels should format correctly")
|
|
}
|
|
|
|
var websocketDepthUpdate = []byte(`{"E":1608001030784,"U":7145637266,"a":[["19455.19000000","0.59490200"],["19455.37000000","0.00000000"],["19456.11000000","0.00000000"],["19456.16000000","0.00000000"],["19458.67000000","0.06400000"],["19460.73000000","0.05139800"],["19461.43000000","0.00000000"],["19464.59000000","0.00000000"],["19466.03000000","0.45000000"],["19466.36000000","0.00000000"],["19508.67000000","0.00000000"],["19572.96000000","0.00217200"],["24386.00000000","0.00256600"]],"b":[["19455.18000000","2.94649200"],["19453.15000000","0.01233600"],["19451.18000000","0.00000000"],["19446.85000000","0.11427900"],["19446.74000000","0.00000000"],["19446.73000000","0.00000000"],["19444.45000000","0.14937800"],["19426.75000000","0.00000000"],["19416.36000000","0.36052100"]],"e":"depthUpdate","s":"BTCUSDT","u":7145637297}`)
|
|
|
|
func TestProcessUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
require.NoError(t, testexch.Setup(b), "Test instance Setup must not error")
|
|
b.setupOrderbookManager()
|
|
p := currency.NewPair(currency.BTC, currency.USDT)
|
|
var depth WebsocketDepthStream
|
|
err := json.Unmarshal(websocketDepthUpdate, &depth)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = b.obm.stageWsUpdate(&depth, p, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = b.obm.fetchBookViaREST(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = b.obm.cleanup(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// reset order book sync status
|
|
b.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0
|
|
}
|
|
|
|
func TestUFuturesHistoricalTrades(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
cp, err := currency.NewPairFromString("BTCUSDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UFuturesHistoricalTrades(context.Background(), cp, "", 5)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.UFuturesHistoricalTrades(context.Background(), cp, "", 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestSetExchangeOrderExecutionLimits(t *testing.T) {
|
|
t.Parallel()
|
|
err := b.UpdateOrderExecutionLimits(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = b.UpdateOrderExecutionLimits(context.Background(), asset.CoinMarginedFutures)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = b.UpdateOrderExecutionLimits(context.Background(), asset.USDTMarginedFutures)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = b.UpdateOrderExecutionLimits(context.Background(), asset.Binary)
|
|
if err == nil {
|
|
t.Fatal("expected unhandled case")
|
|
}
|
|
|
|
cmfCP, err := currency.NewPairFromStrings("BTCUSD", "PERP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
limit, err := b.GetOrderExecutionLimits(asset.CoinMarginedFutures, cmfCP)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if limit == (order.MinMaxLevel{}) {
|
|
t.Fatal("exchange limit should be loaded")
|
|
}
|
|
|
|
err = limit.Conforms(0.000001, 0.1, order.Limit)
|
|
if !errors.Is(err, order.ErrAmountBelowMin) {
|
|
t.Fatalf("expected %v, but received %v", order.ErrAmountBelowMin, err)
|
|
}
|
|
|
|
err = limit.Conforms(0.01, 1, order.Limit)
|
|
if !errors.Is(err, order.ErrPriceBelowMin) {
|
|
t.Fatalf("expected %v, but received %v", order.ErrPriceBelowMin, err)
|
|
}
|
|
}
|
|
|
|
func TestWsOrderExecutionReport(t *testing.T) {
|
|
t.Parallel()
|
|
b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
require.NoError(t, testexch.Setup(b), "Test instance Setup must not error")
|
|
payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616627567900,"s":"BTCUSDT","c":"c4wyKsIhoAaittTYlIVLqk","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028400","p":"52789.10000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"NEW","X":"NEW","r":"NONE","i":5340845958,"l":"0.00000000","z":"0.00000000","L":"0.00000000","n":"0","N":"BTC","T":1616627567900,"t":-1,"I":11388173160,"w":true,"m":false,"M":false,"O":1616627567900,"Z":"0.00000000","Y":"0.00000000","Q":"0.00000000","W":1616627567900}}`)
|
|
// this is a buy BTC order, normally commission is charged in BTC, vice versa.
|
|
expectedResult := order.Detail{
|
|
Price: 52789.1,
|
|
Amount: 0.00028400,
|
|
AverageExecutedPrice: 0,
|
|
QuoteAmount: 0,
|
|
ExecutedAmount: 0,
|
|
RemainingAmount: 0.00028400,
|
|
Cost: 0,
|
|
CostAsset: currency.USDT,
|
|
Fee: 0,
|
|
FeeAsset: currency.BTC,
|
|
Exchange: "Binance",
|
|
OrderID: "5340845958",
|
|
ClientOrderID: "c4wyKsIhoAaittTYlIVLqk",
|
|
Type: order.Limit,
|
|
Side: order.Buy,
|
|
Status: order.New,
|
|
AssetType: asset.Spot,
|
|
Date: time.UnixMilli(1616627567900),
|
|
LastUpdated: time.UnixMilli(1616627567900),
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
}
|
|
// empty the channel. otherwise mock_test will fail
|
|
for len(b.Websocket.DataHandler) > 0 {
|
|
<-b.Websocket.DataHandler
|
|
}
|
|
|
|
err := b.wsHandleData(payload)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
res := <-b.Websocket.DataHandler
|
|
switch r := res.(type) {
|
|
case *order.Detail:
|
|
if !reflect.DeepEqual(expectedResult, *r) {
|
|
t.Errorf("Results do not match:\nexpected: %v\nreceived: %v", expectedResult, *r)
|
|
}
|
|
default:
|
|
t.Fatalf("expected type order.Detail, found %T", res)
|
|
}
|
|
|
|
payload = []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616633041556,"s":"BTCUSDT","c":"YeULctvPAnHj5HXCQo9Mob","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028600","p":"52436.85000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"TRADE","X":"FILLED","r":"NONE","i":5341783271,"l":"0.00028600","z":"0.00028600","L":"52436.85000000","n":"0.00000029","N":"BTC","T":1616633041555,"t":726946523,"I":11390206312,"w":false,"m":false,"M":true,"O":1616633041555,"Z":"14.99693910","Y":"14.99693910","Q":"0.00000000","W":1616633041555}}`)
|
|
err = b.wsHandleData(payload)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestWsOutboundAccountPosition(t *testing.T) {
|
|
t.Parallel()
|
|
payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"outboundAccountPosition","E":1616628815745,"u":1616628815745,"B":[{"a":"BTC","f":"0.00225109","l":"0.00123000"},{"a":"BNB","f":"0.00000000","l":"0.00000000"},{"a":"USDT","f":"54.43390661","l":"0.00000000"}]}}`)
|
|
if err := b.wsHandleData(payload); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestFormatExchangeCurrency(t *testing.T) {
|
|
t.Parallel()
|
|
type testos struct {
|
|
name string
|
|
pair currency.Pair
|
|
asset asset.Item
|
|
expectedDelimiter string
|
|
}
|
|
testerinos := []testos{
|
|
{
|
|
name: "spot-btcusdt",
|
|
pair: currency.NewPairWithDelimiter("BTC", "USDT", currency.UnderscoreDelimiter),
|
|
asset: asset.Spot,
|
|
expectedDelimiter: "",
|
|
},
|
|
{
|
|
name: "coinmarginedfutures-btcusd_perp",
|
|
pair: currency.NewPairWithDelimiter("BTCUSD", "PERP", currency.DashDelimiter),
|
|
asset: asset.CoinMarginedFutures,
|
|
expectedDelimiter: currency.UnderscoreDelimiter,
|
|
},
|
|
{
|
|
name: "coinmarginedfutures-btcusd_211231",
|
|
pair: currency.NewPairWithDelimiter("BTCUSD", "211231", currency.DashDelimiter),
|
|
asset: asset.CoinMarginedFutures,
|
|
expectedDelimiter: currency.UnderscoreDelimiter,
|
|
},
|
|
{
|
|
name: "margin-ltousdt",
|
|
pair: currency.NewPairWithDelimiter("LTO", "USDT", currency.UnderscoreDelimiter),
|
|
asset: asset.Margin,
|
|
expectedDelimiter: "",
|
|
},
|
|
{
|
|
name: "usdtmarginedfutures-btcusdt",
|
|
pair: currency.NewPairWithDelimiter("btc", "usdt", currency.DashDelimiter),
|
|
asset: asset.USDTMarginedFutures,
|
|
expectedDelimiter: "",
|
|
},
|
|
{
|
|
name: "usdtmarginedfutures-btcusdt_211231",
|
|
pair: currency.NewPairWithDelimiter("btcusdt", "211231", currency.UnderscoreDelimiter),
|
|
asset: asset.USDTMarginedFutures,
|
|
expectedDelimiter: currency.UnderscoreDelimiter,
|
|
},
|
|
}
|
|
for i := range testerinos {
|
|
tt := testerinos[i]
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
result, err := b.FormatExchangeCurrency(tt.pair, tt.asset)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if result.Delimiter != tt.expectedDelimiter {
|
|
t.Errorf("received '%v' expected '%v'", result.Delimiter, tt.expectedDelimiter)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFormatSymbol(t *testing.T) {
|
|
t.Parallel()
|
|
type testos struct {
|
|
name string
|
|
pair currency.Pair
|
|
asset asset.Item
|
|
expectedString string
|
|
}
|
|
testerinos := []testos{
|
|
{
|
|
name: "spot-BTCUSDT",
|
|
pair: currency.NewPairWithDelimiter("BTC", "USDT", currency.UnderscoreDelimiter),
|
|
asset: asset.Spot,
|
|
expectedString: "BTCUSDT",
|
|
},
|
|
{
|
|
name: "coinmarginedfutures-btcusdperp",
|
|
pair: currency.NewPairWithDelimiter("BTCUSD", "PERP", currency.DashDelimiter),
|
|
asset: asset.CoinMarginedFutures,
|
|
expectedString: "BTCUSD_PERP",
|
|
},
|
|
{
|
|
name: "coinmarginedfutures-BTCUSD_211231",
|
|
pair: currency.NewPairWithDelimiter("BTCUSD", "211231", currency.DashDelimiter),
|
|
asset: asset.CoinMarginedFutures,
|
|
expectedString: "BTCUSD_211231",
|
|
},
|
|
{
|
|
name: "margin-LTOUSDT",
|
|
pair: currency.NewPairWithDelimiter("LTO", "USDT", currency.UnderscoreDelimiter),
|
|
asset: asset.Margin,
|
|
expectedString: "LTOUSDT",
|
|
},
|
|
{
|
|
name: "usdtmarginedfutures-BTCUSDT",
|
|
pair: currency.NewPairWithDelimiter("btc", "usdt", currency.DashDelimiter),
|
|
asset: asset.USDTMarginedFutures,
|
|
expectedString: "BTCUSDT",
|
|
},
|
|
{
|
|
name: "usdtmarginedfutures-BTCUSDT_211231",
|
|
pair: currency.NewPairWithDelimiter("btcusdt", "211231", currency.UnderscoreDelimiter),
|
|
asset: asset.USDTMarginedFutures,
|
|
expectedString: "BTCUSDT_211231",
|
|
},
|
|
}
|
|
for _, tt := range testerinos {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
result, err := b.FormatSymbol(tt.pair, tt.asset)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if result != tt.expectedString {
|
|
t.Errorf("received '%v' expected '%v'", result, tt.expectedString)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFormatUSDTMarginedFuturesPair(t *testing.T) {
|
|
t.Parallel()
|
|
pairFormat := currency.PairFormat{Uppercase: true}
|
|
resp := b.formatUSDTMarginedFuturesPair(currency.NewPair(currency.DOGE, currency.USDT), pairFormat)
|
|
if resp.String() != "DOGEUSDT" {
|
|
t.Errorf("received '%v' expected '%v'", resp.String(), "DOGEUSDT")
|
|
}
|
|
|
|
resp = b.formatUSDTMarginedFuturesPair(currency.NewPair(currency.DOGE, currency.NewCode("1234567890")), pairFormat)
|
|
if resp.String() != "DOGE_1234567890" {
|
|
t.Errorf("received '%v' expected '%v'", resp.String(), "DOGE_1234567890")
|
|
}
|
|
}
|
|
|
|
func TestFetchExchangeLimits(t *testing.T) {
|
|
t.Parallel()
|
|
limits, err := b.FetchExchangeLimits(context.Background(), asset.Spot)
|
|
assert.NoError(t, err, "FetchExchangeLimits should not error")
|
|
assert.NotEmpty(t, limits, "Should get some limits back")
|
|
|
|
limits, err = b.FetchExchangeLimits(context.Background(), asset.Margin)
|
|
assert.NoError(t, err, "FetchExchangeLimits should not error")
|
|
assert.NotEmpty(t, limits, "Should get some limits back")
|
|
|
|
_, err = b.FetchExchangeLimits(context.Background(), asset.Futures)
|
|
assert.ErrorIs(t, err, asset.ErrNotSupported, "FetchExchangeLimits should error on other asset types")
|
|
}
|
|
|
|
func TestUpdateOrderExecutionLimits(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := map[asset.Item]currency.Pair{
|
|
asset.Spot: currency.NewPair(currency.BTC, currency.USDT),
|
|
asset.Margin: currency.NewPair(currency.ETH, currency.BTC),
|
|
}
|
|
for _, a := range []asset.Item{asset.CoinMarginedFutures, asset.USDTMarginedFutures} {
|
|
pairs, err := b.FetchTradablePairs(context.Background(), a)
|
|
require.NoErrorf(t, err, "FetchTradablePairs should not error for %s", a)
|
|
require.NotEmptyf(t, pairs, "Should get some pairs for %s", a)
|
|
tests[a] = pairs[0]
|
|
}
|
|
|
|
for _, a := range b.GetAssetTypes(false) {
|
|
err := b.UpdateOrderExecutionLimits(context.Background(), a)
|
|
require.NoError(t, err, "UpdateOrderExecutionLimits should not error")
|
|
|
|
p := tests[a]
|
|
limits, err := b.GetOrderExecutionLimits(a, p)
|
|
require.NoErrorf(t, err, "GetOrderExecutionLimits should not error for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MinPrice, "MinPrice must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MaxPrice, "MaxPrice must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.PriceStepIncrementSize, "PriceStepIncrementSize must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MinimumBaseAmount, "MinimumBaseAmount must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MaximumBaseAmount, "MaximumBaseAmount must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.AmountStepIncrementSize, "AmountStepIncrementSize must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MarketMaxQty, "MarketMaxQty must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MaxTotalOrders, "MaxTotalOrders must be positive for %s pair %s", a, p)
|
|
switch a {
|
|
case asset.Spot, asset.Margin:
|
|
assert.Positivef(t, limits.MaxIcebergParts, "MaxIcebergParts must be positive for %s pair %s", a, p)
|
|
case asset.USDTMarginedFutures:
|
|
assert.Positivef(t, limits.MinNotional, "MinNotional must be positive for %s pair %s", a, p)
|
|
fallthrough
|
|
case asset.CoinMarginedFutures:
|
|
assert.Positivef(t, limits.MultiplierUp, "MultiplierUp must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MultiplierDown, "MultiplierDown must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MarketMinQty, "MarketMinQty must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MarketStepIncrementSize, "MarketStepIncrementSize must be positive for %s pair %s", a, p)
|
|
assert.Positivef(t, limits.MaxAlgoOrders, "MaxAlgoOrders must be positive for %s pair %s", a, p)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetFundingRates(t *testing.T) {
|
|
t.Parallel()
|
|
s, e := getTime()
|
|
_, err := b.GetHistoricalFundingRates(context.Background(), &fundingrate.HistoricalRatesRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartDate: s,
|
|
EndDate: e,
|
|
IncludePayments: true,
|
|
IncludePredictedRate: true,
|
|
})
|
|
if !errors.Is(err, common.ErrFunctionNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetHistoricalFundingRates(context.Background(), &fundingrate.HistoricalRatesRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartDate: s,
|
|
EndDate: e,
|
|
PaymentCurrency: currency.DOGE,
|
|
})
|
|
if !errors.Is(err, common.ErrFunctionNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
|
|
r := &fundingrate.HistoricalRatesRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartDate: s,
|
|
EndDate: e,
|
|
}
|
|
if sharedtestvalues.AreAPICredentialsSet(b) {
|
|
r.IncludePayments = true
|
|
}
|
|
_, err = b.GetHistoricalFundingRates(context.Background(), r)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
r.Asset = asset.CoinMarginedFutures
|
|
r.Pair, err = currency.NewPairFromString("BTCUSD_PERP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = b.GetHistoricalFundingRates(context.Background(), r)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetLatestFundingRates(t *testing.T) {
|
|
t.Parallel()
|
|
cp := currency.NewPair(currency.BTC, currency.USDT)
|
|
_, err := b.GetLatestFundingRates(context.Background(), &fundingrate.LatestRateRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pair: cp,
|
|
IncludePredictedRate: true,
|
|
})
|
|
if !errors.Is(err, common.ErrFunctionNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
err = b.CurrencyPairs.EnablePair(asset.USDTMarginedFutures, cp)
|
|
if err != nil && !errors.Is(err, currency.ErrPairAlreadyEnabled) {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = b.GetLatestFundingRates(context.Background(), &fundingrate.LatestRateRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pair: cp,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetLatestFundingRates(context.Background(), &fundingrate.LatestRateRequest{
|
|
Asset: asset.CoinMarginedFutures,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestIsPerpetualFutureCurrency(t *testing.T) {
|
|
t.Parallel()
|
|
is, err := b.IsPerpetualFutureCurrency(asset.Binary, currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if is {
|
|
t.Error("expected false")
|
|
}
|
|
|
|
is, err = b.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if is {
|
|
t.Error("expected false")
|
|
}
|
|
is, err = b.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewPair(currency.BTC, currency.PERP))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if !is {
|
|
t.Error("expected true")
|
|
}
|
|
|
|
is, err = b.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if !is {
|
|
t.Error("expected true")
|
|
}
|
|
is, err = b.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, currency.NewPair(currency.BTC, currency.PERP))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if is {
|
|
t.Error("expected false")
|
|
}
|
|
}
|
|
|
|
func TestGetUserMarginInterestHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetUserMarginInterestHistory(context.Background(), currency.USDT, currency.NewPair(currency.BTC, currency.USDT), time.Now().Add(-time.Hour*24), time.Now(), 1, 10, false)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestSetAssetsMode(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
is, err := b.GetAssetsMode(context.Background())
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("received '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
err = b.SetAssetsMode(context.Background(), !is)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("received '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
err = b.SetAssetsMode(context.Background(), is)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("received '%v', expected '%v'", err, nil)
|
|
}
|
|
}
|
|
|
|
func TestGetAssetsMode(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetAssetsMode(context.Background())
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("received '%v', expected '%v'", err, nil)
|
|
}
|
|
}
|
|
|
|
func TestGetCollateralMode(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.GetCollateralMode(context.Background(), asset.Spot)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Errorf("received '%v', expected '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
_, err = b.GetCollateralMode(context.Background(), asset.CoinMarginedFutures)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Errorf("received '%v', expected '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
_, err = b.GetCollateralMode(context.Background(), asset.USDTMarginedFutures)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("received '%v', expected '%v'", err, nil)
|
|
}
|
|
}
|
|
|
|
func TestSetCollateralMode(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
err := b.SetCollateralMode(context.Background(), asset.Spot, collateral.SingleMode)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Errorf("received '%v', expected '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
err = b.SetCollateralMode(context.Background(), asset.CoinMarginedFutures, collateral.SingleMode)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Errorf("received '%v', expected '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
err = b.SetCollateralMode(context.Background(), asset.USDTMarginedFutures, collateral.MultiMode)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("received '%v', expected '%v'", err, nil)
|
|
}
|
|
err = b.SetCollateralMode(context.Background(), asset.USDTMarginedFutures, collateral.PortfolioMode)
|
|
if !errors.Is(err, order.ErrCollateralInvalid) {
|
|
t.Errorf("received '%v', expected '%v'", err, order.ErrCollateralInvalid)
|
|
}
|
|
}
|
|
|
|
func TestChangePositionMargin(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.ChangePositionMargin(context.Background(), &margin.PositionChangeRequest{
|
|
Pair: currency.NewBTCUSDT(),
|
|
Asset: asset.USDTMarginedFutures,
|
|
MarginType: margin.Isolated,
|
|
OriginalAllocatedMargin: 1337,
|
|
NewAllocatedMargin: 1333337,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetPositionSummary(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
|
|
bb := currency.NewBTCUSDT()
|
|
_, err := b.GetFuturesPositionSummary(context.Background(), &futures.PositionSummaryRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pair: bb,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
bb.Quote = currency.BUSD
|
|
_, err = b.GetFuturesPositionSummary(context.Background(), &futures.PositionSummaryRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pair: bb,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p, err := currency.NewPairFromString("BTCUSD_PERP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
bb.Quote = currency.USD
|
|
_, err = b.GetFuturesPositionSummary(context.Background(), &futures.PositionSummaryRequest{
|
|
Asset: asset.CoinMarginedFutures,
|
|
Pair: p,
|
|
UnderlyingPair: bb,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetFuturesPositionSummary(context.Background(), &futures.PositionSummaryRequest{
|
|
Asset: asset.Spot,
|
|
Pair: p,
|
|
UnderlyingPair: bb,
|
|
})
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesPositionOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetFuturesPositionOrders(context.Background(), &futures.PositionsRequest{
|
|
Asset: asset.USDTMarginedFutures,
|
|
Pairs: []currency.Pair{currency.NewBTCUSDT()},
|
|
StartDate: time.Now().Add(-time.Hour * 24 * 70),
|
|
RespectOrderHistoryLimits: true,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p, err := currency.NewPairFromString("ADAUSD_PERP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = b.GetFuturesPositionOrders(context.Background(), &futures.PositionsRequest{
|
|
Asset: asset.CoinMarginedFutures,
|
|
Pairs: []currency.Pair{p},
|
|
StartDate: time.Now().Add(time.Hour * 24 * -70),
|
|
RespectOrderHistoryLimits: true,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestSetMarginType(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
|
|
err := b.SetMarginType(context.Background(), asset.USDTMarginedFutures, currency.NewPair(currency.BTC, currency.USDT), margin.Isolated)
|
|
if !errors.Is(err, nil) {
|
|
t.Error(err)
|
|
}
|
|
|
|
p, err := currency.NewPairFromString("BTCUSD_PERP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = b.SetMarginType(context.Background(), asset.CoinMarginedFutures, p, margin.Isolated)
|
|
if !errors.Is(err, nil) {
|
|
t.Error(err)
|
|
}
|
|
|
|
err = b.SetMarginType(context.Background(), asset.Spot, currency.NewPair(currency.BTC, currency.USDT), margin.Isolated)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetLeverage(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetLeverage(context.Background(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), 0, order.UnknownSide)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p, err := currency.NewPairFromString("BTCUSD_PERP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = b.GetLeverage(context.Background(), asset.CoinMarginedFutures, p, 0, order.UnknownSide)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetLeverage(context.Background(), asset.Spot, currency.NewBTCUSDT(), 0, order.UnknownSide)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestSetLeverage(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
err := b.SetLeverage(context.Background(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), margin.Multi, 5, order.UnknownSide)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
p, err := currency.NewPairFromString("BTCUSD_PERP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = b.SetLeverage(context.Background(), asset.CoinMarginedFutures, p, margin.Multi, 5, order.UnknownSide)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = b.SetLeverage(context.Background(), asset.Spot, p, margin.Multi, 5, order.UnknownSide)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
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)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesContractDetails(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFuturesContractDetails(context.Background(), asset.Spot)
|
|
if !errors.Is(err, futures.ErrNotFuturesAsset) {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetFuturesContractDetails(context.Background(), asset.Futures)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetFuturesContractDetails(context.Background(), asset.USDTMarginedFutures)
|
|
if !errors.Is(err, nil) {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetFuturesContractDetails(context.Background(), asset.CoinMarginedFutures)
|
|
if !errors.Is(err, nil) {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFundingRateInfo(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFundingRateInfo(context.Background())
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestUGetFundingRateInfo(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.UGetFundingRateInfo(context.Background())
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestGetOpenInterest(t *testing.T) {
|
|
t.Parallel()
|
|
resp, err := b.GetOpenInterest(context.Background(), key.PairAsset{
|
|
Base: currency.BTC.Item,
|
|
Quote: currency.USDT.Item,
|
|
Asset: asset.USDTMarginedFutures,
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
|
|
resp, err = b.GetOpenInterest(context.Background(), key.PairAsset{
|
|
Base: currency.NewCode("BTCUSD").Item,
|
|
Quote: currency.PERP.Item,
|
|
Asset: asset.CoinMarginedFutures,
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
|
|
_, err = b.GetOpenInterest(context.Background(), key.PairAsset{
|
|
Base: currency.BTC.Item,
|
|
Quote: currency.USDT.Item,
|
|
Asset: asset.Spot,
|
|
})
|
|
assert.ErrorIs(t, err, asset.ErrNotSupported)
|
|
}
|
|
|
|
func TestGetCurrencyTradeURL(t *testing.T) {
|
|
t.Parallel()
|
|
testexch.UpdatePairsOnce(t, b)
|
|
for _, a := range b.GetAssetTypes(false) {
|
|
pairs, err := b.CurrencyPairs.GetPairs(a, false)
|
|
require.NoError(t, err, "cannot get pairs for %s", a)
|
|
require.NotEmpty(t, pairs, "no pairs for %s", a)
|
|
resp, err := b.GetCurrencyTradeURL(context.Background(), a, pairs[0])
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
}
|
|
}
|