mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-08 07:26:48 +00:00
* Websocket: Use ErrSubscribedAlready instead of errChannelAlreadySubscribed * Subscriptions: Replace Pair with Pairs Given that some subscriptions have multiple pairs, support that as the standard. * Docs: Update subscriptions in add new exch * RPC: Update Subscription Pairs * Linter: Disable testifylint.Len We deliberately use Equal over Len to avoid spamming the contents of large Slices * Websocket: Add suffix to state consts * Binance: Subscription Pairs support * Bitfinex: Subscription Pairs support * Bithumb: Subscription Pairs support * Bitmex: Subscription Pairs support * Bitstamp: Subscription Pairs support * BTCMarkets: Subscription Pairs support * BTSE: Subscription Pairs support * Coinbase: Subscription Pairs support * Coinut: Subscription Pairs support * GateIO: Subscription Pairs support * Gemini: Subscription Pairs support and improvement * Hitbtc: Subscription Pairs support * Huboi: Subscription Pairs support * Kucoin: Subscription Pairs support * Okcoin: Subscription Pairs support * Poloniex: Subscription Pairs support * Kraken: Add subscription Pairs support Note: This is a naieve implementation because we want to rebase the kraken websocket rewrite on top of this * Bybit: Subscription Pairs support * Okx: Subscription Pairs support * Bitmex: Subsription configuration * Fixes unauthenticated websocket left as CanUseAuth * Fixes auth subs happening privately * CoinbasePro: Subscription Configuration * Consolidate ProductIDs when all subscriptions are for the same list * Websocket: Log actual sent message when Verbose * Subscriptions: Improve clarity of which key is which in Match * Subscriptions: Lint fix for HugeParam * Subscriptions: Add AddPairs and move keys from test * Subscriptions: Simplify subscription keys and add key types * Subscriptions: Add List.GroupPairs Rename sub.AddPairs * Subscription: Fix ExactKey not matching 0 pairs * Subscriptions: Remove unused IdentityKey and HasPairKey * Subscriptions: Fix GetKey test * Subscriptions: Test coverage improvements * Websocket: Change State on Add/Remove * Subscriptions: Improve error context * Subscriptions: Fix Enable: false subs not ignored * Bitfinex: Fix WsAuth test failing on DataHandler DataHandler is eaten by dataMonitor now, so we need to use ToRoutine * Deribit: Subscription Pairs support * Websocket: Accept nil lists for checkSubscriptions If the user passes in a nil (implicitly empty) list, we would not panic. Therefore the burden of correctness about that data lies with them. The list of subscriptions is empty, and that's okay, and possibly convenient * Websocket: Add context to NilPointer errors * Subscriptions: Add context to nil errors * Exchange: Fix error expectations in UnsubToWSChans
2323 lines
64 KiB
Go
2323 lines
64 KiB
Go
package kraken
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"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/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"
|
|
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
|
|
"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
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
k = new(Kraken)
|
|
if err := testexch.Setup(k); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if apiKey != "" && apiSecret != "" {
|
|
k.API.AuthenticatedSupport = true
|
|
k.SetCredentials(apiKey, apiSecret, "", "", "", "")
|
|
}
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
func TestUpdateTradablePairs(t *testing.T) {
|
|
t.Parallel()
|
|
testexch.UpdatePairsOnce(t, k)
|
|
}
|
|
|
|
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()
|
|
k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
require.NoError(t, testexch.Setup(k), "Test instance Setup must not error")
|
|
testexch.UpdatePairsOnce(t, k)
|
|
err := k.UpdateTickers(context.Background(), asset.Spot)
|
|
require.NoError(t, err, "UpdateTickers must not error")
|
|
ap, err := k.GetAvailablePairs(asset.Spot)
|
|
require.NoError(t, err, "GetAvailablePairs must not error")
|
|
for i := range ap {
|
|
_, err = ticker.GetTicker(k.Name, ap[i], asset.Spot)
|
|
require.NoError(t, err, "GetTicker must not error")
|
|
}
|
|
ap, err = k.GetAvailablePairs(asset.Futures)
|
|
require.NoError(t, err, "GetAvailablePairs must not error")
|
|
err = k.UpdateTickers(context.Background(), asset.Futures)
|
|
require.NoError(t, err, "UpdateTickers must not error")
|
|
for i := range ap {
|
|
_, err = ticker.GetTicker(k.Name, ap[i], asset.Futures)
|
|
require.NoError(t, err, "GetTicker must not error")
|
|
}
|
|
|
|
err = k.UpdateTickers(context.Background(), asset.Index)
|
|
assert.ErrorIs(t, err, asset.ErrNotSupported, "UpdateTickers should error correctly on Index asset")
|
|
}
|
|
|
|
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.List{
|
|
{
|
|
Channel: defaultSubscribedChannels[0],
|
|
Pairs: currency.Pairs{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) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders)
|
|
testexch.SetupWs(t, k)
|
|
_, err := k.wsAddOrder(&WsAddOrderRequest{
|
|
OrderType: order.Limit.Lower(),
|
|
OrderSide: order.Buy.Lower(),
|
|
Pair: "XBT/USD",
|
|
Price: -100,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func mockWsCancelOrders(msg []byte, w *websocket.Conn) error {
|
|
var req WsCancelOrderRequest
|
|
if err := json.Unmarshal(msg, &req); err != nil {
|
|
return err
|
|
}
|
|
resp := WsCancelOrderResponse{
|
|
Event: krakenWsCancelOrderStatus,
|
|
Status: "ok",
|
|
RequestID: req.RequestID,
|
|
Count: int64(len(req.TransactionIDs)),
|
|
}
|
|
if len(req.TransactionIDs) == 0 || strings.Contains(req.TransactionIDs[0], "FISH") { // Reject anything that smells suspicious
|
|
resp.Status = "error"
|
|
resp.ErrorMessage = "[EOrder:Unknown order]"
|
|
}
|
|
respJSON, err := json.Marshal(resp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return w.WriteMessage(websocket.TextMessage, respJSON)
|
|
}
|
|
|
|
func TestWsCancelOrders(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
k := testexch.MockWsInstance[Kraken](t, curryWsMockUpgrader(t, mockWsCancelOrders)) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
require.True(t, k.IsWebsocketAuthenticationSupported(), "WS must be authenticated")
|
|
|
|
err := k.wsCancelOrders([]string{"RABBIT", "BATFISH", "SQUIRREL", "CATFISH", "MOUSE"})
|
|
assert.ErrorIs(t, err, errCancellingOrder, "Should error cancelling order")
|
|
assert.ErrorContains(t, err, "BATFISH", "Should error containing txn id")
|
|
assert.ErrorContains(t, err, "CATFISH", "Should error containing txn id")
|
|
assert.ErrorContains(t, err, "[EOrder:Unknown order]", "Should error containing server error")
|
|
|
|
err = k.wsCancelOrders([]string{"RABBIT", "SQUIRREL", "MOUSE"})
|
|
assert.NoError(t, err, "Should not error with valid ids")
|
|
}
|
|
|
|
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()
|
|
k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
require.NoError(t, testexch.Setup(k), "Test instance Setup must not error")
|
|
testexch.UpdatePairsOnce(t, k)
|
|
testexch.FixtureToDataHandler(t, "testdata/wsOpenTrades.json", k.wsHandleData)
|
|
close(k.Websocket.DataHandler)
|
|
assert.Len(t, k.Websocket.DataHandler, 7, "Should see 7 orders")
|
|
for resp := range k.Websocket.DataHandler {
|
|
switch v := resp.(type) {
|
|
case *order.Detail:
|
|
switch len(k.Websocket.DataHandler) {
|
|
case 6:
|
|
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 5:
|
|
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 4:
|
|
assert.Equal(t, "OKB55A-UEMMN-YUXM2A", v.OrderID, "OrderID")
|
|
assert.Equal(t, order.Open, v.Status, "order status")
|
|
case 3:
|
|
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 2:
|
|
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 1:
|
|
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 0:
|
|
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")
|
|
}
|
|
case error:
|
|
t.Error(v)
|
|
default:
|
|
t.Errorf("Unexpected type in DataHandler: %T (%s)", v, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
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 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.Tranche{
|
|
// 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.Tranche{
|
|
{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.Tranche 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)
|
|
}
|
|
|
|
// curryWsMockUpgrader handles Kraken specific http auth token responses prior to handling off to standard Websocket upgrader
|
|
func curryWsMockUpgrader(tb testing.TB, h testexch.WsMockFunc) http.HandlerFunc {
|
|
tb.Helper()
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if strings.Contains(r.URL.Path, "GetWebSocketsToken") {
|
|
_, err := w.Write([]byte(`{"result":{"token":"mockAuth"}}`))
|
|
require.NoError(tb, err, "Write should not error")
|
|
return
|
|
}
|
|
testexch.WsMockUpgrader(tb, w, r, h)
|
|
}
|
|
}
|
|
|
|
func TestGetCurrencyTradeURL(t *testing.T) {
|
|
t.Parallel()
|
|
testexch.UpdatePairsOnce(t, k)
|
|
for _, a := range k.GetAssetTypes(false) {
|
|
pairs, err := k.CurrencyPairs.GetPairs(a, false)
|
|
if len(pairs) == 0 {
|
|
continue
|
|
}
|
|
require.NoError(t, err, "cannot get pairs for %s", a)
|
|
resp, err := k.GetCurrencyTradeURL(context.Background(), a, pairs[0])
|
|
if a != asset.Spot && a != asset.Futures {
|
|
assert.ErrorIs(t, err, asset.ErrNotSupported)
|
|
continue
|
|
}
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
}
|
|
}
|