Files
gocryptotrader/exchanges/kraken/kraken_test.go
Gareth Kirwan d5189930ca Kraken: Fix TestUpdateOrderExecutionLimits (#1489)
Failed again due to kraken re-setting limits due to price increases.
Switch from specific PriceStepIncrementSize and MinimumBaseAmount to just ensuring they are positive so we don't have to do this again
2024-03-07 13:10:44 +11:00

2285 lines
62 KiB
Go

package kraken
import (
"context"
"errors"
"fmt"
"log"
"net/http"
"os"
"strings"
"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/convert"
"github.com/thrasher-corp/gocryptotrader/common/key"
"github.com/thrasher-corp/gocryptotrader/config"
"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/fundingrate"
"github.com/thrasher-corp/gocryptotrader/exchanges/futures"
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
)
var k = &Kraken{}
var wsSetupRan bool
// Please add your own APIkeys to do correct due diligence testing.
const (
apiKey = ""
apiSecret = ""
canManipulateRealOrders = false
)
// TestSetup setup func
func TestMain(m *testing.M) {
k.SetDefaults()
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
log.Fatal(err)
}
krakenConfig, err := cfg.GetExchangeConfig("Kraken")
if err != nil {
log.Fatal(err)
}
krakenConfig.API.AuthenticatedSupport = true
krakenConfig.API.Credentials.Key = apiKey
krakenConfig.API.Credentials.Secret = apiSecret
k.Websocket = sharedtestvalues.NewTestWebsocket()
err = k.Setup(krakenConfig)
if err != nil {
log.Fatal(err)
}
err = k.UpdateTradablePairs(context.Background(), true)
if err != nil {
log.Fatal(err)
}
os.Exit(m.Run())
}
func TestGetCurrentServerTime(t *testing.T) {
t.Parallel()
_, err := k.GetCurrentServerTime(context.Background())
if err != nil {
t.Error("GetCurrentServerTime() error", err)
}
}
func TestWrapperGetServerTime(t *testing.T) {
t.Parallel()
st, err := k.GetServerTime(context.Background(), asset.Spot)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
if st.IsZero() {
t.Error("expected a time")
}
}
// TestUpdateOrderExecutionLimits exercises UpdateOrderExecutionLimits and GetOrderExecutionLimits
func TestUpdateOrderExecutionLimits(t *testing.T) {
t.Parallel()
err := k.UpdateOrderExecutionLimits(context.Background(), asset.Spot)
require.NoError(t, err, "UpdateOrderExecutionLimits must not error")
for _, p := range []currency.Pair{
currency.NewPair(currency.ETH, currency.USDT),
currency.NewPair(currency.XBT, currency.USDT),
} {
limits, err := k.GetOrderExecutionLimits(asset.Spot, p)
require.NoErrorf(t, err, "%s GetOrderExecutionLimits must not error", p)
assert.Positivef(t, limits.PriceStepIncrementSize, "%s PriceStepIncrementSize should be positive", p)
assert.Positivef(t, limits.MinimumBaseAmount, "%s MinimumBaseAmount should be positive", p)
}
}
func TestFetchTradablePairs(t *testing.T) {
t.Parallel()
_, err := k.FetchTradablePairs(context.Background(), asset.Futures)
if err != nil {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
sp, err := currency.NewPairFromString("XBTUSD")
if err != nil {
t.Error(err)
}
_, err = k.UpdateTicker(context.Background(), sp, asset.Spot)
if err != nil {
t.Error(err)
}
fp, err := currency.NewPairFromString("pi_xbtusd")
if err != nil {
t.Error(err)
}
_, err = k.UpdateTicker(context.Background(), fp, asset.Futures)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
ap, err := k.GetAvailablePairs(asset.Spot)
require.NoError(t, err)
err = k.CurrencyPairs.StorePairs(asset.Spot, ap, true)
require.NoError(t, err)
err = k.UpdateTickers(context.Background(), asset.Spot)
assert.NoError(t, err)
for i := range ap {
_, err = ticker.GetTicker(k.Name, ap[i], asset.Spot)
assert.NoError(t, err)
}
ap, err = k.GetAvailablePairs(asset.Futures)
require.NoError(t, err)
err = k.CurrencyPairs.StorePairs(asset.Futures, ap, true)
require.NoError(t, err)
err = k.UpdateTickers(context.Background(), asset.Futures)
assert.NoError(t, err)
for i := range ap {
_, err = ticker.GetTicker(k.Name, ap[i], asset.Futures)
assert.NoError(t, err)
}
err = k.UpdateTickers(context.Background(), asset.Index)
assert.ErrorIs(t, err, asset.ErrNotSupported)
}
func TestUpdateOrderbook(t *testing.T) {
t.Parallel()
sp, err := currency.NewPairFromString("BTCEUR")
if err != nil {
t.Error(err)
}
_, err = k.UpdateOrderbook(context.Background(), sp, asset.Spot)
if err != nil {
t.Error(err)
}
fp, err := currency.NewPairFromString("pi_xbtusd")
if err != nil {
t.Error(err)
}
_, err = k.UpdateOrderbook(context.Background(), fp, asset.Futures)
if err != nil {
t.Error(err)
}
}
func TestUpdateAccountInfo(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.UpdateAccountInfo(context.Background(), asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestWrapperGetOrderInfo(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.GetOrderInfo(context.Background(),
"123", currency.EMPTYPAIR, asset.Futures)
if err != nil {
t.Error(err)
}
}
func TestFuturesBatchOrder(t *testing.T) {
t.Parallel()
var data []PlaceBatchOrderData
var tempData PlaceBatchOrderData
tempData.PlaceOrderType = "meow"
tempData.OrderID = "test123"
tempData.Symbol = "pi_xbtusd"
data = append(data, tempData)
_, err := k.FuturesBatchOrder(context.Background(), data)
if !errors.Is(err, errInvalidBatchOrderType) {
t.Fatalf("received: '%v' but expected: '%v'", err, errInvalidBatchOrderType)
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
data[0].PlaceOrderType = "cancel"
_, err = k.FuturesBatchOrder(context.Background(), data)
if err != nil {
t.Error(err)
}
}
func TestFuturesEditOrder(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
_, err := k.FuturesEditOrder(context.Background(), "test123", "", 5.2, 1, 0)
if err != nil {
t.Error(err)
}
}
func TestFuturesSendOrder(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
cp, err := currency.NewPairFromString("PI_XBTUSD")
if err != nil {
t.Error(err)
}
_, err = k.FuturesSendOrder(context.Background(),
order.Limit, cp, "buy", "", "", "", true, 1, 1, 0.9)
if err != nil {
t.Error(err)
}
}
func TestFuturesCancelOrder(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
_, err := k.FuturesCancelOrder(context.Background(), "test123", "")
if err != nil {
t.Error(err)
}
}
func TestFuturesGetFills(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.FuturesGetFills(context.Background(), time.Now().Add(-time.Hour*24))
if err != nil {
t.Error(err)
}
}
func TestFuturesTransfer(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.FuturesTransfer(context.Background(), "cash", "futures", "btc", 2)
if err != nil {
t.Error(err)
}
}
func TestFuturesGetOpenPositions(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.FuturesGetOpenPositions(context.Background())
if err != nil {
t.Error(err)
}
}
func TestFuturesNotifications(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.FuturesNotifications(context.Background())
if err != nil {
t.Error(err)
}
}
func TestFuturesCancelAllOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
cp, err := currency.NewPairFromString("PI_XBTUSD")
if err != nil {
t.Error(err)
}
_, err = k.FuturesCancelAllOrders(context.Background(), cp)
if err != nil {
t.Error(err)
}
}
func TestGetFuturesAccountData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.GetFuturesAccountData(context.Background())
if err != nil {
t.Error(err)
}
}
func TestFuturesCancelAllOrdersAfter(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
_, err := k.FuturesCancelAllOrdersAfter(context.Background(), 50)
if err != nil {
t.Error(err)
}
}
func TestFuturesOpenOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.FuturesOpenOrders(context.Background())
if err != nil {
t.Error(err)
}
}
func TestFuturesRecentOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
cp, err := currency.NewPairFromString("PI_XBTUSD")
if err != nil {
t.Error(err)
}
_, err = k.FuturesRecentOrders(context.Background(), cp)
if err != nil {
t.Error(err)
}
}
func TestFuturesWithdrawToSpotWallet(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
_, err := k.FuturesWithdrawToSpotWallet(context.Background(), "xbt", 5)
if err != nil {
t.Error(err)
}
}
func TestFuturesGetTransfers(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
_, err := k.FuturesGetTransfers(context.Background(),
time.Now().Add(-time.Hour*24))
if err != nil {
t.Error(err)
}
}
func TestGetFuturesOrderbook(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("FI_xbtusd_200925")
if err != nil {
t.Error(err)
}
_, err = k.GetFuturesOrderbook(context.Background(), cp)
if err != nil {
t.Error(err)
}
}
func TestGetFuturesMarkets(t *testing.T) {
t.Parallel()
_, err := k.GetInstruments(context.Background())
if err != nil {
t.Error(err)
}
}
func TestGetFuturesTickers(t *testing.T) {
t.Parallel()
_, err := k.GetFuturesTickers(context.Background())
if err != nil {
t.Error(err)
}
}
func TestGetFuturesTradeHistory(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("pi_xbtusd")
if err != nil {
t.Error(err)
}
_, err = k.GetFuturesTradeHistory(context.Background(),
cp, time.Now().Add(-time.Hour*24))
if err != nil {
t.Error(err)
}
}
// TestGetAssets API endpoint test
func TestGetAssets(t *testing.T) {
t.Parallel()
_, err := k.GetAssets(context.Background())
if err != nil {
t.Error("GetAssets() error", err)
}
}
func TestSeedAssetTranslator(t *testing.T) {
t.Parallel()
// Test currency pair
if r := assetTranslator.LookupAltName("XXBTZUSD"); r != "XBTUSD" {
t.Error("unexpected result")
}
if r := assetTranslator.LookupCurrency("XBTUSD"); r != "XXBTZUSD" {
t.Error("unexpected result")
}
// Test fiat currency
if r := assetTranslator.LookupAltName("ZUSD"); r != "USD" {
t.Error("unexpected result")
}
if r := assetTranslator.LookupCurrency("USD"); r != "ZUSD" {
t.Error("unexpected result")
}
// Test cryptocurrency
if r := assetTranslator.LookupAltName("XXBT"); r != "XBT" {
t.Error("unexpected result")
}
if r := assetTranslator.LookupCurrency("XBT"); r != "XXBT" {
t.Error("unexpected result")
}
}
func TestSeedAssets(t *testing.T) {
t.Parallel()
var a assetTranslatorStore
if r := a.LookupAltName("ZUSD"); r != "" {
t.Error("unexpected result")
}
a.Seed("ZUSD", "USD")
if r := a.LookupAltName("ZUSD"); r != "USD" {
t.Error("unexpected result")
}
a.Seed("ZUSD", "BLA")
if r := a.LookupAltName("ZUSD"); r != "USD" {
t.Error("unexpected result")
}
}
func TestLookupCurrency(t *testing.T) {
t.Parallel()
var a assetTranslatorStore
if r := a.LookupCurrency("USD"); r != "" {
t.Error("unexpected result")
}
a.Seed("ZUSD", "USD")
if r := a.LookupCurrency("USD"); r != "ZUSD" {
t.Error("unexpected result")
}
if r := a.LookupCurrency("EUR"); r != "" {
t.Error("unexpected result")
}
}
// TestGetAssetPairs API endpoint test
func TestGetAssetPairs(t *testing.T) {
t.Parallel()
_, err := k.GetAssetPairs(context.Background(), []string{}, "fees")
if err != nil {
t.Error("GetAssetPairs() error", err)
}
_, err = k.GetAssetPairs(context.Background(), []string{}, "leverage")
if err != nil {
t.Error("GetAssetPairs() error", err)
}
_, err = k.GetAssetPairs(context.Background(), []string{}, "margin")
if err != nil {
t.Error("GetAssetPairs() error", err)
}
_, err = k.GetAssetPairs(context.Background(), []string{}, "")
if err != nil {
t.Error("GetAssetPairs() error", err)
}
}
// TestGetTicker API endpoint test
func TestGetTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BCHEUR")
if err != nil {
t.Error(err)
}
_, err = k.GetTicker(context.Background(), cp)
if err != nil {
t.Error("GetTicker() error", err)
}
}
// TestGetTickers API endpoint test
func TestGetTickers(t *testing.T) {
t.Parallel()
_, err := k.GetTickers(context.Background(), "LTCUSD,ETCUSD")
if err != nil {
t.Error("GetTickers() error", err)
}
}
// TestGetOHLC API endpoint test
func TestGetOHLC(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("XXBTZUSD")
if err != nil {
t.Error(err)
}
_, err = k.GetOHLC(context.Background(), cp, "1440")
if err != nil {
t.Error("GetOHLC() error", err)
}
}
// TestGetDepth API endpoint test
func TestGetDepth(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BCHEUR")
if err != nil {
t.Error(err)
}
_, err = k.GetDepth(context.Background(), cp)
if err != nil {
t.Error("GetDepth() error", err)
}
}
// TestGetTrades API endpoint test
func TestGetTrades(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BCHEUR")
if err != nil {
t.Error(err)
}
_, err = k.GetTrades(context.Background(), cp)
if err != nil {
t.Error("GetTrades() error", err)
}
cp, err = currency.NewPairFromString("XXXXX")
if err != nil {
t.Error(err)
}
_, err = k.GetTrades(context.Background(), cp)
if err == nil {
t.Error("GetTrades() error: expecting error")
}
}
// TestGetSpread API endpoint test
func TestGetSpread(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BCHEUR")
if err != nil {
t.Error(err)
}
_, err = k.GetSpread(context.Background(), cp)
if err != nil {
t.Error("GetSpread() error", err)
}
}
// TestGetBalance API endpoint test
func TestGetBalance(t *testing.T) {
t.Parallel()
_, err := k.GetBalance(context.Background())
if err == nil {
t.Error("GetBalance() Expected error")
}
}
// TestGetTradeBalance API endpoint test
func TestGetDepositMethods(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.GetDepositMethods(context.Background(), "USDT")
if err != nil {
t.Error(err)
}
}
// TestGetTradeBalance API endpoint test
func TestGetTradeBalance(t *testing.T) {
t.Parallel()
args := TradeBalanceOptions{Asset: "ZEUR"}
_, err := k.GetTradeBalance(context.Background(), args)
if err == nil {
t.Error("GetTradeBalance() Expected error")
}
}
// TestGetOpenOrders API endpoint test
func TestGetOpenOrders(t *testing.T) {
t.Parallel()
args := OrderInfoOptions{Trades: true}
_, err := k.GetOpenOrders(context.Background(), args)
if err == nil {
t.Error("GetOpenOrders() Expected error")
}
}
// TestGetClosedOrders API endpoint test
func TestGetClosedOrders(t *testing.T) {
t.Parallel()
args := GetClosedOrdersOptions{Trades: true, Start: "OE4KV4-4FVQ5-V7XGPU"}
_, err := k.GetClosedOrders(context.Background(), args)
if err == nil {
t.Error("GetClosedOrders() Expected error")
}
}
// TestQueryOrdersInfo API endpoint test
func TestQueryOrdersInfo(t *testing.T) {
t.Parallel()
args := OrderInfoOptions{Trades: true}
_, err := k.QueryOrdersInfo(context.Background(),
args, "OR6ZFV-AA6TT-CKFFIW", "OAMUAJ-HLVKG-D3QJ5F")
if err == nil {
t.Error("QueryOrdersInfo() Expected error")
}
}
// TestGetTradesHistory API endpoint test
func TestGetTradesHistory(t *testing.T) {
t.Parallel()
args := GetTradesHistoryOptions{Trades: true, Start: "TMZEDR-VBJN2-NGY6DX", End: "TVRXG2-R62VE-RWP3UW"}
_, err := k.GetTradesHistory(context.Background(), args)
if err == nil {
t.Error("GetTradesHistory() Expected error")
}
}
// TestQueryTrades API endpoint test
func TestQueryTrades(t *testing.T) {
t.Parallel()
_, err := k.QueryTrades(context.Background(),
true, "TMZEDR-VBJN2-NGY6DX", "TFLWIB-KTT7L-4TWR3L", "TDVRAH-2H6OS-SLSXRX")
if err == nil {
t.Error("QueryTrades() Expected error")
}
}
// TestOpenPositions API endpoint test
func TestOpenPositions(t *testing.T) {
t.Parallel()
_, err := k.OpenPositions(context.Background(), false)
if err == nil {
t.Error("OpenPositions() Expected error")
}
}
// TestGetLedgers API endpoint test
func TestGetLedgers(t *testing.T) {
t.Parallel()
args := GetLedgersOptions{Start: "LRUHXI-IWECY-K4JYGO", End: "L5NIY7-JZQJD-3J4M2V", Ofs: 15}
_, err := k.GetLedgers(context.Background(), args)
if err == nil {
t.Error("GetLedgers() Expected error")
}
}
// TestQueryLedgers API endpoint test
func TestQueryLedgers(t *testing.T) {
t.Parallel()
_, err := k.QueryLedgers(context.Background(), "LVTSFS-NHZVM-EXNZ5M")
if err == nil {
t.Error("QueryLedgers() Expected error")
}
}
// TestGetTradeVolume API endpoint test
func TestGetTradeVolume(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("OAVY7T-MV5VK-KHDF5X")
if err != nil {
t.Error(err)
}
_, err = k.GetTradeVolume(context.Background(), true, cp)
if err == nil {
t.Error("GetTradeVolume() Expected error")
}
}
// TestAddOrder API endpoint test
func TestAddOrder(t *testing.T) {
t.Parallel()
args := AddOrderOptions{OrderFlags: "fcib"}
cp, err := currency.NewPairFromString("XXBTZUSD")
if err != nil {
t.Error(err)
}
_, err = k.AddOrder(context.Background(),
cp,
order.Sell.Lower(), order.Limit.Lower(),
0.00000001, 0, 0, 0, &args)
if err == nil {
t.Error("AddOrder() Expected error")
}
}
// TestCancelExistingOrder API endpoint test
func TestCancelExistingOrder(t *testing.T) {
t.Parallel()
_, err := k.CancelExistingOrder(context.Background(), "OAVY7T-MV5VK-KHDF5X")
if err == nil {
t.Error("CancelExistingOrder() Expected error")
}
}
func setFeeBuilder() *exchange.FeeBuilder {
return &exchange.FeeBuilder{
Amount: 1,
FeeType: exchange.CryptocurrencyTradeFee,
Pair: currency.NewPair(currency.XXBT, currency.ZUSD),
PurchasePrice: 1,
FiatCurrency: currency.USD,
BankTransactionType: exchange.WireTransfer,
}
}
// TestGetFee logic test
// TestGetFeeByTypeOfflineTradeFee logic test
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
t.Parallel()
var feeBuilder = setFeeBuilder()
_, err := k.GetFeeByType(context.Background(), feeBuilder)
if err != nil {
t.Error(err)
}
if !sharedtestvalues.AreAPICredentialsSet(k) {
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(k) {
// CryptocurrencyTradeFee Basic
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
// CryptocurrencyTradeFee High quantity
feeBuilder = setFeeBuilder()
feeBuilder.Amount = 1000
feeBuilder.PurchasePrice = 1000
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
// CryptocurrencyTradeFee IsMaker
feeBuilder = setFeeBuilder()
feeBuilder.IsMaker = true
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
// CryptocurrencyTradeFee Negative purchase price
feeBuilder = setFeeBuilder()
feeBuilder.PurchasePrice = -1000
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
// InternationalBankDepositFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.InternationalBankDepositFee
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
}
// CryptocurrencyDepositFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CryptocurrencyDepositFee
feeBuilder.Pair.Base = currency.XXBT
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
// CryptocurrencyWithdrawalFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
// CryptocurrencyWithdrawalFee Invalid currency
feeBuilder = setFeeBuilder()
feeBuilder.Pair.Base = currency.NewCode("hello")
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
// InternationalBankWithdrawalFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
feeBuilder.FiatCurrency = currency.USD
if _, err := k.GetFee(context.Background(), feeBuilder); err != nil {
t.Error(err)
}
}
// TestFormatWithdrawPermissions logic test
func TestFormatWithdrawPermissions(t *testing.T) {
t.Parallel()
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawCryptoWith2FAText + " & " + exchange.AutoWithdrawFiatWithSetupText + " & " + exchange.WithdrawFiatWith2FAText
withdrawPermissions := k.FormatWithdrawPermissions()
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
// TestGetActiveOrders wrapper test
func TestGetActiveOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
pair, err := currency.NewPairFromString("LTC_USDT")
if err != nil {
t.Error(err)
}
var getOrdersRequest = order.MultiOrderRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Pairs: currency.Pairs{pair},
Side: order.AnySide,
}
_, err = k.GetActiveOrders(context.Background(), &getOrdersRequest)
if err != nil {
t.Error(err)
}
}
// TestGetOrderHistory wrapper test
func TestGetOrderHistory(t *testing.T) {
t.Parallel()
var getOrdersRequest = order.MultiOrderRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := k.GetOrderHistory(context.Background(), &getOrdersRequest)
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// TestGetOrderHistory wrapper test
func TestGetOrderInfo(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
_, err := k.GetOrderInfo(context.Background(),
"OZPTPJ-HVYHF-EDIGXS", currency.EMPTYPAIR, asset.Spot)
if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting error")
}
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
if !strings.Contains(err.Error(), "- Order ID not found:") {
t.Error("Expected Order ID not found error")
} else {
t.Error(err)
}
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
// TestSubmitOrder wrapper test
func TestSubmitOrder(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
var orderSubmission = &order.Submit{
Exchange: k.Name,
Pair: currency.Pair{
Base: currency.XBT,
Quote: currency.USD,
},
Side: order.Buy,
Type: order.Limit,
Price: 1,
Amount: 1,
ClientID: "meowOrder",
AssetType: asset.Spot,
}
response, err := k.SubmitOrder(context.Background(), orderSubmission)
if sharedtestvalues.AreAPICredentialsSet(k) && (err != nil || response.Status != order.New) {
t.Errorf("Order failed to be placed: %v", err)
} else if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// TestCancelExchangeOrder wrapper test
func TestCancelExchangeOrder(t *testing.T) {
t.Parallel()
if err := k.CancelOrder(context.Background(), &order.Cancel{
AssetType: asset.Options,
OrderID: "1337",
}); !errors.Is(err, asset.ErrNotSupported) {
t.Errorf("expected: %v, received: %v", asset.ErrNotSupported, err)
}
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
var orderCancellation = &order.Cancel{
OrderID: "OGEX6P-B5Q74-IGZ72R",
AssetType: asset.Spot,
}
err := k.CancelOrder(context.Background(), orderCancellation)
if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
t.Errorf("Could not cancel orders: %v", err)
}
}
// TestCancelExchangeOrder wrapper test
func TestCancelBatchExchangeOrder(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
pair := currency.Pair{
Delimiter: "/",
Base: currency.BTC,
Quote: currency.USD,
}
var ordersCancellation []order.Cancel
ordersCancellation = append(ordersCancellation, order.Cancel{
Pair: pair,
OrderID: "OGEX6P-B5Q74-IGZ72R,OGEX6P-B5Q74-IGZ722",
AssetType: asset.Spot,
})
_, err := k.CancelBatchOrders(context.Background(), ordersCancellation)
if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
t.Errorf("Could not cancel orders: %v", err)
}
}
// TestCancelAllExchangeOrders wrapper test
func TestCancelAllExchangeOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
resp, err := k.CancelAllOrders(context.Background(),
&order.Cancel{AssetType: asset.Spot})
if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
t.Errorf("Could not cancel orders: %v", err)
}
if len(resp.Status) > 0 {
t.Errorf("%v orders failed to cancel", len(resp.Status))
}
}
// TestGetAccountInfo wrapper test
func TestGetAccountInfo(t *testing.T) {
t.Parallel()
if sharedtestvalues.AreAPICredentialsSet(k) {
_, err := k.UpdateAccountInfo(context.Background(), asset.Spot)
if err != nil {
// Spot and Futures have separate api keys. Please ensure that the correct one is provided
t.Error("GetAccountInfo() error", err)
}
} else {
_, err := k.UpdateAccountInfo(context.Background(), asset.Spot)
if err == nil {
t.Error("GetAccountInfo() Expected error")
}
}
}
func TestUpdateFuturesAccountInfo(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.UpdateAccountInfo(context.Background(), asset.Futures)
if err != nil {
// Spot and Futures have separate api keys. Please ensure that the correct one is provided
t.Error(err)
}
}
// TestModifyOrder wrapper test
func TestModifyOrder(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
_, err := k.ModifyOrder(context.Background(),
&order.Modify{AssetType: asset.Spot})
if err == nil {
t.Error("ModifyOrder() Expected error")
}
}
// TestWithdraw wrapper test
func TestWithdraw(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
withdrawCryptoRequest := withdraw.Request{
Exchange: k.Name,
Crypto: withdraw.CryptoRequest{
Address: core.BitcoinDonationAddress,
},
Amount: -1,
Currency: currency.XXBT,
Description: "WITHDRAW IT ALL",
TradePassword: "Key",
}
_, err := k.WithdrawCryptocurrencyFunds(context.Background(),
&withdrawCryptoRequest)
if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
}
}
// TestWithdrawFiat wrapper test
func TestWithdrawFiat(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
var withdrawFiatRequest = withdraw.Request{
Amount: -1,
Currency: currency.EUR,
Description: "WITHDRAW IT ALL",
TradePassword: "someBank",
}
_, err := k.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest)
if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
}
}
// TestWithdrawInternationalBank wrapper test
func TestWithdrawInternationalBank(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders)
var withdrawFiatRequest = withdraw.Request{
Amount: -1,
Currency: currency.EUR,
Description: "WITHDRAW IT ALL",
TradePassword: "someBank",
}
_, err := k.WithdrawFiatFundsToInternationalBank(context.Background(),
&withdrawFiatRequest)
if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("Expecting an error when no keys are set")
}
if sharedtestvalues.AreAPICredentialsSet(k) && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
}
}
func TestGetCryptoDepositAddress(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, k)
_, err := k.GetCryptoDepositAddress(context.Background(), "Bitcoin", "XBT", false)
if err != nil {
t.Error(err)
}
if !canManipulateRealOrders {
t.Skip("canManipulateRealOrders not set, skipping test")
}
_, err = k.GetCryptoDepositAddress(context.Background(), "Bitcoin", "XBT", true)
if err != nil {
t.Error(err)
}
}
// TestGetDepositAddress wrapper test
func TestGetDepositAddress(t *testing.T) {
t.Parallel()
if sharedtestvalues.AreAPICredentialsSet(k) {
_, err := k.GetDepositAddress(context.Background(), currency.USDT, "", "")
if err != nil {
t.Error("GetDepositAddress() error", err)
}
} else {
_, err := k.GetDepositAddress(context.Background(), currency.BTC, "", "")
if err == nil {
t.Error("GetDepositAddress() error can not be nil")
}
}
}
// TestWithdrawStatus wrapper test
func TestWithdrawStatus(t *testing.T) {
t.Parallel()
if sharedtestvalues.AreAPICredentialsSet(k) {
_, err := k.WithdrawStatus(context.Background(), currency.BTC, "")
if err != nil {
t.Error("WithdrawStatus() error", err)
}
} else {
_, err := k.WithdrawStatus(context.Background(), currency.BTC, "")
if err == nil {
t.Error("GetDepositAddress() error can not be nil")
}
}
}
// TestWithdrawCancel wrapper test
func TestWithdrawCancel(t *testing.T) {
t.Parallel()
_, err := k.WithdrawCancel(context.Background(), currency.BTC, "")
if sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Error("WithdrawCancel() error cannot be nil")
} else if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil {
t.Errorf("WithdrawCancel() error - expecting an error when no keys are set but received nil")
}
}
// ---------------------------- Websocket tests -----------------------------------------
func setupWsTests(t *testing.T) {
t.Helper()
if wsSetupRan {
return
}
if !k.Websocket.IsEnabled() && !k.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(k) {
t.Skip(stream.ErrWebsocketNotEnabled.Error())
}
var dialer websocket.Dialer
err := k.Websocket.Conn.Dial(&dialer, http.Header{})
if err != nil {
t.Fatal(err)
}
err = k.Websocket.AuthConn.Dial(&dialer, http.Header{})
if err != nil {
t.Fatal(err)
}
token, err := k.GetWebsocketToken(context.Background())
if err != nil {
t.Error(err)
}
authToken = token
comms := make(chan stream.Response)
go k.wsFunnelConnectionData(k.Websocket.Conn, comms)
go k.wsFunnelConnectionData(k.Websocket.AuthConn, comms)
go k.wsReadData(comms)
go func() {
err := k.wsPingHandler()
if err != nil {
fmt.Println("error:", err)
}
}()
wsSetupRan = true
}
// TestWebsocketSubscribe tests returning a message with an id
func TestWebsocketSubscribe(t *testing.T) {
setupWsTests(t)
err := k.Subscribe([]subscription.Subscription{
{
Channel: defaultSubscribedChannels[0],
Pair: currency.NewPairWithDelimiter("XBT", "USD", "/"),
},
})
if err != nil {
t.Error(err)
}
}
func TestGetWSToken(t *testing.T) {
t.Parallel()
if !sharedtestvalues.AreAPICredentialsSet(k) {
t.Skip("API keys required, skipping")
}
resp, err := k.GetWebsocketToken(context.Background())
if err != nil {
t.Error(err)
}
if resp == "" {
t.Error("Token not returned")
}
}
func TestWsAddOrder(t *testing.T) {
setupWsTests(t)
_, err := k.wsAddOrder(&WsAddOrderRequest{
OrderType: order.Limit.Lower(),
OrderSide: order.Buy.Lower(),
Pair: "XBT/USD",
Price: -100,
})
if err != nil {
t.Error(err)
}
}
func TestWsCancelOrder(t *testing.T) {
setupWsTests(t)
if err := k.wsCancelOrders([]string{"1337"}); err != nil {
t.Error(err)
}
}
func TestWsCancelAllOrders(t *testing.T) {
setupWsTests(t)
if _, err := k.wsCancelAllOrders(); err != nil {
t.Error(err)
}
}
func TestWsPong(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"event": "pong",
"reqid": 42
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsSystemStatus(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"connectionID": 8628615390848610000,
"event": "systemStatus",
"status": "online",
"version": "1.0.0"
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsSubscriptionStatus(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 10001,
"channelName": "ticker",
"event": "subscriptionStatus",
"pair": "XBT/EUR",
"status": "subscribed",
"subscription": {
"name": "ticker"
}
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`{
"channelID": 10001,
"channelName": "ohlc-5",
"event": "subscriptionStatus",
"pair": "XBT/EUR",
"reqid": 42,
"status": "unsubscribed",
"subscription": {
"interval": 5,
"name": "ohlc"
}
}`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`{
"channelName": "ownTrades",
"event": "subscriptionStatus",
"status": "subscribed",
"subscription": {
"name": "ownTrades"
}
}`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`{
"errorMessage": "Subscription depth not supported",
"event": "subscriptionStatus",
"pair": "XBT/USD",
"status": "error",
"subscription": {
"depth": 42,
"name": "book"
}
}`)
err = k.wsHandleData(pressXToJSON)
if err == nil {
t.Error("Expected error")
}
}
func TestWsTicker(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 1337,
"channelName": "ticker",
"event": "subscriptionStatus",
"pair": "XBT/EUR",
"status": "subscribed",
"subscription": {
"name": "ticker"
}
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`[
1337,
{
"a": [
"5525.40000",
1,
"1.000"
],
"b": [
"5525.10000",
1,
"1.000"
],
"c": [
"5525.10000",
"0.00398963"
],
"h": [
"5783.00000",
"5783.00000"
],
"l": [
"5505.00000",
"5505.00000"
],
"o": [
"5760.70000",
"5763.40000"
],
"p": [
"5631.44067",
"5653.78939"
],
"t": [
11493,
16267
],
"v": [
"2634.11501494",
"3591.17907851"
]
},
"ticker",
"XBT/USD"
]`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsOHLC(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 13337,
"channelName": "ohlc",
"event": "subscriptionStatus",
"pair": "XBT/EUR",
"status": "subscribed",
"subscription": {
"name": "ohlc"
}
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`[
13337,
[
"1542057314.748456",
"1542057360.435743",
"3586.70000",
"3586.70000",
"3586.60000",
"3586.60000",
"3586.68894",
"0.03373000",
2
],
"ohlc-5",
"XBT/USD"
]`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsTrade(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 133337,
"channelName": "trade",
"event": "subscriptionStatus",
"pair": "XBT/EUR",
"status": "subscribed",
"subscription": {
"name": "trade"
}
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`[
133337,
[
[
"5541.20000",
"0.15850568",
"1534614057.321597",
"s",
"l",
""
],
[
"6060.00000",
"0.02455000",
"1534614057.324998",
"b",
"l",
""
]
],
"trade",
"XBT/USD"
]`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsSpread(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 1333337,
"channelName": "spread",
"event": "subscriptionStatus",
"pair": "XBT/EUR",
"status": "subscribed",
"subscription": {
"name": "spread"
}
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`[
1333337,
[
"5698.40000",
"5700.00000",
"1542057299.545897",
"1.01234567",
"0.98765432"
],
"spread",
"XBT/USD"
]`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsOrdrbook(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 13333337,
"channelName": "book",
"event": "subscriptionStatus",
"pair": "XBT/USD",
"status": "subscribed",
"subscription": {
"name": "book"
}
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`[
13333337,
{
"as": [
[
"5541.30000",
"2.50700000",
"1534614248.123678"
],
[
"5541.80000",
"0.33000000",
"1534614098.345543"
],
[
"5542.70000",
"0.64700000",
"1534614244.654432"
],
[
"5544.30000",
"2.50700000",
"1534614248.123678"
],
[
"5545.80000",
"0.33000000",
"1534614098.345543"
],
[
"5546.70000",
"0.64700000",
"1534614244.654432"
],
[
"5547.70000",
"0.64700000",
"1534614244.654432"
],
[
"5548.30000",
"2.50700000",
"1534614248.123678"
],
[
"5549.80000",
"0.33000000",
"1534614098.345543"
],
[
"5550.70000",
"0.64700000",
"1534614244.654432"
]
],
"bs": [
[
"5541.20000",
"1.52900000",
"1534614248.765567"
],
[
"5539.90000",
"0.30000000",
"1534614241.769870"
],
[
"5539.50000",
"5.00000000",
"1534613831.243486"
],
[
"5538.20000",
"1.52900000",
"1534614248.765567"
],
[
"5537.90000",
"0.30000000",
"1534614241.769870"
],
[
"5536.50000",
"5.00000000",
"1534613831.243486"
],
[
"5535.20000",
"1.52900000",
"1534614248.765567"
],
[
"5534.90000",
"0.30000000",
"1534614241.769870"
],
[
"5533.50000",
"5.00000000",
"1534613831.243486"
],
[
"5532.50000",
"5.00000000",
"1534613831.243486"
]
]
},
"book-100",
"XBT/USD"
]`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`[
13333337,
{
"a": [
[
"5541.30000",
"2.50700000",
"1534614248.456738"
],
[
"5542.50000",
"0.40100000",
"1534614248.456738"
]
],
"c": "4187525586"
},
"book-10",
"XBT/USD"
]`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
pressXToJSON = []byte(`[
13333337,
{
"b": [
[
"5541.30000",
"0.00000000",
"1534614335.345903"
]
],
"c": "4187525586"
},
"book-10",
"XBT/USD"
]`)
err = k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsOwnTrades(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`[
[
{
"TDLH43-DVQXD-2KHVYY": {
"cost": "1000000.00000",
"fee": "1600.00000",
"margin": "0.00000",
"ordertxid": "TDLH43-DVQXD-2KHVYY",
"ordertype": "limit",
"pair": "XBT/USD",
"postxid": "OGTT3Y-C6I3P-XRI6HX",
"price": "100000.00000",
"time": "1560516023.070651",
"type": "sell",
"vol": "1000000000.00000000"
}
},
{
"TDLH43-DVQXD-2KHVYY": {
"cost": "1000000.00000",
"fee": "600.00000",
"margin": "0.00000",
"ordertxid": "TDLH43-DVQXD-2KHVYY",
"ordertype": "limit",
"pair": "XBT/USD",
"postxid": "OGTT3Y-C6I3P-XRI6HX",
"price": "100000.00000",
"time": "1560516023.070658",
"type": "buy",
"vol": "1000000000.00000000"
}
},
{
"TDLH43-DVQXD-2KHVYY": {
"cost": "1000000.00000",
"fee": "1600.00000",
"margin": "0.00000",
"ordertxid": "TDLH43-DVQXD-2KHVYY",
"ordertype": "limit",
"pair": "XBT/USD",
"postxid": "OGTT3Y-C6I3P-XRI6HX",
"price": "100000.00000",
"time": "1560520332.914657",
"type": "sell",
"vol": "1000000000.00000000"
}
},
{
"TDLH43-DVQXD-2KHVYY": {
"cost": "1000000.00000",
"fee": "600.00000",
"margin": "0.00000",
"ordertxid": "TDLH43-DVQXD-2KHVYY",
"ordertype": "limit",
"pair": "XBT/USD",
"postxid": "OGTT3Y-C6I3P-XRI6HX",
"price": "100000.00000",
"time": "1560520332.914664",
"type": "buy",
"vol": "1000000000.00000000"
}
}
],
"ownTrades"
]`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsOpenOrders(t *testing.T) {
t.Parallel()
n := new(Kraken)
sharedtestvalues.TestFixtureToDataHandler(t, k, n, "testdata/wsOpenTrades.json", n.wsHandleData)
seen := 0
for reading := true; reading; {
select {
default:
reading = false
case resp := <-n.Websocket.DataHandler:
seen++
switch v := resp.(type) {
case *order.Detail:
switch seen {
case 1:
assert.Equal(t, "OGTT3Y-C6I3P-XRI6HR", v.OrderID, "OrderID")
assert.Equal(t, order.Limit, v.Type, "order type")
assert.Equal(t, order.Sell, v.Side, "order side")
assert.Equal(t, order.Open, v.Status, "order status")
assert.Equal(t, 34.5, v.Price, "price")
assert.Equal(t, 10.00345345, v.Amount, "amount")
case 2:
assert.Equal(t, "OKB55A-UEMMN-YUXM2A", v.OrderID, "OrderID")
assert.Equal(t, order.Market, v.Type, "order type")
assert.Equal(t, order.Buy, v.Side, "order side")
assert.Equal(t, order.Pending, v.Status, "order status")
assert.Equal(t, 0.0, v.Price, "price")
assert.Equal(t, 0.0001, v.Amount, "amount")
assert.Equal(t, time.UnixMicro(1692851641361371), v.Date, "Date")
case 3:
assert.Equal(t, "OKB55A-UEMMN-YUXM2A", v.OrderID, "OrderID")
assert.Equal(t, order.Open, v.Status, "order status")
case 4:
assert.Equal(t, "OKB55A-UEMMN-YUXM2A", v.OrderID, "OrderID")
assert.Equal(t, order.UnknownStatus, v.Status, "order status")
assert.Equal(t, 26425.2, v.AverageExecutedPrice, "AverageExecutedPrice")
assert.Equal(t, 0.0001, v.ExecutedAmount, "ExecutedAmount")
assert.Equal(t, 0.0, v.RemainingAmount, "RemainingAmount") // Not in the message; Testing regression to bad derivation
assert.Equal(t, 0.00687, v.Fee, "Fee")
case 5:
assert.Equal(t, "OKB55A-UEMMN-YUXM2A", v.OrderID, "OrderID")
assert.Equal(t, order.Closed, v.Status, "order status")
assert.Equal(t, 0.0001, v.ExecutedAmount, "ExecutedAmount")
assert.Equal(t, 26425.2, v.AverageExecutedPrice, "AverageExecutedPrice")
assert.Equal(t, 0.00687, v.Fee, "Fee")
assert.Equal(t, time.UnixMicro(1692851641361447), v.LastUpdated, "LastUpdated")
case 6:
assert.Equal(t, "OGTT3Y-C6I3P-XRI6HR", v.OrderID, "OrderID")
assert.Equal(t, order.UnknownStatus, v.Status, "order status")
assert.Equal(t, 10.00345345, v.ExecutedAmount, "ExecutedAmount")
assert.Equal(t, 0.001, v.Fee, "Fee")
assert.Equal(t, 34.5, v.AverageExecutedPrice, "AverageExecutedPrice")
case 7:
assert.Equal(t, "OGTT3Y-C6I3P-XRI6HR", v.OrderID, "OrderID")
assert.Equal(t, order.Closed, v.Status, "order status")
assert.Equal(t, time.UnixMicro(1692675961789052), v.LastUpdated, "LastUpdated")
assert.Equal(t, 10.00345345, v.ExecutedAmount, "ExecutedAmount")
assert.Equal(t, 0.001, v.Fee, "Fee")
assert.Equal(t, 34.5, v.AverageExecutedPrice, "AverageExecutedPrice")
reading = false
}
default:
t.Errorf("Unexpected type in DataHandler: %T (%s)", v, v)
}
}
}
assert.Equal(t, 7, seen, "number of DataHandler emissions")
}
func TestWsAddOrderJSON(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"descr": "buy 0.01770000 XBTUSD @ limit 4000",
"event": "addOrderStatus",
"status": "ok",
"txid": "ONPNXH-KMKMU-F4MR5V"
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestWsCancelOrderJSON(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"event": "cancelOrderStatus",
"status": "ok"
}`)
err := k.wsHandleData(pressXToJSON)
if err != nil {
t.Error(err)
}
}
func TestParseTime(t *testing.T) {
t.Parallel()
// Test REST example
r := convert.TimeFromUnixTimestampDecimal(1373750306.9819).UTC()
if r.Year() != 2013 ||
r.Month().String() != "July" ||
r.Day() != 13 {
t.Error("unexpected result")
}
// Test Websocket time example
r = convert.TimeFromUnixTimestampDecimal(1534614098.345543).UTC()
if r.Year() != 2018 ||
r.Month().String() != "August" ||
r.Day() != 18 {
t.Error("unexpected result")
}
}
func TestGetHistoricCandles(t *testing.T) {
t.Parallel()
pair, err := currency.NewPairFromString("XBT-USD")
if err != nil {
t.Fatal(err)
}
_, err = k.GetHistoricCandles(context.Background(), pair, asset.Spot, kline.OneHour, time.Now().Add(-time.Hour*12), time.Now())
if err != nil {
t.Error(err)
}
pairs, err := k.CurrencyPairs.GetPairs(asset.Futures, false)
if err != nil {
t.Error(err)
}
err = k.CurrencyPairs.EnablePair(asset.Futures, pairs[0])
if err != nil && !errors.Is(err, currency.ErrPairAlreadyEnabled) {
t.Error(err)
}
_, err = k.GetHistoricCandles(context.Background(), pairs[0], asset.Futures, kline.OneHour, time.Now().Add(-time.Hour*12), time.Now())
if !errors.Is(err, asset.ErrNotSupported) {
t.Error(err)
}
}
func TestGetHistoricCandlesExtended(t *testing.T) {
t.Parallel()
pair, err := currency.NewPairFromString("XBT-USD")
if err != nil {
t.Fatal(err)
}
_, err = k.GetHistoricCandlesExtended(context.Background(), pair, asset.Spot, kline.OneMin, time.Now().Add(-time.Minute*3), time.Now())
if !errors.Is(err, common.ErrFunctionNotSupported) {
t.Error(err)
}
}
func Test_FormatExchangeKlineInterval(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
interval kline.Interval
output string
}{
{
"OneMin",
kline.OneMin,
"1",
},
{
"OneDay",
kline.OneDay,
"1440",
},
}
for x := range testCases {
test := testCases[x]
t.Run(test.name, func(t *testing.T) {
t.Parallel()
ret := k.FormatExchangeKlineInterval(test.interval)
if ret != test.output {
t.Errorf("unexpected result return expected: %v received: %v", test.output, ret)
}
})
}
}
func TestGetRecentTrades(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BCHEUR")
if err != nil {
t.Fatal(err)
}
_, err = k.GetRecentTrades(context.Background(), cp, asset.Spot)
if err != nil {
t.Error(err)
}
cp, err = currency.NewPairFromStrings("PI", "BCHUSD")
if err != nil {
t.Error(err)
}
cp.Delimiter = "_"
_, err = k.GetRecentTrades(context.Background(), cp, asset.Futures)
if err != nil {
t.Error(err)
}
}
func TestGetHistoricTrades(t *testing.T) {
t.Parallel()
currencyPair, err := currency.NewPairFromString("XBTUSD")
if err != nil {
t.Fatal(err)
}
_, err = k.GetHistoricTrades(context.Background(),
currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now())
if err != nil && err != common.ErrFunctionNotSupported {
t.Error(err)
}
}
var testOb = orderbook.Base{
Asks: []orderbook.Item{
// NOTE: 0.00000500 float64 == 0.000005
{Price: 0.05005, StrPrice: "0.05005", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05010, StrPrice: "0.05010", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05015, StrPrice: "0.05015", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05020, StrPrice: "0.05020", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05025, StrPrice: "0.05025", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05030, StrPrice: "0.05030", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05035, StrPrice: "0.05035", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05040, StrPrice: "0.05040", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05045, StrPrice: "0.05045", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.05050, StrPrice: "0.05050", Amount: 0.00000500, StrAmount: "0.00000500"},
},
Bids: []orderbook.Item{
{Price: 0.05000, StrPrice: "0.05000", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04995, StrPrice: "0.04995", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04990, StrPrice: "0.04990", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04980, StrPrice: "0.04980", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04975, StrPrice: "0.04975", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04970, StrPrice: "0.04970", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04965, StrPrice: "0.04965", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04960, StrPrice: "0.04960", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04955, StrPrice: "0.04955", Amount: 0.00000500, StrAmount: "0.00000500"},
{Price: 0.04950, StrPrice: "0.04950", Amount: 0.00000500, StrAmount: "0.00000500"},
},
}
const krakenAPIDocChecksum = 974947235
func TestChecksumCalculation(t *testing.T) {
t.Parallel()
expected := "5005"
if v := trim("0.05005"); v != expected {
t.Errorf("expected %s but received %s", expected, v)
}
expected = "500"
if v := trim("0.00000500"); v != expected {
t.Errorf("expected %s but received %s", expected, v)
}
err := validateCRC32(&testOb, krakenAPIDocChecksum)
if err != nil {
t.Error(err)
}
}
func TestGetCharts(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromStrings("PI", "BCHUSD")
if err != nil {
t.Error(err)
}
cp.Delimiter = "_"
resp, err := k.GetFuturesCharts(context.Background(), "1d", "spot", cp, time.Time{}, time.Time{})
if err != nil {
t.Error(err)
}
end := time.UnixMilli(resp.Candles[0].Time)
_, err = k.GetFuturesCharts(context.Background(), "1d", "spot", cp, end.Add(-time.Hour*24*7), end)
if err != nil {
t.Error(err)
}
}
func TestGetFuturesTrades(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromStrings("PI", "BCHUSD")
if err != nil {
t.Error(err)
}
cp.Delimiter = "_"
_, err = k.GetFuturesTrades(context.Background(), cp, time.Time{}, time.Time{})
if err != nil {
t.Error(err)
}
_, err = k.GetFuturesTrades(context.Background(), cp, time.Now().Add(-time.Hour), time.Now())
if err != nil {
t.Error(err)
}
}
var websocketXDGUSDOrderbookUpdates = []string{
`{"channelID":2304,"channelName":"book-10","event":"subscriptionStatus","pair":"XDG/USD","reqid":163845014,"status":"subscribed","subscription":{"depth":10,"name":"book"}}`,
`[2304,{"as":[["0.074602700","278.39626342","1690246067.832139"],["0.074611000","555.65134028","1690246086.243668"],["0.074613300","524.87121572","1690245901.574881"],["0.074624600","77.57180740","1690246060.668500"],["0.074632500","620.64648404","1690246010.904883"],["0.074698400","409.57419037","1690246041.269821"],["0.074700000","61067.71115772","1690246089.485595"],["0.074723200","4394.01869240","1690246087.557913"],["0.074725200","4229.57885125","1690246082.911452"],["0.074738400","212.25501214","1690246089.421559"]],"bs":[["0.074597400","53591.43163675","1690246089.451762"],["0.074596700","33594.18269213","1690246089.514152"],["0.074596600","53598.60351469","1690246089.340781"],["0.074594800","5358.57247081","1690246089.347962"],["0.074594200","30168.21074680","1690246089.345112"],["0.074590900","7089.69894583","1690246088.212880"],["0.074586700","46925.20182082","1690246089.074618"],["0.074577200","5500.00000000","1690246087.568856"],["0.074569600","8132.49888631","1690246086.841219"],["0.074562900","8413.11098009","1690246087.024863"]]},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074700000","0.00000000","1690246089.516119"],["0.074738500","125000.00000000","1690246063.352141","r"]],"c":"2219685759"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074678800","33476.70673703","1690246089.570183"]],"c":"1897176819"},"book-10","XDG/USD"]`,
`[2304,{"b":[["0.074562900","0.00000000","1690246089.570206"],["0.074559600","4000.00000000","1690246086.478591","r"]],"c":"2498018751"},"book-10","XDG/USD"]`,
`[2304,{"b":[["0.074577300","125000.00000000","1690246089.577140"]],"c":"155006629"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074678800","0.00000000","1690246089.584498"],["0.074738500","125000.00000000","1690246063.352141","r"]],"c":"3703147735"},"book-10","XDG/USD"]`,
`[2304,{"b":[["0.074597500","10000.00000000","1690246089.602477"]],"c":"2989534775"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074738500","0.00000000","1690246089.608769"],["0.074750800","51369.02100000","1690246089.495500","r"]],"c":"1842075082"},"book-10","XDG/USD"]`,
`[2304,{"b":[["0.074583500","8413.11098009","1690246089.612144"]],"c":"710274752"},"book-10","XDG/USD"]`,
`[2304,{"b":[["0.074578500","9966.55841398","1690246089.634739"]],"c":"1646135532"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074738400","0.00000000","1690246089.638648"],["0.074751500","80499.09450000","1690246086.679402","r"]],"c":"2509689626"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074750700","290.96851266","1690246089.638754"]],"c":"3981738175"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074720000","61067.71115772","1690246089.662102"]],"c":"1591820326"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074602700","0.00000000","1690246089.670911"],["0.074750800","51369.02100000","1690246089.495500","r"]],"c":"3838272404"},"book-10","XDG/USD"]`,
`[2304,{"a":[["0.074611000","0.00000000","1690246089.680343"],["0.074758500","159144.39750000","1690246035.158327","r"]],"c":"4241552383"},"book-10","XDG/USD"] `,
}
var websocketLUNAEUROrderbookUpdates = []string{
`{"channelID":9536,"channelName":"book-10","event":"subscriptionStatus","pair":"LUNA/EUR","reqid":106845459,"status":"subscribed","subscription":{"depth":10,"name":"book"}}`,
`[9536,{"as":[["0.000074650000","147354.32016076","1690249755.076929"],["0.000074710000","5084881.40000000","1690250711.359411"],["0.000074760000","9700502.70476704","1690250743.279490"],["0.000074990000","2933380.23886300","1690249596.627969"],["0.000075000000","433333.33333333","1690245575.626780"],["0.000075020000","152914.84493416","1690243661.232520"],["0.000075070000","146529.90542161","1690249048.358424"],["0.000075250000","737072.85720004","1690211553.549248"],["0.000075400000","670061.64567140","1690250769.261196"],["0.000075460000","980226.63603417","1690250769.627523"]],"bs":[["0.000074590000","71029.87806720","1690250763.012724"],["0.000074580000","15935576.86404000","1690250763.012710"],["0.000074520000","33758611.79634000","1690250718.290955"],["0.000074350000","3156650.58590277","1690250766.499648"],["0.000074340000","301727260.79999999","1690250766.490238"],["0.000074320000","64611496.53837000","1690250742.680258"],["0.000074310000","104228596.60000000","1690250744.679121"],["0.000074300000","40366046.10582000","1690250762.685914"],["0.000074200000","3690216.57320475","1690250645.311465"],["0.000074060000","1337170.52532521","1690250742.012527"]]},"book-10","LUNA/EUR"]`,
`[9536,{"b":[["0.000074060000","0.00000000","1690250770.616604"],["0.000074050000","16742421.17790510","1690250710.867730","r"]],"c":"418307145"},"book-10","LUNA/EUR"]`,
}
var websocketGSTEUROrderbookUpdates = []string{
`{"channelID":8912,"channelName":"book-10","event":"subscriptionStatus","pair":"GST/EUR","reqid":157734759,"status":"subscribed","subscription":{"depth":10,"name":"book"}}`,
`[8912,{"as":[["0.01300","850.00000000","1690230914.230506"],["0.01400","323483.99590510","1690256356.615823"],["0.01500","100287.34442717","1690219133.193345"],["0.01600","67995.78441017","1690118389.451216"],["0.01700","41776.38397740","1689676303.381189"],["0.01800","11785.76177777","1688631951.812452"],["0.01900","23700.00000000","1686935422.319042"],["0.02000","3941.17000000","1689415829.176481"],["0.02100","16598.69173066","1689420942.541943"],["0.02200","17572.51572836","1689851425.907427"]],"bs":[["0.01200","14220.66466572","1690256540.842831"],["0.01100","160223.61546438","1690256401.072463"],["0.01000","63083.48958963","1690256604.037673"],["0.00900","6750.00000000","1690252470.633938"],["0.00800","213059.49706376","1690256360.386301"],["0.00700","1000.00000000","1689869458.464975"],["0.00600","4000.00000000","1690221333.528698"],["0.00100","245000.00000000","1690051368.753455"]]},"book-10","GST/EUR"]`,
`[8912,{"b":[["0.01000","60583.48958963","1690256620.206768"],["0.01000","63083.48958963","1690256620.206783"]],"c":"69619317"},"book-10","GST/EUR"]`,
}
func TestWsOrderbookMax10Depth(t *testing.T) {
t.Parallel()
for x := range websocketXDGUSDOrderbookUpdates {
err := k.wsHandleData([]byte(websocketXDGUSDOrderbookUpdates[x]))
if err != nil {
t.Fatal(err)
}
}
for x := range websocketLUNAEUROrderbookUpdates {
err := k.wsHandleData([]byte(websocketLUNAEUROrderbookUpdates[x]))
// TODO: Known issue with LUNA pairs and big number float precision
// storage and checksum calc. Might need to store raw strings as fields
// in the orderbook.Item struct.
// Required checksum: 7465000014735432016076747100005084881400000007476000097005027047670474990000293338023886300750000004333333333333375020000152914844934167507000014652990542161752500007370728572000475400000670061645671407546000098022663603417745900007102987806720745800001593557686404000745200003375861179634000743500003156650585902777434000030172726079999999743200006461149653837000743100001042285966000000074300000403660461058200074200000369021657320475740500001674242117790510
if err != nil && x != len(websocketLUNAEUROrderbookUpdates)-1 {
t.Fatal(err)
}
}
// This has less than 10 bids and still needs a checksum calc.
for x := range websocketGSTEUROrderbookUpdates {
err := k.wsHandleData([]byte(websocketGSTEUROrderbookUpdates[x]))
if err != nil {
t.Fatal(err)
}
}
}
func TestGetFuturesContractDetails(t *testing.T) {
t.Parallel()
_, err := k.GetFuturesContractDetails(context.Background(), asset.Spot)
if !errors.Is(err, futures.ErrNotFuturesAsset) {
t.Error(err)
}
_, err = k.GetFuturesContractDetails(context.Background(), asset.USDTMarginedFutures)
if !errors.Is(err, asset.ErrNotSupported) {
t.Error(err)
}
_, err = k.GetFuturesContractDetails(context.Background(), asset.Futures)
assert.NoError(t, err, "GetFuturesContractDetails should not error")
}
func TestGetLatestFundingRates(t *testing.T) {
t.Parallel()
_, err := k.GetLatestFundingRates(context.Background(), &fundingrate.LatestRateRequest{
Asset: asset.USDTMarginedFutures,
Pair: currency.NewPair(currency.BTC, currency.USD),
IncludePredictedRate: true,
})
if !errors.Is(err, asset.ErrNotSupported) {
t.Error(err)
}
_, err = k.GetLatestFundingRates(context.Background(), &fundingrate.LatestRateRequest{
Asset: asset.Futures,
})
if !errors.Is(err, nil) {
t.Error(err)
}
cp := currency.NewPair(currency.PF, currency.NewCode("XBTUSD"))
cp.Delimiter = "_"
err = k.CurrencyPairs.EnablePair(asset.Futures, cp)
if err != nil && !errors.Is(err, currency.ErrPairAlreadyEnabled) {
t.Fatal(err)
}
_, err = k.GetLatestFundingRates(context.Background(), &fundingrate.LatestRateRequest{
Asset: asset.Futures,
Pair: cp,
IncludePredictedRate: true,
})
if err != nil {
t.Error(err)
}
}
func TestIsPerpetualFutureCurrency(t *testing.T) {
t.Parallel()
is, err := k.IsPerpetualFutureCurrency(asset.Binary, currency.NewPair(currency.BTC, currency.USDT))
if err != nil {
t.Error(err)
}
if is {
t.Error("expected false")
}
is, err = k.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.BTC, currency.USDT))
if err != nil {
t.Error(err)
}
if is {
t.Error("expected false")
}
is, err = k.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.PF, currency.NewCode("XBTUSD")))
if err != nil {
t.Error(err)
}
if !is {
t.Error("expected true")
}
}
func TestGetOpenInterest(t *testing.T) {
t.Parallel()
_, err := k.GetOpenInterest(context.Background(), key.PairAsset{
Base: currency.ETH.Item,
Quote: currency.USDT.Item,
Asset: asset.USDTMarginedFutures,
})
assert.ErrorIs(t, err, asset.ErrNotSupported)
cp1 := currency.NewPair(currency.PF, currency.NewCode("ETHUSD"))
cp2 := currency.NewPair(currency.PF, currency.NewCode("XBTUSD"))
sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, k, asset.Futures, cp1, cp2)
resp, err := k.GetOpenInterest(context.Background(), key.PairAsset{
Base: cp1.Base.Item,
Quote: cp1.Quote.Item,
Asset: asset.Futures,
})
assert.NoError(t, err)
assert.NotEmpty(t, resp)
resp, err = k.GetOpenInterest(context.Background(),
key.PairAsset{
Base: cp1.Base.Item,
Quote: cp1.Quote.Item,
Asset: asset.Futures,
},
key.PairAsset{
Base: cp2.Base.Item,
Quote: cp2.Quote.Item,
Asset: asset.Futures,
})
assert.NoError(t, err)
assert.NotEmpty(t, resp)
resp, err = k.GetOpenInterest(context.Background())
assert.NoError(t, err)
assert.NotEmpty(t, resp)
}