mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-02 07:26:53 +00:00
* Bitstamp: Add auth channel subscription handling * Bitstamp: Avoid searching for asset type We've hardcoded asset.Spot in order to find the pair. Looking the asset up from the pair makes no sense. * Bitstamp: Add type for wsOrders * Bitstamp: Working test of Generic DataHandler * Bitstamp: WS Order chan tests and remove type orderType could be derived from status == New and Buy & price == 9+e9 or Sell & price == 0 But it would only be true for the first update and it really doesn't feel worth the risk Consumers are going to have to merge to original request anyway * Bitstamp: Linter fixes * Kraken: Switch to shared fixture test * Bitstamp: Fix lint on TestFixtureToDataHandler * Engine: Add Clone for PairsManager go-vet highlighted that the mutex here is a value when we copied the PairsManager in a test. Options to fix: * Add a deep clone method to PairsManager * Add a shallow clone method with a disclaimer * Make the mutex a pointer * Make the PairsManager itself a pointer Options 3 and 4 are too invasive to justify changing at this point. There's an inherent risk of PM being passed by value, but govet should catch the copylock. There's more risk in changing everything to use a pointer at this stage. * Engine: Fix linter again, ironically * Bitstamp: Rename OHLC const * Bitstamp: Minor fixes to syntax * Bitstamp: Simplify chanSymb=>pair * Bitstamp: Still process order updates without ID If there's a ClientOrderID we'll still process the order. It doesn't seem likely we'd have this happen, but if it does we still want consumers to get something. * Bitstamp: Replace Clone with Lock methods * Engine: Expose PairsManager's Mutex Makes more sense than wrapping functions * Bitstamp: Fix linter copylock (again) * fixup! Engine: Expose PairsManager's Mutex Omit Mutex from Json * fixup! Bitstamp: Add auth channel subscription handling Remove unused wsAuthToken * Bitstamp: Simplify OrderData Unmarshal * Bitstamp: Remove unused contexts I added these following best practices, but the reality is that when/if we get context awareness in GCT, there will be a lot more to fix and this will be a drop in the ocean anyway. * Bitstamp: Only call handleWSOrder for MyOrders * Bitstamp: Avoid allocating again in handleWSOrder * CurrencyPairs: Remove public mutex Simplified to a Load method to avoid making mutex public * Tests: Improve test readability and clarity * Bitstamp: Wrap errWSPairParsingError Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Bitstamp: FetchWSAuth mock and live test --------- Co-authored-by: Scott <gloriousCode@users.noreply.github.com>
2201 lines
58 KiB
Go
2201 lines
58 KiB
Go
package kraken
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
|
"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/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/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 TestStart(t *testing.T) {
|
|
t.Parallel()
|
|
err := k.Start(context.Background(), nil)
|
|
if !errors.Is(err, common.ErrNilPointer) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, common.ErrNilPointer)
|
|
}
|
|
var testWg sync.WaitGroup
|
|
err = k.Start(context.Background(), &testWg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
testWg.Wait()
|
|
}
|
|
|
|
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")
|
|
}
|
|
}
|
|
|
|
func TestUpdateOrderExecutionLimits(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type limitTest struct {
|
|
pair currency.Pair
|
|
step float64
|
|
min float64
|
|
}
|
|
|
|
tests := map[asset.Item][]limitTest{
|
|
asset.Spot: {
|
|
{currency.NewPair(currency.ETH, currency.USDT), 0.01, 0.01},
|
|
{currency.NewPair(currency.XBT, currency.USDT), 0.1, 0.0001},
|
|
},
|
|
}
|
|
|
|
for assetItem, limitTests := range tests {
|
|
if err := k.UpdateOrderExecutionLimits(context.Background(), assetItem); err != nil {
|
|
t.Errorf("Error fetching %s pairs for test: %v", assetItem, err)
|
|
}
|
|
|
|
for _, limitTest := range limitTests {
|
|
limits, err := k.GetOrderExecutionLimits(assetItem, limitTest.pair)
|
|
if err != nil {
|
|
t.Errorf("Kraken GetOrderExecutionLimits() error during TestExecutionLimits; Asset: %s Pair: %s Err: %v", assetItem, limitTest.pair, err)
|
|
continue
|
|
}
|
|
if got := limits.PriceStepIncrementSize; got != limitTest.step {
|
|
t.Errorf("Kraken UpdateOrderExecutionLimits wrong PriceStepIncrementSize; Asset: %s Pair: %s Expected: %v Got: %v", assetItem, limitTest.pair, limitTest.step, got)
|
|
}
|
|
|
|
if got := limits.MinimumBaseAmount; got != limitTest.min {
|
|
t.Errorf("Kraken UpdateOrderExecutionLimits wrong MinAmount; Pair: %s Expected: %v Got: %v", limitTest.pair, limitTest.min, got)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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()
|
|
err := k.UpdateTickers(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
err = k.UpdateTickers(context.Background(), asset.Futures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
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.WebsocketNotEnabled)
|
|
}
|
|
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([]stream.ChannelSubscription{
|
|
{
|
|
Channel: defaultSubscribedChannels[0],
|
|
Currency: 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{
|
|
{Price: 0.05005, Amount: 0.00000500},
|
|
{Price: 0.05010, Amount: 0.00000500},
|
|
{Price: 0.05015, Amount: 0.00000500},
|
|
{Price: 0.05020, Amount: 0.00000500},
|
|
{Price: 0.05025, Amount: 0.00000500},
|
|
{Price: 0.05030, Amount: 0.00000500},
|
|
{Price: 0.05035, Amount: 0.00000500},
|
|
{Price: 0.05040, Amount: 0.00000500},
|
|
{Price: 0.05045, Amount: 0.00000500},
|
|
{Price: 0.05050, Amount: 0.00000500},
|
|
},
|
|
Bids: []orderbook.Item{
|
|
{Price: 0.05000, Amount: 0.00000500},
|
|
{Price: 0.04995, Amount: 0.00000500},
|
|
{Price: 0.04990, Amount: 0.00000500},
|
|
{Price: 0.04980, Amount: 0.00000500},
|
|
{Price: 0.04975, Amount: 0.00000500},
|
|
{Price: 0.04970, Amount: 0.00000500},
|
|
{Price: 0.04965, Amount: 0.00000500},
|
|
{Price: 0.04960, Amount: 0.00000500},
|
|
{Price: 0.04955, Amount: 0.00000500},
|
|
{Price: 0.04950, Amount: 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, 5, 8)
|
|
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)
|
|
if !errors.Is(err, nil) {
|
|
t.Error(err)
|
|
}
|
|
}
|