mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-07 15:11:03 +00:00
* Currency: Variadic Pairs.Add This version of Pairs.Add is simpler and [more performant](https://gist.github.com/gbjk/06a1fc1832d04ee41213ca518938cf74) Behavioural difference: If there's nothing to add, the same slice is returned unaltered. This seems like good sauce * Currency: Variadic Remove * Common: Add Batch function * Common: Add common.SortStrings for stringers * Subscriptions: Add batching to templates * Subscriptions: Sort list of pairs * Kucoin: Switch to sub templating * Kucoin: Simplify channel prefix usage * Kucoin: Fix race on fetchedFuturesOrderbook * Subscriptions: Filter AssetPairs Now only the assetPairs relevant to the subscription are in the context * Subscriptions: Respect subscription Pairs * Subscriptions: Trim AssetSeparator early We want to trim before checking for "AssetSeparator vs All" because a template should be allowed to reuse a range template and generate just one trailing AssetSeparator whilst using a specific Asset * Kucoin: Fix empty margin asset added * Kucoin: Add Subscription batching Turns out that contary to the documentation, kucoin supports batching of all symbols and currencies * Kucoin: Fix checkSubscriptions and coverage * Subscriptions: Simplify error checking This reduces the complexity of error checking to just be "do we get the correct numbers". Fixes Asset.All with only one asset erroring on xpandPairs, because we trimmed the only asset separator, and then errored that we're not xpanding Assets and the asset on the sub is asset.All This use-case conflicted with commit 6bbd546d74, which required: ``` Subscriptions: Trim AssetSeparator early We want to trim before checking for "AssetSeparator vs All" because a template should be allowed to reuse a range template and generate just one trailing AssetSeparator whilst using a specific Asset ``` Now we set up the assets earlier, and we remove the check for xpandAssets, since the number of asset lines matching is all that matters. I've removed the asset tests for this, but they were correctly erroring on the number of asset lines instead. Everything hits coverage, as well. * Kucoin: Remove deprecated fundingBook endpoint * BTCMarkets: Use common.Batch
2837 lines
102 KiB
Go
2837 lines
102 KiB
Go
package kucoin
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/common/key"
|
|
"github.com/thrasher-corp/gocryptotrader/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/margin"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
|
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
|
|
testsubs "github.com/thrasher-corp/gocryptotrader/internal/testing/subscriptions"
|
|
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
|
)
|
|
|
|
// Please supply your own keys here to do authenticated endpoint testing
|
|
const (
|
|
apiKey = ""
|
|
apiSecret = ""
|
|
passPhrase = ""
|
|
canManipulateRealOrders = false
|
|
)
|
|
|
|
var ku *Kucoin
|
|
var spotTradablePair, marginTradablePair, futuresTradablePair currency.Pair
|
|
|
|
func TestMain(m *testing.M) {
|
|
ku = new(Kucoin)
|
|
if err := testexch.Setup(ku); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if apiKey != "" && apiSecret != "" && passPhrase != "" {
|
|
ku.API.AuthenticatedSupport = true
|
|
ku.API.AuthenticatedWebsocketSupport = true
|
|
ku.API.CredentialsValidator.RequiresBase64DecodeSecret = false
|
|
ku.SetCredentials(apiKey, apiSecret, passPhrase, "", "", "")
|
|
ku.Websocket.SetCanUseAuthenticatedEndpoints(true)
|
|
}
|
|
|
|
getFirstTradablePairOfAssets()
|
|
ku.setupOrderbookManager()
|
|
fetchedFuturesOrderbook = map[string]bool{}
|
|
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
// Spot asset test cases starts from here
|
|
func TestGetSymbols(t *testing.T) {
|
|
t.Parallel()
|
|
symbols, err := ku.GetSymbols(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetSymbols() error", err)
|
|
}
|
|
assert.NotEmpty(t, symbols, "should return all available spot/margin symbols")
|
|
// Using market string reduces the scope of what is returned.
|
|
symbols, err = ku.GetSymbols(context.Background(), "ETF")
|
|
if err != nil {
|
|
t.Error("GetSymbols() error", err)
|
|
}
|
|
assert.NotEmpty(t, symbols, "should return all available ETF symbols")
|
|
}
|
|
|
|
func TestGetTicker(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetTicker(context.Background(), "BTC-USDT")
|
|
if err != nil {
|
|
t.Error("GetTicker() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAllTickers(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetTickers(context.Background())
|
|
if err != nil {
|
|
t.Error("GetAllTickers() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesTickers(t *testing.T) {
|
|
t.Parallel()
|
|
tickers, err := ku.GetFuturesTickers(context.Background())
|
|
assert.NoError(t, err, "GetFuturesTickers should not error")
|
|
for i := range tickers {
|
|
assert.Positive(t, tickers[i].Last, "Last should be positive")
|
|
assert.Positive(t, tickers[i].Bid, "Bid should be positive")
|
|
assert.Positive(t, tickers[i].Ask, "Ask should be positive")
|
|
assert.NotEmpty(t, tickers[i].Pair, "Pair should not be empty")
|
|
assert.NotEmpty(t, tickers[i].LastUpdated, "LastUpdated should not be empty")
|
|
assert.Equal(t, ku.Name, tickers[i].ExchangeName, "Exchange name should be correct")
|
|
assert.Equal(t, asset.Futures, tickers[i].AssetType, "Asset type should be correct")
|
|
}
|
|
}
|
|
|
|
func TestGet24hrStats(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.Get24hrStats(context.Background(), "BTC-USDT")
|
|
if err != nil {
|
|
t.Error("Get24hrStats() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarketList(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetMarketList(context.Background())
|
|
if err != nil {
|
|
t.Error("GetMarketList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetPartOrderbook20(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetPartOrderbook20(context.Background(), "BTC-USDT")
|
|
if err != nil {
|
|
t.Error("GetPartOrderbook20() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetPartOrderbook100(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetPartOrderbook100(context.Background(), "BTC-USDT")
|
|
if err != nil {
|
|
t.Error("GetPartOrderbook100() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetOrderbook(context.Background(), "BTC-USDT")
|
|
if err != nil {
|
|
t.Error("GetOrderbook() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTradeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetTradeHistory(context.Background(), "BTC-USDT")
|
|
if err != nil {
|
|
t.Error("GetTradeHistory() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetKlines(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetKlines(context.Background(), "BTC-USDT", "1week", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetKlines() error", err)
|
|
}
|
|
_, err = ku.GetKlines(context.Background(), "BTC-USDT", "5min", time.Now().Add(-time.Hour*1), time.Now())
|
|
if err != nil {
|
|
t.Error("GetKlines() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetCurrencies(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetCurrencies(context.Background())
|
|
if err != nil {
|
|
t.Error("GetCurrencies() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetCurrency(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetCurrencyDetail(context.Background(), "BTC", "")
|
|
if err != nil {
|
|
t.Error("GetCurrency() error", err)
|
|
}
|
|
|
|
_, err = ku.GetCurrencyDetail(context.Background(), "BTC", "ETH")
|
|
if err != nil {
|
|
t.Error("GetCurrency() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFiatPrice(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFiatPrice(context.Background(), "", "")
|
|
if err != nil {
|
|
t.Error("GetFiatPrice() error", err)
|
|
}
|
|
|
|
_, err = ku.GetFiatPrice(context.Background(), "EUR", "ETH,BTC")
|
|
if err != nil {
|
|
t.Error("GetFiatPrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarkPrice(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetMarkPrice(context.Background(), "USDT-BTC")
|
|
if err != nil {
|
|
t.Error("GetMarkPrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarginConfiguration(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetMarginConfiguration(context.Background())
|
|
if err != nil {
|
|
t.Error("GetMarginConfiguration() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarginAccount(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetMarginAccount(context.Background())
|
|
if err != nil {
|
|
t.Error("GetMarginAccount() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarginRiskLimit(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetMarginRiskLimit(context.Background(), "cross")
|
|
if err != nil {
|
|
t.Error("GetMarginRiskLimit() error", err)
|
|
}
|
|
|
|
_, err = ku.GetMarginRiskLimit(context.Background(), "isolated")
|
|
if err != nil {
|
|
t.Error("GetMarginRiskLimit() error", err)
|
|
}
|
|
}
|
|
|
|
func TestPostBorrowOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.PostBorrowOrder(context.Background(), "USDT", "FOK", "", 10, 0)
|
|
if err != nil {
|
|
t.Error("PostBorrowOrder() error", err)
|
|
}
|
|
|
|
_, err = ku.PostBorrowOrder(context.Background(), "USDT", "IOC", "7,14,28", 10, 0.05)
|
|
if err != nil {
|
|
t.Error("PostBorrowOrder() error", err)
|
|
}
|
|
}
|
|
|
|
const borrowOrderJSON = `{"orderId": "a2111213","currency": "USDT","size": "1.009","filled": 1.009,"matchList": [{"currency": "USDT","dailyIntRate": "0.001","size": "12.9","term": 7,"timestamp": "1544657947759","tradeId": "1212331"}],"status": "DONE"}`
|
|
|
|
func TestGetBorrowOrder(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *BorrowOrder
|
|
err := json.Unmarshal([]byte(borrowOrderJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetBorrowOrder(context.Background(), "orderID")
|
|
if err != nil {
|
|
t.Error("GetBorrowOrder() error", err)
|
|
}
|
|
}
|
|
|
|
const outstandingRecordResponseJSON = `{"currentPage": 0, "pageSize": 0, "totalNum": 0, "totalPage": 0, "items": [ { "tradeId": "1231141", "currency": "USDT", "accruedInterest": "0.22121", "dailyIntRate": "0.0021", "liability": "1.32121", "maturityTime": "1544657947759", "principal": "1.22121", "repaidSize": "0", "term": 7, "createdAt": "1544657947759" } ] }`
|
|
|
|
func TestGetOutstandingRecord(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *OutstandingRecordResponse
|
|
err := json.Unmarshal([]byte(outstandingRecordResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetOutstandingRecord(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetOutstandingRecord() error", err)
|
|
}
|
|
}
|
|
|
|
const repaidRecordJSON = `{"pageSize": 0, "totalNum": 0, "totalPage": 0, "currentPage": 0, "items": [ { "tradeId": "1231141", "currency": "USDT", "dailyIntRate": "0.0021", "interest": "0.22121", "principal": "1.22121", "repaidSize": "0", "repayTime": "1544657947759", "term": 7 } ] }`
|
|
|
|
func TestGetRepaidRecord(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *RepaidRecordsResponse
|
|
err := json.Unmarshal([]byte(repaidRecordJSON), &resp)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetRepaidRecord(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetRepaidRecord() error", err)
|
|
}
|
|
}
|
|
|
|
func TestOneClickRepayment(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.OneClickRepayment(context.Background(), "BTC", "RECENTLY_EXPIRE_FIRST", 2.5)
|
|
if err != nil {
|
|
t.Error("OneClickRepayment() error", err)
|
|
}
|
|
}
|
|
|
|
func TestSingleOrderRepayment(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.SingleOrderRepayment(context.Background(), "BTC", "fa3e34c980062c10dad74016", 2.5)
|
|
if err != nil {
|
|
t.Error("SingleOrderRepayment() error", err)
|
|
}
|
|
}
|
|
|
|
func TestPostLendOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.PostLendOrder(context.Background(), "BTC", 0.0001, 5, 7)
|
|
if err != nil {
|
|
t.Error("PostLendOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelLendOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.CancelLendOrder(context.Background(), "OrderID")
|
|
if err != nil {
|
|
t.Error("CancelLendOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestSetAutoLend(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.SetAutoLend(context.Background(), "BTC", 0.0002, 0.005, 7, true)
|
|
if err != nil {
|
|
t.Error("SetAutoLend() error", err)
|
|
}
|
|
}
|
|
|
|
const activeOrderResponseJSON = `[ { "orderId": "5da59f5ef943c033b2b643e4", "currency": "BTC", "size": "0.51", "filledSize": "0", "dailyIntRate": "0.0001", "term": 7, "createdAt": 1571135326913 } ]`
|
|
|
|
func TestGetActiveOrder(t *testing.T) {
|
|
t.Parallel()
|
|
var resp []LendOrder
|
|
err := json.Unmarshal([]byte(activeOrderResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetActiveOrder(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetActiveOrder() error", err)
|
|
}
|
|
|
|
_, err = ku.GetActiveOrder(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetActiveOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetLendHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetLendHistory(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetLendHistory() error", err)
|
|
}
|
|
_, err = ku.GetLendHistory(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetLendHistory() error", err)
|
|
}
|
|
}
|
|
|
|
const activeLentOrderResponseJSON = `[ { "tradeId": "5da6dba0f943c0c81f5d5db5", "currency": "BTC", "size": "0.51", "accruedInterest": "0", "repaid": "0.10999968", "dailyIntRate": "0.0001", "term": 14, "maturityTime": 1572425888958 } ]`
|
|
|
|
func TestGetUnsettleLendOrder(t *testing.T) {
|
|
t.Parallel()
|
|
var resp []UnsettleLendOrder
|
|
err := json.Unmarshal([]byte(activeLentOrderResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetUnsettledLendOrder(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetUnsettledLendOrder() error", err)
|
|
}
|
|
|
|
_, err = ku.GetUnsettledLendOrder(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetUnsettledLendOrder() error", err)
|
|
}
|
|
}
|
|
|
|
const settledLendOrderResponseJSON = `[{ "tradeId": "5da59fe6f943c033b2b6440b", "currency": "BTC", "size": "0.51", "interest": "0.00004899", "repaid": "0.510041641", "dailyIntRate": "0.0001", "term": 7, "settledAt": 1571216254767, "note": "The account of the borrowers reached a negative balance, and the system has supplemented the loss via the insurance fund. Deposit funds: 0.51." } ]`
|
|
|
|
func TestGetSettleLendOrder(t *testing.T) {
|
|
t.Parallel()
|
|
var resp []SettleLendOrder
|
|
err := json.Unmarshal([]byte(settledLendOrderResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetSettledLendOrder(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetSettledLendOrder() error", err)
|
|
}
|
|
_, err = ku.GetSettledLendOrder(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetSettledLendOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccountLendRecord(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetAccountLendRecord(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetAccountLendRecord() error", err)
|
|
}
|
|
_, err = ku.GetAccountLendRecord(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetAccountLendRecord() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetLendingMarketData(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetLendingMarketData(context.Background(), "BTC", 0)
|
|
if err != nil {
|
|
t.Error("GetLendingMarketData() error", err)
|
|
}
|
|
_, err = ku.GetLendingMarketData(context.Background(), "BTC", 7)
|
|
if err != nil {
|
|
t.Error("GetLendingMarketData() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarginTradeData(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetMarginTradeData(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetMarginTradeData() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetIsolatedMarginPairConfig(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetIsolatedMarginPairConfig(context.Background())
|
|
if err != nil {
|
|
t.Error("GetIsolatedMarginPairConfig() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetIsolatedMarginAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetIsolatedMarginAccountInfo(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetIsolatedMarginAccountInfo() error", err)
|
|
}
|
|
_, err = ku.GetIsolatedMarginAccountInfo(context.Background(), "USDT")
|
|
if err != nil {
|
|
t.Error("GetIsolatedMarginAccountInfo() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetSingleIsolatedMarginAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetSingleIsolatedMarginAccountInfo(context.Background(), "BTC-USDT")
|
|
if err != nil {
|
|
t.Error("GetSingleIsolatedMarginAccountInfo() error", err)
|
|
}
|
|
}
|
|
|
|
func TestInitiateIsolateMarginBorrowing(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.InitiateIsolatedMarginBorrowing(context.Background(), "BTC-USDT", "USDT", "FOK", "", 10, 0)
|
|
if err != nil {
|
|
t.Error("InitiateIsolateMarginBorrowing() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetIsolatedOutstandingRepaymentRecords(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetIsolatedOutstandingRepaymentRecords(context.Background(), "", "", 0, 0)
|
|
if err != nil {
|
|
t.Error("GetIsolatedOutstandingRepaymentRecords() error", err)
|
|
}
|
|
_, err = ku.GetIsolatedOutstandingRepaymentRecords(context.Background(), "BTC-USDT", "USDT", 0, 0)
|
|
if err != nil {
|
|
t.Error("GetIsolatedOutstandingRepaymentRecords() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetIsolatedMarginRepaymentRecords(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetIsolatedMarginRepaymentRecords(context.Background(), "", "", 0, 0)
|
|
if err != nil {
|
|
t.Error("GetIsolatedMarginRepaymentRecords() error", err)
|
|
}
|
|
_, err = ku.GetIsolatedMarginRepaymentRecords(context.Background(), "BTC-USDT", "USDT", 0, 0)
|
|
if err != nil {
|
|
t.Error("GetIsolatedMarginRepaymentRecords() error", err)
|
|
}
|
|
}
|
|
|
|
func TestInitiateIsolatedMarginQuickRepayment(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.InitiateIsolatedMarginQuickRepayment(context.Background(), "BTC-USDT", "USDT", "RECENTLY_EXPIRE_FIRST", 10)
|
|
if err != nil {
|
|
t.Error("InitiateIsolatedMarginQuickRepayment() error", err)
|
|
}
|
|
}
|
|
|
|
func TestInitiateIsolatedMarginSingleRepayment(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.InitiateIsolatedMarginSingleRepayment(context.Background(), "BTC-USDT", "USDT", "628c570f7818320001d52b69", 10)
|
|
if err != nil {
|
|
t.Error("InitiateIsolatedMarginSingleRepayment() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetCurrentServerTime(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetCurrentServerTime(context.Background())
|
|
if err != nil {
|
|
t.Error("GetCurrentServerTime() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetServiceStatus(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetServiceStatus(context.Background())
|
|
if err != nil {
|
|
t.Error("GetServiceStatus() error", err)
|
|
}
|
|
}
|
|
|
|
func TestPostOrder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// default order type is limit
|
|
_, err := ku.PostOrder(context.Background(), &SpotOrderParam{
|
|
ClientOrderID: ""})
|
|
if !errors.Is(err, errInvalidClientOrderID) {
|
|
t.Errorf("PostOrder() expected %v, but found %v", errInvalidClientOrderID, err)
|
|
}
|
|
|
|
customID, err := uuid.NewV4()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = ku.PostOrder(context.Background(), &SpotOrderParam{
|
|
ClientOrderID: customID.String(), Symbol: spotTradablePair,
|
|
OrderType: ""})
|
|
if !errors.Is(err, order.ErrSideIsInvalid) {
|
|
t.Errorf("PostOrder() expected %v, but found %v", order.ErrSideIsInvalid, err)
|
|
}
|
|
_, err = ku.PostOrder(context.Background(), &SpotOrderParam{
|
|
ClientOrderID: customID.String(), Symbol: currency.EMPTYPAIR,
|
|
Size: 0.1, Side: "buy", Price: 234565})
|
|
if !errors.Is(err, currency.ErrCurrencyPairEmpty) {
|
|
t.Errorf("PostOrder() expected %v, but found %v", currency.ErrCurrencyPairEmpty, err)
|
|
}
|
|
_, err = ku.PostOrder(context.Background(), &SpotOrderParam{
|
|
ClientOrderID: customID.String(), Side: "buy",
|
|
Symbol: spotTradablePair,
|
|
OrderType: "limit", Size: 0.1})
|
|
if !errors.Is(err, errInvalidPrice) {
|
|
t.Errorf("PostOrder() expected %v, but found %v", errInvalidPrice, err)
|
|
}
|
|
_, err = ku.PostOrder(context.Background(), &SpotOrderParam{
|
|
ClientOrderID: customID.String(), Symbol: spotTradablePair, Side: "buy",
|
|
OrderType: "limit", Price: 234565})
|
|
if !errors.Is(err, errInvalidSize) {
|
|
t.Errorf("PostOrder() expected %v, but found %v", errInvalidSize, err)
|
|
}
|
|
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err = ku.PostOrder(context.Background(), &SpotOrderParam{
|
|
ClientOrderID: customID.String(),
|
|
Side: "buy",
|
|
Symbol: spotTradablePair,
|
|
OrderType: "limit",
|
|
Size: 0.005,
|
|
Price: 1000})
|
|
if err != nil {
|
|
t.Error("PostOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestPostMarginOrder(t *testing.T) {
|
|
t.Parallel()
|
|
// default order type is limit
|
|
_, err := ku.PostMarginOrder(context.Background(), &MarginOrderParam{
|
|
ClientOrderID: ""})
|
|
if !errors.Is(err, errInvalidClientOrderID) {
|
|
t.Errorf("PostMarginOrder() expected %v, but found %v", errInvalidClientOrderID, err)
|
|
}
|
|
_, err = ku.PostMarginOrder(context.Background(), &MarginOrderParam{
|
|
ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: marginTradablePair,
|
|
OrderType: ""})
|
|
if !errors.Is(err, order.ErrSideIsInvalid) {
|
|
t.Errorf("PostMarginOrder() expected %v, but found %v", order.ErrSideIsInvalid, err)
|
|
}
|
|
_, err = ku.PostMarginOrder(context.Background(), &MarginOrderParam{
|
|
ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: currency.EMPTYPAIR,
|
|
Size: 0.1, Side: "buy", Price: 234565})
|
|
if !errors.Is(err, currency.ErrCurrencyPairEmpty) {
|
|
t.Errorf("PostMarginOrder() expected %v, but found %v", currency.ErrCurrencyPairEmpty, err)
|
|
}
|
|
_, err = ku.PostMarginOrder(context.Background(), &MarginOrderParam{
|
|
ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy",
|
|
Symbol: marginTradablePair,
|
|
OrderType: "limit", Size: 0.1})
|
|
if !errors.Is(err, errInvalidPrice) {
|
|
t.Errorf("PostMarginOrder() expected %v, but found %v", errInvalidPrice, err)
|
|
}
|
|
_, err = ku.PostMarginOrder(context.Background(), &MarginOrderParam{
|
|
ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: marginTradablePair, Side: "buy",
|
|
OrderType: "limit", Price: 234565})
|
|
if !errors.Is(err, errInvalidSize) {
|
|
t.Errorf("PostMarginOrder() expected %v, but found %v", errInvalidSize, err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
// default order type is limit and margin mode is cross
|
|
_, err = ku.PostMarginOrder(context.Background(),
|
|
&MarginOrderParam{
|
|
ClientOrderID: "5bd6e9286d99522a52e458de",
|
|
Side: "buy", Symbol: marginTradablePair,
|
|
Price: 1000, Size: 0.1, PostOnly: true})
|
|
if err != nil {
|
|
t.Error("PostMarginOrder() error", err)
|
|
}
|
|
|
|
// market isolated order
|
|
_, err = ku.PostMarginOrder(context.Background(),
|
|
&MarginOrderParam{
|
|
ClientOrderID: "5bd6e9286d99522a52e458de",
|
|
Side: "buy", Symbol: marginTradablePair,
|
|
OrderType: "market", Funds: 1234,
|
|
Remark: "remark", MarginMode: "cross", Price: 1000, PostOnly: true, AutoBorrow: true})
|
|
if err != nil {
|
|
t.Error("PostMarginOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestPostBulkOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
|
|
req := []OrderRequest{
|
|
{
|
|
ClientOID: "3d07008668054da6b3cb12e432c2b13a",
|
|
Side: "buy",
|
|
Type: "limit",
|
|
Price: 1000,
|
|
Size: 0.01,
|
|
},
|
|
{
|
|
ClientOID: "37245dbe6e134b5c97732bfb36cd4a9d",
|
|
Side: "buy",
|
|
Type: "limit",
|
|
Price: 1000,
|
|
Size: 0.01,
|
|
},
|
|
}
|
|
|
|
_, err := ku.PostBulkOrder(context.Background(), "BTC-USDT", req)
|
|
if err != nil {
|
|
t.Error("PostBulkOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelSingleOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
|
|
_, err := ku.CancelSingleOrder(context.Background(), "5bd6e9286d99522a52e458de")
|
|
if err != nil {
|
|
t.Error("CancelSingleOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelOrderByClientOID(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
|
|
_, err := ku.CancelOrderByClientOID(context.Background(), "5bd6e9286d99522a52e458de")
|
|
if err != nil {
|
|
t.Error("CancelOrderByClientOID() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
|
|
_, err := ku.CancelAllOpenOrders(context.Background(), "", "")
|
|
if err != nil {
|
|
t.Error("CancelAllOpenOrders() error", err)
|
|
}
|
|
}
|
|
|
|
const ordersListResponseJSON = `{"currentPage": 1, "pageSize": 1, "totalNum": 153408, "totalPage": 153408, "items": [ { "id": "5c35c02703aa673ceec2a168", "symbol": "BTC-USDT", "opType": "DEAL", "type": "limit", "side": "buy", "price": "10", "size": "2", "funds": "0", "dealFunds": "0.166", "dealSize": "2", "fee": "0", "feeCurrency": "USDT", "stp": "", "stop": "", "stopTriggered": false, "stopPrice": "0", "timeInForce": "GTC", "postOnly": false, "hidden": false, "iceberg": false, "visibleSize": "0", "cancelAfter": 0, "channel": "IOS", "clientOid": "", "remark": "", "tags": "", "isActive": false, "cancelExist": false, "createdAt": 1547026471000, "tradeType": "TRADE" } ] }`
|
|
|
|
func TestGetOrders(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *OrdersListResponse
|
|
err := json.Unmarshal([]byte(ordersListResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err = ku.ListOrders(context.Background(), "", "", "", "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetRecentOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetRecentOrders(context.Background())
|
|
if err != nil {
|
|
t.Error("GetRecentOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderByID(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetOrderByID(context.Background(), "5c35c02703aa673ceec2a168")
|
|
if err != nil {
|
|
t.Error("GetOrderByID() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderByClientOID(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetOrderByClientSuppliedOrderID(context.Background(), "6d539dc614db312")
|
|
if err != nil {
|
|
t.Error("GetOrderByClientOID() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFills(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFills(context.Background(), "", "", "", "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFills() error", err)
|
|
}
|
|
_, err = ku.GetFills(context.Background(), "5c35c02703aa673ceec2a168", "BTC-USDT", "buy", "limit", "TRADE", time.Now().Add(-time.Hour*12), time.Now())
|
|
if err != nil {
|
|
t.Error("GetFills() error", err)
|
|
}
|
|
}
|
|
|
|
const limitFillsResponseJSON = `[{ "counterOrderId":"5db7ee769797cf0008e3beea", "createdAt":1572335233000, "fee":"0.946357371456", "feeCurrency":"USDT", "feeRate":"0.001", "forceTaker":true, "funds":"946.357371456", "liquidity":"taker", "orderId":"5db7ee805d53620008dce1ba", "price":"9466.8", "side":"buy", "size":"0.09996592", "stop":"", "symbol":"BTC-USDT", "tradeId":"5db7ee8054c05c0008069e21", "tradeType":"MARGIN_TRADE", "type":"market" }, { "counterOrderId":"5db7ee4b5d53620008dcde8e", "createdAt":1572335207000, "fee":"0.94625", "feeCurrency":"USDT", "feeRate":"0.001", "forceTaker":true, "funds":"946.25", "liquidity":"taker", "orderId":"5db7ee675d53620008dce01e", "price":"9462.5", "side":"sell", "size":"0.1", "stop":"", "symbol":"BTC-USDT", "tradeId":"5db7ee6754c05c0008069e03", "tradeType":"MARGIN_TRADE", "type":"market" }]`
|
|
|
|
func TestGetRecentFills(t *testing.T) {
|
|
t.Parallel()
|
|
var resp []Fill
|
|
err := json.Unmarshal([]byte(limitFillsResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetRecentFills(context.Background())
|
|
if err != nil {
|
|
t.Error("GetRecentFills() error", err)
|
|
}
|
|
}
|
|
|
|
func TestPostStopOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.PostStopOrder(context.Background(), "5bd6e9286d99522a52e458de", "buy", "BTC-USDT", "", "", "entry", "CO", "TRADE", "", 0.1, 1, 10, 0, 0, 0, true, false, false)
|
|
if err != nil {
|
|
t.Error("PostStopOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelStopOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.CancelStopOrder(context.Background(), "5bd6e9286d99522a52e458de")
|
|
if err != nil {
|
|
t.Error("CancelStopOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllStopOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.CancelStopOrders(context.Background(), "", "", "")
|
|
if err != nil {
|
|
t.Error("CancelAllStopOrder() error", err)
|
|
}
|
|
}
|
|
|
|
const stopOrderResponseJSON = `{"id": "vs8hoo8q2ceshiue003b67c0", "symbol": "KCS-USDT", "userId": "60fe4956c43cbc0006562c2c", "status": "NEW", "type": "limit", "side": "buy", "price": "0.01000000000000000000", "size": "0.01000000000000000000", "funds": null, "stp": null, "timeInForce": "GTC", "cancelAfter": -1, "postOnly": false, "hidden": false, "iceberg": false, "visibleSize": null, "channel": "API", "clientOid": "40e0eb9efe6311eb8e58acde48001122", "remark": null, "tags": null, "orderTime": 1629098781127530345, "domainId": "kucoin", "tradeSource": "USER", "tradeType": "TRADE", "feeCurrency": "USDT", "takerFeeRate": "0.00200000000000000000", "makerFeeRate": "0.00200000000000000000", "createdAt": 1629098781128, "stop": "loss", "stopTriggerTime": null, "stopPrice": "10.00000000000000000000" }`
|
|
|
|
func TestGetStopOrder(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *StopOrder
|
|
err := json.Unmarshal([]byte(stopOrderResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetStopOrder(context.Background(), "5bd6e9286d99522a52e458de")
|
|
if err != nil {
|
|
t.Error("GetStopOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAllStopOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.ListStopOrders(context.Background(), "", "", "", "", "", time.Time{}, time.Time{}, 0, 0)
|
|
if err != nil {
|
|
t.Error("GetAllStopOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetStopOrderByClientID(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetStopOrderByClientID(context.Background(), "", "5bd6e9286d99522a52e458de")
|
|
if err != nil {
|
|
t.Error("GetStopOrderByClientID() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelStopOrderByClientID(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.CancelStopOrderByClientID(context.Background(), "", "5bd6e9286d99522a52e458de")
|
|
if err != nil {
|
|
t.Error("CancelStopOrderByClientID() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAllAccounts(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err := ku.GetAllAccounts(context.Background(), "", "")
|
|
if err != nil {
|
|
t.Error("GetAllAccounts() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccount(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err := ku.GetAccount(context.Background(), "62fcd1969474ea0001fd20e4")
|
|
if err != nil {
|
|
t.Error("GetAccount() error", err)
|
|
}
|
|
}
|
|
|
|
const accountLedgerResponseJSON = `{"currentPage": 1, "pageSize": 50, "totalNum": 2, "totalPage": 1, "items": [ { "id": "611a1e7c6a053300067a88d9", "currency": "USDT", "amount": "10.00059547", "fee": "0", "balance": "0", "accountType": "MAIN", "bizType": "Loans Repaid", "direction": "in", "createdAt": 1629101692950, "context": "{\"borrowerUserId\":\"601ad03e50dc810006d242ea\",\"loanRepayDetailNo\":\"611a1e7cc913d000066cf7ec\"}" }, { "id": "611a18bc6a0533000671e1bf", "currency": "USDT", "amount": "10.00059547", "fee": "0", "balance": "0", "accountType": "MAIN", "bizType": "Loans Repaid", "direction": "in", "createdAt": 1629100220843, "context": "{\"borrowerUserId\":\"5e3f4623dbf52d000800292f\",\"loanRepayDetailNo\":\"611a18bc7255c200063ea545\"}" } ] }`
|
|
|
|
func TestGetAccountLedgers(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *AccountLedgerResponse
|
|
err := json.Unmarshal([]byte(accountLedgerResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetAccountLedgers(context.Background(), "", "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetAccountLedgers() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccountSummaryInformation(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetAccountSummaryInformation(context.Background()); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetSubAccountBalance(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetSubAccountBalance(context.Background(), "62fcd1969474ea0001fd20e4", false)
|
|
if err != nil {
|
|
t.Error("GetSubAccountBalance() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAggregatedSubAccountBalance(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetAggregatedSubAccountBalance(context.Background())
|
|
if err != nil {
|
|
t.Error("GetAggregatedSubAccountBalance() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetPaginatedSubAccountInformation(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetPaginatedSubAccountInformation(context.Background(), 0, 10)
|
|
if err != nil {
|
|
t.Error("GetPaginatedSubAccountInformation() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTransferableBalance(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err := ku.GetTransferableBalance(context.Background(), "BTC", "MAIN", "")
|
|
if err != nil {
|
|
t.Error("GetTransferableBalance() error", err)
|
|
}
|
|
}
|
|
|
|
func TestTransferMainToSubAccount(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.TransferMainToSubAccount(context.Background(), "62fcd1969474ea0001fd20e4", "BTC", "1", "OUT", "", "", "5caefba7d9575a0688f83c45")
|
|
if err != nil {
|
|
t.Error("TransferMainToSubAccount() error", err)
|
|
}
|
|
}
|
|
|
|
func TestMakeInnerTransfer(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.MakeInnerTransfer(context.Background(), "62fcd1969474ea0001fd20e4", "BTC", "trade", "main", "1", "", "")
|
|
if err != nil {
|
|
t.Error("MakeInnerTransfer() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCreateDepositAddress(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.CreateDepositAddress(context.Background(), "BTC", "")
|
|
if err != nil {
|
|
t.Error("CreateDepositAddress() error", err)
|
|
}
|
|
|
|
_, err = ku.CreateDepositAddress(context.Background(), "USDT", "TRC20")
|
|
if err != nil {
|
|
t.Error("CreateDepositAddress() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetDepositAddressV2(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetDepositAddressesV2(context.Background(), "BTC")
|
|
if err != nil {
|
|
t.Error("GetDepositAddressV2() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetDepositAddressesV1(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetDepositAddressV1(context.Background(), "BTC", "")
|
|
if err != nil {
|
|
t.Error("GetDepositAddressV1() error", err)
|
|
}
|
|
}
|
|
|
|
const depositResponseJSON = `{"currentPage": 1, "pageSize": 50, "totalNum": 1, "totalPage": 1, "items": [ { "currency": "XRP", "chain": "xrp", "status": "SUCCESS", "address": "rNFugeoj3ZN8Wv6xhuLegUBBPXKCyWLRkB", "memo": "1919537769", "isInner": false, "amount": "20.50000000", "fee": "0.00000000", "walletTxId": "2C24A6D5B3E7D5B6AA6534025B9B107AC910309A98825BF5581E25BEC94AD83B@e8902757998fc352e6c9d8890d18a71c", "createdAt": 1666600519000, "updatedAt": 1666600549000, "remark": "Deposit" } ] }`
|
|
|
|
func TestGetDepositList(t *testing.T) {
|
|
t.Parallel()
|
|
var resp DepositResponse
|
|
err := json.Unmarshal([]byte(depositResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetDepositList(context.Background(), "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetDepositList() error", err)
|
|
}
|
|
}
|
|
|
|
const historicalDepositResponseJSON = `{"currentPage":1, "pageSize":1, "totalNum":9, "totalPage":9, "items":[ { "currency":"BTC", "createAt":1528536998, "amount":"0.03266638", "walletTxId":"55c643bc2c68d6f17266383ac1be9e454038864b929ae7cee0bc408cc5c869e8@12ffGWmMMD1zA1WbFm7Ho3JZ1w6NYXjpFk@234", "isInner":false, "status":"SUCCESS" } ] }`
|
|
|
|
func TestGetHistoricalDepositList(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *HistoricalDepositWithdrawalResponse
|
|
err := json.Unmarshal([]byte(historicalDepositResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err = ku.GetHistoricalDepositList(context.Background(), "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetHistoricalDepositList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetWithdrawalList(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err := ku.GetWithdrawalList(context.Background(), "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetWithdrawalList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricalWithdrawalList(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err := ku.GetHistoricalWithdrawalList(context.Background(), "", "", time.Time{}, time.Time{}, 0, 0)
|
|
if err != nil {
|
|
t.Error("GetHistoricalWithdrawalList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetWithdrawalQuotas(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err := ku.GetWithdrawalQuotas(context.Background(), "BTC", "")
|
|
if err != nil {
|
|
t.Error("GetWithdrawalQuotas() error", err)
|
|
}
|
|
}
|
|
|
|
func TestApplyWithdrawal(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.ApplyWithdrawal(context.Background(), "ETH", "0x597873884BC3a6C10cB6Eb7C69172028Fa85B25A", "", "", "", "", false, 1)
|
|
if err != nil {
|
|
t.Error("ApplyWithdrawal() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelWithdrawal(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.CancelWithdrawal(context.Background(), "5bffb63303aa675e8bbe18f9")
|
|
if err != nil {
|
|
t.Error("CancelWithdrawal() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetBasicFee(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetBasicFee(context.Background(), "1")
|
|
if err != nil {
|
|
t.Error("GetBasicFee() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTradingFee(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := ku.GetTradingFee(context.Background(), nil)
|
|
if !errors.Is(err, currency.ErrCurrencyPairsEmpty) {
|
|
t.Fatalf("received %v, expected %v", err, currency.ErrCurrencyPairsEmpty)
|
|
}
|
|
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
avail, err := ku.GetAvailablePairs(asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pairs := currency.Pairs{avail[0]}
|
|
btcusdTradingFee, err := ku.GetTradingFee(context.Background(), pairs)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received %v, expected %v", err, nil)
|
|
}
|
|
|
|
if len(btcusdTradingFee) != 1 {
|
|
t.Error("GetTradingFee() error, expected 1 pair")
|
|
}
|
|
|
|
// NOTE: Test below will error out from an external call as this will exceed
|
|
// the allowed pairs. If this does not error then this endpoint will allow
|
|
// more items to be requested.
|
|
pairs = append(pairs, avail[1:11]...)
|
|
_, err = ku.GetTradingFee(context.Background(), pairs)
|
|
if errors.Is(err, nil) {
|
|
t.Fatalf("received %v, expected %v", err, "code: 200000 message: symbols size invalid.")
|
|
}
|
|
|
|
got, err := ku.GetTradingFee(context.Background(), pairs[:10])
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received %v, expected %v", err, nil)
|
|
}
|
|
|
|
if len(got) != 10 {
|
|
t.Error("GetTradingFee() error, expected 10 pairs")
|
|
}
|
|
}
|
|
|
|
// futures
|
|
func TestGetFuturesOpenContracts(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesOpenContracts(context.Background())
|
|
if err != nil {
|
|
t.Error("GetFuturesOpenContracts() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesContract(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesContract(context.Background(), "XBTUSDTM")
|
|
if err != nil {
|
|
t.Error("GetFuturesContract() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesTicker(t *testing.T) {
|
|
t.Parallel()
|
|
tick, err := ku.GetFuturesTicker(context.Background(), "XBTUSDTM")
|
|
if assert.NoError(t, err, "GetFuturesTicker should not error") {
|
|
assert.Positive(t, tick.Sequence, "Sequence should be positive")
|
|
assert.Equal(t, "XBTUSDTM", tick.Symbol, "Symbol should be correct")
|
|
assert.Contains(t, []order.Side{order.Buy, order.Sell}, tick.Side, "Side should be a side")
|
|
assert.Positive(t, tick.Size, "Size should be positive")
|
|
assert.Positive(t, tick.Price.Float64(), "Price should be positive")
|
|
assert.Positive(t, tick.BestBidPrice.Float64(), "BestBidPrice should be positive")
|
|
assert.Positive(t, tick.BestBidSize, "BestBidSize should be positive")
|
|
assert.Positive(t, tick.BestAskPrice.Float64(), "BestAskPrice should be positive")
|
|
assert.Positive(t, tick.BestAskSize, "BestAskSize should be positive")
|
|
assert.NotEmpty(t, tick.TradeID, "TradeID should not be empty")
|
|
assert.WithinRange(t, tick.FilledTime.Time(), time.Now().Add(time.Hour*-24), time.Now(), "FilledTime should be within last 24 hours")
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesOrderbook(context.Background(), futuresTradablePair.String())
|
|
if err != nil {
|
|
t.Error("GetFuturesOrderbook() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesPartOrderbook20(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesPartOrderbook20(context.Background(), "XBTUSDTM")
|
|
if err != nil {
|
|
t.Error("GetFuturesPartOrderbook20() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesPartOrderbook100(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesPartOrderbook100(context.Background(), "XBTUSDTM")
|
|
if err != nil {
|
|
t.Error("GetFuturesPartOrderbook100() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesTradeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesTradeHistory(context.Background(), "XBTUSDTM")
|
|
if err != nil {
|
|
t.Error("GetFuturesTradeHistory() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesInterestRate(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesInterestRate(context.Background(), "XBTUSDTM", time.Time{}, time.Time{}, false, false, 0, 0)
|
|
if err != nil {
|
|
t.Error("GetFuturesInterestRate() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesIndexList(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesIndexList(context.Background(), futuresTradablePair.String(), time.Time{}, time.Time{}, false, false, 0, 10)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesCurrentMarkPrice(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesCurrentMarkPrice(context.Background(), "XBTUSDTM")
|
|
if err != nil {
|
|
t.Error("GetFuturesCurrentMarkPrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesPremiumIndex(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesPremiumIndex(context.Background(), "XBTUSDTM", time.Time{}, time.Time{}, false, false, 0, 0)
|
|
if err != nil {
|
|
t.Error("GetFuturesPremiumIndex() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesCurrentFundingRate(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesCurrentFundingRate(context.Background(), "XBTUSDTM")
|
|
if err != nil {
|
|
t.Error("GetFuturesCurrentFundingRate() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesServerTime(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesServerTime(context.Background())
|
|
if err != nil {
|
|
t.Error("GetFuturesServerTime() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesServiceStatus(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesServiceStatus(context.Background())
|
|
if err != nil {
|
|
t.Error("GetFuturesServiceStatus() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesKline(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesKline(context.Background(), int64(kline.ThirtyMin.Duration().Minutes()), "XBTUSDTM", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesKline() error", err)
|
|
}
|
|
}
|
|
|
|
func TestPostFuturesOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de"})
|
|
if !errors.Is(err, errInvalidLeverage) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidLeverage, err)
|
|
}
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{Side: "buy", Leverage: 0.02})
|
|
if !errors.Is(err, errInvalidClientOrderID) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidClientOrderID, err)
|
|
}
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Leverage: 0.02})
|
|
if !errors.Is(err, order.ErrSideIsInvalid) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", order.ErrSideIsInvalid, err)
|
|
}
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Leverage: 0.02})
|
|
if !errors.Is(err, currency.ErrCurrencyPairEmpty) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", currency.ErrCurrencyPairEmpty, err)
|
|
}
|
|
|
|
// With Stop order configuration
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10",
|
|
Stop: "up", StopPriceType: "", TimeInForce: "", Size: 1, Price: 1000, StopPrice: 0, Leverage: 0.02, VisibleSize: 0})
|
|
if !errors.Is(err, errInvalidStopPriceType) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidStopPriceType, err)
|
|
}
|
|
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10",
|
|
Stop: "up", StopPriceType: "TP", TimeInForce: "", Size: 1, Price: 1000, StopPrice: 0, Leverage: 0.02, VisibleSize: 0})
|
|
if !errors.Is(err, errInvalidPrice) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidPrice, err)
|
|
}
|
|
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10",
|
|
Stop: "up", StopPriceType: "TP", StopPrice: 123456, TimeInForce: "", Size: 1, Price: 1000, Leverage: 0.02, VisibleSize: 0})
|
|
if err != nil {
|
|
t.Errorf("PostFuturesOrder expected %v", err)
|
|
}
|
|
|
|
// Limit Orders
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair,
|
|
OrderType: "limit", Remark: "10", Leverage: 0.02})
|
|
if !errors.Is(err, errInvalidPrice) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidPrice, err)
|
|
}
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Price: 1000, Leverage: 0.02, VisibleSize: 0})
|
|
if !errors.Is(err, errInvalidSize) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidSize, err)
|
|
}
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10",
|
|
Size: 1, Price: 1000, Leverage: 0.02, VisibleSize: 0})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// Market Orders
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair,
|
|
OrderType: "market", Remark: "10", Leverage: 0.02})
|
|
if !errors.Is(err, errInvalidSize) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidSize, err)
|
|
}
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "market", Remark: "10",
|
|
Size: 1, Leverage: 0.02, VisibleSize: 0})
|
|
if !errors.Is(err, errInvalidSize) {
|
|
t.Errorf("PostFuturesOrder expected %v, but found %v", errInvalidSize, err)
|
|
}
|
|
|
|
_, err = ku.PostFuturesOrder(context.Background(), &FuturesOrderParam{
|
|
ClientOrderID: "5bd6e9286d99522a52e458de",
|
|
Side: "buy",
|
|
Symbol: futuresTradablePair,
|
|
OrderType: "limit",
|
|
Remark: "10",
|
|
Stop: "",
|
|
StopPriceType: "",
|
|
TimeInForce: "",
|
|
Size: 1,
|
|
Price: 1000,
|
|
StopPrice: 0,
|
|
Leverage: 0.02,
|
|
VisibleSize: 0})
|
|
if err != nil {
|
|
t.Error("PostFuturesOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelFuturesOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
|
|
_, err := ku.CancelFuturesOrder(context.Background(), "5bd6e9286d99522a52e458de")
|
|
if err != nil {
|
|
t.Error("CancelFuturesOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllFuturesOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
|
|
_, err := ku.CancelAllFuturesOpenOrders(context.Background(), "XBTUSDM")
|
|
if err != nil {
|
|
t.Error("CancelAllFuturesOpenOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllFuturesStopOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.CancelAllFuturesStopOrders(context.Background(), "XBTUSDM")
|
|
if err != nil {
|
|
t.Error("CancelAllFuturesStopOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesOrders(context.Background(), "", "", "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetUntriggeredFuturesStopOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetUntriggeredFuturesStopOrders(context.Background(), "", "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetUntriggeredFuturesStopOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesRecentCompletedOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesRecentCompletedOrders(context.Background())
|
|
if err != nil {
|
|
t.Error("GetFuturesRecentCompletedOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesOrderDetails(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesOrderDetails(context.Background(), "5cdfc138b21023a909e5ad55")
|
|
if err != nil {
|
|
t.Error("GetFuturesOrderDetails() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesOrderDetailsByClientID(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesOrderDetailsByClientID(context.Background(), "eresc138b21023a909e5ad59")
|
|
if err != nil {
|
|
t.Error("GetFuturesOrderDetailsByClientID() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesFills(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesFills(context.Background(), "", "", "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesFills() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesRecentFills(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesRecentFills(context.Background())
|
|
if err != nil {
|
|
t.Error("GetFuturesRecentFills() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesOpenOrderStats(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesOpenOrderStats(context.Background(), "XBTUSDM")
|
|
if err != nil {
|
|
t.Error("GetFuturesOpenOrderStats() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesPosition(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesPosition(context.Background(), "XBTUSDM")
|
|
if err != nil {
|
|
t.Error("GetFuturesPosition() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesPositionList(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesPositionList(context.Background())
|
|
if err != nil {
|
|
t.Error("GetFuturesPositionList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestSetAutoDepositMargin(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.SetAutoDepositMargin(context.Background(), "ADAUSDTM", true)
|
|
if err != nil {
|
|
t.Error("SetAutoDepositMargin() error", err)
|
|
}
|
|
}
|
|
|
|
func TestAddMargin(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.AddMargin(context.Background(), "XBTUSDTM", "6200c9b83aecfb000152dasfdee", 1)
|
|
if err != nil {
|
|
t.Error("AddMargin() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesRiskLimitLevel(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
|
|
_, err := ku.GetFuturesRiskLimitLevel(context.Background(), "ADAUSDTM")
|
|
if err != nil {
|
|
t.Error("GetFuturesRiskLimitLevel() error", err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateRiskLmitLevel(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.FuturesUpdateRiskLmitLevel(context.Background(), "ADASUDTM", 2)
|
|
if err != nil {
|
|
t.Error("UpdateRiskLmitLevel() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesFundingHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesFundingHistory(context.Background(), futuresTradablePair.String(), 0, 0, true, true, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesFundingHistory() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesAccountOverview(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesAccountOverview(context.Background(), "")
|
|
if err != nil {
|
|
t.Error("GetFuturesAccountOverview() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesTransactionHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesTransactionHistory(context.Background(), "", "", 0, 0, true, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesTransactionHistory() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCreateFuturesSubAccountAPIKey(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err := ku.CreateFuturesSubAccountAPIKey(context.Background(), "", "passphrase", "", "remark", "subAccName")
|
|
if err != nil {
|
|
t.Error("CreateFuturesSubAccountAPIKey() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesDepositAddress(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesDepositAddress(context.Background(), "XBT")
|
|
if err != nil {
|
|
t.Error("GetFuturesDepositAddress() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesDepositsList(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesDepositsList(context.Background(), "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesDepositsList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesWithdrawalLimit(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesWithdrawalLimit(context.Background(), "XBT")
|
|
if err != nil {
|
|
t.Error("GetFuturesWithdrawalLimit() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesWithdrawalList(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesWithdrawalList(context.Background(), "", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesWithdrawalList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelFuturesWithdrawal(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
|
|
_, err := ku.CancelFuturesWithdrawal(context.Background(), "5cda659603aa67131f305f7e")
|
|
if err != nil {
|
|
t.Error("CancelFuturesWithdrawal() error", err)
|
|
}
|
|
}
|
|
|
|
func TestTransferFuturesFundsToMainAccount(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *TransferRes
|
|
err := json.Unmarshal([]byte(transferFuturesFundsResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
_, err = ku.TransferFuturesFundsToMainAccount(context.Background(), 1, "USDT", "MAIN")
|
|
if err != nil {
|
|
t.Error("TransferFuturesFundsToMainAccount() error", err)
|
|
}
|
|
}
|
|
|
|
func TestTransferFundsToFuturesAccount(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.TransferFundsToFuturesAccount(context.Background(), 1, "USDT", "MAIN")
|
|
if err != nil {
|
|
t.Error("TransferFundsToFuturesAccount() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesTransferOutList(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetFuturesTransferOutList(context.Background(), "USDT", "", time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("GetFuturesTransferOutList() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelFuturesTransferOut(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
err := ku.CancelFuturesTransferOut(context.Background(), "5cd53be30c19fc3754b60928")
|
|
if err != nil {
|
|
t.Error("CancelFuturesTransferOut() error", err)
|
|
}
|
|
}
|
|
|
|
func TestFetchTradablePairs(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.FetchTradablePairs(context.Background(), asset.Futures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.FetchTradablePairs(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.FetchTradablePairs(context.Background(), asset.Margin)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
if _, err := ku.UpdateOrderbook(context.Background(), futuresTradablePair, asset.Futures); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.UpdateOrderbook(context.Background(), marginTradablePair, asset.Margin); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.UpdateOrderbook(context.Background(), spotTradablePair, asset.Spot); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
func TestUpdateTickers(t *testing.T) {
|
|
t.Parallel()
|
|
for _, a := range ku.GetAssetTypes(true) {
|
|
err := ku.UpdateTickers(context.Background(), a)
|
|
assert.NoError(t, err, "UpdateTickers should not error")
|
|
pairs, err := ku.GetEnabledPairs(a)
|
|
assert.NoError(t, err, "GetEnabledPairs should not error")
|
|
for _, p := range pairs {
|
|
tick, err := ticker.GetTicker(ku.Name, p, a)
|
|
if assert.NoError(t, err, "GetTicker %s %s should not error", a, p) {
|
|
assert.Positive(t, tick.Last, "%s %s Tick Last should be positive", a, p)
|
|
assert.NotEmpty(t, tick.Pair, "%s %s Tick Pair should not be empty", a, p)
|
|
assert.Equal(t, ku.Name, tick.ExchangeName, "ExchangeName should be correct")
|
|
assert.Equal(t, a, tick.AssetType, "AssetType should be correct")
|
|
assert.NotEmpty(t, tick.LastUpdated, "%s %s Tick LastUpdated should not be empty", a, p)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
func TestUpdateTicker(t *testing.T) {
|
|
t.Parallel()
|
|
var err error
|
|
_, err = ku.UpdateTicker(context.Background(), spotTradablePair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.UpdateTicker(context.Background(), marginTradablePair, asset.Margin)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.UpdateTicker(context.Background(), futuresTradablePair, asset.Futures)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestFetchTicker(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.FetchTicker(context.Background(), spotTradablePair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err = ku.FetchTicker(context.Background(), marginTradablePair, asset.Margin); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err = ku.FetchTicker(context.Background(), futuresTradablePair, asset.Futures); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFetchOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
if _, err := ku.FetchOrderbook(context.Background(), spotTradablePair, asset.Spot); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.FetchOrderbook(context.Background(), marginTradablePair, asset.Margin); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.FetchOrderbook(context.Background(), futuresTradablePair, asset.Futures); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandles(t *testing.T) {
|
|
startTime := time.Now().Add(-time.Hour * 48)
|
|
endTime := time.Now().Add(-time.Hour * 3)
|
|
var err error
|
|
_, err = ku.GetHistoricCandles(context.Background(), futuresTradablePair, asset.Futures, kline.OneHour, startTime, endTime)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.GetHistoricCandles(context.Background(), spotTradablePair, asset.Spot, kline.OneHour, startTime, time.Now())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.GetHistoricCandles(context.Background(), marginTradablePair, asset.Margin, kline.OneHour, startTime, time.Now())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandlesExtended(t *testing.T) {
|
|
startTime := time.Now().Add(-time.Hour * 48)
|
|
endTime := time.Now().Add(-time.Hour * 1)
|
|
var err error
|
|
_, err = ku.GetHistoricCandlesExtended(context.Background(), spotTradablePair, asset.Spot, kline.OneHour, startTime, endTime)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.GetHistoricCandlesExtended(context.Background(), spotTradablePair, asset.Spot, kline.FiveMin, startTime, endTime)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.GetHistoricCandlesExtended(context.Background(), marginTradablePair, asset.Margin, kline.OneHour, startTime, endTime)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.GetHistoricCandlesExtended(context.Background(), futuresTradablePair, asset.Futures, kline.FiveMin, startTime, endTime)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetServerTime(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetServerTime(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.GetServerTime(context.Background(), asset.Futures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.GetServerTime(context.Background(), asset.Margin)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetRecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetRecentTrades(context.Background(), futuresTradablePair, asset.Futures)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.GetRecentTrades(context.Background(), spotTradablePair, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.GetRecentTrades(context.Background(), marginTradablePair, asset.Margin)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
var enabledPairs currency.Pairs
|
|
var getOrdersRequest order.MultiOrderRequest
|
|
var err error
|
|
enabledPairs, err = ku.GetEnabledPairs(asset.Futures)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.Limit,
|
|
Pairs: append([]currency.Pair{currency.NewPair(currency.BTC, currency.USDT)}, enabledPairs[:3]...),
|
|
AssetType: asset.Futures,
|
|
Side: order.AnySide,
|
|
}
|
|
_, err = ku.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
getOrdersRequest.Pairs = []currency.Pair{}
|
|
_, err = ku.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.Limit,
|
|
Pairs: []currency.Pair{spotTradablePair},
|
|
AssetType: asset.Spot,
|
|
Side: order.Sell,
|
|
}
|
|
_, err = ku.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
getOrdersRequest.Pairs = []currency.Pair{}
|
|
_, err = ku.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
getOrdersRequest.AssetType = asset.Margin
|
|
getOrdersRequest.Pairs = currency.Pairs{marginTradablePair}
|
|
_, err = ku.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
var getOrdersRequest order.MultiOrderRequest
|
|
var enabledPairs currency.Pairs
|
|
var err error
|
|
enabledPairs, err = ku.GetEnabledPairs(asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.Limit,
|
|
Pairs: enabledPairs,
|
|
AssetType: asset.Spot,
|
|
Side: order.Buy,
|
|
}
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Pairs = []currency.Pair{}
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Type = order.Market
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Type = order.OCO
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); !errors.Is(err, order.ErrUnsupportedOrderType) {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
enabledPairs, err = ku.GetEnabledPairs(asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.Limit,
|
|
Pairs: enabledPairs,
|
|
AssetType: asset.Margin,
|
|
Side: order.Buy,
|
|
}
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Pairs = []currency.Pair{}
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Type = order.Market
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Type = order.OCO
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); !errors.Is(err, order.ErrUnsupportedOrderType) {
|
|
t.Errorf("expected %v, but found %v", order.ErrUnsupportedOrderType, err)
|
|
}
|
|
enabledPairs, err = ku.GetEnabledPairs(asset.Futures)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.Limit,
|
|
Pairs: enabledPairs,
|
|
AssetType: asset.Futures,
|
|
Side: order.Buy,
|
|
}
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Pairs = []currency.Pair{}
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Type = order.StopLimit
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); err != nil {
|
|
t.Error("Kucoin GetActiveOrders() error", err)
|
|
}
|
|
getOrdersRequest.Type = order.OCO
|
|
if _, err = ku.GetActiveOrders(context.Background(), &getOrdersRequest); !errors.Is(err, order.ErrUnsupportedOrderType) {
|
|
t.Errorf("expected %v, but found %v", order.ErrUnsupportedOrderType, err)
|
|
}
|
|
}
|
|
|
|
func TestGetFeeByType(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetFeeByType(context.Background(), &exchange.FeeBuilder{
|
|
Amount: 1,
|
|
FeeType: exchange.CryptocurrencyTradeFee,
|
|
Pair: currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), currency.DashDelimiter),
|
|
PurchasePrice: 1,
|
|
FiatCurrency: currency.USD,
|
|
BankTransactionType: exchange.WireTransfer,
|
|
}); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestValidateCredentials(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
assetTypes := ku.CurrencyPairs.GetAssetTypes(true)
|
|
for _, at := range assetTypes {
|
|
if err := ku.ValidateCredentials(context.Background(), at); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetInstanceServers(t *testing.T) {
|
|
t.Parallel()
|
|
if _, err := ku.GetInstanceServers(context.Background()); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAuthenticatedServersInstances(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetAuthenticatedInstanceServers(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestPushData(t *testing.T) {
|
|
t.Parallel()
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
testexch.FixtureToDataHandler(t, "testdata/wsHandleData.json", ku.wsHandleData)
|
|
}
|
|
|
|
func TestGenerateSubscriptions(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
|
|
// Pairs overlap for spot/margin tests:
|
|
// Only in Spot: BTC-USDT, ETH-USDT
|
|
// In Both: ETH-BTC, LTC-USDT
|
|
// Only in Margin: TRX-BTC, SOL-USDC
|
|
subPairs := currency.Pairs{}
|
|
for _, pp := range [][]string{
|
|
{"BTC", "USDT", "-"}, {"ETH", "BTC", "-"}, {"ETH", "USDT", "-"}, {"LTC", "USDT", "-"}, // Spot
|
|
{"ETH", "BTC", "-"}, {"LTC", "USDT", "-"}, {"SOL", "USDC", "-"}, {"TRX", "BTC", "-"}, // Margin
|
|
{"ETH", "USDCM", ""}, {"SOL", "USDTM", ""}, {"XBT", "USDCM", ""}, // Futures
|
|
} {
|
|
subPairs = append(subPairs, currency.NewPairWithDelimiter(pp[0], pp[1], pp[2]))
|
|
}
|
|
|
|
exp := subscription.List{
|
|
{Channel: subscription.TickerChannel, Asset: asset.Spot, Pairs: subPairs[0:4], QualifiedChannel: "/market/ticker:" + subPairs[0:4].Join()},
|
|
{Channel: subscription.TickerChannel, Asset: asset.Margin, Pairs: subPairs[6:8], QualifiedChannel: "/market/ticker:" + subPairs[6:8].Join()},
|
|
{Channel: subscription.TickerChannel, Asset: asset.Futures, Pairs: subPairs[8:], QualifiedChannel: "/contractMarket/tickerV2:" + subPairs[8:].Join()},
|
|
{Channel: subscription.OrderbookChannel, Asset: asset.Spot, Pairs: subPairs[0:4], QualifiedChannel: "/spotMarket/level2Depth5:" + subPairs[0:4].Join(),
|
|
Interval: kline.HundredMilliseconds},
|
|
{Channel: subscription.OrderbookChannel, Asset: asset.Margin, Pairs: subPairs[6:8], QualifiedChannel: "/spotMarket/level2Depth5:" + subPairs[6:8].Join(),
|
|
Interval: kline.HundredMilliseconds},
|
|
{Channel: subscription.OrderbookChannel, Asset: asset.Futures, Pairs: subPairs[8:], QualifiedChannel: "/contractMarket/level2Depth5:" + subPairs[8:].Join(),
|
|
Interval: kline.HundredMilliseconds},
|
|
{Channel: subscription.AllTradesChannel, Asset: asset.Spot, Pairs: subPairs[0:4], QualifiedChannel: "/market/match:" + subPairs[0:4].Join()},
|
|
{Channel: subscription.AllTradesChannel, Asset: asset.Margin, Pairs: subPairs[6:8], QualifiedChannel: "/market/match:" + subPairs[6:8].Join()},
|
|
}
|
|
|
|
subs, err := ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions must not error")
|
|
testsubs.EqualLists(t, exp, subs)
|
|
|
|
ku.Websocket.SetCanUseAuthenticatedEndpoints(true)
|
|
|
|
var loanPairs currency.Pairs
|
|
loanCurrs := common.SortStrings(subPairs[0:8].GetCurrencies())
|
|
for _, c := range loanCurrs {
|
|
loanPairs = append(loanPairs, currency.Pair{Base: c})
|
|
}
|
|
|
|
exp = append(exp, subscription.List{
|
|
{Asset: asset.Futures, Channel: futuresTradeOrderChannel, QualifiedChannel: "/contractMarket/tradeOrders", Pairs: subPairs[8:]},
|
|
{Asset: asset.Futures, Channel: futuresStopOrdersLifecycleEventChannel, QualifiedChannel: "/contractMarket/advancedOrders", Pairs: subPairs[8:]},
|
|
{Asset: asset.Futures, Channel: futuresAccountBalanceEventChannel, QualifiedChannel: "/contractAccount/wallet", Pairs: subPairs[8:]},
|
|
{Asset: asset.Margin, Channel: marginPositionChannel, QualifiedChannel: "/margin/position", Pairs: subPairs[4:8]},
|
|
{Asset: asset.Margin, Channel: marginLoanChannel, QualifiedChannel: "/margin/loan:" + loanCurrs.Join(), Pairs: loanPairs},
|
|
{Channel: accountBalanceChannel, QualifiedChannel: "/account/balance"},
|
|
}...)
|
|
|
|
subs, err = ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions with Auth must not error")
|
|
testsubs.EqualLists(t, exp, subs)
|
|
}
|
|
|
|
func TestGenerateTickerAllSub(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
avail, err := ku.GetAvailablePairs(asset.Spot)
|
|
require.NoError(t, err, "GetAvailablePairs must not error")
|
|
for i := 0; i <= 10; i++ {
|
|
err = ku.CurrencyPairs.EnablePair(asset.Spot, avail[i])
|
|
require.NoError(t, common.ExcludeError(err, currency.ErrPairAlreadyEnabled), "EnablePair must not error")
|
|
}
|
|
|
|
enabled, err := ku.GetEnabledPairs(asset.Spot)
|
|
require.NoError(t, err, "GetEnabledPairs must not error")
|
|
|
|
ku.Features.Subscriptions = subscription.List{{Channel: subscription.TickerChannel, Asset: asset.Spot}}
|
|
exp := subscription.List{
|
|
{Channel: subscription.TickerChannel, Asset: asset.Spot, QualifiedChannel: "/market/ticker:all", Pairs: enabled},
|
|
}
|
|
subs, err := ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions with Auth must not error")
|
|
testsubs.EqualLists(t, exp, subs)
|
|
}
|
|
|
|
// TestGenerateOtherSubscriptions exercises non-default subscriptions
|
|
func TestGenerateOtherSubscriptions(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
|
|
subs := subscription.List{
|
|
{Channel: subscription.CandlesChannel, Asset: asset.Spot, Interval: kline.FourHour},
|
|
{Channel: marketSnapshotChannel, Asset: asset.Spot},
|
|
}
|
|
|
|
for _, s := range subs {
|
|
ku.Features.Subscriptions = subscription.List{s}
|
|
got, err := ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions should not error")
|
|
require.Len(t, got, 1, "Should generate just one sub")
|
|
assert.NotEmpty(t, got[0].QualifiedChannel, "Qualified Channel should not be empty")
|
|
if got[0].Channel == subscription.CandlesChannel {
|
|
assert.Equal(t, "/market/candles:BTC-USDT_4hour,ETH-BTC_4hour,ETH-USDT_4hour,LTC-USDT_4hour", got[0].QualifiedChannel, "QualifiedChannel should be correct")
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestCheckSubscriptions ensures checkSubscriptions upgrades user config correctly
|
|
func TestCheckSubscriptions(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := &Kucoin{ //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
Base: exchange.Base{
|
|
Config: &config.Exchange{
|
|
Features: &config.FeaturesConfig{
|
|
Subscriptions: subscription.List{
|
|
{Enabled: true, Channel: "ticker"},
|
|
{Enabled: true, Channel: "allTrades"},
|
|
{Enabled: true, Channel: "orderbook", Interval: kline.HundredMilliseconds},
|
|
{Enabled: true, Channel: "/contractMarket/tickerV2:%s"},
|
|
{Enabled: true, Channel: "/contractMarket/level2Depth50:%s"},
|
|
{Enabled: true, Channel: "/margin/fundingBook:%s", Authenticated: true},
|
|
{Enabled: true, Channel: "/account/balance", Authenticated: true},
|
|
{Enabled: true, Channel: "/margin/position", Authenticated: true},
|
|
{Enabled: true, Channel: "/margin/loan:%s", Authenticated: true},
|
|
{Enabled: true, Channel: "/contractMarket/tradeOrders", Authenticated: true},
|
|
{Enabled: true, Channel: "/contractMarket/advancedOrders", Authenticated: true},
|
|
{Enabled: true, Channel: "/contractAccount/wallet", Authenticated: true},
|
|
},
|
|
},
|
|
},
|
|
Features: exchange.Features{},
|
|
},
|
|
}
|
|
|
|
ku.checkSubscriptions()
|
|
testsubs.EqualLists(t, defaultSubscriptions, ku.Features.Subscriptions)
|
|
testsubs.EqualLists(t, defaultSubscriptions, ku.Config.Features.Subscriptions)
|
|
}
|
|
|
|
func TestGetAvailableTransferChains(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetAvailableTransferChains(context.Background(), currency.BTC); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetWithdrawalsHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetWithdrawalsHistory(context.Background(), currency.BTC, asset.Futures); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.GetWithdrawalsHistory(context.Background(), currency.BTC, asset.Spot); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.GetWithdrawalsHistory(context.Background(), currency.BTC, asset.Margin); !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
var err error
|
|
_, err = ku.GetOrderInfo(context.Background(), "123", futuresTradablePair, asset.Futures)
|
|
if err != nil {
|
|
t.Errorf("expected %s, but found %v", "Order does not exist", err)
|
|
}
|
|
_, err = ku.GetOrderInfo(context.Background(), "123", futuresTradablePair, asset.Spot)
|
|
if err != nil {
|
|
t.Errorf("expected %s, but found %v", "Order does not exist", err)
|
|
}
|
|
_, err = ku.GetOrderInfo(context.Background(), "123", futuresTradablePair, asset.Margin)
|
|
if err != nil {
|
|
t.Errorf("expected %s, but found %v", "Order does not exist", err)
|
|
}
|
|
}
|
|
|
|
func TestGetDepositAddress(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetDepositAddress(context.Background(), currency.BTC, "", ""); err != nil && !errors.Is(err, errNoDepositAddress) {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWithdrawCryptocurrencyFunds(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
withdrawCryptoRequest := withdraw.Request{
|
|
Exchange: ku.Name,
|
|
Amount: 0.00000000001,
|
|
Currency: currency.BTC,
|
|
Crypto: withdraw.CryptoRequest{
|
|
Address: core.BitcoinDonationAddress,
|
|
},
|
|
}
|
|
if _, err := ku.WithdrawCryptocurrencyFunds(context.Background(), &withdrawCryptoRequest); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestSubmitOrder(t *testing.T) {
|
|
t.Parallel()
|
|
orderSubmission := &order.Submit{
|
|
Pair: spotTradablePair,
|
|
Exchange: ku.Name,
|
|
Side: order.Bid,
|
|
Type: order.Limit,
|
|
Price: 1,
|
|
Amount: 100000,
|
|
ClientOrderID: "myOrder",
|
|
AssetType: asset.Spot,
|
|
}
|
|
orderSubmission.AssetType = asset.Options
|
|
_, err := ku.SubmitOrder(context.Background(), orderSubmission)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Errorf("expected %v, but found %v", asset.ErrNotSupported, err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
orderSubmission.AssetType = asset.Spot
|
|
orderSubmission.Side = order.Buy
|
|
orderSubmission.Pair = spotTradablePair
|
|
_, err = ku.SubmitOrder(context.Background(), orderSubmission)
|
|
if err != order.ErrTypeIsInvalid {
|
|
t.Errorf("expected %v, but found %v", order.ErrTypeIsInvalid, err)
|
|
}
|
|
orderSubmission.AssetType = asset.Spot
|
|
orderSubmission.Pair = spotTradablePair
|
|
_, err = ku.SubmitOrder(context.Background(), orderSubmission)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
orderSubmission.AssetType = asset.Margin
|
|
orderSubmission.Pair = marginTradablePair
|
|
_, err = ku.SubmitOrder(context.Background(), orderSubmission)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
orderSubmission.AssetType = asset.Margin
|
|
orderSubmission.Pair = marginTradablePair
|
|
orderSubmission.MarginType = margin.Isolated
|
|
_, err = ku.SubmitOrder(context.Background(), orderSubmission)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
orderSubmission.AssetType = asset.Futures
|
|
orderSubmission.Pair = futuresTradablePair
|
|
_, err = ku.SubmitOrder(context.Background(), orderSubmission)
|
|
if !errors.Is(err, errInvalidLeverage) {
|
|
t.Error(err)
|
|
}
|
|
orderSubmission.Leverage = 0.01
|
|
_, err = ku.SubmitOrder(context.Background(), orderSubmission)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
var orderCancellation = &order.Cancel{
|
|
OrderID: "1",
|
|
WalletAddress: core.BitcoinDonationAddress,
|
|
AccountID: "1",
|
|
Pair: spotTradablePair,
|
|
AssetType: asset.Spot,
|
|
}
|
|
if err := ku.CancelOrder(context.Background(), orderCancellation); err != nil {
|
|
t.Error(err)
|
|
}
|
|
orderCancellation.Pair = marginTradablePair
|
|
orderCancellation.AssetType = asset.Margin
|
|
if err := ku.CancelOrder(context.Background(), orderCancellation); err != nil {
|
|
t.Error(err)
|
|
}
|
|
orderCancellation.Pair = futuresTradablePair
|
|
orderCancellation.AssetType = asset.Futures
|
|
if err := ku.CancelOrder(context.Background(), orderCancellation); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
if _, err := ku.CancelAllOrders(context.Background(), &order.Cancel{
|
|
AssetType: asset.Futures,
|
|
MarginType: margin.Isolated,
|
|
}); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.CancelAllOrders(context.Background(), &order.Cancel{
|
|
AssetType: asset.Margin,
|
|
MarginType: margin.Isolated,
|
|
}); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if _, err := ku.CancelAllOrders(context.Background(), &order.Cancel{
|
|
AssetType: asset.Spot,
|
|
MarginType: margin.Isolated,
|
|
}); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
const (
|
|
subUserResponseJSON = `{"userId":"635002438793b80001dcc8b3", "uid":62356, "subName":"margin01", "status":2, "type":4, "access":"Margin", "createdAt":1666187844000, "remarks":null }`
|
|
positionSettlementPushData = `{"userId": "xbc453tg732eba53a88ggyt8c", "topic": "/contract/position:XBTUSDM", "subject": "position.settlement", "data": { "fundingTime": 1551770400000, "qty": 100, "markPrice": 3610.85, "fundingRate": -0.002966, "fundingFee": -296, "ts": 1547697294838004923, "settleCurrency": "XBT" } }`
|
|
transferFuturesFundsResponseJSON = `{"applyId": "620a0bbefeaa6a000110e833", "bizNo": "620a0bbefeaa6a000110e832", "payAccountType": "CONTRACT", "payTag": "DEFAULT", "remark": "", "recAccountType": "MAIN", "recTag": "DEFAULT", "recRemark": "", "recSystem": "KUCOIN", "status": "PROCESSING", "currency": "USDT", "amount": "0.001", "fee": "0", "sn": 889048787670001, "reason": "", "createdAt": 1644825534000, "updatedAt": 1644825534000 }`
|
|
modifySubAccountSpotAPIs = `{"subName": "AAAAAAAAAA0007", "remark": "remark", "apiKey": "630325e0e750870001829864", "apiSecret": "110f31fc-61c5-4baf-a29f-3f19a62bbf5d", "passphrase": "passphrase", "permission": "General", "ipWhitelist": "", "createdAt": 1661150688000 }`
|
|
)
|
|
|
|
func TestCreateSubUser(t *testing.T) {
|
|
t.Parallel()
|
|
var resp *SubAccount
|
|
err := json.Unmarshal([]byte(subUserResponseJSON), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
if _, err := ku.CreateSubUser(context.Background(), "SamuaelTee1", "sdfajdlkad", "", ""); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetSubAccountSpotAPIList(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetSubAccountSpotAPIList(context.Background(), "sam", ""); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCreateSpotAPIsForSubAccount(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
if _, err := ku.CreateSpotAPIsForSubAccount(context.Background(), &SpotAPISubAccountParams{
|
|
SubAccountName: "gocryptoTrader1",
|
|
Passphrase: "mysecretPassphrase123",
|
|
Remark: "123456",
|
|
}); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestModifySubAccountSpotAPIs(t *testing.T) {
|
|
t.Parallel()
|
|
var resp SpotAPISubAccount
|
|
err := json.Unmarshal([]byte(modifySubAccountSpotAPIs), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
if _, err := ku.ModifySubAccountSpotAPIs(context.Background(), &SpotAPISubAccountParams{
|
|
SubAccountName: "gocryptoTrader1",
|
|
Passphrase: "mysecretPassphrase123",
|
|
Remark: "123456",
|
|
}); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteSubAccountSpotAPI(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
if _, err := ku.DeleteSubAccountSpotAPI(context.Background(), apiKey, "mysecretPassphrase123", "gocryptoTrader1"); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetUserInfoOfAllSubAccounts(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetUserInfoOfAllSubAccounts(context.Background()); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetPaginatedListOfSubAccounts(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
if _, err := ku.GetPaginatedListOfSubAccounts(context.Background(), 1, 100); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFundingHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.GetAccountFundingHistory(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func getFirstTradablePairOfAssets() {
|
|
if err := ku.UpdateTradablePairs(context.Background(), true); err != nil {
|
|
log.Fatalf("Kucoin error while updating tradable pairs. %v", err)
|
|
}
|
|
enabledPairs, err := ku.GetEnabledPairs(asset.Spot)
|
|
if err != nil {
|
|
log.Fatalf("Kucoin %v, trying to get %v enabled pairs error", err, asset.Spot)
|
|
}
|
|
spotTradablePair = enabledPairs[0]
|
|
enabledPairs, err = ku.GetEnabledPairs(asset.Margin)
|
|
if err != nil {
|
|
log.Fatalf("Kucoin %v, trying to get %v enabled pairs error", err, asset.Margin)
|
|
}
|
|
marginTradablePair = enabledPairs[0]
|
|
enabledPairs, err = ku.GetEnabledPairs(asset.Futures)
|
|
if err != nil {
|
|
log.Fatalf("Kucoin %v, trying to get %v enabled pairs error", err, asset.Futures)
|
|
}
|
|
futuresTradablePair = enabledPairs[0]
|
|
futuresTradablePair.Delimiter = ""
|
|
}
|
|
|
|
func TestFetchAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
var err error
|
|
_, err = ku.FetchAccountInfo(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.FetchAccountInfo(context.Background(), asset.Margin)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = ku.FetchAccountInfo(context.Background(), asset.Futures)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku)
|
|
_, err := ku.UpdateAccountInfo(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error("Kucoin UpdateAccountInfo() error", err)
|
|
}
|
|
_, err = ku.UpdateAccountInfo(context.Background(), asset.Futures)
|
|
if err != nil {
|
|
t.Error("Kucoin UpdateAccountInfo() error", err)
|
|
}
|
|
_, err = ku.UpdateAccountInfo(context.Background(), asset.Margin)
|
|
if err != nil {
|
|
t.Error("Kucoin UpdateAccountInfo() error", err)
|
|
}
|
|
}
|
|
|
|
const (
|
|
orderbookLevel5PushData = `{"type": "message","topic": "/spotMarket/level2Depth50:BTC-USDT","subject": "level2","data": {"asks": [["21621.7","3.03206193"],["21621.8","1.00048239"],["21621.9","0.29558803"],["21622","0.0049653"],["21622.4","0.06177582"],["21622.9","0.39664116"],["21623.7","0.00803466"],["21624.2","0.65405"],["21624.3","0.34661426"],["21624.6","0.00035589"],["21624.9","0.61282048"],["21625.2","0.16421424"],["21625.4","0.90107014"],["21625.5","0.73484442"],["21625.9","0.04"],["21626.2","0.28569324"],["21626.4","0.18403701"],["21627.1","0.06503999"],["21627.2","0.56105832"],["21627.7","0.10649999"],["21628.1","2.66459953"],["21628.2","0.32"],["21628.5","0.27605551"],["21628.6","1.59482596"],["21628.9","0.16"],["21629.8","0.08"],["21630","0.04"],["21631.6","0.1"],["21631.8","0.0920185"],["21633.6","0.00447983"],["21633.7","0.00015044"],["21634.3","0.32193346"],["21634.4","0.00004"],["21634.5","0.1"],["21634.6","0.0002865"],["21635.6","0.12069941"],["21635.8","0.00117158"],["21636","0.00072816"],["21636.5","0.98611492"],["21636.6","0.00007521"],["21637.2","0.00699999"],["21637.6","0.00017129"],["21638","0.00013035"],["21638.1","0.05"],["21638.5","0.92427"],["21639.2","1.84998696"],["21639.3","0.04827233"],["21640","0.56255996"],["21640.9","0.8"],["21641","0.12"]],"bids": [["21621.6","0.40949924"],["21621.5","0.27703279"],["21621.3","0.04"],["21621.1","0.0086"],["21621","0.6653104"],["21620.9","0.35435999"],["21620.8","0.37224309"],["21620.5","0.416184"],["21620.3","0.24"],["21619.6","0.13883999"],["21619.5","0.21053355"],["21618.7","0.2"],["21618.6","0.001"],["21618.5","0.2258151"],["21618.4","0.06503999"],["21618.3","0.00370056"],["21618","0.12067842"],["21617.7","0.34844131"],["21617.6","0.92845495"],["21617.5","0.66460535"],["21617","0.01"],["21616.7","0.0004624"],["21616.4","0.02"],["21615.6","0.04828251"],["21615","0.59065665"],["21614.4","0.00227"],["21614.3","0.1"],["21613","0.32193346"],["21612.9","0.0028638"],["21612.6","0.1"],["21612.5","0.92539"],["21610.7","0.08208616"],["21610.6","0.00967666"],["21610.3","0.12"],["21610.2","0.00611126"],["21609.9","0.00226344"],["21609.8","0.00315812"],["21609.1","0.00547218"],["21608.6","0.09793157"],["21608.5","0.00437793"],["21608.4","1.85013454"],["21608.1","0.00366647"],["21607.9","0.00611595"],["21607.7","0.83263561"],["21607.6","0.00368919"],["21607.5","0.00280702"],["21607.1","0.66610849"],["21606.8","0.00364164"],["21606.2","0.80351642"],["21605.7","0.075"]],"timestamp": 1676319280783}}`
|
|
wsOrderbookData = `{"changes":{"asks":[["21621.7","3.03206193",""],["21621.8","1.00048239",""],["21621.9","0.29558803",""],["21622","0.0049653",""],["21622.4","0.06177582",""],["21622.9","0.39664116",""],["21623.7","0.00803466",""],["21624.2","0.65405",""],["21624.3","0.34661426",""],["21624.6","0.00035589",""],["21624.9","0.61282048",""],["21625.2","0.16421424",""],["21625.4","0.90107014",""],["21625.5","0.73484442",""],["21625.9","0.04",""],["21626.2","0.28569324",""],["21626.4","0.18403701",""],["21627.1","0.06503999",""],["21627.2","0.56105832",""],["21627.7","0.10649999",""],["21628.1","2.66459953",""],["21628.2","0.32",""],["21628.5","0.27605551",""],["21628.6","1.59482596",""],["21628.9","0.16",""],["21629.8","0.08",""],["21630","0.04",""],["21631.6","0.1",""],["21631.8","0.0920185",""],["21633.6","0.00447983",""],["21633.7","0.00015044",""],["21634.3","0.32193346",""],["21634.4","0.00004",""],["21634.5","0.1",""],["21634.6","0.0002865",""],["21635.6","0.12069941",""],["21635.8","0.00117158",""],["21636","0.00072816",""],["21636.5","0.98611492",""],["21636.6","0.00007521",""],["21637.2","0.00699999",""],["21637.6","0.00017129",""],["21638","0.00013035",""],["21638.1","0.05",""],["21638.5","0.92427",""],["21639.2","1.84998696",""],["21639.3","0.04827233",""],["21640","0.56255996",""],["21640.9","0.8",""],["21641","0.12",""]],"bids":[["21621.6","0.40949924",""],["21621.5","0.27703279",""],["21621.3","0.04",""],["21621.1","0.0086",""],["21621","0.6653104",""],["21620.9","0.35435999",""],["21620.8","0.37224309",""],["21620.5","0.416184",""],["21620.3","0.24",""],["21619.6","0.13883999",""],["21619.5","0.21053355",""],["21618.7","0.2",""],["21618.6","0.001",""],["21618.5","0.2258151",""],["21618.4","0.06503999",""],["21618.3","0.00370056",""],["21618","0.12067842",""],["21617.7","0.34844131",""],["21617.6","0.92845495",""],["21617.5","0.66460535",""],["21617","0.01",""],["21616.7","0.0004624",""],["21616.4","0.02",""],["21615.6","0.04828251",""],["21615","0.59065665",""],["21614.4","0.00227",""],["21614.3","0.1",""],["21613","0.32193346",""],["21612.9","0.0028638",""],["21612.6","0.1",""],["21612.5","0.92539",""],["21610.7","0.08208616",""],["21610.6","0.00967666",""],["21610.3","0.12",""],["21610.2","0.00611126",""],["21609.9","0.00226344",""],["21609.8","0.00315812",""],["21609.1","0.00547218",""],["21608.6","0.09793157",""],["21608.5","0.00437793",""],["21608.4","1.85013454",""],["21608.1","0.00366647",""],["21607.9","0.00611595",""],["21607.7","0.83263561",""],["21607.6","0.00368919",""],["21607.5","0.00280702",""],["21607.1","0.66610849",""],["21606.8","0.00364164",""],["21606.2","0.80351642",""],["21605.7","0.075",""]]},"sequenceEnd":1676319280783,"sequenceStart":0,"symbol":"BTC-USDT","time":1676319280783}`
|
|
)
|
|
|
|
func TestProcessOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
response := &WsOrderbook{}
|
|
err := json.Unmarshal([]byte(wsOrderbookData), &response)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = ku.UpdateLocalBuffer(response, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = ku.processOrderbook([]byte(orderbookLevel5PushData), "BTC-USDT", "")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = ku.wsHandleData([]byte(orderbookLevel5PushData))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestProcessMarketSnapshot(t *testing.T) {
|
|
t.Parallel()
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
testexch.FixtureToDataHandler(t, "testdata/wsMarketSnapshot.json", ku.wsHandleData)
|
|
close(ku.Websocket.DataHandler)
|
|
assert.Len(t, ku.Websocket.DataHandler, 4, "Should see 4 tickers")
|
|
seenAssetTypes := map[asset.Item]int{}
|
|
for resp := range ku.Websocket.DataHandler {
|
|
switch v := resp.(type) {
|
|
case *ticker.Price:
|
|
switch len(ku.Websocket.DataHandler) {
|
|
case 3:
|
|
assert.Equal(t, asset.Margin, v.AssetType, "AssetType")
|
|
assert.Equal(t, time.UnixMilli(1700555342007), v.LastUpdated, "datetime")
|
|
assert.Equal(t, 0.004445, v.High, "high")
|
|
assert.Equal(t, 0.004415, v.Last, "lastTradedPrice")
|
|
assert.Equal(t, 0.004191, v.Low, "low")
|
|
assert.Equal(t, currency.NewPairWithDelimiter("TRX", "BTC", "-"), v.Pair, "symbol")
|
|
assert.Equal(t, 13097.3357, v.Volume, "volume")
|
|
assert.Equal(t, 57.44552981, v.QuoteVolume, "volValue")
|
|
case 2, 1:
|
|
assert.Equal(t, time.UnixMilli(1700555340197), v.LastUpdated, "datetime")
|
|
assert.Contains(t, []asset.Item{asset.Spot, asset.Margin}, v.AssetType, "AssetType is Spot or Margin")
|
|
seenAssetTypes[v.AssetType]++
|
|
assert.Equal(t, 1, seenAssetTypes[v.AssetType], "Each Asset Type is sent only once per unique snapshot")
|
|
assert.Equal(t, 0.054846, v.High, "high")
|
|
assert.Equal(t, 0.053778, v.Last, "lastTradedPrice")
|
|
assert.Equal(t, 0.05364, v.Low, "low")
|
|
assert.Equal(t, currency.NewPairWithDelimiter("ETH", "BTC", "-"), v.Pair, "symbol")
|
|
assert.Equal(t, 2958.3139116, v.Volume, "volume")
|
|
assert.Equal(t, 160.7847672784213, v.QuoteVolume, "volValue")
|
|
case 0:
|
|
assert.Equal(t, asset.Spot, v.AssetType, "AssetType")
|
|
assert.Equal(t, time.UnixMilli(1700555342151), v.LastUpdated, "datetime")
|
|
assert.Equal(t, 37750.0, v.High, "high")
|
|
assert.Equal(t, 37366.8, v.Last, "lastTradedPrice")
|
|
assert.Equal(t, 36700.0, v.Low, "low")
|
|
assert.Equal(t, currency.NewPairWithDelimiter("BTC", "USDT", "-"), v.Pair, "symbol")
|
|
assert.Equal(t, 2900.37846402, v.Volume, "volume")
|
|
assert.Equal(t, 108210331.34015164, v.QuoteVolume, "volValue")
|
|
}
|
|
case error:
|
|
t.Error(v)
|
|
default:
|
|
t.Errorf("Got unexpected data: %T %v", v, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestSubscribeBatches ensures that endpoints support batching, contrary to kucoin api docs
|
|
func TestSubscribeBatches(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
ku.Features.Subscriptions = subscription.List{}
|
|
testexch.SetupWs(t, ku)
|
|
|
|
ku.Features.Subscriptions = subscription.List{
|
|
{Asset: asset.Spot, Channel: subscription.CandlesChannel, Interval: kline.OneMin},
|
|
{Asset: asset.Futures, Channel: subscription.TickerChannel},
|
|
{Asset: asset.Spot, Channel: marketSnapshotChannel},
|
|
}
|
|
|
|
subs, err := ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions must not error")
|
|
require.Len(t, subs, len(ku.Features.Subscriptions), "Must generate batched subscriptions")
|
|
|
|
err = ku.Subscribe(subs)
|
|
require.NoError(t, err, "Subscribe to small batches should not error")
|
|
}
|
|
|
|
// TestSubscribeTickerAll ensures that ticker subscriptions switch to using all and it works
|
|
|
|
// TestSubscribeBatchLimit exercises the kucoin batch limits of 300 per connection
|
|
// Ensures batching of 100 pairs and the connection symbol limit is still 300 at Kucoin's end
|
|
func TestSubscribeBatchLimit(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
ku.Features.Subscriptions = subscription.List{}
|
|
testexch.SetupWs(t, ku)
|
|
|
|
avail, err := ku.GetAvailablePairs(asset.Spot)
|
|
require.NoError(t, err, "GetAvailablePairs must not error")
|
|
|
|
err = ku.CurrencyPairs.StorePairs(asset.Spot, avail[:299], true)
|
|
require.NoError(t, err, "StorePairs must not error")
|
|
|
|
ku.Features.Subscriptions = subscription.List{{Asset: asset.Spot, Channel: subscription.AllTradesChannel}}
|
|
subs, err := ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions must not error")
|
|
require.Len(t, subs, 3, "Must get 3 subs")
|
|
|
|
err = ku.Subscribe(subs)
|
|
require.NoError(t, err, "Subscribe must not error")
|
|
|
|
err = ku.Unsubscribe(subs)
|
|
require.NoError(t, err, "Unsubscribe must not error")
|
|
|
|
err = ku.CurrencyPairs.StorePairs(asset.Spot, avail[:320], true)
|
|
require.NoError(t, err, "StorePairs must not error")
|
|
|
|
ku.Features.Subscriptions = subscription.List{{Asset: asset.Spot, Channel: subscription.AllTradesChannel}}
|
|
subs, err = ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions must not error")
|
|
require.Len(t, subs, 4, "Must get 4 subs")
|
|
|
|
err = ku.Subscribe(subs)
|
|
require.ErrorContains(t, err, "exceed max subscription count limitation of 300 per session", "Subscribe to MarketSnapshot must error above connection symbol limit")
|
|
}
|
|
|
|
func TestSubscribeTickerAll(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
ku.Features.Subscriptions = subscription.List{}
|
|
testexch.SetupWs(t, ku)
|
|
|
|
avail, err := ku.GetAvailablePairs(asset.Spot)
|
|
require.NoError(t, err, "GetAvailablePairs must not error")
|
|
|
|
err = ku.CurrencyPairs.StorePairs(asset.Spot, avail[:500], true)
|
|
require.NoError(t, err, "StorePairs must not error")
|
|
|
|
ku.Features.Subscriptions = subscription.List{{Asset: asset.Spot, Channel: subscription.TickerChannel}}
|
|
|
|
subs, err := ku.generateSubscriptions()
|
|
require.NoError(t, err, "generateSubscriptions must not error")
|
|
require.Len(t, subs, 1, "Must generate one subscription")
|
|
require.Equal(t, "/market/ticker:all", subs[0].QualifiedChannel, "QualifiedChannel must be correct")
|
|
|
|
err = ku.Subscribe(subs)
|
|
require.NoError(t, err, "Subscribe to must not error")
|
|
}
|
|
|
|
func TestSeedLocalCache(t *testing.T) {
|
|
t.Parallel()
|
|
pair, err := currency.NewPairFromString("ETH-USDT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = ku.SeedLocalCache(context.Background(), pair, asset.Margin)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFuturesContractDetails(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesContractDetails(context.Background(), asset.Spot)
|
|
assert.ErrorIs(t, err, futures.ErrNotFuturesAsset)
|
|
_, err = ku.GetFuturesContractDetails(context.Background(), asset.USDTMarginedFutures)
|
|
assert.ErrorIs(t, err, asset.ErrNotSupported)
|
|
_, err = ku.GetFuturesContractDetails(context.Background(), asset.Futures)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestGetLatestFundingRates(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetLatestFundingRates(context.Background(), nil)
|
|
assert.ErrorIs(t, err, common.ErrNilPointer)
|
|
|
|
req := &fundingrate.LatestRateRequest{
|
|
Asset: asset.Futures,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
}
|
|
_, err = ku.GetLatestFundingRates(context.Background(), req)
|
|
assert.ErrorIs(t, err, futures.ErrNotPerpetualFuture)
|
|
|
|
req = &fundingrate.LatestRateRequest{
|
|
Asset: asset.Futures,
|
|
Pair: currency.NewPair(currency.XBT, currency.USDTM),
|
|
}
|
|
resp, err := ku.GetLatestFundingRates(context.Background(), req)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, resp, 1)
|
|
|
|
req = &fundingrate.LatestRateRequest{
|
|
Asset: asset.Futures,
|
|
Pair: currency.EMPTYPAIR,
|
|
}
|
|
resp, err = ku.GetLatestFundingRates(context.Background(), req)
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
}
|
|
|
|
func TestIsPerpetualFutureCurrency(t *testing.T) {
|
|
t.Parallel()
|
|
is, err := ku.IsPerpetualFutureCurrency(asset.Spot, currency.EMPTYPAIR)
|
|
assert.NoError(t, err)
|
|
assert.False(t, is)
|
|
is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.EMPTYPAIR)
|
|
assert.NoError(t, err)
|
|
assert.False(t, is)
|
|
is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.EOS))
|
|
assert.NoError(t, err)
|
|
assert.False(t, is)
|
|
is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.USDTM))
|
|
assert.NoError(t, err)
|
|
assert.True(t, is)
|
|
is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.USDM))
|
|
assert.NoError(t, err)
|
|
assert.True(t, is)
|
|
}
|
|
|
|
func TestChangePositionMargin(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.ChangePositionMargin(context.Background(), nil)
|
|
assert.ErrorIs(t, err, common.ErrNilPointer)
|
|
|
|
req := &margin.PositionChangeRequest{}
|
|
_, err = ku.ChangePositionMargin(context.Background(), req)
|
|
assert.ErrorIs(t, err, futures.ErrNotFuturesAsset)
|
|
|
|
req.Asset = asset.Futures
|
|
_, err = ku.ChangePositionMargin(context.Background(), req)
|
|
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
|
|
|
|
req.Pair = currency.NewPair(currency.XBT, currency.USDTM)
|
|
_, err = ku.ChangePositionMargin(context.Background(), req)
|
|
assert.ErrorIs(t, err, margin.ErrMarginTypeUnsupported)
|
|
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
req.MarginType = margin.Isolated
|
|
_, err = ku.ChangePositionMargin(context.Background(), req)
|
|
assert.Error(t, err)
|
|
|
|
req.NewAllocatedMargin = 1337
|
|
_, err = ku.ChangePositionMargin(context.Background(), req)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestGetFuturesPositionSummary(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesPositionSummary(context.Background(), nil)
|
|
assert.ErrorIs(t, err, common.ErrNilPointer)
|
|
|
|
req := &futures.PositionSummaryRequest{}
|
|
_, err = ku.GetFuturesPositionSummary(context.Background(), req)
|
|
assert.ErrorIs(t, err, futures.ErrNotPerpetualFuture)
|
|
|
|
req.Asset = asset.Futures
|
|
_, err = ku.GetFuturesPositionSummary(context.Background(), req)
|
|
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
|
|
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
req.Pair = currency.NewPair(currency.XBT, currency.USDTM)
|
|
_, err = ku.GetFuturesPositionSummary(context.Background(), req)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestGetFuturesPositionOrders(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := ku.GetFuturesPositionOrders(context.Background(), nil)
|
|
assert.ErrorIs(t, err, common.ErrNilPointer)
|
|
|
|
req := &futures.PositionsRequest{}
|
|
_, err = ku.GetFuturesPositionOrders(context.Background(), req)
|
|
assert.ErrorIs(t, err, futures.ErrNotPerpetualFuture)
|
|
|
|
req.Asset = asset.Futures
|
|
_, err = ku.GetFuturesPositionOrders(context.Background(), req)
|
|
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
|
|
|
|
req.Pairs = currency.Pairs{
|
|
currency.NewPair(currency.XBT, currency.USDTM),
|
|
}
|
|
_, err = ku.GetFuturesPositionOrders(context.Background(), req)
|
|
assert.ErrorIs(t, err, common.ErrDateUnset)
|
|
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders)
|
|
req.EndDate = time.Now()
|
|
req.StartDate = req.EndDate.Add(-time.Hour * 24 * 7)
|
|
_, err = ku.GetFuturesPositionOrders(context.Background(), req)
|
|
assert.NoError(t, err)
|
|
|
|
req.StartDate = req.EndDate.Add(-time.Hour * 24 * 30)
|
|
_, err = ku.GetFuturesPositionOrders(context.Background(), req)
|
|
assert.ErrorIs(t, err, futures.ErrOrderHistoryTooLarge)
|
|
|
|
req.RespectOrderHistoryLimits = true
|
|
_, err = ku.GetFuturesPositionOrders(context.Background(), req)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestUpdateOrderExecutionLimits(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
err := ku.UpdateOrderExecutionLimits(context.Background(), asset.Binary)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Fatalf("Received %v, expected %v", err, asset.ErrNotSupported)
|
|
}
|
|
|
|
assets := []asset.Item{asset.Spot, asset.Futures, asset.Margin}
|
|
for x := range assets {
|
|
err = ku.UpdateOrderExecutionLimits(context.Background(), assets[x])
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received %v, expected %v", err, nil)
|
|
}
|
|
|
|
enabled, err := ku.GetEnabledPairs(assets[x])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for y := range enabled {
|
|
lim, err := ku.GetOrderExecutionLimits(assets[x], enabled[y])
|
|
if err != nil {
|
|
t.Fatalf("%v %s %v", err, enabled[y], assets[x])
|
|
}
|
|
assert.NotEmpty(t, lim, "limit cannot be empty")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetOpenInterest(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
|
|
|
|
_, err := ku.GetOpenInterest(context.Background(), key.PairAsset{
|
|
Base: currency.ETH.Item,
|
|
Quote: currency.USDT.Item,
|
|
Asset: asset.USDTMarginedFutures,
|
|
})
|
|
assert.ErrorIs(t, err, asset.ErrNotSupported)
|
|
|
|
resp, err := ku.GetOpenInterest(context.Background(), key.PairAsset{
|
|
Base: futuresTradablePair.Base.Item,
|
|
Quote: futuresTradablePair.Quote.Item,
|
|
Asset: asset.Futures,
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
|
|
cp1 := currency.NewPair(currency.ETH, currency.USDTM)
|
|
sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, ku, asset.Futures, cp1)
|
|
resp, err = ku.GetOpenInterest(context.Background(),
|
|
key.PairAsset{
|
|
Base: futuresTradablePair.Base.Item,
|
|
Quote: futuresTradablePair.Quote.Item,
|
|
Asset: asset.Futures,
|
|
},
|
|
key.PairAsset{
|
|
Base: cp1.Base.Item,
|
|
Quote: cp1.Quote.Item,
|
|
Asset: asset.Futures,
|
|
},
|
|
)
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
|
|
resp, err = ku.GetOpenInterest(context.Background())
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
}
|
|
|
|
func TestGetCurrencyTradeURL(t *testing.T) {
|
|
t.Parallel()
|
|
testexch.UpdatePairsOnce(t, ku)
|
|
for _, a := range ku.GetAssetTypes(false) {
|
|
pairs, err := ku.CurrencyPairs.GetPairs(a, false)
|
|
require.NoError(t, err, "cannot get pairs for %s", a)
|
|
require.NotEmpty(t, pairs, "no pairs for %s", a)
|
|
resp, err := ku.GetCurrencyTradeURL(context.Background(), a, pairs[0])
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, resp)
|
|
}
|
|
}
|
|
|
|
// testInstance returns a local Kucoin for isolated testing
|
|
func testInstance(tb testing.TB) *Kucoin {
|
|
tb.Helper()
|
|
ku := new(Kucoin)
|
|
require.NoError(tb, testexch.Setup(ku), "Test instance Setup must not error")
|
|
ku.obm = &orderbookManager{
|
|
state: make(map[currency.Code]map[currency.Code]map[asset.Item]*update),
|
|
jobs: make(chan job, maxWSOrderbookJobs),
|
|
}
|
|
return ku
|
|
}
|