mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-22 15:10:13 +00:00
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
2285 lines
62 KiB
Go
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)
|
|
}
|