Files
gocryptotrader/exchanges/okx/okx_test.go
Bea 3d212b6279 Okx: Fix sending trades to the websocket DataHandler (#1833)
* Send trades down the DataHandler, add test

* Send the trades down to the DataHandler

Update the test to process trades for each asset type
Add raw trade data from OKX
Update the timestamp in the method

* Replace pair repetition with p var

* Update the test, remove repetition

* Rename trade var in the test

* Fix nits and slice sorting

* Compare trades

* Fix nits
2025-03-17 10:07:28 +11:00

6724 lines
269 KiB
Go

package okx
import (
"context"
"errors"
"fmt"
"log"
"os"
"slices"
"strings"
"sync"
"testing"
"time"
"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"
"github.com/thrasher-corp/gocryptotrader/encoding/json"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/collateral"
"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/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
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
useTestNet = false
)
var (
ok = &Okx{}
leadTraderUniqueID string
loadLeadTraderOnce sync.Once
spotTP, marginTP, futuresTP, perpetualSwapTP, optionsTP, spreadTP currency.Pair
)
func TestMain(m *testing.M) {
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
log.Fatal(err)
}
exchCfg, err := cfg.GetExchangeConfig("Okx")
if err != nil {
log.Fatal(err)
}
exchCfg.API.Credentials.Key = apiKey
exchCfg.API.Credentials.Secret = apiSecret
exchCfg.API.Credentials.ClientID = passphrase
ok.SetDefaults()
if apiKey != "" && apiSecret != "" && passphrase != "" {
exchCfg.API.AuthenticatedSupport = true
exchCfg.API.AuthenticatedWebsocketSupport = true
ok.API.CredentialsValidator.RequiresBase64DecodeSecret = false
ok.SetCredentials(apiKey, apiSecret, passphrase, "", "", "")
ok.Websocket.SetCanUseAuthenticatedEndpoints(true)
}
if !useTestNet {
ok.Websocket = sharedtestvalues.NewTestWebsocket()
}
err = ok.Setup(exchCfg)
if err != nil {
log.Fatal(err)
}
err = ok.UpdateTradablePairs(contextGenerate(), true)
if err != nil {
log.Fatal(err)
}
if !useTestNet {
ok.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride()
ok.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride()
setupWS()
}
err = populateTradablePairs()
if err != nil {
log.Fatal(err)
}
syncLeadTraderUniqueID()
os.Exit(m.Run())
}
func populateTradablePairs() error {
errNoEnabledPair := errors.New("no enabled pair found")
err := ok.UpdateTradablePairs(contextGenerate(), true)
if err != nil {
return err
}
assetToTradablePairMap := map[asset.Item]currency.Pair{
asset.Spot: spotTP,
asset.Margin: marginTP,
asset.Futures: futuresTP,
asset.Options: optionsTP,
asset.PerpetualSwap: perpetualSwapTP,
asset.Spread: spreadTP,
}
for a := range assetToTradablePairMap {
tradablePairs, err := ok.GetEnabledPairs(a)
if err != nil {
return err
}
if len(tradablePairs) == 0 {
return fmt.Errorf("%w %v", errNoEnabledPair, a)
}
switch a {
case asset.Spot:
spotTP = tradablePairs[0]
case asset.Margin:
marginTP = tradablePairs[0]
case asset.Futures:
futuresTP = tradablePairs[0]
case asset.Options:
optionsTP = tradablePairs[0]
case asset.PerpetualSwap:
perpetualSwapTP = tradablePairs[0]
case asset.Spread:
spreadTP = tradablePairs[0]
}
}
return nil
}
func syncLeadTraderUniqueID() {
loadLeadTraderOnce.Do(func() {
result, err := ok.GetLeadTradersRanks(contextGenerate(), "SWAP", "pnl_ratio", "1", "", "", "", "", "", "", "", 10)
if err != nil {
log.Fatal(err)
}
if len(result) == 0 {
log.Fatal("No lead trader found")
}
if len(result[0].Ranks) == 0 {
log.Fatal("could not load lead traders ranks")
}
leadTraderUniqueID = result[0].Ranks[0].UniqueCode
})
}
// contextGenerate sends an optional value to allow test requests
// named this way, so it shows up in auto-complete and reminds you to use it
func contextGenerate() context.Context {
ctx := context.Background()
if useTestNet {
ctx = context.WithValue(ctx, testNetKey("testnet"), useTestNet)
}
return ctx
}
func TestGetTickers(t *testing.T) {
t.Parallel()
instFamily, err := ok.instrumentFamilyFromInstID(instTypeOption, optionsTP.String())
require.NoError(t, err)
_, err = ok.GetTickers(contextGenerate(), "", "", instFamily)
require.ErrorIs(t, err, errInvalidInstrumentType)
result, err := ok.GetTickers(contextGenerate(), instTypeOption, "", instFamily)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetIndexTicker(t *testing.T) {
t.Parallel()
_, err := ok.GetIndexTickers(contextGenerate(), currency.EMPTYCODE, "")
require.ErrorIs(t, err, errEitherInstIDOrCcyIsRequired)
result, err := ok.GetIndexTickers(contextGenerate(), currency.USDT, "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTicker(t *testing.T) {
t.Parallel()
_, err := ok.GetTicker(contextGenerate(), "")
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetTicker(contextGenerate(), perpetualSwapTP.String())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPremiumHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetPremiumHistory(contextGenerate(), "", time.Time{}, time.Time{}, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetPremiumHistory(contextGenerate(), perpetualSwapTP.String(), time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOrderBookDepth(t *testing.T) {
t.Parallel()
_, err := ok.GetOrderBookDepth(contextGenerate(), "", 400)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetOrderBookDepth(contextGenerate(), spotTP.String(), 400)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCandlesticks(t *testing.T) {
t.Parallel()
_, err := ok.GetCandlesticks(contextGenerate(), "", kline.OneHour, time.Now().Add(-time.Minute*2), time.Now(), 2)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetCandlesticks(contextGenerate(), spotTP.String(), kline.OneHour, time.Now().Add(-time.Minute*2), time.Now(), 2)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCandlesticksHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetCandlesticksHistory(contextGenerate(), "", kline.OneHour, time.Unix(time.Now().Unix()-int64(time.Minute), 3), time.Now(), 3)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetCandlesticksHistory(contextGenerate(), spotTP.String(), kline.OneHour, time.Unix(time.Now().Unix()-int64(time.Minute), 3), time.Now(), 3)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTrades(t *testing.T) {
t.Parallel()
_, err := ok.GetTrades(contextGenerate(), "", 3)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetTrades(contextGenerate(), spotTP.String(), 3)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTradeHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetTradesHistory(contextGenerate(), "", "", "", 2)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetTradesHistory(contextGenerate(), spotTP.String(), "", "", 2)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetoptionTradesByInstrumentFamily(t *testing.T) {
t.Parallel()
_, err := ok.GetOptionTradesByInstrumentFamily(contextGenerate(), "")
require.ErrorIs(t, err, errInstrumentFamilyRequired)
instFamily, err := ok.instrumentFamilyFromInstID(instTypeOption, optionsTP.String())
require.NoError(t, err)
result, err := ok.GetOptionTradesByInstrumentFamily(contextGenerate(), instFamily)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOptionTrades(t *testing.T) {
t.Parallel()
_, err := ok.GetOptionTrades(contextGenerate(), "", "", "C")
require.ErrorIs(t, err, errInstrumentIDorFamilyRequired)
instFamily, err := ok.instrumentFamilyFromInstID(instTypeOption, optionsTP.String())
require.NoError(t, err)
result, err := ok.GetOptionTrades(contextGenerate(), "", instFamily, "C")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGet24HTotalVolume(t *testing.T) {
t.Parallel()
result, err := ok.Get24HTotalVolume(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOracle(t *testing.T) {
t.Parallel()
t.Skip("Skipping test: The server endpoint has a rate-limiting issue that needs to be fixed.")
result, err := ok.GetOracle(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetExchangeRate(t *testing.T) {
t.Parallel()
result, err := ok.GetExchangeRate(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetIndexComponents(t *testing.T) {
t.Parallel()
_, err := ok.GetIndexComponents(contextGenerate(), "")
require.ErrorIs(t, err, errIndexComponentNotFound)
result, err := ok.GetIndexComponents(contextGenerate(), "ETH-USDT")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBlockTickers(t *testing.T) {
t.Parallel()
_, err := ok.GetBlockTickers(contextGenerate(), "", "")
require.ErrorIs(t, err, errInvalidInstrumentType)
result, err := ok.GetBlockTickers(contextGenerate(), "SWAP", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBlockTicker(t *testing.T) {
t.Parallel()
_, err := ok.GetBlockTicker(contextGenerate(), "")
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetBlockTicker(contextGenerate(), "BTC-USDT")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBlockTrade(t *testing.T) {
t.Parallel()
_, err := ok.GetPublicBlockTrades(contextGenerate(), "")
require.ErrorIs(t, err, errMissingInstrumentID)
trades, err := ok.GetPublicBlockTrades(contextGenerate(), "BTC-USDT")
require.NoError(t, err)
if assert.NotEmpty(t, trades, "Should get some block trades") {
trade := trades[0]
assert.Equal(t, "BTC-USDT", trade.InstrumentID, "InstrumentID should have correct value")
assert.NotEmpty(t, trade.TradeID, "TradeID should not be empty")
assert.Positive(t, trade.Price, "Price should have a positive value")
assert.Positive(t, trade.Size, "Size should have a positive value")
assert.Contains(t, []order.Side{order.Buy, order.Sell}, trade.Side, "Side should be a side")
assert.WithinRange(t, trade.Timestamp.Time(), time.Now().Add(time.Hour*-24*90), time.Now(), "Timestamp should be within last 90 days")
}
testexch.UpdatePairsOnce(t, ok)
pairs, err := ok.GetAvailablePairs(asset.Options)
require.NoError(t, err)
require.NotEmpty(t, pairs)
publicTrades, err := ok.GetPublicRFQTrades(contextGenerate(), "", "", 100)
require.NoError(t, err)
tested := false
LOOP:
for _, trade := range publicTrades {
for _, leg := range trade.Legs {
p, err := ok.MatchSymbolWithAvailablePairs(leg.InstrumentID, asset.Options, true)
if err != nil {
continue
}
trades, err = ok.GetPublicBlockTrades(contextGenerate(), p.String())
require.NoError(t, err, "GetBlockTrades should not error on Options")
for _, trade := range trades {
assert.Equal(t, p.String(), trade.InstrumentID, "InstrumentID should have correct value")
assert.NotEmpty(t, trade.TradeID, "TradeID should not be empty")
assert.Positive(t, trade.Price, "Price should have a positive value")
assert.Positive(t, trade.Size, "Size should have a positive value")
assert.Contains(t, []order.Side{order.Buy, order.Sell}, trade.Side, "Side should be a side")
assert.Positive(t, trade.FillVolatility, "FillVolatility should have a positive value")
assert.Positive(t, trade.ForwardPrice, "ForwardPrice should have a positive value")
assert.Positive(t, trade.IndexPrice, "IndexPrice should have a positive value")
assert.Positive(t, trade.MarkPrice, "MarkPrice should have a positive value")
assert.NotEmpty(t, trade.Timestamp, "Timestamp should not be empty")
tested = true
break LOOP
}
}
}
assert.True(t, tested, "Should find at least one BlockTrade somewhere")
}
func TestGetInstrument(t *testing.T) {
t.Parallel()
_, err := ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{Underlying: "SOL-USD"})
assert.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{
InstrumentType: instTypeOption, Underlying: ""})
assert.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
result, err := ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{
InstrumentType: instTypeFutures,
Underlying: "SOL-USD",
})
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{
InstrumentType: instTypeSpot,
})
require.NoError(t, err)
assert.NotNil(t, result)
_, err = ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{
InstrumentType: instTypeSwap,
Underlying: "SOL-USD",
})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetDeliveryHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetDeliveryHistory(contextGenerate(), "", "BTC-USDT", "", time.Time{}, time.Time{}, 3)
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.GetDeliveryHistory(contextGenerate(), instTypeFutures, "", "", time.Time{}, time.Time{}, 3)
require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
_, err = ok.GetDeliveryHistory(contextGenerate(), instTypeFutures, "BTC-USDT", "", time.Time{}, time.Time{}, 345)
require.ErrorIs(t, err, errLimitValueExceedsMaxOf100)
result, err := ok.GetDeliveryHistory(contextGenerate(), instTypeFutures, "BTC-USDT", "", time.Time{}, time.Time{}, 3)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOpenInterestData(t *testing.T) {
t.Parallel()
_, err := ok.GetOpenInterestData(contextGenerate(), "", "BTC-USDT", "", "")
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.GetOpenInterestData(contextGenerate(), instTypeOption, "", "", "")
require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
uly, err := ok.underlyingFromInstID(instTypeFutures, futuresTP.String())
require.NoError(t, err)
result, err := ok.GetOpenInterestData(contextGenerate(), instTypeFutures, uly, "", futuresTP.String())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSingleFundingRate(t *testing.T) {
t.Parallel()
_, err := ok.GetSingleFundingRate(contextGenerate(), "")
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetSingleFundingRate(contextGenerate(), "BTC-USD-SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFundingRateHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetFundingRateHistory(contextGenerate(), "", time.Time{}, time.Time{}, 2)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetFundingRateHistory(contextGenerate(), "BTC-USD-SWAP", time.Time{}, time.Time{}, 2)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLimitPrice(t *testing.T) {
t.Parallel()
_, err := ok.GetLimitPrice(contextGenerate(), "")
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetLimitPrice(contextGenerate(), "BTC-USD-SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOptionMarketData(t *testing.T) {
t.Parallel()
_, err := ok.GetOptionMarketData(contextGenerate(), "", "", time.Time{})
require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
result, err := ok.GetOptionMarketData(contextGenerate(), "BTC-USD", "", time.Time{})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetEstimatedDeliveryPrice(t *testing.T) {
t.Parallel()
_, err := ok.GetEstimatedDeliveryPrice(contextGenerate(), "")
require.ErrorIs(t, err, errMissingInstrumentID)
r, err := ok.FetchTradablePairs(contextGenerate(), asset.Futures)
require.NoError(t, err)
result, err := ok.GetEstimatedDeliveryPrice(contextGenerate(), r[0].String())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetDiscountRateAndInterestFreeQuota(t *testing.T) {
t.Parallel()
result, err := ok.GetDiscountRateAndInterestFreeQuota(contextGenerate(), currency.EMPTYCODE, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSystemTime(t *testing.T) {
t.Parallel()
result, err := ok.GetSystemTime(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLiquidationOrders(t *testing.T) {
t.Parallel()
insts, err := ok.FetchTradablePairs(contextGenerate(), asset.Margin)
require.NoError(t, err)
result, err := ok.GetLiquidationOrders(contextGenerate(), &LiquidationOrderRequestParams{
InstrumentType: instTypeMargin,
Underlying: insts[0].String(),
Currency: currency.BTC,
Limit: 2,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMarkPrice(t *testing.T) {
t.Parallel()
_, err := ok.GetMarkPrice(contextGenerate(), "", "", "", "BTC-USDT")
require.ErrorIs(t, err, errInvalidInstrumentType)
result, err := ok.GetMarkPrice(contextGenerate(), "MARGIN", "", "", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPositionTiers(t *testing.T) {
t.Parallel()
_, err := ok.GetPositionTiers(contextGenerate(), "", "cross", "BTC-USDT", "", "", "", currency.ETH)
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.GetPositionTiers(contextGenerate(), instTypeFutures, "", "BTC-USDT", "", "", "", currency.ETH)
require.ErrorIs(t, err, errInvalidTradeMode)
_, err = ok.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", "", "", "", "", currency.EMPTYCODE)
require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
_, err = ok.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", "BTC-USDT", "", "", "", currency.EMPTYCODE)
require.ErrorIs(t, err, errEitherInstIDOrCcyIsRequired)
result, err := ok.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", "BTC-USDT", "", "", "", currency.ETH)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetInterestRateAndLoanQuota(t *testing.T) {
t.Parallel()
result, err := ok.GetInterestRateAndLoanQuota(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetInterestRateAndLoanQuotaForVIPLoans(t *testing.T) {
t.Parallel()
result, err := ok.GetInterestRateAndLoanQuotaForVIPLoans(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPublicUnderlyings(t *testing.T) {
t.Parallel()
_, err := ok.GetPublicUnderlyings(contextGenerate(), "")
require.ErrorIs(t, err, errInvalidInstrumentType)
result, err := ok.GetPublicUnderlyings(contextGenerate(), instTypeFutures)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetInsuranceFundInformation(t *testing.T) {
t.Parallel()
_, err := ok.GetInsuranceFundInformation(contextGenerate(), &InsuranceFundInformationRequestParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &InsuranceFundInformationRequestParams{Limit: 2}
_, err = ok.GetInsuranceFundInformation(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidInstrumentType)
arg.InstrumentType = instTypeSwap
_, err = ok.GetInsuranceFundInformation(contextGenerate(), arg)
require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
arg.Underlying = "BTC-USDT"
r, err := ok.GetInsuranceFundInformation(contextGenerate(), arg)
assert.NoError(t, err)
assert.Positive(t, r.Total, "Total should be positive")
assert.NotEmpty(t, r.Details, "Should have some details")
for _, d := range r.Details {
assert.Positive(t, d.Balance, "Balance should be positive")
assert.NotEmpty(t, d.InsuranceType, "Type should not be empty")
assert.Positive(t, d.Timestamp, "Timestamp should be positive")
}
r, err = ok.GetInsuranceFundInformation(contextGenerate(), &InsuranceFundInformationRequestParams{
InstrumentType: instTypeFutures,
Underlying: "BTC-USDT",
Limit: 2,
})
assert.NoError(t, err)
assert.Positive(t, r.Total, "Total should be positive")
assert.NotEmpty(t, r.Details, "Should have some details")
for _, d := range r.Details {
assert.Positive(t, d.Balance, "Balance should be positive")
assert.NotEmpty(t, d.InsuranceType, "Type should not be empty")
assert.Positive(t, d.Timestamp, "Timestamp should be positive")
}
}
func TestCurrencyUnitConvert(t *testing.T) {
t.Parallel()
_, err := ok.CurrencyUnitConvert(contextGenerate(), "", 1, 3500, 1, currency.EMPTYCODE, false)
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.CurrencyUnitConvert(contextGenerate(), "BTC-USD-SWAP", 0, 3500, 1, currency.EMPTYCODE, false)
require.ErrorIs(t, err, errMissingQuantity)
result, err := ok.CurrencyUnitConvert(contextGenerate(), perpetualSwapTP.String(), 1, 3500, 1, currency.EMPTYCODE, false)
require.NoError(t, err)
assert.NotNil(t, result)
}
// Trading related endpoints test functions.
func TestGetSupportCoins(t *testing.T) {
t.Parallel()
result, err := ok.GetSupportCoins(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTakerVolume(t *testing.T) {
t.Parallel()
_, err := ok.GetTakerVolume(contextGenerate(), currency.BTC, "", "", time.Time{}, time.Time{}, kline.OneDay)
require.ErrorIs(t, err, errInvalidInstrumentType)
result, err := ok.GetTakerVolume(contextGenerate(), currency.BTC, instTypeSpot, "", time.Time{}, time.Time{}, kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMarginLendingRatio(t *testing.T) {
t.Parallel()
result, err := ok.GetMarginLendingRatio(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.FiveMin)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLongShortRatio(t *testing.T) {
t.Parallel()
result, err := ok.GetLongShortRatio(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetContractsOpenInterestAndVolume(t *testing.T) {
t.Parallel()
result, err := ok.GetContractsOpenInterestAndVolume(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOptionsOpenInterestAndVolume(t *testing.T) {
t.Parallel()
result, err := ok.GetOptionsOpenInterestAndVolume(contextGenerate(), currency.BTC, kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPutCallRatio(t *testing.T) {
t.Parallel()
result, err := ok.GetPutCallRatio(contextGenerate(), currency.BTC, kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOpenInterestAndVolumeExpiry(t *testing.T) {
t.Parallel()
result, err := ok.GetOpenInterestAndVolumeExpiry(contextGenerate(), currency.BTC, kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOpenInterestAndVolumeStrike(t *testing.T) {
t.Parallel()
_, err := ok.GetOpenInterestAndVolumeStrike(contextGenerate(), currency.BTC, time.Time{}, kline.OneDay)
require.ErrorIs(t, err, errMissingExpiryTimeParameter)
result, err := ok.GetOpenInterestAndVolumeStrike(contextGenerate(), currency.BTC, time.Now(), kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTakerFlow(t *testing.T) {
t.Parallel()
result, err := ok.GetTakerFlow(contextGenerate(), currency.BTC, kline.OneDay)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
arg := &PlaceOrderRequestParam{
ReduceOnly: true,
AssetType: asset.Margin,
}
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = order.Buy.Lower()
arg.TradeMode = "abc"
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = "cross"
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = order.Limit.String()
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.AssetType = asset.Futures
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.PositionSide = "long"
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.Amount = 1
arg.QuantityType = "abcd"
_, err = ok.PlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errCurrencyQuantityTypeRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceOrder(contextGenerate(), &PlaceOrderRequestParam{
InstrumentID: "BTC-USDC",
TradeMode: "cross",
Side: order.Buy.String(),
OrderType: "limit",
Amount: 2.6,
Price: 2.1,
Currency: "BTC",
AssetType: asset.Margin,
})
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.PlaceOrder(contextGenerate(), &PlaceOrderRequestParam{
InstrumentID: "BTC-USDC",
TradeMode: "cross",
Side: order.Buy.Lower(),
PositionSide: "long",
OrderType: "limit",
Amount: 2.6,
Price: 2.1,
Currency: "BTC",
AssetType: asset.Futures,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
const (
instrumentJSON = `{"alias":"","baseCcy":"","category":"1","ctMult":"1","ctType":"linear","ctVal":"0.0001","ctValCcy":"BTC","expTime":"","instFamily":"BTC-USDC","instId":"BTC-USDC-SWAP","instType":"SWAP","lever":"125","listTime":"1666076190000","lotSz":"1","maxIcebergSz":"100000000.0000000000000000","maxLmtSz":"100000000","maxMktSz":"85000","maxStopSz":"85000","maxTriggerSz":"100000000.0000000000000000","maxTwapSz":"","minSz":"1","optType":"","quoteCcy":"","settleCcy":"USDC","state":"live","stk":"","tickSz":"0.1","uly":"BTC-USDC"}`
placeOrderArgs = `[{"side": "buy","instId": "BTC-USDT","tdMode": "cash","ordType": "market","sz": "100"},{"side": "buy","instId": "LTC-USDT","tdMode": "cash","ordType": "market","sz": "1"}]`
calculateOrderbookChecksumUpdateOrderbookJSON = `{"Bids":[{"Amount":56,"Price":0.07014,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":608,"Price":0.07011,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":110,"Price":0.07009,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1264,"Price":0.07006,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":2347,"Price":0.07004,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":279,"Price":0.07003,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":52,"Price":0.07001,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":91,"Price":0.06997,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":4242,"Price":0.06996,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":486,"Price":0.06995,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":161,"Price":0.06992,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":63,"Price":0.06991,"ID":0,"Period":0,"LiquidationOrders":0,
"OrderCount":0},{"Amount":7518,"Price":0.06988,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":186,"Price":0.06976,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":71,"Price":0.06975,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1086,"Price":0.06973,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":513,"Price":0.06961,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":4603,"Price":0.06959,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":186,"Price":0.0695,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":3043,"Price":0.06946,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":103,"Price":0.06939,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5053,"Price":0.0693,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5039,"Price":0.06909,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5037,"Price":0.06888,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1526,"Price":0.06886,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5008,"Price":0.06867,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5065,"Price":0.06846,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1572,"Price":0.06826,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1565,"Price":0.06801,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":67,"Price":0.06748,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":111,"Price":0.0674,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":10038,"Price":0.0672,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.06652,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1526,"Price":0.06625,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":10924,"Price":0.06619,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.05986,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.05387,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.04848,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.04363,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0}],"Asks":[{"Amount":5,"Price":0.07026,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":765,"Price":0.07027,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":110,"Price":0.07028,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1264,"Price":0.0703,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":280,"Price":0.07034,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":2255,"Price":0.07035,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":28,"Price":0.07036,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":63,"Price":0.07037,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":137,"Price":0.07039,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":48,"Price":0.0704,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":32,"Price":0.07041,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":3985,"Price":0.07043,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":257,"Price":0.07057,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":7870,"Price":0.07058,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":161,"Price":0.07059,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":4539,"Price":0.07061,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1438,"Price":0.07068,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":3162,"Price":0.07088,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":99,"Price":0.07104,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5018,"Price":0.07108,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1540,"Price":0.07115,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5080,"Price":0.07129,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1512,"Price":0.07145,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5016,"Price":0.0715,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5026,"Price":0.07171,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":5062,"Price":0.07192,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1517,"Price":0.07197,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1511,"Price":0.0726,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":10376,"Price":0.07314,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.07354,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":10277,"Price":0.07466,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":269,"Price":0.07626,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":269,"Price":0.07636,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.0809,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.08899,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.09789,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0},{"Amount":1,"Price":0.10768,"ID":0,"Period":0,"LiquidationOrders":0,"OrderCount":0}],"Exchange":"Okx","Pair":"BTC-USDT","Asset":"spot","LastUpdated":"0001-01-01T00:00:00Z","LastUpdateID":0,"PriceDuplication":false,"IsFundingRate":false,"RestSnapshot":false,"IDAlignment":false}`
placeMultipleOrderParamsJSON = `[{"instId":"BTC-USDT","tdMode":"cash","clOrdId":"b159","side":"buy","ordType":"limit","px":"2.15","sz":"2"},{"instId":"BTC-USDT","tdMode":"cash","clOrdId":"b15","side":"buy","ordType":"limit","px":"2.15","sz":"2"}]`
)
func TestPlaceMultipleOrders(t *testing.T) {
t.Parallel()
var params []PlaceOrderRequestParam
err := json.Unmarshal([]byte(placeMultipleOrderParamsJSON), &params)
assert.NoError(t, err)
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{})
require.ErrorIs(t, err, order.ErrSubmissionIsNil)
arg := PlaceOrderRequestParam{
ReduceOnly: true,
}
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = "buy"
arg.TradeMode = "abc"
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = "cross"
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = orderLimit
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.AssetType = asset.Futures
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.PositionSide = "long"
_, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceMultipleOrders(contextGenerate(), params)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelSingleOrder(t *testing.T) {
t.Parallel()
_, err := ok.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{OrderID: "12321312312"})
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{InstrumentID: "BTC-USDT"})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelSingleOrder(contextGenerate(),
&CancelOrderRequestParam{
InstrumentID: spotTP.String(),
OrderID: "2510789768709120",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelMultipleOrders(t *testing.T) {
t.Parallel()
_, err := ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := CancelOrderRequestParam{}
_, err = ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{
{
InstrumentID: spotTP.String(),
OrderID: "2510789768709120",
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendOrder(t *testing.T) {
t.Parallel()
_, err := ok.AmendOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
arg := &AmendOrderRequestParams{}
_, err = ok.AmendOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.AmendOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
arg.OrderID = "1234"
_, err = ok.AmendOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendOrder(contextGenerate(), &AmendOrderRequestParams{
InstrumentID: spotTP.String(),
OrderID: "2510789768709120",
NewPrice: 1233324.332,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendMultipleOrders(t *testing.T) {
t.Parallel()
_, err := ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := AmendOrderRequestParams{
NewPriceInUSD: 1233,
}
_, err = ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
arg.ClientOrderID = "123212"
_, err = ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg})
require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{{
InstrumentID: spotTP.String(),
OrderID: "2510789768709120",
NewPrice: 1233324.332,
}})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestClosePositions(t *testing.T) {
t.Parallel()
_, err := ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{MarginMode: "cross"})
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{InstrumentID: "BTC-USDT", MarginMode: "abc"})
require.ErrorIs(t, err, margin.ErrMarginTypeUnsupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{
InstrumentID: spotTP.String(),
MarginMode: "cross",
Currency: "BTC",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOrderDetail(t *testing.T) {
t.Parallel()
_, err := ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{})
assert.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{OrderID: "1234"})
assert.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{InstrumentID: "BTC-USDT"})
assert.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{InstrumentID: "SUI-USDT", OrderID: "1974857619964870656"})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOrderList(t *testing.T) {
t.Parallel()
_, err := ok.GetOrderList(contextGenerate(), &OrderListRequestParams{})
assert.ErrorIs(t, err, common.ErrEmptyParams)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetOrderList(contextGenerate(), &OrderListRequestParams{Limit: 1})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGet7DayOrderHistory(t *testing.T) {
t.Parallel()
_, err := ok.getOrderHistory(contextGenerate(), &OrderHistoryRequestParams{}, "", request.UnAuth)
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.getOrderHistory(contextGenerate(), &OrderHistoryRequestParams{Category: "abc"}, "", request.UnAuth)
require.ErrorIs(t, err, errInvalidInstrumentType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.Get7DayOrderHistory(contextGenerate(), &OrderHistoryRequestParams{OrderListRequestParams: OrderListRequestParams{InstrumentType: "MARGIN"}})
require.NoError(t, err)
require.NotNil(t, result)
}
func TestGet3MonthOrderHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.Get3MonthOrderHistory(contextGenerate(), &OrderHistoryRequestParams{OrderListRequestParams: OrderListRequestParams{InstrumentType: "MARGIN"}})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestTransactionHistory(t *testing.T) {
t.Parallel()
_, err := ok.getTransactionDetails(contextGenerate(), &TransactionDetailRequestParams{}, "", request.UnAuth)
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.getTransactionDetails(contextGenerate(), &TransactionDetailRequestParams{Limit: 10}, "", request.UnAuth)
require.ErrorIs(t, err, errInvalidInstrumentType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetTransactionDetailsLast3Days(contextGenerate(), &TransactionDetailRequestParams{InstrumentType: "MARGIN", Limit: 1})
require.NoError(t, err)
require.NotNil(t, result)
}
func TestGetTransactionDetailsLast3Months(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetTransactionDetailsLast3Months(contextGenerate(), &TransactionDetailRequestParams{InstrumentType: "MARGIN"})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceAlgoOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceAlgoOrder(contextGenerate(), &AlgoOrderParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &AlgoOrderParams{
ReduceOnly: true,
}
arg.OrderType = "conditional"
_, err = ok.PlaceAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.PlaceAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = TradeModeCross
_, err = ok.PlaceAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = order.Sell.Lower()
arg.OrderType = ""
_, err = ok.PlaceAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = "limit"
_, err = ok.PlaceAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
}
func TestStopOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceStopOrder(contextGenerate(), &AlgoOrderParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &AlgoOrderParams{
ReduceOnly: true,
}
arg.OrderType = "conditional"
_, err = ok.PlaceStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.TakeProfitTriggerPrice = 123
_, err = ok.PlaceStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrUnknownPriceType)
arg.TakeProfitTriggerPriceType = "last_price"
arg.AlgoClientOrderID = "12345"
_, err = ok.PlaceStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.PlaceStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = TradeModeCross
_, err = ok.PlaceStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = order.Sell.Lower()
arg.OrderType = ""
_, err = ok.PlaceStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = "limit"
_, err = ok.PlaceStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
// Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder.
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceStopOrder(contextGenerate(), &AlgoOrderParams{
AlgoClientOrderID: "681096944655273984",
TakeProfitTriggerPriceType: "index",
InstrumentID: "BTC-USDT",
OrderType: "conditional",
Side: order.Sell.Lower(),
TradeMode: "isolated",
Size: 12,
TakeProfitTriggerPrice: 12335,
TakeProfitOrderPrice: 1234,
})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceIcebergOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true})
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
_, err = ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{OrderType: "iceberg"})
require.ErrorIs(t, err, errMissingSizeLimit)
_, err = ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{OrderType: "iceberg", SizeLimit: 123})
require.ErrorIs(t, err, errInvalidPriceLimit)
// Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder.
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{
AlgoClientOrderID: "681096944655273984",
LimitPrice: 100.22, SizeLimit: 9999.9,
PriceSpread: 0.04, InstrumentID: "BTC-USDT",
OrderType: "iceberg", Side: order.Buy.Lower(),
TradeMode: "isolated", Size: 6,
})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceTWAPOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true})
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
_, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{OrderType: "twap"})
require.ErrorIs(t, err, errMissingSizeLimit)
_, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{SizeLimit: 2, OrderType: "twap"})
require.ErrorIs(t, err, errInvalidPriceLimit)
_, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{SizeLimit: 2, OrderType: "twap", LimitPrice: 1234.5})
require.ErrorIs(t, err, errMissingIntervalValue)
// Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder.
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{
AlgoClientOrderID: "681096944655273984",
InstrumentID: "BTC-USDT",
LimitPrice: 100.22,
SizeLimit: 9999.9,
OrderType: "twap",
PriceSpread: 0.4,
TradeMode: "cross",
Side: order.Sell.Lower(),
Size: 6,
TimeInterval: kline.ThreeDay,
})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceTakeProfitStopLossOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true})
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
_, err = ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{OrderType: "conditional"})
require.ErrorIs(t, err, order.ErrPriceBelowMin)
_, err = ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{
OrderType: "conditional",
StopLossTriggerPrice: 1234,
StopLossTriggerPriceType: "abcd"})
require.ErrorIs(t, err, order.ErrUnknownPriceType)
// Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder.
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{
OrderType: "conditional",
StopLossTriggerPrice: 1234,
StopLossTriggerPriceType: "last",
AlgoClientOrderID: "681096944655273984",
InstrumentID: "BTC-USDT",
LimitPrice: 100.22,
SizeLimit: 9999.9,
PriceSpread: 0.4,
TradeMode: "cross",
Side: order.Sell.Lower(),
Size: 6,
TimeInterval: kline.ThreeDay,
})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceChaseAlgoOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceChaseAlgoOrder(contextGenerate(), &AlgoOrderParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &AlgoOrderParams{
ReduceOnly: true,
}
_, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = "chase"
arg.MaxChaseType = "percentage"
_, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errPriceTrackingNotSet)
arg.MaxChaseType = "percentage"
arg.MaxChaseValue = .5
_, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = "BTC-USDT"
_, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = "cross"
_, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = order.Sell.Lower()
_, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
// Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder.
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceChaseAlgoOrder(contextGenerate(), &AlgoOrderParams{
AlgoClientOrderID: "681096944655273984",
InstrumentID: "BTC-USDT",
LimitPrice: 100.22,
OrderType: "chase",
TradeMode: "cross",
Side: order.Sell.Lower(),
MaxChaseType: "distance",
MaxChaseValue: .5,
Size: 6,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestTriggerAlgoOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234"})
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
_, err = ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234", OrderType: "trigger"})
require.ErrorIs(t, err, order.ErrPriceBelowMin)
_, err = ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234", OrderType: "trigger", TriggerPrice: 123., TriggerPriceType: "abcd"})
require.ErrorIs(t, err, order.ErrUnknownPriceType)
// Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder.
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{
AlgoClientOrderID: "681096944655273984",
TriggerPriceType: "mark",
TriggerPrice: 1234,
InstrumentID: "BTC-USDT",
OrderType: "trigger",
Side: order.Buy.Lower(),
TradeMode: "cross",
Size: 5,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceTrailingStopOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{})
assert.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{Size: 2})
assert.ErrorIs(t, err, order.ErrTypeIsInvalid)
_, err = ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{Size: 2, OrderType: "move_order_stop"})
assert.ErrorIs(t, err, errPriceTrackingNotSet)
// Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder.
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{
AlgoClientOrderID: "681096944655273984", CallbackRatio: 0.01,
InstrumentID: "BTC-USDT", OrderType: "move_order_stop",
Side: order.Buy.Lower(), TradeMode: "isolated",
Size: 2, ActivePrice: 1234})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAlgoOrder(t *testing.T) {
t.Parallel()
arg := AlgoOrderCancelParams{}
_, err := ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg.AlgoOrderID = "90994943"
_, err = ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = "BTC-USDT"
arg.AlgoOrderID = ""
_, err = ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{
{
InstrumentID: "BTC-USDT",
AlgoOrderID: "90994943",
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAdvanceAlgoOrder(t *testing.T) {
t.Parallel()
_, err := ok.CancelAdvanceAlgoOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{}})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{InstrumentID: "90994943"}})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{AlgoOrderID: "90994943"}})
require.ErrorIs(t, err, errMissingInstrumentID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{
InstrumentID: "BTC-USDT",
AlgoOrderID: "90994943",
}})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAlgoOrderList(t *testing.T) {
t.Parallel()
_, err := ok.GetAlgoOrderList(contextGenerate(), "", "", "", "", "", time.Time{}, time.Time{}, 1)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAlgoOrderList(contextGenerate(), "conditional", "", "", "", "", time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAlgoOrderHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetAlgoOrderHistory(contextGenerate(), "", "effective", "", "", "", time.Time{}, time.Time{}, 1)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
_, err = ok.GetAlgoOrderHistory(contextGenerate(), "conditional", "", "", "", "", time.Time{}, time.Time{}, 1)
require.ErrorIs(t, err, errMissingEitherAlgoIDOrState)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAlgoOrderHistory(contextGenerate(), "conditional", "effective", "", "", "", time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetEasyConvertCurrencyList(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetEasyConvertCurrencyList(contextGenerate(), "1")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOneClickRepayCurrencyList(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetOneClickRepayCurrencyList(contextGenerate(), "cross")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceEasyConvert(t *testing.T) {
t.Parallel()
_, err := ok.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{FromCurrency: []string{"BTC"}})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{FromCurrency: []string{"BTC"}, ToCurrency: "USDT"})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetEasyConvertHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetEasyConvertHistory(contextGenerate(), time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOneClickRepayHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetOneClickRepayHistory(contextGenerate(), time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestTradeOneClickRepay(t *testing.T) {
t.Parallel()
_, err := ok.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{DebtCurrency: []string{}, RepayCurrency: "USDT"})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{DebtCurrency: []string{"BTC"}, RepayCurrency: ""})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{
DebtCurrency: []string{"BTC"},
RepayCurrency: "USDT",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCounterparties(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetCounterparties(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
const createRFQInputJSON = `{"anonymous": true,"counterparties":["Trader1","Trader2"],"clRfqId":"rfq01","legs":[{"sz":"25","side":"buy","instId":"BTCUSD-221208-100000-C"},{"sz":"150","side":"buy","instId":"ETH-USDT","tgtCcy":"base_ccy"}]}`
func TestCreateRFQ(t *testing.T) {
t.Parallel()
var input *CreateRFQInput
err := json.Unmarshal([]byte(createRFQInputJSON), &input)
require.NoError(t, err)
_, err = ok.CreateRFQ(contextGenerate(), &CreateRFQInput{CounterParties: []string{}})
require.ErrorIs(t, err, errInvalidCounterParties)
_, err = ok.CreateRFQ(contextGenerate(), &CreateRFQInput{CounterParties: []string{"Trader1"}})
require.ErrorIs(t, err, errMissingLegs)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CreateRFQ(contextGenerate(), input)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelRFQ(t *testing.T) {
t.Parallel()
_, err := ok.CancelRFQ(contextGenerate(), "", "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelRFQ(contextGenerate(), "", "somersdjskfjsdkfjxvxv")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestMultipleCancelRFQ(t *testing.T) {
t.Parallel()
_, err := ok.CancelMultipleRFQs(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
_, err = ok.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{RFQIDs: make([]string, 100), ClientRFQIDs: make([]string, 100)})
require.ErrorIs(t, err, errMaxRFQOrdersToCancel)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{ClientRFQIDs: []string{"somersdjskfjsdkfjxvxv"}})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAllRFQs(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAllRFQs(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestExecuteQuote(t *testing.T) {
t.Parallel()
_, err := ok.ExecuteQuote(contextGenerate(), "", "")
assert.ErrorIs(t, err, errMissingRFQIDOrQuoteID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ExecuteQuote(contextGenerate(), "22540", "84073")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetQuoteProducts(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetQuoteProducts(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetQuoteProducts(t *testing.T) {
t.Parallel()
_, err := ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{{InstrumentType: "ABC"}})
require.ErrorIs(t, err, errInvalidInstrumentType)
arg := SetQuoteProductParam{InstrumentType: "SWAP"}
_, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg})
require.ErrorIs(t, err, errMissingMakerInstrumentSettings)
data := MakerInstrumentSetting{MaxBlockSize: 10000, MakerPriceBand: 5}
arg.Data = []MakerInstrumentSetting{data}
_, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg})
require.ErrorIs(t, err, errInvalidUnderlying)
arg.InstrumentType = "SPOT"
data = MakerInstrumentSetting{Underlying: "BTC-USD", MaxBlockSize: 10000, MakerPriceBand: 5}
arg.Data = []MakerInstrumentSetting{data}
_, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{
{
InstrumentType: "SWAP",
Data: []MakerInstrumentSetting{
{
Underlying: "BTC-USD",
MaxBlockSize: 10000,
MakerPriceBand: 5,
},
{
Underlying: "ETH-USDT",
},
},
}})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestResetRFQMMPStatus(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ResetRFQMMPStatus(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCreateQuote(t *testing.T) {
t.Parallel()
_, err := ok.CreateQuote(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
arg := &CreateQuoteParams{}
_, err = ok.CreateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingRFQID)
arg.RFQID = "123456789"
_, err = ok.CreateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.QuoteSide = "sell"
_, err = ok.CreateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingLegs)
subArg := QuoteLeg{}
arg.Legs = []QuoteLeg{subArg}
_, err = ok.CreateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
subArg.InstrumentID = "SOL-USD-220909"
arg.Legs = []QuoteLeg{subArg}
_, err = ok.CreateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingSizeOfQuote)
subArg.SizeOfQuoteLeg = 2
arg.Legs = []QuoteLeg{subArg}
_, err = ok.CreateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingLegsQuotePrice)
subArg.Price = 1234
arg.Legs = []QuoteLeg{subArg}
_, err = ok.CreateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CreateQuote(contextGenerate(), &CreateQuoteParams{
RFQID: "12345",
QuoteSide: order.Buy.Lower(),
Legs: []QuoteLeg{
{
Price: 1234,
SizeOfQuoteLeg: 2,
InstrumentID: "SOL-USD-220909",
Side: order.Sell,
},
{
Price: 1234,
SizeOfQuoteLeg: 1,
InstrumentID: "SOL-USD-220909",
Side: order.Buy,
},
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelQuote(t *testing.T) {
t.Parallel()
_, err := ok.CancelQuote(contextGenerate(), "", "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelQuote(contextGenerate(), "1234", "")
require.NoError(t, err)
require.NotNil(t, result)
result, err = ok.CancelQuote(contextGenerate(), "", "1234")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelMultipleQuote(t *testing.T) {
t.Parallel()
_, err := ok.CancelMultipleQuote(contextGenerate(), CancelQuotesRequestParams{})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelMultipleQuote(contextGenerate(), CancelQuotesRequestParams{
QuoteIDs: []string{"1150", "1151", "1152"},
// Block trades require a minimum of $100,000 in assets in your trading account
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAllRFQQuotes(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
tt, err := ok.CancelAllRFQQuotes(contextGenerate())
require.NoError(t, err)
assert.NotEmpty(t, tt)
}
func TestGetRFQs(t *testing.T) {
t.Parallel()
_, err := ok.GetRFQs(contextGenerate(), &RFQRequestParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetRFQs(contextGenerate(), &RFQRequestParams{
Limit: 1,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetQuotes(t *testing.T) {
t.Parallel()
_, err := ok.GetQuotes(contextGenerate(), &QuoteRequestParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetQuotes(contextGenerate(), &QuoteRequestParams{
Limit: 3,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetRFQTrades(t *testing.T) {
t.Parallel()
_, err := ok.GetRFQTrades(contextGenerate(), &RFQTradesRequestParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetRFQTrades(contextGenerate(), &RFQTradesRequestParams{Limit: 1})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPublicRFQTrades(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetPublicRFQTrades(contextGenerate(), "", "", 3)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFundingCurrencies(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFundingCurrencies(contextGenerate(), currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBalance(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBalance(contextGenerate(), currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetNonTradableAssets(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetNonTradableAssets(contextGenerate(), currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAccountAssetValuation(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAccountAssetValuation(contextGenerate(), currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestFundingTransfer(t *testing.T) {
t.Parallel()
_, err := ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{})
assert.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{
BeneficiaryAccountType: "6", RemittingAccountType: "18", Currency: currency.BTC})
assert.ErrorIs(t, err, order.ErrAmountBelowMin)
_, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{
Amount: 12.000, BeneficiaryAccountType: "6",
RemittingAccountType: "18", Currency: currency.EMPTYCODE})
assert.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{
Amount: 12.000, BeneficiaryAccountType: "2",
RemittingAccountType: "3", Currency: currency.BTC})
assert.ErrorIs(t, err, errAddressRequired)
_, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{
Amount: 12.000, BeneficiaryAccountType: "2",
RemittingAccountType: "18", Currency: currency.BTC})
assert.ErrorIs(t, err, errAddressRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{
Amount: 12.000,
BeneficiaryAccountType: "6",
RemittingAccountType: "18",
Currency: currency.BTC,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFundsTransferState(t *testing.T) {
t.Parallel()
_, err := ok.GetFundsTransferState(contextGenerate(), "", "", 1)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFundsTransferState(contextGenerate(), "754147", "1232", 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAssetBillsDetails(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAssetBillsDetails(contextGenerate(), currency.EMPTYCODE, "", time.Time{}, time.Time{}, 0, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLightningDeposits(t *testing.T) {
t.Parallel()
_, err := ok.GetLightningDeposits(contextGenerate(), currency.EMPTYCODE, 1.00, 0)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.GetLightningDeposits(contextGenerate(), currency.BTC, 0, 0)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLightningDeposits(contextGenerate(), currency.BTC, 1.00, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCurrencyDepositAddress(t *testing.T) {
t.Parallel()
_, err := ok.GetCurrencyDepositAddress(contextGenerate(), currency.EMPTYCODE)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetCurrencyDepositAddress(contextGenerate(), currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCurrencyDepositHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetCurrencyDepositHistory(contextGenerate(), currency.BTC, "", "", "", "271", time.Time{}, time.Time{}, 0, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWithdrawal(t *testing.T) {
t.Parallel()
_, err := ok.Withdrawal(contextGenerate(), &WithdrawalInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.EMPTYCODE, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
_, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, ToAddress: core.BitcoinDonationAddress})
require.ErrorIs(t, err, errAddressRequired)
_, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4"})
require.ErrorIs(t, err, errAddressRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress})
require.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{
Amount: 0.1,
WithdrawalDestination: "4",
TransactionFee: 0.00005,
Currency: currency.BTC,
ChainName: "BTC-Bitcoin",
ToAddress: core.BitcoinDonationAddress,
RecipientInformation: &WithdrawalRecipientInformation{
WalletType: "exchange",
ExchangeID: "did:ethr:0xfeb4f99829a9acdf52979abee87e83addf22a7e1",
ReceiverFirstName: "Bruce",
ReceiverLastName: "Wayne",
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestLightningWithdrawal(t *testing.T) {
t.Parallel()
_, err := ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{
Invoice: "lnbc100u1psnnvhtpp5yq2x3q5hhrzsuxpwx7ptphwzc4k4wk0j3stp0099968m44cyjg9sdqqcqzpgxqzjcsp5hz", Currency: currency.EMPTYCODE})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{Invoice: "", Currency: currency.BTC})
require.ErrorIs(t, err, errInvoiceTextMissing)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{
Currency: currency.BTC,
Invoice: "lnbc100u1psnnvhtpp5yq2x3q5hhrzsuxpwx7ptphwzc4k4wk0j3stp0099968m44cyjg9sdqqcqzpgxqzjcsp5hz",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelWithdrawal(t *testing.T) {
t.Parallel()
_, err := ok.CancelWithdrawal(contextGenerate(), "")
require.ErrorIs(t, err, errMissingValidWithdrawalID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelWithdrawal(contextGenerate(), "fjasdfkjasdk")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetWithdrawalHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetWithdrawalHistory(contextGenerate(), currency.BTC, "", "", "", "", time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSmallAssetsConvert(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SmallAssetsConvert(contextGenerate(), []string{"BTC", "USDT"})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSavingBalance(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSavingBalance(contextGenerate(), currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSavingsPurchase(t *testing.T) {
t.Parallel()
_, err := ok.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &SavingsPurchaseRedemptionInput{Rate: 1}
_, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.Currency = currency.BTC
_, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.Amount = 123.4
_, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Rate = 0.001
arg.ActionType = "purchase"
_, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg)
require.ErrorIs(t, err, errRateRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{
Amount: 123.4,
Currency: currency.BTC,
Rate: 1,
ActionType: "purchase",
})
require.NoError(t, err)
require.NotNil(t, result)
result, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{
Amount: 123.4,
Currency: currency.BTC,
Rate: 1,
ActionType: "redempt",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetLendingRate(t *testing.T) {
t.Parallel()
_, err := ok.SetLendingRate(contextGenerate(), &LendingRate{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.EMPTYCODE, Rate: 2})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.BTC})
require.ErrorIs(t, err, errRateRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.BTC, Rate: 2})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLendingHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLendingHistory(contextGenerate(), currency.USDT, time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPublicBorrowInfo(t *testing.T) {
t.Parallel()
result, err := ok.GetPublicBorrowInfo(contextGenerate(), currency.EMPTYCODE)
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.GetPublicBorrowInfo(contextGenerate(), currency.USDT)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPublicBorrowHistory(t *testing.T) {
t.Parallel()
result, err := ok.GetPublicBorrowHistory(contextGenerate(), currency.USDT, time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMonthlyStatement(t *testing.T) {
t.Parallel()
_, err := ok.GetMonthlyStatement(contextGenerate(), "")
require.ErrorIs(t, err, errMonthNameRequired)
_, err = ok.GetMonthlyStatement(contextGenerate(), "")
require.ErrorIs(t, err, errMonthNameRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMonthlyStatement(contextGenerate(), "Jan")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestApplyForMonthlyStatement(t *testing.T) {
t.Parallel()
_, err := ok.ApplyForMonthlyStatement(contextGenerate(), "")
require.ErrorIs(t, err, errMonthNameRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ApplyForMonthlyStatement(contextGenerate(), "Jan")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetConvertCurrencies(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetConvertCurrencies(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetConvertCurrencyPair(t *testing.T) {
t.Parallel()
_, err := ok.GetConvertCurrencyPair(contextGenerate(), currency.EMPTYCODE, currency.BTC)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.GetConvertCurrencyPair(contextGenerate(), currency.USDT, currency.EMPTYCODE)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetConvertCurrencyPair(contextGenerate(), currency.USDT, currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestEstimateQuote(t *testing.T) {
t.Parallel()
_, err := ok.EstimateQuote(contextGenerate(), &EstimateQuoteRequestInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &EstimateQuoteRequestInput{Tag: "abcd"}
_, err = ok.EstimateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.BaseCurrency = currency.BTC
_, err = ok.EstimateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.QuoteCurrency = currency.BTC
_, err = ok.EstimateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = order.Sell.Lower()
_, err = ok.EstimateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.RFQAmount = 30
_, err = ok.EstimateQuote(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.EstimateQuote(contextGenerate(), &EstimateQuoteRequestInput{
BaseCurrency: currency.BTC,
QuoteCurrency: currency.USDT,
Side: order.Sell.Lower(),
RFQAmount: 30,
RFQSzCurrency: "USDT",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestConvertTrade(t *testing.T) {
t.Parallel()
_, err := ok.ConvertTrade(contextGenerate(), &ConvertTradeInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &ConvertTradeInput{Tag: "123"}
_, err = ok.ConvertTrade(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.BaseCurrency = "BTC"
_, err = ok.ConvertTrade(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.QuoteCurrency = "USDT"
_, err = ok.ConvertTrade(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = order.Buy.Lower()
_, err = ok.ConvertTrade(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.Size = 2
_, err = ok.ConvertTrade(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.SizeCurrency = currency.USDT
_, err = ok.ConvertTrade(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ConvertTrade(contextGenerate(), &ConvertTradeInput{
BaseCurrency: "BTC",
QuoteCurrency: "USDT",
Side: order.Buy.Lower(),
Size: 2,
SizeCurrency: currency.USDT,
QuoteID: "16461885104612381",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetConvertHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetConvertHistory(contextGenerate(), time.Time{}, time.Time{}, 1, "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetNonZeroAccountBalance(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.AccountBalance(contextGenerate(), currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPositions(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetPositions(contextGenerate(), "", "", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPositionsHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetPositionsHistory(contextGenerate(), "", "", "", "1234213123", 0, 1, time.Time{}, time.Time{})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAccountAndPositionRisk(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAccountAndPositionRisk(contextGenerate(), "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBillsDetail(t *testing.T) {
t.Parallel()
_, err := ok.GetBillsDetailLast7Days(contextGenerate(), &BillsDetailQueryParameter{})
require.ErrorIs(t, err, common.ErrEmptyParams)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBillsDetailLast7Days(contextGenerate(), &BillsDetailQueryParameter{
Limit: 3})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBillsDetail3Months(t *testing.T) {
t.Parallel()
_, err := ok.GetBillsDetail3Months(contextGenerate(), &BillsDetailQueryParameter{})
require.ErrorIs(t, err, common.ErrEmptyParams)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBillsDetail3Months(contextGenerate(), &BillsDetailQueryParameter{Limit: 3})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestApplyBillDetails(t *testing.T) {
t.Parallel()
_, err := ok.ApplyBillDetails(contextGenerate(), "", "Q2")
require.ErrorIs(t, err, errYearRequired)
_, err = ok.ApplyBillDetails(contextGenerate(), "2023", "")
require.ErrorIs(t, err, errQuarterValueRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.ApplyBillDetails(contextGenerate(), "2023", "Q2")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBillsHistoryArchive(t *testing.T) {
t.Parallel()
_, err := ok.GetBillsHistoryArchive(contextGenerate(), "", "Q2")
require.ErrorIs(t, err, errYearRequired)
_, err = ok.GetBillsHistoryArchive(contextGenerate(), "2023", "")
require.ErrorIs(t, err, errQuarterValueRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBillsHistoryArchive(contextGenerate(), "2023", "Q2")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAccountConfiguration(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAccountConfiguration(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetPositionMode(t *testing.T) {
t.Parallel()
_, err := ok.SetPositionMode(contextGenerate(), "")
require.ErrorIs(t, err, errInvalidPositionMode)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.SetPositionMode(contextGenerate(), "net_mode")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetLeverageRate(t *testing.T) {
t.Parallel()
_, err := ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{Leverage: 5, MarginMode: "isolated", AssetType: asset.Futures})
require.ErrorIs(t, err, errEitherInstIDOrCcyIsRequired)
_, err = ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{
Currency: currency.USDT,
Leverage: 5,
MarginMode: "isolated",
InstrumentID: "BTC-USDT",
AssetType: asset.Futures,
})
require.ErrorIs(t, err, order.ErrSideIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
_, err = ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{
Currency: currency.USDT,
Leverage: 5,
MarginMode: "cross",
InstrumentID: "BTC-USDT",
})
assert.True(t, err == nil || errors.Is(err, common.ErrNoResponse))
}
func TestGetMaximumBuySellAmountOROpenAmount(t *testing.T) {
t.Parallel()
_, err := ok.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, "", "cross", "", 5, true)
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, "BTC-USDT", "", "", 5, true)
require.ErrorIs(t, err, errInvalidTradeModeValue)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, "BTC-USDT", "cross", "", 5, true)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMaximumAvailableTradableAmount(t *testing.T) {
t.Parallel()
_, err := ok.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, "", "cross", "", true, false, 123)
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, "BTC-USDT", "", "", true, false, 123)
require.ErrorIs(t, err, errInvalidTradeModeValue)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, "BTC-USDT", "cross", "", true, false, 123)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestIncreaseDecreaseMargin(t *testing.T) {
t.Parallel()
_, err := ok.IncreaseDecreaseMargin(contextGenerate(), &IncreaseDecreaseMarginInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &IncreaseDecreaseMarginInput{Currency: "USD"}
_, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = "BTC-USDT"
_, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.PositionSide = "long"
_, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.MarginBalanceType = "reduce"
_, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.IncreaseDecreaseMargin(contextGenerate(), &IncreaseDecreaseMarginInput{
InstrumentID: "BTC-USDT",
PositionSide: "long",
MarginBalanceType: "add",
Amount: 1000,
Currency: "USD",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLeverageRate(t *testing.T) {
t.Parallel()
_, err := ok.GetLeverageRate(contextGenerate(), "", "cross", currency.EMPTYCODE)
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.GetLeverageRate(contextGenerate(), "BTC-USDT", "", currency.EMPTYCODE)
require.ErrorIs(t, err, margin.ErrMarginTypeUnsupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLeverageRate(contextGenerate(), "BTC-USDT", "cross", currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMaximumLoanOfInstrument(t *testing.T) {
t.Parallel()
_, err := ok.GetMaximumLoanOfInstrument(contextGenerate(), "", "isolated", currency.ZRX)
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.GetMaximumLoanOfInstrument(contextGenerate(), "ZRX-BTC", "", currency.ZRX)
require.ErrorIs(t, err, margin.ErrInvalidMarginType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMaximumLoanOfInstrument(contextGenerate(), spotTP.String(), "isolated", currency.ZRX)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTradeFee(t *testing.T) {
t.Parallel()
_, err := ok.GetTradeFee(contextGenerate(), "", "", "", "", "")
require.ErrorIs(t, err, errInvalidInstrumentType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetTradeFee(contextGenerate(), instTypeSpot, "", "", "", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetInterestAccruedData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetInterestAccruedData(contextGenerate(), 0, 1, currency.EMPTYCODE, "", "", time.Time{}, time.Time{})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetInterestRate(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetInterestRate(contextGenerate(), currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetGreeks(t *testing.T) {
t.Parallel()
_, err := ok.SetGreeks(contextGenerate(), "")
require.ErrorIs(t, err, errMissingValidGreeksType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetGreeks(contextGenerate(), "PA")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestIsolatedMarginTradingSettings(t *testing.T) {
t.Parallel()
_, err := ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "", InstrumentType: "MARGIN"})
require.ErrorIs(t, err, errMissingIsolatedMarginTradingSetting)
_, err = ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "autonomy", InstrumentType: ""})
require.ErrorIs(t, err, errInvalidInstrumentType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "autonomy", InstrumentType: "MARGIN"})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMaximumWithdrawals(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMaximumWithdrawals(contextGenerate(), currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAccountRiskState(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAccountRiskState(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestVIPLoansBorrowAndRepay(t *testing.T) {
t.Parallel()
_, err := ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.EMPTYCODE, Side: "borrow", Amount: 12})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "", Amount: 12})
require.ErrorIs(t, err, order.ErrSideIsInvalid)
_, err = ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "borrow", Amount: 0})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "borrow", Amount: 12})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBorrowAndRepayHistoryForVIPLoans(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBorrowAndRepayHistoryForVIPLoans(contextGenerate(), currency.EMPTYCODE, time.Time{}, time.Time{}, 3)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBorrowInterestAndLimit(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBorrowInterestAndLimit(contextGenerate(), 1, currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFixedLoanBorrowLimit(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFixedLoanBorrowLimit(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFixedLoanBorrowQuote(t *testing.T) {
t.Parallel()
_, err := ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "", "30D", "123423423", 1, .4)
require.ErrorIs(t, err, errBorrowTypeRequired)
_, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.EMPTYCODE, "normal", "30D", "123423423", 1, .4)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "", 0, .4)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
_, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "123423423", 1, 0)
require.ErrorIs(t, err, errMaxRateRequired)
_, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "", "123423423", 1, .4)
require.ErrorIs(t, err, errLendingTermIsRequired)
_, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "reborrow", "30D", "", 1, .4)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "123423423", 1, .4)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceFixedLoanBorrowingOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.EMPTYCODE, 1, .3, .2, "30D", false)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 0, .3, .2, "30D", false)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
_, err = ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, 0, .2, "30D", false)
require.ErrorIs(t, err, errMaxRateRequired)
_, err = ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, .3, .2, "", false)
require.ErrorIs(t, err, errLendingTermIsRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, .3, .2, "30D", false)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendFixedLoanBorrowingOrder(t *testing.T) {
t.Parallel()
_, err := ok.AmendFixedLoanBorrowingOrder(contextGenerate(), "", false, .4)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendFixedLoanBorrowingOrder(contextGenerate(), "12312312", false, .4)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestManualRenewFixedLoanBorrowingOrder(t *testing.T) {
t.Parallel()
_, err := ok.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "", .3)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "12312312", 0)
require.ErrorIs(t, err, errMaxRateRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "12312312", .3)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestRepayFixedLoanBorrowingOrder(t *testing.T) {
t.Parallel()
_, err := ok.RepayFixedLoanBorrowingOrder(contextGenerate(), "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.RepayFixedLoanBorrowingOrder(contextGenerate(), "12321")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestConvertFixedLoanToMarketLoan(t *testing.T) {
t.Parallel()
_, err := ok.ConvertFixedLoanToMarketLoan(contextGenerate(), "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ConvertFixedLoanToMarketLoan(contextGenerate(), "12321")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestReduceLiabilitiesForFixedLoan(t *testing.T) {
t.Parallel()
_, err := ok.ReduceLiabilitiesForFixedLoan(contextGenerate(), "", false)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ReduceLiabilitiesForFixedLoan(contextGenerate(), "123123", false)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFixedLoanBorrowOrderList(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFixedLoanBorrowOrderList(contextGenerate(), currency.USDT, "1231231", "8", "30D", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestManualBorrowOrRepay(t *testing.T) {
t.Parallel()
_, err := ok.ManualBorrowOrRepay(contextGenerate(), currency.EMPTYCODE, "borrow", 1)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "", 1)
require.ErrorIs(t, err, errLendingSideRequired)
_, err = ok.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "borrow", 0)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "borrow", 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetAutoRepay(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetAutoRepay(contextGenerate(), true)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBorrowRepayHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBorrowRepayHistory(contextGenerate(), currency.ETH, "auto_borrow", time.Time{}, time.Time{}, 100)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestNewPositionBuilder(t *testing.T) {
t.Parallel()
_, err := ok.NewPositionBuilder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.NewPositionBuilder(contextGenerate(), &PositionBuilderParam{
InclRealPosAndEq: false,
SimPos: []SimulatedPosition{
{
Position: "-10",
InstrumentID: "BTC-USDT-SWAP",
},
{
Position: "10",
InstrumentID: "LTC-USDT-SWAP",
},
},
SimAsset: []SimulatedAsset{
{
Currency: "USDT",
Amount: 100,
},
},
SpotOffsetType: "1",
GreeksType: "CASH",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetRiskOffsetAmount(t *testing.T) {
t.Parallel()
_, err := ok.SetRiskOffsetAmount(contextGenerate(), currency.EMPTYCODE, 123)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.SetRiskOffsetAmount(contextGenerate(), currency.USDT, 0)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.SetRiskOffsetAmount(contextGenerate(), currency.USDT, 123)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetGreeks(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
_, err := ok.GetGreeks(contextGenerate(), currency.EMPTYCODE)
assert.NoError(t, err)
}
func TestGetPMLimitation(t *testing.T) {
t.Parallel()
_, err := ok.GetPMPositionLimitation(contextGenerate(), "", "BTC-USDT", "")
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.GetPMPositionLimitation(contextGenerate(), "SWAP", "", "")
require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetPMPositionLimitation(contextGenerate(), "SWAP", "BTC-USDT", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestViewSubaccountList(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.ViewSubAccountList(contextGenerate(), false, "", time.Time{}, time.Time{}, 2)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestResetSubAccountAPIKey(t *testing.T) {
t.Parallel()
_, err := ok.ResetSubAccountAPIKey(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
_, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{APIKey: apiKey, APIKeyPermission: "trade"})
require.ErrorIs(t, err, errInvalidSubAccountName)
_, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{SubAccountName: "sam", APIKey: "", APIKeyPermission: "trade"})
require.ErrorIs(t, err, errInvalidAPIKey)
_, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{IP: "1.2.3.", SubAccountName: "sam", APIKeyPermission: "trade", APIKey: "sample-api-key"})
require.ErrorIs(t, err, errInvalidIPAddress)
_, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{APIKeyPermission: "abc", APIKey: "sample-api-key", SubAccountName: "sam"})
require.ErrorIs(t, err, errInvalidAPIKeyPermission)
_, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{
Permissions: []string{"abc"}, SubAccountName: "sam",
APIKey: "sample-api-key"})
require.ErrorIs(t, err, errInvalidAPIKeyPermission)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{
SubAccountName: "sam",
APIKey: apiKey,
APIKeyPermission: "trade",
})
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{
SubAccountName: "sam",
APIKey: apiKey,
Permissions: []string{"trade", "read"},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSubaccountTradingBalance(t *testing.T) {
t.Parallel()
_, err := ok.GetSubaccountTradingBalance(contextGenerate(), "")
assert.ErrorIs(t, err, errInvalidSubAccountName)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSubaccountTradingBalance(contextGenerate(), "test1")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSubaccountFundingBalance(t *testing.T) {
t.Parallel()
_, err := ok.GetSubaccountFundingBalance(contextGenerate(), "", currency.EMPTYCODE)
require.ErrorIs(t, err, errInvalidSubAccountName)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSubaccountFundingBalance(contextGenerate(), "test1", currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSubAccountMaximumWithdrawal(t *testing.T) {
t.Parallel()
_, err := ok.GetSubAccountMaximumWithdrawal(contextGenerate(), "", currency.BTC)
require.ErrorIs(t, err, errInvalidSubAccountName)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSubAccountMaximumWithdrawal(contextGenerate(), "test1", currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestHistoryOfSubaccountTransfer(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.HistoryOfSubaccountTransfer(contextGenerate(), currency.EMPTYCODE, "0", "", time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetHistoryOfManagedSubAccountTransfer(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetHistoryOfManagedSubAccountTransfer(contextGenerate(), currency.BTC, "", "", "", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestMasterAccountsManageTransfersBetweenSubaccounts(t *testing.T) {
t.Parallel()
_, err := ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), &SubAccountAssetTransferParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &SubAccountAssetTransferParams{LoanTransfer: true}
_, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.Currency = currency.BTC
_, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.Amount = 1234
_, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidSubaccount)
arg.From = 1
_, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidSubaccount)
arg.To = 7
_, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidSubaccount)
arg.To = 6
_, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidSubAccountName)
arg.FromSubAccount = "sami"
_, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidSubAccountName)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), &SubAccountAssetTransferParams{Currency: currency.BTC, Amount: 1200, From: 6, To: 6, FromSubAccount: "test1", ToSubAccount: "test2", LoanTransfer: true})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetPermissionOfTransferOut(t *testing.T) {
t.Parallel()
_, err := ok.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{CanTransOut: true})
require.ErrorIs(t, err, errInvalidSubAccountName)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{SubAcct: "Test1"})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCustodyTradingSubaccountList(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetCustodyTradingSubaccountList(contextGenerate(), "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetSubAccountVIPLoanAllocation(t *testing.T) {
t.Parallel()
_, err := ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := subAccountVIPLoanAllocationInfo{}
_, err = ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg.LoanAlloc = 123
_, err = ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}})
require.ErrorIs(t, err, errInvalidSubAccountName)
arg.LoanAlloc = -1
arg.SubAcct = "sams"
_, err = ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}})
require.ErrorIs(t, err, errInvalidLoanAllocationValue)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{
Enable: true,
Alloc: []subAccountVIPLoanAllocationInfo{
{
SubAcct: "subAcct1",
LoanAlloc: 20.01,
},
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSubAccountBorrowInterestAndLimit(t *testing.T) {
t.Parallel()
_, err := ok.GetSubAccountBorrowInterestAndLimit(contextGenerate(), "", currency.ETH)
require.ErrorIs(t, err, errInvalidSubAccountName)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSubAccountBorrowInterestAndLimit(contextGenerate(), "123456", currency.ETH)
require.NoError(t, err)
assert.NotNil(t, result)
}
// ETH Staking
func TestGetProductInfo(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetProductInfo(contextGenerate())
require.NoError(t, err)
assert.NotEmpty(t, result)
}
func TestPurcahseETHStaking(t *testing.T) {
t.Parallel()
err := ok.PurchaseETHStaking(contextGenerate(), 0)
assert.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
err = ok.PurchaseETHStaking(contextGenerate(), 100)
assert.NoError(t, err)
}
// RedeemETHStaking
func TestRedeemETHStaking(t *testing.T) {
t.Parallel()
err := ok.RedeemETHStaking(contextGenerate(), 0)
assert.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
err = ok.RedeemETHStaking(contextGenerate(), 100)
assert.NoError(t, err)
}
func TestGetBETHAssetsBalance(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBETHAssetsBalance(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPurchaseAndRedeemHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetPurchaseAndRedeemHistory(contextGenerate(), "", "pending", time.Time{}, time.Now(), 10)
require.ErrorIs(t, err, errLendingTermIsRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetPurchaseAndRedeemHistory(contextGenerate(), "purchase", "pending", time.Time{}, time.Now(), 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAPYHistory(t *testing.T) {
t.Parallel()
result, err := ok.GetAPYHistory(contextGenerate(), 34)
require.NoError(t, err)
assert.NotNil(t, result)
}
const gridTradingPlaceOrder = `{"instId": "BTC-USD-SWAP","algoOrdType": "contract_grid","maxPx": "5000","minPx": "400","gridNum": "10","runType": "1","sz": "200", "direction": "long","lever": "2"}`
func TestPlaceGridAlgoOrder(t *testing.T) {
t.Parallel()
var input GridAlgoOrder
err := json.Unmarshal([]byte(gridTradingPlaceOrder), &input)
require.NoError(t, err)
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), &GridAlgoOrder{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &GridAlgoOrder{BasePosition: true}
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingAlgoOrderType)
arg.AlgoOrdType = "contract_grid"
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.MaxPrice = 1000
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.MinPrice = 1200
arg.GridQuantity = -1
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidGridQuantity)
arg.GridQuantity = 123
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountMustBeSet)
arg.Size = 123
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingRequiredArgumentDirection)
arg.Direction = positionSideLong
_, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidLeverage)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceGridAlgoOrder(contextGenerate(), &input)
require.NoError(t, err)
assert.NotNil(t, result)
}
const gridOrderAmendAlgo = `{
"algoId":"448965992920907776",
"instId":"BTC-USDT",
"slTriggerPx":"1200",
"tpTriggerPx":""
}`
func TestAmendGridAlgoOrder(t *testing.T) {
t.Parallel()
var input *GridAlgoOrderAmend
err := json.Unmarshal([]byte(gridOrderAmendAlgo), &input)
require.NoError(t, err)
arg := &GridAlgoOrderAmend{}
_, err = ok.AmendGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, common.ErrEmptyParams)
arg.TakeProfitTriggerPrice = 1234.5
_, err = ok.AmendGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errAlgoIDRequired)
arg.AlgoID = "560472804207104000"
_, err = ok.AmendGridAlgoOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendGridAlgoOrder(contextGenerate(), input)
require.NoError(t, err)
assert.NotNil(t, result)
}
const stopGridAlgoOrderJSON = `{"algoId":"198273485", "instId":"BTC-USDT", "stopType":"1", "algoOrdType":"grid"}`
func TestStopGridAlgoOrder(t *testing.T) {
t.Parallel()
var resp StopGridAlgoOrderRequest
err := json.Unmarshal([]byte(stopGridAlgoOrderJSON), &resp)
require.NoError(t, err)
_, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := StopGridAlgoOrderRequest{}
_, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg.StopType = 20
_, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg})
require.ErrorIs(t, err, errAlgoIDRequired)
arg.AlgoID = "algo_id"
_, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg})
require.ErrorIs(t, err, errMissingAlgoOrderType)
arg.AlgoOrderType = AlgoOrdTypeGrid
_, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg})
require.ErrorIs(t, err, errMissingValidStopType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{resp})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetGridAlgoOrdersList(t *testing.T) {
t.Parallel()
_, err := ok.GetGridAlgoOrdersList(contextGenerate(), "abc", "", "", "", "", "", 1)
require.ErrorIs(t, err, errMissingAlgoOrderType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetGridAlgoOrdersList(contextGenerate(), "grid", "", "", "", "", "", 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetGridAlgoOrderHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetGridAlgoOrderHistory(contextGenerate(), "abc", "", "", "", "", "", 1)
require.ErrorIs(t, err, errMissingAlgoOrderType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetGridAlgoOrderHistory(contextGenerate(), "contract_grid", "", "", "", "", "", 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetGridAlgoOrderDetails(t *testing.T) {
t.Parallel()
_, err := ok.GetGridAlgoOrderDetails(contextGenerate(), "grid", "")
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetGridAlgoOrderDetails(contextGenerate(), "grid", "7878")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetGridAlgoSubOrders(t *testing.T) {
t.Parallel()
_, err := ok.GetGridAlgoSubOrders(contextGenerate(), "", "", "", "", "", "", 2)
require.ErrorIs(t, err, errMissingAlgoOrderType)
_, err = ok.GetGridAlgoSubOrders(contextGenerate(), "grid", "", "", "", "", "", 2)
require.ErrorIs(t, err, errAlgoIDRequired)
_, err = ok.GetGridAlgoSubOrders(contextGenerate(), "grid", "1234", "", "", "", "", 2)
require.ErrorIs(t, err, errMissingSubOrderType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetGridAlgoSubOrders(contextGenerate(), "grid", "1234", "live", "", "", "", 2)
require.NoError(t, err)
assert.NotNil(t, result)
}
const spotGridAlgoOrderPosition = `{"adl": "1","algoId": "449327675342323712","avgPx": "29215.0142857142857149","cTime": "1653400065917","ccy": "USDT","imr": "2045.386","instId": "BTC-USDT-SWAP","instType": "SWAP","last": "29206.7","lever": "5","liqPx": "661.1684795867162","markPx": "29213.9","mgnMode": "cross","mgnRatio": "217.19370606167573","mmr": "40.907720000000005","notionalUsd": "10216.70307","pos": "35","posSide": "net","uTime": "1653400066938","upl": "1.674999999999818","uplRatio": "0.0008190504784478"}`
func TestGetGridAlgoOrderPositions(t *testing.T) {
t.Parallel()
var resp AlgoOrderPosition
err := json.Unmarshal([]byte(spotGridAlgoOrderPosition), &resp)
require.NoError(t, err)
_, err = ok.GetGridAlgoOrderPositions(contextGenerate(), "", "")
require.ErrorIs(t, err, errInvalidAlgoOrderType)
_, err = ok.GetGridAlgoOrderPositions(contextGenerate(), "contract_grid", "")
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetGridAlgoOrderPositions(contextGenerate(), "contract_grid", "448965992920907776")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSpotGridWithdrawProfit(t *testing.T) {
t.Parallel()
_, err := ok.SpotGridWithdrawProfit(contextGenerate(), "")
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SpotGridWithdrawProfit(contextGenerate(), "1234")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestComputeMarginBalance(t *testing.T) {
t.Parallel()
_, err := ok.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{AlgoID: "123456", AdjustMarginBalanceType: "other"})
require.ErrorIs(t, err, errInvalidMarginTypeAdjust)
_, err = ok.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{AdjustMarginBalanceType: "other"})
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{
AlgoID: "123456",
AdjustMarginBalanceType: "reduce",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAdjustMarginBalance(t *testing.T) {
t.Parallel()
arg := &MarginBalanceParam{}
_, err := ok.AdjustMarginBalance(contextGenerate(), arg)
require.ErrorIs(t, err, common.ErrEmptyParams)
arg.Amount = 12345
_, err = ok.AdjustMarginBalance(contextGenerate(), arg)
require.ErrorIs(t, err, errAlgoIDRequired)
arg.AlgoID = "1234"
_, err = ok.AdjustMarginBalance(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidMarginTypeAdjust)
arg.AdjustMarginBalanceType = "reduce"
arg.Amount = 0
_, err = ok.AdjustMarginBalance(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AdjustMarginBalance(contextGenerate(), &MarginBalanceParam{
AlgoID: "1234",
AdjustMarginBalanceType: "reduce",
Amount: 12345,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
const gridAIParamJSON = `{"algoOrdType": "grid","annualizedRate": "1.5849","ccy": "USDT","direction": "", "duration": "7D","gridNum": "5","instId": "BTC-USDT","lever": "0","maxPx": "21373.3","minInvestment": "0.89557758", "minPx": "15544.2", "perMaxProfitRate": "0.0733865364573281","perMinProfitRate": "0.0561101403446263","runType": "1"}`
func TestGetGridAIParameter(t *testing.T) {
t.Parallel()
var response GridAIParameterResponse
err := json.Unmarshal([]byte(gridAIParamJSON), &response)
require.NoError(t, err)
_, err = ok.GetGridAIParameter(contextGenerate(), "", "BTC-USDT", "", "")
require.ErrorIs(t, err, errInvalidAlgoOrderType)
_, err = ok.GetGridAIParameter(contextGenerate(), "grid", "", "", "")
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.GetGridAIParameter(contextGenerate(), "contract_grid", "BTC-USDT", "", "")
require.ErrorIs(t, err, errMissingRequiredArgumentDirection)
_, err = ok.GetGridAIParameter(contextGenerate(), "grid", "BTC-USDT", "", "12M")
require.ErrorIs(t, err, errInvalidDuration)
result, err := ok.GetGridAIParameter(contextGenerate(), "grid", "BTC-USDT", "", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOffers(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetOffers(contextGenerate(), "", "", currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPurchase(t *testing.T) {
t.Parallel()
_, err := ok.Purchase(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
_, err = ok.Purchase(contextGenerate(), &PurchaseRequestParam{Term: 2})
require.ErrorIs(t, err, errMissingRequiredParameter)
_, err = ok.Purchase(contextGenerate(), &PurchaseRequestParam{ProductID: "1234", Term: 2, InvestData: []PurchaseInvestDataItem{{Amount: 1}}})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.Purchase(contextGenerate(), &PurchaseRequestParam{ProductID: "1234", Term: 2, InvestData: []PurchaseInvestDataItem{{Currency: currency.USDT}}})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.Purchase(contextGenerate(), &PurchaseRequestParam{
ProductID: "1234",
InvestData: []PurchaseInvestDataItem{
{
Currency: currency.BTC,
Amount: 100,
},
{
Currency: currency.ETH,
Amount: 100,
},
},
Term: 30,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestRedeem(t *testing.T) {
t.Parallel()
_, err := ok.Redeem(contextGenerate(), &RedeemRequestParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.Redeem(contextGenerate(), &RedeemRequestParam{AllowEarlyRedeem: true})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.Redeem(contextGenerate(), &RedeemRequestParam{OrderID: "754147"})
require.ErrorIs(t, err, errInvalidProtocolType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.Redeem(contextGenerate(), &RedeemRequestParam{
OrderID: "754147",
ProtocolType: "defi",
AllowEarlyRedeem: true,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelPurchaseOrRedemption(t *testing.T) {
t.Parallel()
_, err := ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{ProtocolType: "defi"})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{OrderID: "754147"})
require.ErrorIs(t, err, errInvalidProtocolType)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{
OrderID: "754147",
ProtocolType: "defi",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetEarnActiveOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetEarnActiveOrders(contextGenerate(), "", "", "", currency.EMPTYCODE)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFundingOrderHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFundingOrderHistory(contextGenerate(), "", "", currency.EMPTYCODE, time.Time{}, time.Time{}, 1)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSystemStatusResponse(t *testing.T) {
t.Parallel()
result, err := ok.SystemStatusResponse(contextGenerate(), "completed")
require.NoError(t, err)
assert.NotNil(t, result)
}
var instrumentTypeToAssetTypeMap = map[string]struct {
AssetType asset.Item
Error error
}{
instTypeSwap: {AssetType: asset.PerpetualSwap},
instTypeContract: {AssetType: asset.PerpetualSwap},
instTypeSpot: {AssetType: asset.Spot},
instTypeMargin: {AssetType: asset.Margin},
instTypeFutures: {AssetType: asset.Futures},
instTypeOption: {AssetType: asset.Options},
"": {AssetType: asset.Empty},
"lol": {AssetType: asset.Empty, Error: asset.ErrNotSupported},
}
func TestAssetTypeFromInstrumentType(t *testing.T) {
t.Parallel()
for k, v := range instrumentTypeToAssetTypeMap {
assetItem, err := assetTypeFromInstrumentType(k)
require.ErrorIs(t, err, v.Error)
assert.Equal(t, v.AssetType, assetItem)
}
}
/********************************** Wrapper Functions **************************************/
func TestFetchTradablePairs(t *testing.T) {
t.Parallel()
for _, a := range []asset.Item{asset.Options, asset.PerpetualSwap, asset.Futures, asset.Spot, asset.Spread} {
result, err := ok.FetchTradablePairs(contextGenerate(), a)
assert.NoError(t, err)
assert.NotNil(t, result)
}
}
func TestUpdateTradablePairs(t *testing.T) {
t.Parallel()
testexch.UpdatePairsOnce(t, ok)
}
func TestUpdateOrderExecutionLimits(t *testing.T) {
t.Parallel()
tests := map[asset.Item][]currency.Pair{
asset.Spot: {
currency.NewPair(currency.ETH, currency.USDT),
currency.NewPair(currency.BTC, currency.USDT),
},
asset.Margin: {
currency.NewPair(currency.ETH, currency.USDT),
currency.NewPair(currency.ETH, currency.BTC),
},
}
for _, a := range []asset.Item{asset.PerpetualSwap, asset.Futures, asset.Options} {
pairs, err := ok.FetchTradablePairs(contextGenerate(), a)
if assert.NoErrorf(t, err, "FetchTradablePairs should not error for %s", a) {
tests[a] = []currency.Pair{pairs[0]}
}
}
var err error
for _, a := range ok.GetAssetTypes(false) {
err = ok.UpdateOrderExecutionLimits(contextGenerate(), a)
if !assert.NoError(t, err) {
continue
}
for _, p := range tests[a] {
limits, err := ok.GetOrderExecutionLimits(a, p)
if assert.NoError(t, err, "GetOrderExecutionLimits should not error") {
require.Positivef(t, limits.PriceStepIncrementSize, "PriceStepIncrementSize should be positive for %s", p)
require.Positivef(t, limits.MinimumBaseAmount, "PriceStepIncrementSize should be positive for %s", p)
}
}
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
result, err := ok.UpdateTicker(contextGenerate(), currency.NewPair(currency.BTC, currency.USDT), asset.Spot)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := ok.UpdateTickers(contextGenerate(), asset.Spot)
require.NoError(t, err)
err = ok.UpdateTickers(contextGenerate(), asset.Spread)
assert.NoError(t, err)
}
func TestUpdateOrderbook(t *testing.T) {
t.Parallel()
result, err := ok.UpdateOrderbook(contextGenerate(), currency.NewPair(currency.BTC, currency.NewCode("USDT-SWAP")), asset.Spot)
require.NoError(t, err)
require.NotNil(t, result)
result, err = ok.UpdateOrderbook(contextGenerate(), spreadTP, asset.Spread)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestUpdateAccountInfo(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.UpdateAccountInfo(contextGenerate(), asset.Spot)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAccountFundingHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAccountFundingHistory(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetWithdrawalsHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetWithdrawalsHistory(contextGenerate(), currency.BTC, asset.Spot)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetRecentTrades(t *testing.T) {
t.Parallel()
result, err := ok.GetRecentTrades(contextGenerate(), currency.NewPair(currency.BTC, currency.USDT), asset.PerpetualSwap)
require.NoError(t, err)
require.NotNil(t, result)
result, err = ok.GetRecentTrades(contextGenerate(), currency.NewPair(currency.BTC, currency.USDT), asset.Spread)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSubmitOrder(t *testing.T) {
t.Parallel()
var resp []PlaceOrderRequestParam
err := json.Unmarshal([]byte(placeOrderArgs), &resp)
require.NoError(t, err)
arg := &order.Submit{
Exchange: ok.Name,
Side: order.Buy,
Type: order.Limit,
Price: 1,
ClientID: "yeneOrder",
AssetType: asset.Binary,
}
_, err = ok.SubmitOrder(contextGenerate(), arg)
require.ErrorIs(t, err, asset.ErrNotSupported)
arg.AssetType = asset.Spot
_, err = ok.SubmitOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.Amount = 1000000000
_, err = ok.SubmitOrder(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
arg.Pair = spotTP
arg.AssetType = asset.Futures
arg.Leverage = -1
_, err = ok.SubmitOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSubmitLeverageNotSupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
arg = &order.Submit{
Pair: currency.Pair{
Base: currency.LTC,
Quote: currency.BTC,
},
Exchange: ok.Name,
Side: order.Sell,
Type: order.Limit,
Price: 120000,
Amount: 1000000000,
ClientID: "yeneOrder",
AssetType: asset.Spot,
}
result, err := ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.Trigger
arg.TriggerPrice = 11999
arg.TriggerPriceType = order.LastPrice
result, err = ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.ConditionalStop
arg.TriggerPrice = 11999
arg.TriggerPriceType = order.IndexPrice
result, err = ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.Chase
_, err = ok.SubmitOrder(contextGenerate(), arg)
assert.ErrorIs(t, err, order.ErrUnknownTrackingMode)
arg.TrackingMode = order.Percentage
_, err = ok.SubmitOrder(contextGenerate(), arg)
assert.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.TrackingValue = .5
result, err = ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.TWAP
result, err = ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.TrailingStop
result, err = ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.OCO
_, err = ok.SubmitOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.RiskManagementModes = order.RiskManagementModes{
TakeProfit: order.RiskManagement{
Price: 11999,
LimitPrice: 12000,
},
StopLoss: order.RiskManagement{
Price: 10999,
LimitPrice: 11000,
},
}
result, err = ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
cp, err := currency.NewPairFromString("BTC-USDT-230630")
require.NoError(t, err)
arg = &order.Submit{
Pair: cp,
Exchange: ok.Name,
Side: order.Long,
Type: order.Market,
Amount: 1,
ClientID: "hellomoto",
AssetType: asset.Futures,
MarginType: margin.Multi,
}
result, err = ok.SubmitOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
pair, err := currency.NewPairFromString("BTC-USDT-SWAP_BTC-USDT-250328")
require.NoError(t, err)
result, err = ok.SubmitOrder(contextGenerate(), &order.Submit{
Pair: pair,
Exchange: ok.Name,
Side: order.Sell,
Type: order.Limit,
Price: 120000,
Amount: 1,
ClientID: "hellomoto",
AssetType: asset.Spread,
MarginType: margin.Multi,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelOrder(t *testing.T) {
t.Parallel()
var arg = &order.Cancel{
WalletAddress: core.BitcoinDonationAddress,
AccountID: "1",
AssetType: asset.Binary,
}
err := ok.CancelOrder(contextGenerate(), arg)
require.ErrorIs(t, err, asset.ErrNotSupported)
arg.AssetType = asset.Spot
err = ok.CancelOrder(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
arg.Pair = spotTP
err = ok.CancelOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
err = ok.CancelOrder(contextGenerate(), &order.Cancel{
OrderID: "1", WalletAddress: core.BitcoinDonationAddress,
AccountID: "1", Pair: spotTP, AssetType: asset.Spot})
assert.NoError(t, err)
err = ok.CancelOrder(contextGenerate(), &order.Cancel{
Type: order.OCO,
OrderID: "1", WalletAddress: core.BitcoinDonationAddress,
AccountID: "1", Pair: spotTP, AssetType: asset.Spot})
assert.NoError(t, err)
err = ok.CancelOrder(contextGenerate(), &order.Cancel{OrderID: "1",
WalletAddress: core.BitcoinDonationAddress, AccountID: "1",
Pair: spreadTP, AssetType: asset.Spread})
assert.NoError(t, err)
}
func TestCancelBatchOrders(t *testing.T) {
t.Parallel()
_, err := ok.CancelBatchOrders(contextGenerate(), make([]order.Cancel, 21))
require.ErrorIs(t, err, errExceedLimit)
_, err = ok.CancelBatchOrders(contextGenerate(), nil)
require.ErrorIs(t, err, order.ErrCancelOrderIsNil)
arg := order.Cancel{
WalletAddress: core.BitcoinDonationAddress,
AccountID: "1",
AssetType: asset.Binary,
}
_, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg})
require.ErrorIs(t, err, asset.ErrNotSupported)
arg.AssetType = asset.Spot
_, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg})
require.ErrorIs(t, err, currency.ErrCurrencyPairsEmpty)
arg.Pair = spotTP
arg.Type = order.Liquidation
_, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg})
require.ErrorIs(t, err, order.ErrUnsupportedOrderType)
arg.Type = order.Trigger
_, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
arg.Type = order.Limit
_, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
var orderCancellationParams = []order.Cancel{
{
OrderID: "1",
WalletAddress: core.BitcoinDonationAddress,
AccountID: "1",
Pair: spotTP,
AssetType: asset.Spot,
},
{
OrderID: "1",
WalletAddress: core.BitcoinDonationAddress,
AccountID: "1",
Pair: perpetualSwapTP,
AssetType: asset.PerpetualSwap,
},
{
OrderID: "1",
WalletAddress: core.BitcoinDonationAddress,
AccountID: "1",
Type: order.Trigger,
Pair: spotTP,
AssetType: asset.Spot,
},
}
result, err := ok.CancelBatchOrders(contextGenerate(), orderCancellationParams)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAllOrders(t *testing.T) {
t.Parallel()
_, err := ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Binary})
require.ErrorIs(t, err, asset.ErrNotSupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Spread})
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Futures})
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Spot})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestModifyOrder(t *testing.T) {
t.Parallel()
_, err := ok.ModifyOrder(contextGenerate(), nil)
require.ErrorIs(t, err, order.ErrModifyOrderIsNil)
arg := &order.Modify{}
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPairIsEmpty)
arg.Pair = spotTP
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAssetNotSet)
arg.AssetType = asset.Spot
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
arg.OrderID = "1234"
arg.Type = order.Liquidation
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrUnsupportedOrderType)
arg.Type = order.Limit
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation)
arg.Type = order.Trigger
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.Type = order.OCO
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
arg = &order.Modify{
AssetType: asset.Spot,
Pair: spotTP,
OrderID: "1234",
Price: 123456.44,
Amount: 123,
}
result, err := ok.ModifyOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.Limit
result, err = ok.ModifyOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.Trigger
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.TriggerPrice = 12345678
_, err = ok.ModifyOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
arg.Type = order.OCO
_, err = ok.ModifyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.RiskManagementModes = order.RiskManagementModes{
TakeProfit: order.RiskManagement{Price: 12345677},
StopLoss: order.RiskManagement{Price: 12345667},
}
result, err = ok.ModifyOrder(contextGenerate(), arg)
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.ModifyOrder(contextGenerate(),
&order.Modify{
AssetType: asset.Spread,
Pair: spotTP,
OrderID: "1234",
Price: 123456.44,
Amount: 123,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOrderInfo(t *testing.T) {
t.Parallel()
enabled, err := ok.GetEnabledPairs(asset.Spot)
require.NoError(t, err)
if len(enabled) == 0 {
t.SkipNow()
}
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetOrderInfo(contextGenerate(), "123", enabled[0], asset.Futures)
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.GetOrderInfo(contextGenerate(), "123", enabled[0], asset.Spread)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetDepositAddress(t *testing.T) {
t.Parallel()
_, err := ok.GetDepositAddress(contextGenerate(), currency.EMPTYCODE, "", "")
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetDepositAddress(contextGenerate(), currency.BTC, core.BitcoinDonationAddress, "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWithdraw(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
withdrawCryptoRequest := withdraw.Request{
Exchange: ok.Name,
Amount: 0.00000000001,
Currency: currency.BTC,
Crypto: withdraw.CryptoRequest{
Address: core.BitcoinDonationAddress,
},
}
result, err := ok.WithdrawCryptocurrencyFunds(contextGenerate(), &withdrawCryptoRequest)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPairFromInstrumentID(t *testing.T) {
t.Parallel()
instruments := []string{
"BTC-USDT",
"BTC-USDT-SWAP",
"BTC-USDT-ER33234",
}
dPair, err := ok.GetPairFromInstrumentID(instruments[0])
require.NoError(t, err)
require.NotNil(t, dPair)
dPair, err = ok.GetPairFromInstrumentID(instruments[1])
require.NoError(t, err)
require.NotNil(t, dPair)
dPair, err = ok.GetPairFromInstrumentID(instruments[2])
require.NoError(t, err)
assert.NotNil(t, dPair)
}
func TestGetActiveOrders(t *testing.T) {
t.Parallel()
pair, err := currency.NewPairFromString("BTC-USD")
require.NoError(t, err)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetActiveOrders(contextGenerate(), &order.MultiOrderRequest{
Type: order.Limit,
Pairs: currency.Pairs{pair, spotTP, currency.NewPair(currency.USD, currency.LTC)},
AssetType: asset.Spot,
Side: order.Buy,
})
require.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.GetActiveOrders(contextGenerate(), &order.MultiOrderRequest{
Type: order.Limit,
Pairs: currency.Pairs{pair, spotTP, currency.NewPair(currency.USD, currency.LTC)},
AssetType: asset.Spread,
Side: order.Buy,
})
assert.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOrderHistory(t *testing.T) {
t.Parallel()
var getOrdersRequest = order.MultiOrderRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.Buy,
}
_, err := ok.GetOrderHistory(contextGenerate(), &getOrdersRequest)
require.ErrorIs(t, err, currency.ErrCurrencyPairsEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
getOrdersRequest.Pairs = []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)}
result, err := ok.GetOrderHistory(contextGenerate(), &getOrdersRequest)
assert.NoError(t, err)
assert.NotNil(t, result)
getOrdersRequest.AssetType = asset.Spread
getOrdersRequest.Type = order.Market
result, err = ok.GetOrderHistory(contextGenerate(), &getOrdersRequest)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFeeByType(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFeeByType(contextGenerate(), &exchange.FeeBuilder{
Amount: 1,
FeeType: exchange.CryptocurrencyTradeFee,
Pair: currency.NewPairWithDelimiter(currency.BTC.String(),
currency.USDT.String(),
"-"),
PurchasePrice: 1,
FiatCurrency: currency.USD,
BankTransactionType: exchange.WireTransfer,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestValidateAPICredentials(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.ValidateAPICredentials(contextGenerate(), asset.Spot)
assert.NoError(t, err)
}
func TestGetHistoricCandles(t *testing.T) {
t.Parallel()
pair := currency.NewPair(currency.BTC, currency.USDT)
startTime := time.Date(2021, 2, 1, 0, 0, 0, 0, time.UTC)
endTime := startTime.AddDate(0, 0, 100)
_, err := ok.GetHistoricCandles(contextGenerate(), pair, asset.Spot, kline.Interval(time.Hour*4), startTime, endTime)
require.ErrorIs(t, err, kline.ErrRequestExceedsExchangeLimits)
result, err := ok.GetHistoricCandles(contextGenerate(), pair, asset.Spot, kline.OneDay, startTime, endTime)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetHistoricCandlesExtended(t *testing.T) {
t.Parallel()
currencyPair := currency.NewPair(currency.BTC, currency.USDT)
result, err := ok.GetHistoricCandlesExtended(contextGenerate(), currencyPair, asset.Spot, kline.OneMin, time.Now().Add(-time.Hour), time.Now())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCalculateUpdateOrderbookChecksum(t *testing.T) {
t.Parallel()
var orderbookBase orderbook.Base
err := json.Unmarshal([]byte(calculateOrderbookChecksumUpdateOrderbookJSON), &orderbookBase)
require.NoError(t, err)
err = ok.CalculateUpdateOrderbookChecksum(&orderbookBase, 2832680552)
assert.NoError(t, err)
}
func TestOrderPushData(t *testing.T) {
t.Parallel()
ok := new(Okx) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
require.NoError(t, testexch.Setup(ok), "Test instance Setup must not error")
testexch.FixtureToDataHandler(t, "testdata/wsOrders.json", ok.WsHandleData)
close(ok.Websocket.DataHandler)
require.Len(t, ok.Websocket.DataHandler, 4, "Should see 4 orders")
for resp := range ok.Websocket.DataHandler {
switch v := resp.(type) {
case *order.Detail:
switch len(ok.Websocket.DataHandler) {
case 3:
require.Equal(t, "452197707845865472", v.OrderID, "OrderID")
require.Equal(t, "HamsterParty14", v.ClientOrderID, "ClientOrderID")
require.Equal(t, asset.Spot, v.AssetType, "AssetType")
require.Equal(t, order.Sell, v.Side, "Side")
require.Equal(t, order.Filled, v.Status, "Status")
require.Equal(t, order.Limit, v.Type, "Type")
require.Equal(t, currency.NewPairWithDelimiter("BTC", "USDT", "-"), v.Pair, "Pair")
require.Equal(t, 31527.1, v.AverageExecutedPrice, "AverageExecutedPrice")
require.Equal(t, time.UnixMilli(1654084334977), v.Date, "Date")
require.Equal(t, time.UnixMilli(1654084353263), v.CloseTime, "CloseTime")
require.Equal(t, 0.001, v.Amount, "Amount")
require.Equal(t, 0.001, v.ExecutedAmount, "ExecutedAmount")
require.Equal(t, 0.000, v.RemainingAmount, "RemainingAmount")
require.Equal(t, 31527.1, v.Price, "Price")
require.Equal(t, 0.02522168, v.Fee, "Fee")
require.Equal(t, currency.USDT, v.FeeAsset, "FeeAsset")
case 2:
require.Equal(t, "620258920632008725", v.OrderID, "OrderID")
require.Equal(t, asset.Spot, v.AssetType, "AssetType")
require.Equal(t, order.Market, v.Type, "Type")
require.Equal(t, order.Sell, v.Side, "Side")
require.Equal(t, order.Active, v.Status, "Status")
require.Equal(t, 0.0, v.Amount, "Amount should be 0 for a market sell")
require.Equal(t, 10.0, v.QuoteAmount, "QuoteAmount")
case 1:
require.Equal(t, "620258920632008725", v.OrderID, "OrderID")
require.Equal(t, 10.0, v.QuoteAmount, "QuoteAmount")
require.Equal(t, 0.00038127046945832905, v.Amount, "Amount")
require.Equal(t, 0.010000249968, v.Fee, "Fee")
require.Equal(t, 0.0, v.RemainingAmount, "RemainingAmount")
require.Equal(t, 0.00038128, v.ExecutedAmount, "ExecutedAmount")
require.Equal(t, order.PartiallyFilled, v.Status, "Status")
case 0:
require.Equal(t, "620258920632008725", v.OrderID, "OrderID")
require.Equal(t, 10.0, v.QuoteAmount, "QuoteAmount")
require.Equal(t, 0.010000249968, v.Fee, "Fee")
require.Equal(t, 0.0, v.RemainingAmount, "RemainingAmount")
require.Equal(t, 0.00038128, v.ExecutedAmount, "ExecutedAmount")
require.Equal(t, 0.00038128, v.Amount, "Amount should be derived because order filled")
require.Equal(t, order.Filled, v.Status, "Status")
}
case error:
t.Error(v)
default:
t.Errorf("Got unexpected data: %T %v", v, v)
}
}
}
var pushDataMap = map[string]string{
"Algo Orders": `{"arg": {"channel": "orders-algo","uid": "77982378738415879","instType": "FUTURES","instId": "BTC-USD-200329"},"data": [{"instType": "FUTURES","instId": "BTC-USD-200329","ordId": "312269865356374016","ccy": "BTC","algoId": "1234","px": "999","sz": "3","tdMode": "cross","tgtCcy": "","notionalUsd": "","ordType": "trigger","side": "buy","posSide": "long","state": "live","lever": "20","tpTriggerPx": "","tpTriggerPxType": "","tpOrdPx": "","slTriggerPx": "","slTriggerPxType": "","triggerPx": "99","triggerPxType": "last","ordPx": "12","actualSz": "","actualPx": "","tag": "adadadadad","actualSide": "","triggerTime": "1597026383085","cTime": "1597026383000"}]}`,
"Advanced Algo Order": `{"arg": {"channel":"algo-advance","uid": "77982378738415879","instType":"SPOT","instId":"BTC-USDT"},"data":[{"actualPx":"","actualSide":"","actualSz":"0","algoId":"355056228680335360","cTime":"1630924001545","ccy":"","count":"1","instId":"BTC-USDT","instType":"SPOT","lever":"0","notionalUsd":"","ordPx":"","ordType":"iceberg","pTime":"1630924295204","posSide":"net","pxLimit":"10","pxSpread":"1","pxVar":"","side":"buy","slOrdPx":"","slTriggerPx":"","state":"pause","sz":"0.1","szLimit":"0.1","tdMode":"cash","timeInterval":"","tpOrdPx":"","tpTriggerPx":"","tag": "adadadadad","triggerPx":"","triggerTime":"","callbackRatio":"","callbackSpread":"","activePx":"","moveTriggerPx":""}]}`,
"Position Risk": `{"arg": {"channel": "liquidation-warning","uid": "77982378738415879","instType": "FUTURES"},"data": [{"adl":"1","availPos":"1","avgPx":"2566.31","cTime":"1619507758793","ccy":"ETH","deltaBS":"","deltaPA":"","gammaBS":"","gammaPA":"","imr":"","instId":"ETH-USD-210430","instType":"FUTURES","interest":"0","last":"2566.22","lever":"10","liab":"","liabCcy":"","liqPx":"2352.8496681818233","markPx":"2353.849","margin":"0.0003896645377994","mgnMode":"isolated","mgnRatio":"11.731726509588816","mmr":"0.0000311811092368","notionalUsd":"2276.2546609009605","optVal":"","pTime":"1619507761462","pos":"1","posCcy":"","posId":"307173036051017730","posSide":"long","thetaBS":"","thetaPA":"","tradeId":"109844","uTime":"1619507761462","upl":"-0.0000009932766034","uplRatio":"-0.0025490556801078","vegaBS":"","vegaPA":""}, {"adl":"1","availPos":"1","avgPx":"2566.31","cTime":"1619507758793","ccy":"ETH","deltaBS":"","deltaPA":"","gammaBS":"","gammaPA":"","imr":"","instId":"ETH-USD-SWAP","instType":"SWAP","interest":"0","last":"2566.22","lever":"10","liab":"","liabCcy":"","liqPx":"2352.8496681818233","markPx":"2353.849","margin":"0.0003896645377994","mgnMode":"isolated","mgnRatio":"11.731726509588816","mmr":"0.0000311811092368","notionalUsd":"2276.2546609009605","optVal":"","pTime":"1619507761462","pos":"1","posCcy":"","posId":"307173036051017730","posSide":"long","thetaBS":"","thetaPA":"","tradeId":"109844","uTime":"1619507761462","upl":"-0.0000009932766034","uplRatio":"-0.0025490556801078","vegaBS":"","vegaPA":""}]}`,
"Account Greeks": `{"arg": {"channel": "account-greeks","ccy": "BTC"},"data": [{"thetaBS": "","thetaPA":"","deltaBS":"","deltaPA":"","gammaBS":"","gammaPA":"","vegaBS":"","vegaPA":"","ccy":"BTC","ts":"1620282889345"}]}`,
"RFQs": `{"arg": {"channel": "account-greeks","ccy": "BTC"},"data": [{"thetaBS": "","thetaPA":"","deltaBS":"","deltaPA":"","gammaBS":"","gammaPA":"","vegaBS":"","vegaPA":"","ccy":"BTC","ts":"1620282889345"}]}`,
"Accounts": `{"arg": {"channel": "account","ccy": "BTC","uid": "77982378738415879"}, "data": [{"uTime": "1597026383085","totalEq": "41624.32","isoEq": "3624.32","adjEq": "41624.32","ordFroz": "0","imr": "4162.33","mmr": "4","notionalUsd": "","mgnRatio": "41624.32","details": [{"availBal": "","availEq": "1","ccy": "BTC","cashBal": "1","uTime": "1617279471503","disEq": "50559.01","eq": "1","eqUsd": "45078.3790756226851775","frozenBal": "0","interest": "0","isoEq": "0","liab": "0","maxLoan": "","mgnRatio": "","notionalLever": "0.0022195262185864","ordFrozen": "0","upl": "0","uplLiab": "0","crossLiab": "0","isoLiab": "0","coinUsdPrice": "60000","stgyEq":"0","spotInUseAmt":"","isoUpl":""}]}]}`,
"Quotes": `{"arg": {"channel":"quotes"},"data":[{"validUntil":"1608997227854","uTime":"1608267227834","cTime":"1608267227834","legs":[{"px":"0.0023","sz":"25.0","instId":"BTC-USD-220114-25000-C","side":"sell","tgtCcy":""},{"px":"0.0045","sz":"25","instId":"BTC-USD-220114-35000-C","side":"buy","tgtCcy":""}],"quoteId":"25092","rfqId":"18753","traderCode":"SATS","quoteSide":"sell","state":"canceled","clQuoteId":""}]}`,
"Structure Block Trades": `{"arg": {"channel":"struc-block-trades"},"data":[{"cTime":"1608267227834","rfqId":"18753","clRfqId":"","quoteId":"25092","clQuoteId":"","blockTdId":"180184","tTraderCode":"ANAND","mTraderCode":"WAGMI","legs":[{"px":"0.0023","sz":"25.0","instId":"BTC-USD-20220630-60000-C","side":"sell","fee":"0.1001","feeCcy":"BTC","tradeId":"10211","tgtCcy":""},{"px":"0.0033","sz":"25","instId":"BTC-USD-20220630-50000-C","side":"buy","fee":"0.1001","feeCcy":"BTC","tradeId":"10212","tgtCcy":""}]}]}`,
"Spot Grid Algo Orders": `{"arg": {"channel": "grid-orders-spot","instType": "ANY"},"data": [{"algoId": "448965992920907776","algoOrdType": "grid","annualizedRate": "0","arbitrageNum": "0","baseSz": "0","cTime": "1653313834104","cancelType": "0","curBaseSz": "0.001776289214","curQuoteSz": "46.801755866","floatProfit": "-0.4953878967772","gridNum": "6","gridProfit": "0","instId": "BTC-USDC","instType": "SPOT","investment": "100","maxPx": "33444.8","minPx": "24323.5","pTime": "1653476023742","perMaxProfitRate": "0.060375293181491054543","perMinProfitRate": "0.0455275366818586","pnlRatio": "0","quoteSz": "100","runPx": "30478.1","runType": "1","singleAmt": "0.00059261","slTriggerPx": "","state": "running","stopResult": "0","stopType": "0","totalAnnualizedRate": "-0.9643551057262827","totalPnl": "-0.4953878967772","tpTriggerPx": "","tradeNum": "3","triggerTime": "1653378736894","uTime": "1653378736894"}]}`,
"Contract Grid Algo Orders": `{"arg": {"channel": "grid-orders-contract","instType": "ANY"},"data": [{"actualLever": "1.02","algoId": "449327675342323712","algoOrdType": "contract_grid","annualizedRate": "0.7572437878956523","arbitrageNum": "1","basePos": true,"cTime": "1653400065912","cancelType": "0","direction": "long","eq": "10129.419829834853","floatProfit": "109.537858234853","gridNum": "50","gridProfit": "19.8819716","instId": "BTC-USDT-SWAP","instType": "SWAP","investment": "10000","lever": "5","liqPx": "603.2149534767834","maxPx": "100000","minPx": "10","pTime": "1653484573918","perMaxProfitRate": "995.7080916791230692","perMinProfitRate": "0.0946277854875634","pnlRatio": "0.0129419829834853","runPx": "29216.3","runType": "1","singleAmt": "1","slTriggerPx": "","state": "running","stopType": "0","sz": "10000","tag": "","totalAnnualizedRate": "4.929207431970923","totalPnl": "129.419829834853","tpTriggerPx": "","tradeNum": "37","triggerTime": "1653400066940","uTime": "1653484573589","uly": "BTC-USDT"}]}`,
"Grid Positions": `{"arg": {"channel": "grid-positions","uid": "44705892343619584","algoId": "449327675342323712"},"data": [{"adl": "1","algoId": "449327675342323712","avgPx": "29181.4638888888888895","cTime": "1653400065917","ccy": "USDT","imr": "2089.2690000000002","instId": "BTC-USDT-SWAP","instType": "SWAP","last": "29852.7","lever": "5","liqPx": "604.7617536513744","markPx": "29849.7","mgnMode": "cross","mgnRatio": "217.71740878394456","mmr": "41.78538","notionalUsd": "10435.794191550001","pTime": "1653536068723","pos": "35","posSide": "net","uTime": "1653445498682","upl": "232.83263888888962","uplRatio": "0.1139826489932205"}]}`,
"Grid Sub Orders": `{"arg": {"channel": "grid-sub-orders","uid": "44705892343619584","algoId": "449327675342323712"},"data": [{"accFillSz": "0","algoId": "449327675342323712","algoOrdType": "contract_grid","avgPx": "0","cTime": "1653445498664","ctVal": "0.01","fee": "0","feeCcy": "USDT","groupId": "-1","instId": "BTC-USDT-SWAP","instType": "SWAP","lever": "5","ordId": "449518234142904321","ordType": "limit","pTime": "1653486524502","pnl": "","posSide": "net","px": "28007.2","side": "buy","state": "live","sz": "1","tag":"","tdMode": "cross","uTime": "1653445498674"}]}`,
"Instrument": `{"arg": {"channel": "instruments","instType": "FUTURES"},"data": [{"instType": "FUTURES","instId": "BTC-USD-191115","uly": "BTC-USD","category": "1","baseCcy": "","quoteCcy": "","settleCcy": "BTC","ctVal": "10","ctMult": "1","ctValCcy": "USD","optType": "","stk": "","listTime": "","expTime": "","tickSz": "0.01","lotSz": "1","minSz": "1","ctType": "linear","alias": "this_week","state": "live","maxLmtSz":"10000","maxMktSz":"99999","maxTwapSz":"99999","maxIcebergSz":"99999","maxTriggerSz":"9999","maxStopSz":"9999"}]}`,
"Open Interest": `{"arg": {"channel": "open-interest","instId": "LTC-USD-SWAP"},"data": [{"instType": "SWAP","instId": "LTC-USD-SWAP","oi": "5000","oiCcy": "555.55","ts": "1597026383085"}]}`,
"Trade": `{"arg": {"channel": "trades","instId": "BTC-USDT"},"data": [{"instId": "BTC-USDT","tradeId": "130639474","px": "42219.9","sz": "0.12060306","side": "buy","ts": "1630048897897"}]}`,
"Estimated Delivery And Exercise Price": `{"arg": {"args": "estimated-price","instType": "FUTURES","uly": "BTC-USD"},"data": [{"instType": "FUTURES","instId": "BTC-USD-170310","settlePx": "200","ts": "1597026383085"}]}`,
"Mark Price": `{"arg": {"channel": "mark-price","instId": "LTC-USD-190628"},"data": [{"instType": "FUTURES","instId": "LTC-USD-190628","markPx": "0.1","ts": "1597026383085"}]}`,
"Mark Price Candlestick": `{"arg": {"channel": "mark-price-candle1D","instId": "BTC-USD-190628"},"data": [["1597026383085", "3.721", "3.743", "3.677", "3.708"],["1597026383085", "3.731", "3.799", "3.494", "3.72"]]}`,
"Price Limit": `{"arg": {"channel": "price-limit","instId": "LTC-USD-190628"},"data": [{"instId": "LTC-USD-190628","buyLmt": "200","sellLmt": "300","ts": "1597026383085"}]}`,
"Test Snapshot Orderbook": `{"arg": {"channel":"books","instId":"BTC-USDT"},"action":"snapshot","data":[{"asks":[["0.07026","5","0","1"],["0.07027","765","0","3"],["0.07028","110","0","1"],["0.0703","1264","0","1"],["0.07034","280","0","1"],["0.07035","2255","0","1"],["0.07036","28","0","1"],["0.07037","63","0","1"],["0.07039","137","0","2"],["0.0704","48","0","1"],["0.07041","32","0","1"],["0.07043","3985","0","1"],["0.07057","257","0","1"],["0.07058","7870","0","1"],["0.07059","161","0","1"],["0.07061","4539","0","1"],["0.07068","1438","0","3"],["0.07088","3162","0","1"],["0.07104","99","0","1"],["0.07108","5018","0","1"],["0.07115","1540","0","1"],["0.07129","5080","0","1"],["0.07145","1512","0","1"],["0.0715","5016","0","1"],["0.07171","5026","0","1"],["0.07192","5062","0","1"],["0.07197","1517","0","1"],["0.0726","1511","0","1"],["0.07314","10376","0","1"],["0.07354","1","0","1"],["0.07466","10277","0","1"],["0.07626","269","0","1"],["0.07636","269","0","1"],["0.0809","1","0","1"],["0.08899","1","0","1"],["0.09789","1","0","1"],["0.10768","1","0","1"]],"bids":[["0.07014","56","0","2"],["0.07011","608","0","1"],["0.07009","110","0","1"],["0.07006","1264","0","1"],["0.07004","2347","0","3"],["0.07003","279","0","1"],["0.07001","52","0","1"],["0.06997","91","0","1"],["0.06996","4242","0","2"],["0.06995","486","0","1"],["0.06992","161","0","1"],["0.06991","63","0","1"],["0.06988","7518","0","1"],["0.06976","186","0","1"],["0.06975","71","0","1"],["0.06973","1086","0","1"],["0.06961","513","0","2"],["0.06959","4603","0","1"],["0.0695","186","0","1"],["0.06946","3043","0","1"],["0.06939","103","0","1"],["0.0693","5053","0","1"],["0.06909","5039","0","1"],["0.06888","5037","0","1"],["0.06886","1526","0","1"],["0.06867","5008","0","1"],["0.06846","5065","0","1"],["0.06826","1572","0","1"],["0.06801","1565","0","1"],["0.06748","67","0","1"],["0.0674","111","0","1"],["0.0672","10038","0","1"],["0.06652","1","0","1"],["0.06625","1526","0","1"],["0.06619","10924","0","1"],["0.05986","1","0","1"],["0.05387","1","0","1"],["0.04848","1","0","1"],["0.04363","1","0","1"]],"ts":"1659792392540","checksum":-1462286744}]}`,
"Options Trades": `{"arg": {"channel": "option-trades", "instType": "OPTION", "instFamily": "BTC-USD" }, "data": [ { "fillVol": "0.5066007836914062", "fwdPx": "16469.69928595038", "idxPx": "16537.2", "instFamily": "BTC-USD", "instId": "BTC-USD-230224-18000-C", "markPx": "0.04690107010619562", "optType": "C", "px": "0.045", "side": "sell", "sz": "2", "tradeId": "38", "ts": "1672286551080" } ] }`,
"Public Block Trades": `{"arg": {"channel":"public-block-trades", "instId":"BTC-USD-231020-5000-P" }, "data":[ { "fillVol":"5", "fwdPx":"26808.16", "idxPx":"27222.5", "instId":"BTC-USD-231020-5000-P", "markPx":"0.0022406326071111", "px":"0.0048", "side":"buy", "sz":"1", "tradeId":"633971452580106242", "ts":"1697422572972"}]}`,
"Option Summary": `{"arg": {"channel": "opt-summary","uly": "BTC-USD"},"data": [{"instType": "OPTION","instId": "BTC-USD-200103-5500-C","uly": "BTC-USD","delta": "0.7494223636","gamma": "-0.6765419039","theta": "-0.0000809873","vega": "0.0000077307","deltaBS": "0.7494223636","gammaBS": "-0.6765419039","thetaBS": "-0.0000809873","vegaBS": "0.0000077307","realVol": "0","bidVol": "","askVol": "1.5625","markVol": "0.9987","lever": "4.0342","fwdPx": "39016.8143629068452065","ts": "1597026383085"}]}`,
"Funding Rate": `{"arg": {"channel": "funding-rate","instId": "BTC-USD-SWAP"},"data": [{"instType": "SWAP","instId": "BTC-USD-SWAP","fundingRate": "0.018","nextFundingRate": "","fundingTime": "1597026383085"}]}`,
"Index Candlestick": `{"arg": {"channel": "index-candle30m","instId": "BTC-USDT"},"data": [["1597026383085", "3811.31", "3811.31", "3811.31", "3811.31"]]}`,
"Index Ticker": `{"arg": {"channel": "index-tickers","instId": "BTC-USDT"},"data": [{"instId": "BTC-USDT","idxPx": "0.1","high24h": "0.5","low24h": "0.1","open24h": "0.1","sodUtc0": "0.1","sodUtc8": "0.1","ts": "1597026383085"}]}`,
"Status": `{"arg": {"channel": "status"},"data": [{"title": "Spot System Upgrade","state": "scheduled","begin": "1610019546","href": "","end": "1610019546","serviceType": "1","system": "classic","scheDesc": "","ts": "1597026383085"}]}`,
"Public Struct Block Trades": `{"arg": {"channel":"public-struc-block-trades"},"data":[{"cTime":"1608267227834","blockTdId":"1802896","legs":[{"px":"0.323","sz":"25.0","instId":"BTC-USD-20220114-13250-C","side":"sell","tradeId":"15102"},{"px":"0.666","sz":"25","instId":"BTC-USD-20220114-21125-C","side":"buy","tradeId":"15103"}]}]}`,
"Block Ticker": `{"arg": {"channel": "block-tickers"},"data": [{"instType": "SWAP","instId": "LTC-USD-SWAP","volCcy24h": "0","vol24h": "0","ts": "1597026383085"}]}`,
"Account": `{"arg": {"channel": "block-tickers"},"data": [{"instType": "SWAP","instId": "LTC-USD-SWAP","volCcy24h": "0","vol24h": "0","ts": "1597026383085"}]}`,
"Position": `{"arg": {"channel":"positions","instType":"FUTURES"},"data":[{"adl":"1","availPos":"1","avgPx":"2566.31","cTime":"1619507758793","ccy":"ETH","deltaBS":"","deltaPA":"","gammaBS":"","gammaPA":"","imr":"","instId":"ETH-USD-210430","instType":"FUTURES","interest":"0","last":"2566.22","lever":"10","liab":"","liabCcy":"","liqPx":"2352.8496681818233","markPx":"2353.849","margin":"0.0003896645377994","mgnMode":"isolated","mgnRatio":"11.731726509588816","mmr":"0.0000311811092368","notionalUsd":"2276.2546609009605","optVal":"","pTime":"1619507761462","pos":"1","posCcy":"","posId":"307173036051017730","posSide":"long","thetaBS":"","thetaPA":"","tradeId":"109844","uTime":"1619507761462","upl":"-0.0000009932766034","uplRatio":"-0.0025490556801078","vegaBS":"","vegaPA":""}]}`,
"Position Data With Underlying": `{"arg": {"channel": "positions","uid": "77982378738415879","instType": "FUTURES"},"data": [{"adl":"1","availPos":"1","avgPx":"2566.31","cTime":"1619507758793","ccy":"ETH","deltaBS":"","deltaPA":"","gammaBS":"","gammaPA":"","imr":"","instId":"ETH-USD-210430","instType":"FUTURES","interest":"0","last":"2566.22","usdPx":"","lever":"10","liab":"","liabCcy":"","liqPx":"2352.8496681818233","markPx":"2353.849","margin":"0.0003896645377994","mgnMode":"isolated","mgnRatio":"11.731726509588816","mmr":"0.0000311811092368","notionalUsd":"2276.2546609009605","optVal":"","pTime":"1619507761462","pos":"1","posCcy":"","posId":"307173036051017730","posSide":"long","thetaBS":"","thetaPA":"","tradeId":"109844","uTime":"1619507761462","upl":"-0.0000009932766034","uplRatio":"-0.0025490556801078","vegaBS":"","vegaPA":""}, {"adl":"1","availPos":"1","avgPx":"2566.31","cTime":"1619507758793","ccy":"ETH","deltaBS":"","deltaPA":"","gammaBS":"","gammaPA":"","imr":"","instId":"ETH-USD-SWAP","instType":"SWAP","interest":"0","last":"2566.22","usdPx":"","lever":"10","liab":"","liabCcy":"","liqPx":"2352.8496681818233","markPx":"2353.849","margin":"0.0003896645377994","mgnMode":"isolated","mgnRatio":"11.731726509588816","mmr":"0.0000311811092368","notionalUsd":"2276.2546609009605","optVal":"","pTime":"1619507761462","pos":"1","posCcy":"","posId":"307173036051017730","posSide":"long","thetaBS":"","thetaPA":"","tradeId":"109844","uTime":"1619507761462","upl":"-0.0000009932766034","uplRatio":"-0.0025490556801078","vegaBS":"","vegaPA":""}]}`,
"Balance And Position": `{"arg": {"channel": "balance_and_position","uid": "77982378738415879"},"data": [{"pTime": "1597026383085","eventType": "snapshot","balData": [{"ccy": "BTC","cashBal": "1","uTime": "1597026383085"}],"posData": [{"posId": "1111111111","tradeId": "2","instId": "BTC-USD-191018","instType": "FUTURES","mgnMode": "cross","posSide": "long","pos": "10","ccy": "BTC","posCcy": "","avgPx": "3320","uTIme": "1597026383085"}]}]}`,
"Deposit Info Details": `{"arg": {"channel": "deposit-info", "uid": "289320****60975104" }, "data": [{ "actualDepBlkConfirm": "0", "amt": "1", "areaCodeFrom": "", "ccy": "USDT", "chain": "USDT-TRC20", "depId": "88165462", "from": "", "fromWdId": "", "pTime": "1674103661147", "state": "0", "subAcct": "test", "to": "TEhFAqpuHa3LY*****8ByNoGnrmexeGMw", "ts": "1674103661123", "txId": "bc5376817*****************dbb0d729f6b", "uid": "289320****60975104" }] }`,
"Withdrawal Info Details": `{"arg": {"channel": "deposit-info", "uid": "289320****60975104" }, "data": [{ "actualDepBlkConfirm": "0", "amt": "1", "areaCodeFrom": "", "ccy": "USDT", "chain": "USDT-TRC20", "depId": "88165462", "from": "", "fromWdId": "", "pTime": "1674103661147", "state": "0", "subAcct": "test", "to": "TEhFAqpuHa3LY*****8ByNoGnrmexeGMw", "ts": "1674103661123", "txId": "bc5376817*****************dbb0d729f6b", "uid": "289320****60975104" }] }`,
"Recurring Buy Order": `{"arg": {"channel": "algo-recurring-buy", "instType": "SPOT", "uid": "447*******584" }, "data": [{ "algoClOrdId": "", "algoId": "644497312047435776", "algoOrdType": "recurring", "amt": "100", "cTime": "1699932133373", "cycles": "0", "instType": "SPOT", "investmentAmt": "0", "investmentCcy": "USDC", "mktCap": "0", "nextInvestTime": "1699934415300", "pTime": "1699933314691", "period": "hourly", "pnlRatio": "0", "recurringDay": "", "recurringHour": "1", "recurringList": [{ "avgPx": "0", "ccy": "BTC", "profit": "0", "px": "36482", "ratio": "0.2", "totalAmt": "0" }, { "avgPx": "0", "ccy": "ETH", "profit": "0", "px": "2057.54", "ratio": "0.8", "totalAmt": "0" }], "recurringTime": "12", "state": "running", "stgyName": "stg1", "tag": "", "timeZone": "8", "totalAnnRate": "0", "totalPnl": "0", "uTime": "1699932136249" }] }`,
"Liquidation Orders": `{"arg": {"channel": "liquidation-orders", "instType": "SWAP" }, "data": [ { "details": [ { "bkLoss": "0", "bkPx": "0.007831", "ccy": "", "posSide": "short", "side": "buy", "sz": "13", "ts": "1692266434010" } ], "instFamily": "IOST-USDT", "instId": "IOST-USDT-SWAP", "instType": "SWAP", "uly": "IOST-USDT"}]}`,
"Economic Calendar": `{"arg": {"channel": "economic-calendar" }, "data": [ { "calendarId": "319275", "date": "1597026383085", "region": "United States", "category": "Manufacturing PMI", "event": "S&P Global Manufacturing PMI Final", "refDate": "1597026383085", "actual": "49.2", "previous": "47.3", "forecast": "49.3", "importance": "2", "prevInitial": "", "ccy": "", "unit": "", "ts": "1698648096590" } ] }`,
"Failure": `{ "event": "error", "code": "60012", "msg": "Invalid request: {\"op\": \"subscribe\", \"args\":[{ \"channel\" : \"block-tickers\", \"instId\" : \"LTC-USD-200327\"}]}", "connId": "a4d3ae55" }`,
}
func TestPushData(t *testing.T) {
t.Parallel()
var err error
for x := range pushDataMap {
err = ok.WsHandleData([]byte(pushDataMap[x]))
require.NoErrorf(t, err, "Okx %s error %v", x, err)
}
}
func TestPushDataDynamic(t *testing.T) {
t.Parallel()
dataMap := map[string]string{
"Ticker": `{"arg": {"channel": "tickers","instId": "BTC-USD-SWAP"},"data": [{"instType": "SWAP","instId": "BTC-USD-SWAP","last": "9999.99","lastSz": "0.1","askPx": "9999.99","askSz": "11","bidPx": "8888.88","bidSz": "5","open24h": "9000","high24h": "10000","low24h": "8888.88","volCcy24h": "2222","vol24h": "2222","sodUtc0": "2222","sodUtc8": "2222","ts": "1597026383085"}]}`,
"Candlesticks": `{"arg": {"channel": "candle1D","instId": "BTC-USD-SWAP"},"data": [["1597026383085","8533.02","8553.74","8527.17","8548.26","45247","529.5858061"]]}`,
"Snapshot OrderBook": `{"arg":{"channel":"books","instId":"BTC-USD-SWAP"},"action":"snapshot","data":[{"asks":[["0.07026","5","0","1"],["0.07027","765","0","3"],["0.07028","110","0","1"],["0.0703","1264","0","1"],["0.07034","280","0","1"],["0.07035","2255","0","1"],["0.07036","28","0","1"],["0.07037","63","0","1"],["0.07039","137","0","2"],["0.0704","48","0","1"],["0.07041","32","0","1"],["0.07043","3985","0","1"],["0.07057","257","0","1"],["0.07058","7870","0","1"],["0.07059","161","0","1"],["0.07061","4539","0","1"],["0.07068","1438","0","3"],["0.07088","3162","0","1"],["0.07104","99","0","1"],["0.07108","5018","0","1"],["0.07115","1540","0","1"],["0.07129","5080","0","1"],["0.07145","1512","0","1"],["0.0715","5016","0","1"],["0.07171","5026","0","1"],["0.07192","5062","0","1"],["0.07197","1517","0","1"],["0.0726","1511","0","1"],["0.07314","10376","0","1"],["0.07354","1","0","1"],["0.07466","10277","0","1"],["0.07626","269","0","1"],["0.07636","269","0","1"],["0.0809","1","0","1"],["0.08899","1","0","1"],["0.09789","1","0","1"],["0.10768","1","0","1"]],"bids":[["0.07014","56","0","2"],["0.07011","608","0","1"],["0.07009","110","0","1"],["0.07006","1264","0","1"],["0.07004","2347","0","3"],["0.07003","279","0","1"],["0.07001","52","0","1"],["0.06997","91","0","1"],["0.06996","4242","0","2"],["0.06995","486","0","1"],["0.06992","161","0","1"],["0.06991","63","0","1"],["0.06988","7518","0","1"],["0.06976","186","0","1"],["0.06975","71","0","1"],["0.06973","1086","0","1"],["0.06961","513","0","2"],["0.06959","4603","0","1"],["0.0695","186","0","1"],["0.06946","3043","0","1"],["0.06939","103","0","1"],["0.0693","5053","0","1"],["0.06909","5039","0","1"],["0.06888","5037","0","1"],["0.06886","1526","0","1"],["0.06867","5008","0","1"],["0.06846","5065","0","1"],["0.06826","1572","0","1"],["0.06801","1565","0","1"],["0.06748","67","0","1"],["0.0674","111","0","1"],["0.0672","10038","0","1"],["0.06652","1","0","1"],["0.06625","1526","0","1"],["0.06619","10924","0","1"],["0.05986","1","0","1"],["0.05387","1","0","1"],["0.04848","1","0","1"],["0.04363","1","0","1"]],"ts":"1659792392540","checksum":-1462286744}]}`,
}
var err error
for x := range dataMap {
err = ok.WsHandleData([]byte(dataMap[x]))
require.NoError(t, err)
}
}
func TestGetHistoricTrades(t *testing.T) {
t.Parallel()
result, err := ok.GetHistoricTrades(contextGenerate(), currency.NewPair(currency.BTC, currency.USDT), asset.Spot, time.Now().Add(-time.Minute*4), time.Now().Add(-time.Minute*2))
require.NoError(t, err)
assert.NotNil(t, result)
}
func setupWS() {
if !ok.Websocket.IsEnabled() {
return
}
if !sharedtestvalues.AreAPICredentialsSet(ok) {
ok.Websocket.SetCanUseAuthenticatedEndpoints(false)
}
err := ok.WsConnect()
if err != nil {
log.Fatal(err)
}
}
func TestWSProcessTrades(t *testing.T) {
t.Parallel()
ok := new(Okx) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
require.NoError(t, testexch.Setup(ok), "Test instance Setup must not error")
assets, err := ok.getAssetsFromInstrumentID("BTC-USDT")
require.NoError(t, err, "getAssetsFromInstrumentID must not error")
p := currency.NewPairWithDelimiter("BTC", "USDT", currency.DashDelimiter)
for _, a := range assets {
err := ok.Websocket.AddSubscriptions(ok.Websocket.Conn, &subscription.Subscription{
Asset: a,
Pairs: currency.Pairs{p},
Channel: subscription.AllTradesChannel,
Key: fmt.Sprintf("%s-%s", p, a)})
require.NoError(t, err, "AddSubscriptions must not error")
}
testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", ok.WsHandleData)
exp := []trade.Data{
{
Timestamp: time.UnixMilli(1740394561685).UTC(),
Price: 95634.9,
Amount: 0.00011186,
Side: order.Buy,
TID: "674510826",
},
{
Timestamp: time.UnixMilli(1740394561686).UTC(),
Price: 95635.3,
Amount: 0.00011194,
Side: order.Sell,
TID: "674510827",
},
}
total := len(assets) * len(exp)
require.Len(t, ok.Websocket.DataHandler, total, "Must see correct number of trades")
trades := make(map[asset.Item][]trade.Data)
for len(ok.Websocket.DataHandler) > 0 {
resp := <-ok.Websocket.DataHandler
switch v := resp.(type) {
case trade.Data:
trades[v.AssetType] = append(trades[v.AssetType], v)
case error:
t.Error(v)
default:
t.Errorf("Unexpected type in DataHandler: %T (%s)", v, v)
}
}
for _, assetType := range assets {
require.Len(t, trades[assetType], len(exp), "Must have received %d trades for asset %v", len(exp), assetType)
slices.SortFunc(trades[assetType], func(a, b trade.Data) int {
return strings.Compare(a.TID, b.TID)
})
for i, tradeData := range trades[assetType] {
expected := exp[i]
expected.AssetType = assetType
expected.Exchange = ok.Name
expected.CurrencyPair = p
require.Equal(t, expected, tradeData, "Trade %d (TID: %s) for asset %v must match expected data", i, tradeData.TID, assetType)
}
}
}
// ************************** Public Channel Subscriptions *****************************
func TestInstrumentsSubscription(t *testing.T) {
t.Parallel()
err := ok.InstrumentsSubscription(contextGenerate(), "subscribe", asset.Spot, currency.NewPair(currency.BTC, currency.USDT))
assert.NoError(t, err)
}
func TestTickersSubscription(t *testing.T) {
t.Parallel()
err := ok.TickersSubscription(contextGenerate(), "subscribe", asset.Margin, currency.NewPair(currency.BTC, currency.USDT))
require.NoError(t, err)
err = ok.TickersSubscription(contextGenerate(), "unsubscribe", asset.Spot, currency.NewPair(currency.BTC, currency.USDT))
assert.NoError(t, err)
}
func TestOpenInterestSubscription(t *testing.T) {
t.Parallel()
err := ok.OpenInterestSubscription(contextGenerate(), "subscribe", asset.PerpetualSwap, currency.NewPair(currency.BTC, currency.NewCode("USD-SWAP")))
assert.NoError(t, err)
}
func TestCandlesticksSubscription(t *testing.T) {
t.Parallel()
enabled, err := ok.GetEnabledPairs(asset.PerpetualSwap)
require.NoError(t, err)
if len(enabled) == 0 {
t.SkipNow()
}
err = ok.CandlesticksSubscription(contextGenerate(), "subscribe", channelCandle1m, asset.Futures, enabled[0])
assert.NoError(t, err)
}
func TestTradesSubscription(t *testing.T) {
t.Parallel()
err := ok.TradesSubscription(contextGenerate(), "subscribe", asset.Spot, currency.NewPair(currency.BTC, currency.USDT))
assert.NoError(t, err)
}
func TestEstimatedDeliveryExercisePriceSubscription(t *testing.T) {
t.Parallel()
futuresPairs, err := ok.FetchTradablePairs(contextGenerate(), asset.Futures)
require.NoErrorf(t, err, "%s error while fetching tradable pairs for instrument type %v: %v", ok.Name, asset.Futures, err)
if len(futuresPairs) == 0 {
t.SkipNow()
}
err = ok.EstimatedDeliveryExercisePriceSubscription(contextGenerate(), "subscribe", asset.Futures, futuresPairs[0])
assert.NoError(t, err)
}
func TestMarkPriceSubscription(t *testing.T) {
t.Parallel()
futuresPairs, err := ok.FetchTradablePairs(contextGenerate(), asset.Futures)
require.NoErrorf(t, err, "%s error while fetching tradable pairs for instrument type %v: %v", ok.Name, asset.Futures, err)
if len(futuresPairs) == 0 {
t.SkipNow()
}
err = ok.MarkPriceSubscription(contextGenerate(), "subscribe", asset.Futures, futuresPairs[0])
assert.NoError(t, err)
}
func TestMarkPriceCandlesticksSubscription(t *testing.T) {
t.Parallel()
enabled, err := ok.GetEnabledPairs(asset.Spot)
require.NoError(t, err)
if len(enabled) == 0 {
t.SkipNow()
}
err = ok.MarkPriceCandlesticksSubscription(contextGenerate(), "subscribe", channelMarkPriceCandle1Y, asset.Futures, enabled[0])
assert.NoError(t, err)
}
func TestPriceLimitSubscription(t *testing.T) {
t.Parallel()
err := ok.PriceLimitSubscription(contextGenerate(), "subscribe", asset.PerpetualSwap, currency.NewPairWithDelimiter("BTC", "USD-SWAP", currency.DashDelimiter))
assert.NoError(t, err)
}
func TestOrderBooksSubscription(t *testing.T) {
t.Parallel()
enabled, err := ok.GetEnabledPairs(asset.Spot)
require.NoError(t, err)
if len(enabled) == 0 {
t.SkipNow()
}
err = ok.OrderBooksSubscription(contextGenerate(), "subscribe", channelOrderBooks, asset.Futures, enabled[0])
require.NoError(t, err)
err = ok.OrderBooksSubscription(contextGenerate(), "unsubscribe", channelOrderBooks, asset.Futures, enabled[0])
assert.NoError(t, err)
}
func TestOptionSummarySubscription(t *testing.T) {
t.Parallel()
err := ok.OptionSummarySubscription(contextGenerate(), "subscribe", currency.NewPair(currency.SOL, currency.USD))
require.NoError(t, err)
err = ok.OptionSummarySubscription(contextGenerate(), "unsubscribe", currency.NewPair(currency.SOL, currency.USD))
assert.NoError(t, err)
}
func TestFundingRateSubscription(t *testing.T) {
t.Parallel()
err := ok.FundingRateSubscription(contextGenerate(), "subscribe", asset.Spot, currency.NewPair(currency.BTC, currency.NewCode("USDT-SWAP")))
require.NoError(t, err)
err = ok.FundingRateSubscription(contextGenerate(), "unsubscribe", asset.Spot, currency.NewPair(currency.BTC, currency.NewCode("USDT-SWAP")))
assert.NoError(t, err)
}
func TestIndexCandlesticksSubscription(t *testing.T) {
t.Parallel()
err := ok.IndexCandlesticksSubscription(contextGenerate(), "subscribe", channelIndexCandle6M, asset.Spot, currency.NewPair(currency.SOL, currency.USD))
require.NoError(t, err)
err = ok.IndexCandlesticksSubscription(contextGenerate(), "unsubscribe", channelIndexCandle6M, asset.Spot, currency.NewPair(currency.SOL, currency.USD))
assert.NoError(t, err)
}
func TestIndexTickerChannelIndexTickerChannel(t *testing.T) {
t.Parallel()
err := ok.IndexTickerChannel(contextGenerate(), "subscribe", asset.Spot, currency.NewPair(currency.SOL, currency.USD))
require.NoError(t, err)
err = ok.IndexTickerChannel(contextGenerate(), "unsubscribe", asset.Spot, currency.NewPair(currency.SOL, currency.USD))
assert.NoError(t, err)
}
func TestStatusSubscription(t *testing.T) {
t.Parallel()
err := ok.StatusSubscription(contextGenerate(), "subscribe", asset.Spot, currency.NewPair(currency.SOL, currency.USD))
require.NoError(t, err)
err = ok.StatusSubscription(contextGenerate(), "unsubscribe", asset.Spot, currency.NewPair(currency.SOL, currency.USD))
assert.NoError(t, err)
}
func TestPublicStructureBlockTradesSubscription(t *testing.T) {
t.Parallel()
err := ok.PublicStructureBlockTradesSubscription(contextGenerate(), "subscribe", asset.Spot, currency.NewPair(currency.SOL, currency.USD))
require.NoError(t, err)
err = ok.PublicStructureBlockTradesSubscription(contextGenerate(), "unsubscribe", asset.Spot, currency.NewPair(currency.SOL, currency.USD))
assert.NoError(t, err)
}
func TestBlockTickerSubscription(t *testing.T) {
t.Parallel()
err := ok.BlockTickerSubscription(contextGenerate(), "subscribe", asset.Options, currency.NewPair(currency.BTC, currency.USDT))
require.NoError(t, err)
err = ok.BlockTickerSubscription(contextGenerate(), "unsubscribe", asset.Options, currency.NewPair(currency.BTC, currency.USDT))
assert.NoError(t, err)
}
func TestPublicBlockTradesSubscription(t *testing.T) {
t.Parallel()
err := ok.PublicBlockTradesSubscription(contextGenerate(), "subscribe", asset.Options, currency.NewPairWithDelimiter("BTC", "USDT-SWAP", "-"))
require.NoError(t, err)
err = ok.PublicBlockTradesSubscription(contextGenerate(), "unsubscribe", asset.Options, currency.NewPairWithDelimiter("BTC", "USDT-SWAP", "-"))
assert.NoError(t, err)
}
// ************ Authenticated Websocket endpoints Test **********************************************
func TestWsAccountSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.WsAccountSubscription(contextGenerate(), "subscribe", asset.Spot, currency.NewPair(currency.BTC, currency.USDT))
assert.NoError(t, err)
}
func TestWsPlaceOrder(t *testing.T) {
t.Parallel()
_, err := ok.WsPlaceOrder(contextGenerate(), &PlaceOrderRequestParam{})
require.ErrorIs(t, err, common.ErrNilPointer)
arg := &PlaceOrderRequestParam{
ReduceOnly: true,
AssetType: asset.Margin,
}
_, err = ok.WsPlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.WsPlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = "Buy"
arg.TradeMode = "abc"
_, err = ok.WsPlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = "cross"
_, err = ok.WsPlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = order.Limit.String()
_, err = ok.WsPlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.AssetType = asset.Futures
_, err = ok.WsPlaceOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsPlaceOrder(contextGenerate(), &PlaceOrderRequestParam{
InstrumentID: "BTC-USDC",
TradeMode: "cross",
Side: order.Buy.Lower(),
OrderType: "limit",
Amount: 2.6,
Price: 2.1,
Currency: "BTC",
})
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.WsPlaceOrder(contextGenerate(), &PlaceOrderRequestParam{
InstrumentID: "BTC-USDC",
TradeMode: "cross",
Side: order.Buy.Lower(),
PositionSide: "long",
OrderType: "limit",
Amount: 2.6,
Price: 2.1,
Currency: "BTC",
AssetType: asset.Futures,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsPlaceMultipleOrder(t *testing.T) {
t.Parallel()
var resp []PlaceOrderRequestParam
err := json.Unmarshal([]byte(placeOrderArgs), &resp)
require.NoError(t, err)
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{})
require.ErrorIs(t, err, order.ErrSubmissionIsNil)
arg := PlaceOrderRequestParam{
ReduceOnly: true,
}
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = "buy"
arg.TradeMode = "abc"
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = "cross"
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = "limit"
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.AssetType = asset.Futures
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.PositionSide = "long"
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
_, err = ok.WsPlaceMultipleOrders(contextGenerate(), resp)
assert.False(t, (err != nil && !errors.Is(err, errWebsocketStreamNotAuthenticated)), err)
}
func TestWsCancelOrder(t *testing.T) {
t.Parallel()
_, err := ok.WsCancelOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
_, err = ok.WsCancelOrder(contextGenerate(), &CancelOrderRequestParam{OrderID: "1234"})
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.WsCancelOrder(contextGenerate(), &CancelOrderRequestParam{InstrumentID: "BTC-USD-190927"})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsCancelOrder(contextGenerate(), &CancelOrderRequestParam{
InstrumentID: "BTC-USD-190927",
OrderID: "2510789768709120",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsCancleMultipleOrder(t *testing.T) {
t.Parallel()
arg := CancelOrderRequestParam{
OrderID: "2510789768709120",
}
_, err := ok.WsCancelMultipleOrder(contextGenerate(), []CancelOrderRequestParam{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = "DCR-BTC"
arg.OrderID = ""
_, err = ok.WsCancelMultipleOrder(contextGenerate(), []CancelOrderRequestParam{arg})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsCancelMultipleOrder(contextGenerate(), []CancelOrderRequestParam{{
InstrumentID: "DCR-BTC",
OrderID: "2510789768709120",
}})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsAmendOrder(t *testing.T) {
t.Parallel()
_, err := ok.WsAmendOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
arg := &AmendOrderRequestParams{}
_, err = ok.WsAmendOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = spotTP.String()
_, err = ok.WsAmendOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
arg.OrderID = "1234"
_, err = ok.WsAmendOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsAmendOrder(contextGenerate(), &AmendOrderRequestParams{
InstrumentID: spotTP.String(),
OrderID: "2510789768709120",
NewQuantity: 1234,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsAmendMultipleOrders(t *testing.T) {
t.Parallel()
arg := AmendOrderRequestParams{
CancelOnFail: true,
}
_, err := ok.WsAmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg})
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = "DCR-BTC"
_, err = ok.WsAmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
arg.OrderID = "2510789768709120"
_, err = ok.WsAmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg})
require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsAmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{
{
InstrumentID: "DCR-BTC",
OrderID: "2510789768709120",
NewPrice: 1233324.332,
NewQuantity: 1234,
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsMassCancelOrders(t *testing.T) {
t.Parallel()
_, err := ok.WsMassCancelOrders(contextGenerate(), []CancelMassReqParam{{}})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.WsMassCancelOrders(contextGenerate(), []CancelMassReqParam{{InstrumentFamily: "BTC-USD"}})
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.WsMassCancelOrders(contextGenerate(), []CancelMassReqParam{{InstrumentType: "OPTION"}})
require.ErrorIs(t, err, errInstrumentFamilyRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsMassCancelOrders(contextGenerate(), []CancelMassReqParam{
{
InstrumentType: "OPTION",
InstrumentFamily: "BTC-USD",
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsPositionChannel(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.WsPositionChannel(contextGenerate(), "subscribe", asset.Options, currency.NewPair(currency.USD, currency.BTC))
assert.NoError(t, err)
}
func TestBalanceAndPositionSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.BalanceAndPositionSubscription(contextGenerate(), "subscribe", "1234")
require.NoError(t, err)
err = ok.BalanceAndPositionSubscription(contextGenerate(), "unsubscribe", "1234")
assert.NoError(t, err)
}
func TestWsOrderChannel(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.WsOrderChannel(contextGenerate(), "subscribe", asset.Margin, currency.NewPair(currency.SOL, currency.USDT), "")
require.NoError(t, err)
err = ok.WsOrderChannel(contextGenerate(), "unsubscribe", asset.Margin, currency.NewPair(currency.SOL, currency.USDT), "")
assert.NoError(t, err)
}
func TestAlgoOrdersSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.AlgoOrdersSubscription(contextGenerate(), "subscribe", asset.PerpetualSwap, currency.NewPair(currency.SOL, currency.NewCode("USD-SWAP")))
require.NoError(t, err)
err = ok.AlgoOrdersSubscription(contextGenerate(), "unsubscribe", asset.PerpetualSwap, currency.NewPair(currency.SOL, currency.NewCode("USD-SWAP")))
assert.NoError(t, err)
}
func TestAdvanceAlgoOrdersSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.AdvanceAlgoOrdersSubscription(contextGenerate(), "subscribe", asset.PerpetualSwap, currency.NewPair(currency.SOL, currency.NewCode("USD-SWAP")), "")
require.NoError(t, err)
err = ok.AdvanceAlgoOrdersSubscription(contextGenerate(), "unsubscribe", asset.PerpetualSwap, currency.NewPair(currency.SOL, currency.NewCode("USD-SWAP")), "")
assert.NoError(t, err)
}
func TestPositionRiskWarningSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.PositionRiskWarningSubscription(contextGenerate(), "subscribe", asset.PerpetualSwap, currency.NewPair(currency.SOL, currency.NewCode("USD-SWAP")))
require.NoError(t, err)
err = ok.PositionRiskWarningSubscription(contextGenerate(), "unsubscribe", asset.PerpetualSwap, currency.NewPair(currency.SOL, currency.NewCode("USD-SWAP")))
assert.NoError(t, err)
}
func TestAccountGreeksSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.AccountGreeksSubscription(contextGenerate(), "subscribe", currency.NewPair(currency.SOL, currency.USD))
require.NoError(t, err)
err = ok.AccountGreeksSubscription(contextGenerate(), "unsubscribe", currency.NewPair(currency.SOL, currency.USD))
assert.NoError(t, err)
}
func TestRFQSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.RFQSubscription(contextGenerate(), "subscribe", "")
require.NoError(t, err)
err = ok.RFQSubscription(contextGenerate(), "unsubscribe", "")
assert.NoError(t, err)
}
func TestQuotesSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.QuotesSubscription(contextGenerate(), "subscribe")
require.NoError(t, err)
err = ok.QuotesSubscription(contextGenerate(), "unsubscribe")
assert.NoError(t, err)
}
func TestStructureBlockTradesSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.StructureBlockTradesSubscription(contextGenerate(), "subscribe")
require.NoError(t, err)
err = ok.StructureBlockTradesSubscription(contextGenerate(), "unsubscribe")
assert.NoError(t, err)
}
func TestSpotGridAlgoOrdersSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.SpotGridAlgoOrdersSubscription(contextGenerate(), "subscribe", asset.Empty, currency.EMPTYPAIR, "")
require.NoError(t, err)
err = ok.SpotGridAlgoOrdersSubscription(contextGenerate(), "unsubscribe", asset.Empty, currency.EMPTYPAIR, "")
assert.NoError(t, err)
}
func TestContractGridAlgoOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.ContractGridAlgoOrders(contextGenerate(), "subscribe", asset.Empty, currency.EMPTYPAIR, "")
require.NoError(t, err)
err = ok.ContractGridAlgoOrders(contextGenerate(), "unsubscribe", asset.Empty, currency.EMPTYPAIR, "")
assert.NoError(t, err)
}
func TestGridPositionsSubscription(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.GridPositionsSubscription(contextGenerate(), "subscribe", "1234")
require.NoError(t, err)
err = ok.GridPositionsSubscription(contextGenerate(), "unsubscribe", "1234")
assert.NoError(t, err)
}
func TestGridSubOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
err := ok.GridSubOrders(contextGenerate(), "subscribe", "")
require.NoError(t, err)
err = ok.GridSubOrders(contextGenerate(), "unsubscribe", "")
assert.NoError(t, err)
}
func TestGetServerTime(t *testing.T) {
t.Parallel()
result, err := ok.GetServerTime(contextGenerate(), asset.Empty)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAvailableTransferChains(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAvailableTransferChains(contextGenerate(), currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetIntervalEnum(t *testing.T) {
t.Parallel()
tests := []struct {
Description string
Interval kline.Interval
Expected string
AppendUTC bool
}{
{Expected: "", AppendUTC: true},
{Description: "kline.OneMin ", Interval: kline.OneMin, Expected: "1m"},
{Description: "kline.ThreeMin ", Interval: kline.ThreeMin, Expected: "3m"},
{Description: "kline.FiveMin ", Interval: kline.FiveMin, Expected: "5m"},
{Description: "kline.FifteenMin ", Interval: kline.FifteenMin, Expected: "15m"},
{Description: "kline.ThirtyMin ", Interval: kline.ThirtyMin, Expected: "30m"},
{Description: "kline.OneHour ", Interval: kline.OneHour, Expected: "1H"},
{Description: "kline.TwoHour ", Interval: kline.TwoHour, Expected: "2H"},
{Description: "kline.FourHour ", Interval: kline.FourHour, Expected: "4H"},
{Description: "kline.SixHour ", Interval: kline.SixHour, Expected: "6H"},
{Description: "kline.TwelveHour ", Interval: kline.TwelveHour, Expected: "12H"},
{Description: "kline.OneDay ", Interval: kline.OneDay, Expected: "1D"},
{Description: "kline.TwoDay ", Interval: kline.TwoDay, Expected: "2D"},
{Description: "kline.ThreeDay ", Interval: kline.ThreeDay, Expected: "3D"},
{Description: "kline.OneWeek ", Interval: kline.OneWeek, Expected: "1W"},
{Description: "kline.FiveDay ", Interval: kline.FiveDay, Expected: "5D"},
{Description: "kline.OneMonth ", Interval: kline.OneMonth, Expected: "1M"},
{Description: "kline.ThreeMonth ", Interval: kline.ThreeMonth, Expected: "3M"},
{Description: "kline.SixMonth ", Interval: kline.SixMonth, Expected: "6M"},
{Description: "kline.OneYear ", Interval: kline.OneYear, Expected: "1Y"},
{Description: "kline.SixHour + UTC", Interval: kline.SixHour, Expected: "6Hutc", AppendUTC: true},
{Description: "kline.TwelveHour + UTC ", Interval: kline.TwelveHour, Expected: "12Hutc", AppendUTC: true},
{Description: "kline.OneDay + UTC ", Interval: kline.OneDay, Expected: "1Dutc", AppendUTC: true},
{Description: "kline.TwoDay + UTC ", Interval: kline.TwoDay, Expected: "2Dutc", AppendUTC: true},
{Description: "kline.ThreeDay + UTC ", Interval: kline.ThreeDay, Expected: "3Dutc", AppendUTC: true},
{Description: "kline.FiveDay + UTC ", Interval: kline.FiveDay, Expected: "5Dutc", AppendUTC: true},
{Description: "kline.OneWeek + UTC ", Interval: kline.OneWeek, Expected: "1Wutc", AppendUTC: true},
{Description: "kline.OneMonth + UTC ", Interval: kline.OneMonth, Expected: "1Mutc", AppendUTC: true},
{Description: "kline.ThreeMonth + UTC ", Interval: kline.ThreeMonth, Expected: "3Mutc", AppendUTC: true},
{Description: "kline.SixMonth + UTC ", Interval: kline.SixMonth, Expected: "6Mutc", AppendUTC: true},
{Description: "kline.OneYear + UTC ", Interval: kline.OneYear, Expected: "1Yutc", AppendUTC: true},
}
for _, tt := range tests {
t.Run(tt.Description, func(t *testing.T) {
t.Parallel()
r := IntervalFromString(tt.Interval, tt.AppendUTC)
require.Equalf(t, tt.Expected, r, "%s: received: %s but expected: %s", tt.Description, r, tt.Expected)
})
}
}
func TestInstrument(t *testing.T) {
t.Parallel()
var i Instrument
err := json.Unmarshal([]byte(instrumentJSON), &i)
require.NoError(t, err)
require.Empty(t, i.Alias, "expected empty alias")
assert.Empty(t, i.BaseCurrency, "expected empty base currency")
assert.Equal(t, "1", i.Category, "expected 1 category")
assert.Equal(t, 1, int(i.ContractMultiplier.Int64()), "expected 1 contract multiplier")
assert.Equal(t, "linear", i.ContractType, "expected linear contract type")
assert.Equal(t, 0.0001, i.ContractValue.Float64(), "expected 0.0001 contract value")
assert.Equal(t, currency.BTC.String(), i.ContractValueCurrency, "expected BTC contract value currency")
assert.True(t, i.ExpTime.Time().IsZero(), "expected empty expiry time")
assert.Equal(t, "BTC-USDC", i.InstrumentFamily, "expected BTC-USDC instrument family")
assert.Equal(t, "BTC-USDC-SWAP", i.InstrumentID, "expected BTC-USDC-SWAP instrument ID")
swap := GetInstrumentTypeFromAssetItem(asset.PerpetualSwap)
assert.Equal(t, swap, i.InstrumentType, "expected SWAP instrument type")
assert.Equal(t, 125, int(i.MaxLeverage), "expected 125 leverage")
assert.Equal(t, int64(1666076190000), i.ListTime.Time().UnixMilli(), "expected 1666076190000 listing time")
assert.Equal(t, 1, int(i.LotSize))
assert.Equal(t, 100000000.0000000000000000, i.MaxSpotIcebergSize.Float64())
assert.Equal(t, 100000000, int(i.MaxQuantityOfSpotLimitOrder))
assert.Equal(t, 85000, int(i.MaxQuantityOfMarketLimitOrder))
assert.Equal(t, 85000, int(i.MaxStopSize))
assert.Equal(t, 100000000.0000000000000000, i.MaxTriggerSize.Float64())
assert.Equal(t, 0, int(i.MaxQuantityOfSpotTwapLimitOrder), "expected empty max TWAP size")
assert.Equal(t, 1, int(i.MinimumOrderSize))
assert.Empty(t, i.OptionType, "expected empty option type")
assert.Empty(t, i.QuoteCurrency, "expected empty quote currency")
assert.Equal(t, currency.USDC.String(), i.SettlementCurrency, "expected USDC settlement currency")
assert.Equal(t, "live", i.State)
assert.Empty(t, i.StrikePrice, "expected empty strike price")
assert.Equal(t, 0.1, i.TickSize.Float64())
assert.Equal(t, "BTC-USDC", i.Underlying, "expected BTC-USDC underlying")
}
func TestGetLatestFundingRate(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BTC-USD-SWAP")
require.NoError(t, err)
result, err := ok.GetLatestFundingRates(contextGenerate(), &fundingrate.LatestRateRequest{
Asset: asset.PerpetualSwap,
Pair: cp,
IncludePredictedRate: true,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetHistoricalFundingRates(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BTC-USD-SWAP")
require.NoError(t, err)
r := &fundingrate.HistoricalRatesRequest{
Asset: asset.PerpetualSwap,
Pair: cp,
PaymentCurrency: currency.USDT,
StartDate: time.Now().Add(-time.Hour * 24 * 2),
EndDate: time.Now(),
IncludePredictedRate: true,
}
r.StartDate = time.Now().Add(-time.Hour * 24 * 120)
_, err = ok.GetHistoricalFundingRates(contextGenerate(), r)
require.ErrorIs(t, err, fundingrate.ErrFundingRateOutsideLimits)
if sharedtestvalues.AreAPICredentialsSet(ok) {
r.IncludePayments = true
}
r.StartDate = time.Now().Add(-time.Hour * 24 * 12)
result, err := ok.GetHistoricalFundingRates(contextGenerate(), r)
require.NoError(t, err)
require.NotNil(t, result)
r.RespectHistoryLimits = true
result, err = ok.GetHistoricalFundingRates(contextGenerate(), r)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestIsPerpetualFutureCurrency(t *testing.T) {
t.Parallel()
is, err := ok.IsPerpetualFutureCurrency(asset.Binary, currency.NewPair(currency.BTC, currency.USDT))
require.NoError(t, err)
require.False(t, is)
cp, err := currency.NewPairFromString("BTC-USD-SWAP")
require.NoError(t, err)
is, err = ok.IsPerpetualFutureCurrency(asset.PerpetualSwap, cp)
require.NoError(t, err)
assert.True(t, is, "expected true")
}
func TestGetAssetsFromInstrumentTypeOrID(t *testing.T) {
t.Parallel()
ok := new(Okx) //nolint:govet // Intentional shadow
require.NoError(t, testexch.Setup(ok), "Setup must not error")
_, err := ok.getAssetsFromInstrumentID("")
assert.ErrorIs(t, err, errMissingInstrumentID)
for _, a := range []asset.Item{asset.Spot, asset.Futures, asset.PerpetualSwap, asset.Options} {
assets, err2 := ok.getAssetsFromInstrumentID(ok.CurrencyPairs.Pairs[a].Enabled[0].String())
require.NoErrorf(t, err2, "GetAssetsFromInstrumentTypeOrID must not error for asset: %s", a)
switch a {
case asset.Spot, asset.Margin:
// spot and margin instruments are similar
require.Len(t, assets, 2)
default:
require.Len(t, assets, 1)
}
assert.Contains(t, assets, a, "Should contain asset: %s", a)
}
_, err = ok.getAssetsFromInstrumentID("test")
assert.ErrorIs(t, err, currency.ErrCurrencyNotSupported)
_, err = ok.getAssetsFromInstrumentID("test-test")
assert.ErrorIs(t, err, asset.ErrNotEnabled)
for _, a := range []asset.Item{asset.Margin, asset.Spot} {
assets, err2 := ok.getAssetsFromInstrumentID(ok.CurrencyPairs.Pairs[a].Enabled[0].String())
require.NoErrorf(t, err2, "GetAssetsFromInstrumentTypeOrID must not error for asset: %s", a)
assert.Contains(t, assets, a)
}
}
func TestSetMarginType(t *testing.T) {
t.Parallel()
err := ok.SetMarginType(contextGenerate(), asset.Spot, currency.NewBTCUSDT(), margin.Isolated)
assert.ErrorIs(t, err, common.ErrFunctionNotSupported)
}
func TestChangePositionMargin(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
cp, err := currency.NewPairFromString("eth/btc")
require.NoError(t, err)
result, err := ok.ChangePositionMargin(contextGenerate(), &margin.PositionChangeRequest{
Pair: cp,
Asset: asset.Margin,
MarginType: margin.Isolated,
OriginalAllocatedMargin: 4.0695,
NewAllocatedMargin: 5,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCollateralMode(t *testing.T) {
t.Parallel()
_, err := ok.GetCollateralMode(contextGenerate(), asset.USDTMarginedFutures)
require.ErrorIs(t, err, asset.ErrNotSupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetCollateralMode(contextGenerate(), asset.Spot)
assert.NoError(t, err)
assert.NotNil(t, result)
_, err = ok.GetCollateralMode(contextGenerate(), asset.Futures)
assert.True(t, errors.Is(err, nil) || errors.Is(err, asset.ErrNotSupported))
}
func TestSetCollateralMode(t *testing.T) {
t.Parallel()
err := ok.SetCollateralMode(contextGenerate(), asset.Spot, collateral.SingleMode)
assert.ErrorIs(t, err, common.ErrFunctionNotSupported)
}
func TestGetPositionSummary(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
pp, err := ok.CurrencyPairs.GetPairs(asset.PerpetualSwap, true)
require.NoError(t, err)
result, err := ok.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{
Asset: asset.PerpetualSwap,
Pair: pp[0],
UnderlyingPair: currency.EMPTYPAIR,
})
require.NoError(t, err)
require.NotNil(t, result)
pp, err = ok.CurrencyPairs.GetPairs(asset.Futures, true)
require.NoError(t, err)
_, err = ok.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{
Asset: asset.Spot,
Pair: pp[0],
UnderlyingPair: currency.NewBTCUSDT(),
})
require.ErrorIsf(t, err, futures.ErrNotFuturesAsset, "received '%v', expected '%v'", err, futures.ErrNotFuturesAsset)
result, err = ok.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{
Asset: asset.Futures,
Pair: pp[0],
UnderlyingPair: currency.EMPTYPAIR,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFuturesPositions(t *testing.T) {
t.Parallel()
pp, err := ok.CurrencyPairs.GetPairs(asset.Futures, true)
require.NoError(t, err)
_, err = ok.GetFuturesPositionOrders(contextGenerate(), &futures.PositionsRequest{
Asset: asset.Spot,
Pairs: []currency.Pair{pp[0]},
StartDate: time.Now().Add(time.Hour * 24 * -7),
})
require.ErrorIs(t, err, asset.ErrNotSupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFuturesPositionOrders(contextGenerate(), &futures.PositionsRequest{
Asset: asset.Futures,
Pairs: []currency.Pair{pp[0]},
StartDate: time.Now().Add(time.Hour * 24 * -7),
EndDate: time.Now(),
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLeverage(t *testing.T) {
t.Parallel()
pp, err := ok.CurrencyPairs.GetPairs(asset.Futures, true)
require.NoError(t, err)
_, err = ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.UnknownSide)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Multi, order.UnknownSide)
require.NoError(t, err)
require.NotNil(t, result)
result, err = ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.Long)
require.NoError(t, err)
require.NotNil(t, result)
result, err = ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.Short)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetLeverage(t *testing.T) {
t.Parallel()
pp, err := ok.CurrencyPairs.GetPairs(asset.Futures, true)
require.NoError(t, err)
err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.UnknownSide)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.CouldNotBuy)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
err = ok.SetLeverage(contextGenerate(), asset.Spot, pp[0], margin.Multi, 5, order.UnknownSide)
require.ErrorIs(t, err, asset.ErrNotSupported)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Multi, 5, order.UnknownSide)
require.NoError(t, err)
err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.Long)
require.NoError(t, err)
err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.Short)
assert.NoError(t, err)
}
func TestGetFuturesContractDetails(t *testing.T) {
t.Parallel()
_, err := ok.GetFuturesContractDetails(contextGenerate(), asset.Spot)
require.ErrorIs(t, err, futures.ErrNotFuturesAsset)
_, err = ok.GetFuturesContractDetails(contextGenerate(), asset.USDTMarginedFutures)
require.ErrorIs(t, err, asset.ErrNotSupported)
for _, a := range []asset.Item{asset.Futures, asset.PerpetualSwap, asset.Spread} {
result, err := ok.GetFuturesContractDetails(context.Background(), a)
require.NoError(t, err)
require.NotNil(t, result)
}
}
func TestWsProcessOrderbook5(t *testing.T) {
t.Parallel()
var ob5payload = []byte(`{"arg":{"channel":"books5","instId":"OKB-USDT"},"data":[{"asks":[["0.0000007465","2290075956","0","4"],["0.0000007466","1747284705","0","4"],["0.0000007467","1338861655","0","3"],["0.0000007468","1661668387","0","6"],["0.0000007469","2715477116","0","5"]],"bids":[["0.0000007464","15693119","0","1"],["0.0000007463","2330835024","0","4"],["0.0000007462","1182926517","0","2"],["0.0000007461","3818684357","0","4"],["0.000000746","6021641435","0","7"]],"instId":"OKB-USDT","ts":"1695864901807","seqId":4826378794}]}`)
err := ok.wsProcessOrderbook5(ob5payload)
require.NoError(t, err)
required := currency.NewPairWithDelimiter("OKB", "USDT", "-")
got, err := orderbook.Get("okx", required, asset.Spot)
require.NoError(t, err)
require.Len(t, got.Asks, 5)
require.Len(t, got.Bids, 5)
// Book replicated to margin
got, err = orderbook.Get("okx", required, asset.Margin)
require.NoError(t, err)
require.Len(t, got.Asks, 5)
assert.Len(t, got.Bids, 5)
}
func TestGetLeverateEstimatedInfo(t *testing.T) {
t.Parallel()
_, err := ok.GetLeverageEstimatedInfo(contextGenerate(), "", "cross", "1", "", "BTC-USDT", currency.BTC)
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "", "1", "", "BTC-USDT", currency.BTC)
require.ErrorIs(t, err, margin.ErrMarginTypeUnsupported)
_, err = ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "", "", "BTC-USDT", currency.BTC)
require.ErrorIs(t, err, errInvalidLeverage)
_, err = ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "1", "", "BTC-USDT", currency.EMPTYCODE)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "1", "", "BTC-USDT", currency.BTC)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestManualBorrowAndRepayInQuickMarginMode(t *testing.T) {
t.Parallel()
_, err := ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{
InstrumentID: "BTC-USDT",
LoanCcy: currency.USDT,
Side: "borrow"})
require.ErrorIs(t, err, order.ErrAmountBelowMin)
_, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{
Amount: 1,
InstrumentID: "BTC-USDT",
Side: "borrow",
})
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{
Amount: 1,
InstrumentID: "BTC-USDT",
LoanCcy: currency.USDT,
})
require.ErrorIs(t, err, order.ErrSideIsInvalid)
_, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{
Amount: 1,
LoanCcy: currency.USDT,
Side: "borrow",
})
require.ErrorIs(t, err, errMissingInstrumentID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{
Amount: 1,
InstrumentID: "BTC-USDT",
LoanCcy: currency.USDT,
Side: "borrow",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetBorrowAndRepayHistoryInQuickMarginMode(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetBorrowAndRepayHistoryInQuickMarginMode(contextGenerate(), currency.EMPTYPAIR, currency.BTC, "borrow", "", "", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetVIPInterestAccruedData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetVIPInterestAccruedData(contextGenerate(), currency.ETH, "", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetVIPInterestDeductedData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetVIPInterestDeductedData(contextGenerate(), currency.ETH, "", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetVIPLoanOrderList(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetVIPLoanOrderList(contextGenerate(), "", "1", currency.BTC, time.Time{}, time.Now(), 20)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetVIPLoanOrderDetail(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetVIPLoanOrderDetail(contextGenerate(), "123456", currency.BTC, time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetRiskOffsetType(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetRiskOffsetType(contextGenerate(), "3")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestActivateOption(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.ActivateOption(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetAutoLoan(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.SetAutoLoan(contextGenerate(), true)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetAccountMode(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetAccountMode(contextGenerate(), "1")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestResetMMPStatus(t *testing.T) {
t.Parallel()
_, err := ok.ResetMMPStatus(contextGenerate(), instTypeOption, "")
require.ErrorIs(t, err, errInstrumentFamilyRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ResetMMPStatus(contextGenerate(), instTypeOption, "BTC-USD")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetMMP(t *testing.T) {
t.Parallel()
_, err := ok.SetMMP(contextGenerate(), &MMPConfig{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.SetMMP(contextGenerate(), &MMPConfig{
TimeInterval: 5000,
})
require.ErrorIs(t, err, errInstrumentFamilyRequired)
_, err = ok.SetMMP(contextGenerate(), &MMPConfig{
InstrumentFamily: "BTC-USD",
})
require.ErrorIs(t, err, errInvalidQuantityLimit)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetMMP(contextGenerate(), &MMPConfig{
InstrumentFamily: "BTC-USD",
TimeInterval: 5000,
FrozenInterval: 2000,
QuantityLimit: 100,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMMPConfig(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMMPConfig(contextGenerate(), "BTC-USD")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestMassCancelOrder(t *testing.T) {
t.Parallel()
_, err := ok.CancelAllMMPOrders(contextGenerate(), "", "BTC-USD", 2000)
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.CancelAllMMPOrders(contextGenerate(), "OPTION", "", 2000)
require.ErrorIs(t, err, errInstrumentFamilyRequired)
_, err = ok.CancelAllMMPOrders(contextGenerate(), "OPTION", "BTC-USD", -1)
require.ErrorIs(t, err, errMissingIntervalValue)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAllMMPOrders(contextGenerate(), "OPTION", "BTC-USD", 2000)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAllDelayed(t *testing.T) {
t.Parallel()
_, err := ok.CancelAllDelayed(contextGenerate(), 2, "")
require.ErrorIs(t, err, errCountdownTimeoutRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAllDelayed(contextGenerate(), 60, "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTradeAccountRateLimit(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetTradeAccountRateLimit(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPreCheckOrder(t *testing.T) {
t.Parallel()
_, err := ok.PreCheckOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
arg := &OrderPreCheckParams{
ClientOrderID: "b15",
}
_, err = ok.PreCheckOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = "BTC-USDT"
_, err = ok.PreCheckOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidTradeModeValue)
arg.TradeMode = "cash"
_, err = ok.PreCheckOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
arg.Side = "buy"
_, err = ok.PreCheckOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = "limit"
_, err = ok.PreCheckOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PreCheckOrder(contextGenerate(), &OrderPreCheckParams{
InstrumentID: "BTC-USDT",
TradeMode: "cash",
ClientOrderID: "b15",
Side: order.Buy.Lower(),
OrderType: "limit",
Price: 2.15,
Size: 2,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendAlgoOrder(t *testing.T) {
t.Parallel()
_, err := ok.AmendAlgoOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{NewSize: 2})
require.ErrorIs(t, err, errMissingInstrumentID)
_, err = ok.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{
InstrumentID: perpetualSwapTP.String(),
NewSize: 2,
})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{
AlgoID: "2510789768709120",
InstrumentID: perpetualSwapTP.String(),
NewSize: 2,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAlgoOrderDetail(t *testing.T) {
t.Parallel()
_, err := ok.GetAlgoOrderDetail(contextGenerate(), "", "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAlgoOrderDetail(contextGenerate(), "1234231231423", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestClosePositionForContractID(t *testing.T) {
t.Parallel()
_, err := ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "", MarketCloseAllPositions: true})
require.ErrorIs(t, err, errAlgoIDRequired)
_, err = ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "448965992920907776", MarketCloseAllPositions: false})
require.ErrorIs(t, err, order.ErrAmountMustBeSet)
_, err = ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "448965992920907776", MarketCloseAllPositions: false, Size: 123})
require.ErrorIs(t, err, order.ErrPriceBelowMin)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{
AlgoID: "448965992920907776",
MarketCloseAllPositions: true,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelClosePositionOrderForContractGrid(t *testing.T) {
t.Parallel()
_, err := ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{OrderID: "570627699870375936"})
require.ErrorIs(t, err, errAlgoIDRequired)
_, err = ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{AlgoID: "448965992920907776"})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{
AlgoID: "448965992920907776",
OrderID: "570627699870375936",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestInstantTriggerGridAlgoOrder(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.InstantTriggerGridAlgoOrder(contextGenerate(), "123456789")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestComputeMinInvestment(t *testing.T) {
t.Parallel()
arg := &ComputeInvestmentDataParam{
RunType: "1",
}
_, err := ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.InstrumentID = "ETH-USDT"
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidAlgoOrderType)
arg.AlgoOrderType = "grid"
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.MaxPrice = 5000
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.MinPrice = 5000
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidGridQuantity)
arg.GridNumber = 1234
arg.RunType = ""
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, errRunTypeRequired)
arg.RunType = "1"
arg.AlgoOrderType = "contract_grid"
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingRequiredArgumentDirection)
arg.Direction = positionSideLong
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidLeverage)
arg.Leverage = 5
arg.InvestmentData = []InvestmentData{{Currency: currency.ETH}}
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.InvestmentData = []InvestmentData{{Amount: 0.01}}
_, err = ok.ComputeMinInvestment(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
result, err := ok.ComputeMinInvestment(contextGenerate(), &ComputeInvestmentDataParam{
InstrumentID: "ETH-USDT",
AlgoOrderType: "grid",
GridNumber: 50,
MaxPrice: 5000,
MinPrice: 3000,
RunType: "1",
InvestmentData: []InvestmentData{
{
Amount: 0.01,
Currency: currency.ETH,
},
{
Amount: 100,
Currency: currency.USDT,
},
},
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestRSIBackTesting(t *testing.T) {
t.Parallel()
_, err := ok.RSIBackTesting(contextGenerate(), "", "", "", 50, 14, kline.FiveMin)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.RSIBackTesting(contextGenerate(), "BTC-USDT", "", "", 50, 14, kline.FiveMin)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSignalBotTrading(t *testing.T) {
t.Parallel()
_, err := ok.GetSignalBotOrderDetail(contextGenerate(), "", "623833708424069120")
require.ErrorIs(t, err, errInvalidAlgoOrderType)
_, err = ok.GetSignalBotOrderDetail(contextGenerate(), "contract", "")
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.GetSignalBotOrderDetail(contextGenerate(), "contract", "623833708424069120")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSignalOrderPositions(t *testing.T) {
t.Parallel()
_, err := ok.GetSignalOrderPositions(contextGenerate(), "", "623833708424069120")
require.ErrorIs(t, err, errInvalidAlgoOrderType)
_, err = ok.GetSignalOrderPositions(contextGenerate(), "contract", "")
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSignalOrderPositions(contextGenerate(), "contract", "623833708424069120")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSignalBotSubOrders(t *testing.T) {
t.Parallel()
_, err := ok.GetSignalBotSubOrders(contextGenerate(), "", "contract", "filled", "", "", "", time.Time{}, time.Time{}, 0)
require.ErrorIs(t, err, errAlgoIDRequired)
_, err = ok.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "", "filled", "", "", "", time.Time{}, time.Time{}, 0)
require.ErrorIs(t, err, errInvalidAlgoOrderType)
_, err = ok.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "contract", "", "", "", "", time.Time{}, time.Time{}, 0)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "contract", "filled", "", "", "", time.Time{}, time.Time{}, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSignalBotEventHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetSignalBotEventHistory(contextGenerate(), "", time.Time{}, time.Now(), 50)
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSignalBotEventHistory(contextGenerate(), "12345", time.Time{}, time.Now(), 50)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceRecurringBuyOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceRecurringBuyOrder(contextGenerate(), nil)
require.ErrorIs(t, err, common.ErrNilPointer)
arg := &PlaceRecurringBuyOrderParam{
TimeZone: "3",
}
_, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errStrategyNameRequired)
arg.StrategyName = "BTC|ETH recurring buy monthly"
_, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, common.ErrEmptyParams)
arg.RecurringList = []RecurringListItem{{}}
_, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.RecurringList = []RecurringListItem{{Currency: currency.BTC}}
_, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errRecurringDayRequired)
arg.RecurringDay = "1"
arg.RecurringTime = -10
_, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errRecurringBuyTimeRequired)
arg.RecurringTime = 2
_, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errInvalidTradeModeValue)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceRecurringBuyOrder(contextGenerate(), &PlaceRecurringBuyOrderParam{
StrategyName: "BTC|ETH recurring buy monthly",
Amount: 100,
RecurringList: []RecurringListItem{
{
Currency: currency.BTC,
Ratio: 0.2,
},
{
Currency: currency.ETH,
Ratio: 0.8,
},
},
Period: "monthly",
RecurringDay: "1",
RecurringTime: 0,
TimeZone: "8", // UTC +8
TradeMode: "cross",
InvestmentCurrency: "USDT",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendRecurringBuyOrder(t *testing.T) {
t.Parallel()
_, err := ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{StrategyName: "stg1"})
require.ErrorIs(t, err, errAlgoIDRequired)
_, err = ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{AlgoID: "448965992920907776"})
require.ErrorIs(t, err, errStrategyNameRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{
AlgoID: "448965992920907776",
StrategyName: "stg1",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestStopRecurringBuyOrder(t *testing.T) {
t.Parallel()
_, err := ok.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{{}})
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{{AlgoID: "1232323434234"}})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetRecurringBuyOrderList(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetRecurringBuyOrderList(contextGenerate(), "", "paused", time.Time{}, time.Time{}, 30)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetRecurringBuyOrderHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetRecurringBuyOrderHistory(contextGenerate(), "", time.Time{}, time.Time{}, 30)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetRecurringOrderDetails(t *testing.T) {
t.Parallel()
_, err := ok.GetRecurringOrderDetails(contextGenerate(), "", "")
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetRecurringOrderDetails(contextGenerate(), "560473220642766848", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetRecurringSubOrders(t *testing.T) {
t.Parallel()
_, err := ok.GetRecurringSubOrders(contextGenerate(), "", "123422", time.Time{}, time.Now(), 0)
require.ErrorIs(t, err, errAlgoIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetRecurringSubOrders(contextGenerate(), "560473220642766848", "123422", time.Time{}, time.Now(), 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetExistingLeadingPositions(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetExistingLeadingPositions(contextGenerate(), instTypeSpot, "BTC-USDT", time.Now(), time.Time{}, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLeadingPositionsHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLeadingPositionsHistory(contextGenerate(), "OPTION", "", time.Time{}, time.Time{}, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceLeadingStopOrder(t *testing.T) {
t.Parallel()
arg := &TPSLOrderParam{}
_, err := ok.PlaceLeadingStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, common.ErrEmptyParams)
arg.Tag = "1235454"
_, err = ok.PlaceLeadingStopOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errSubPositionIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceLeadingStopOrder(contextGenerate(), &TPSLOrderParam{
SubPositionID: "1235454",
TakeProfitTriggerPrice: 123455,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCloseLeadingPosition(t *testing.T) {
t.Parallel()
_, err := ok.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{Tag: "tag-here"})
require.ErrorIs(t, err, errSubPositionIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{
SubPositionID: "518541406042591232",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLeadingInstrument(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLeadingInstrument(contextGenerate(), "SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendLeadingInstruments(t *testing.T) {
t.Parallel()
_, err := ok.AmendLeadingInstruments(contextGenerate(), "", "")
require.ErrorIs(t, err, errMissingInstrumentID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendLeadingInstruments(contextGenerate(), "BTC-USDT-SWAP", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetProfitSharingDetails(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetProfitSharingDetails(contextGenerate(), "", time.Now(), time.Time{}, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTotalProfitSharing(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetTotalProfitSharing(contextGenerate(), "SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetUnrealizedProfitSharingDetails(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetUnrealizedProfitSharingDetails(contextGenerate(), "SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetFirstCopySettings(t *testing.T) {
t.Parallel()
_, err := ok.AmendCopySettings(contextGenerate(), &FirstCopySettings{})
require.ErrorIs(t, err, common.ErrEmptyParams)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendCopySettings(contextGenerate(), &FirstCopySettings{
InstrumentType: "SWAP",
UniqueCode: "25CD5A80241D6FE6",
CopyMarginMode: "cross",
CopyInstrumentIDType: "copy",
CopyMode: "ratio_copy",
CopyRatio: 1,
CopyTotalAmount: 500,
SubPosCloseType: "copy_close",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendCopySettings(t *testing.T) {
t.Parallel()
_, err := ok.SetFirstCopySettings(contextGenerate(), &FirstCopySettings{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &FirstCopySettings{
CopyMode: "ratio_copy",
}
_, err = ok.SetFirstCopySettings(contextGenerate(), arg)
require.ErrorIs(t, err, errUniqueCodeRequired)
arg.UniqueCode = "25CD5A80241D6FE6"
_, err = ok.SetFirstCopySettings(contextGenerate(), arg)
require.ErrorIs(t, err, errCopyInstrumentIDTypeRequired)
arg.CopyInstrumentIDType = "copy"
_, err = ok.SetFirstCopySettings(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.CopyTotalAmount = 500
_, err = ok.SetFirstCopySettings(contextGenerate(), arg)
require.ErrorIs(t, err, errSubPositionCloseTypeRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.SetFirstCopySettings(contextGenerate(), &FirstCopySettings{
InstrumentType: "SWAP",
UniqueCode: "25CD5A80241D6FE6",
CopyMarginMode: "cross",
CopyInstrumentIDType: "copy",
CopyMode: "ratio_copy",
CopyRatio: 1,
CopyTotalAmount: 500,
SubPosCloseType: "copy_close",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestStopCopying(t *testing.T) {
t.Parallel()
_, err := ok.StopCopying(contextGenerate(), &StopCopyingParameter{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.StopCopying(contextGenerate(), &StopCopyingParameter{
InstrumentType: "SWAP",
SubPositionCloseType: "manual_close",
})
require.ErrorIs(t, err, errUniqueCodeRequired)
_, err = ok.StopCopying(contextGenerate(), &StopCopyingParameter{InstrumentType: "SWAP",
UniqueCode: "25CD5A80241D6FE6"})
require.ErrorIs(t, err, errSubPositionCloseTypeRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.StopCopying(contextGenerate(), &StopCopyingParameter{
InstrumentType: "SWAP",
UniqueCode: "25CD5A80241D6FE6",
SubPositionCloseType: "manual_close",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCopySettings(t *testing.T) {
t.Parallel()
_, err := ok.GetCopySettings(contextGenerate(), "SWAP", "")
require.ErrorIs(t, err, errUniqueCodeRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetCopySettings(contextGenerate(), "SWAP", "213E8C92DC61EFAC")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMultipleLeverages(t *testing.T) {
t.Parallel()
_, err := ok.GetMultipleLeverages(contextGenerate(), "", "213E8C92DC61EFAC", "")
require.ErrorIs(t, err, margin.ErrInvalidMarginType)
_, err = ok.GetMultipleLeverages(contextGenerate(), "isolated", "", "")
require.ErrorIs(t, err, errUniqueCodeRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMultipleLeverages(contextGenerate(), "isolated", "213E8C92DC61EFAC", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestSetMultipleLeverages(t *testing.T) {
t.Parallel()
_, err := ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{Leverage: 5})
require.ErrorIs(t, err, margin.ErrInvalidMarginType)
_, err = ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{MarginMode: "cross"})
require.ErrorIs(t, err, errInvalidLeverage)
_, err = ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{
MarginMode: "cross",
Leverage: 5,
})
require.ErrorIs(t, err, errMissingInstrumentID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{
MarginMode: "cross",
Leverage: 5,
InstrumentID: "BTC-USDT-SWAP",
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetMyLeadTraders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetMyLeadTraders(contextGenerate(), "SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetHistoryLeadTraders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetHistoryLeadTraders(contextGenerate(), "", "", "", 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetWeeklyTraderProfitAndLoss(t *testing.T) {
t.Parallel()
_, err := ok.GetWeeklyTraderProfitAndLoss(contextGenerate(), "", "")
require.ErrorIs(t, err, errUniqueCodeRequired)
mainResult, err := ok.GetWeeklyTraderProfitAndLoss(contextGenerate(), "", leadTraderUniqueID)
require.NoError(t, err)
assert.NotNil(t, mainResult)
}
func TestGetDailyLeadTraderPNL(t *testing.T) {
t.Parallel()
_, err := ok.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", "", "2")
require.ErrorIs(t, err, errUniqueCodeRequired)
_, err = ok.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", leadTraderUniqueID, "")
require.ErrorIs(t, err, errLastDaysRequired)
mainResult, err := ok.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", leadTraderUniqueID, "2")
require.NoError(t, err)
assert.NotNil(t, mainResult)
}
func TestGetLeadTraderStats(t *testing.T) {
t.Parallel()
_, err := ok.GetLeadTraderStats(contextGenerate(), "SWAP", "", "2")
require.ErrorIs(t, err, errUniqueCodeRequired)
_, err = ok.GetLeadTraderStats(contextGenerate(), "SWAP", leadTraderUniqueID, "")
require.ErrorIs(t, err, errLastDaysRequired)
result, err := ok.GetLeadTraderStats(contextGenerate(), "SWAP", leadTraderUniqueID, "2")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLeadTraderCurrencyPreferences(t *testing.T) {
t.Parallel()
_, err := ok.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", "", "2")
require.ErrorIs(t, err, errUniqueCodeRequired)
_, err = ok.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", leadTraderUniqueID, "")
require.ErrorIs(t, err, errLastDaysRequired)
result, err := ok.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", leadTraderUniqueID, "2")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLeadTraderCurrentLeadPositions(t *testing.T) {
t.Parallel()
_, err := ok.GetLeadTraderCurrentLeadPositions(contextGenerate(), instTypeSwap, "", "", "", 10)
require.ErrorIs(t, err, errUniqueCodeRequired)
result, err := ok.GetLeadTraderCurrentLeadPositions(contextGenerate(), "SWAP", leadTraderUniqueID, "", "", 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLeadTraderLeadPositionHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetLeadTraderLeadPositionHistory(contextGenerate(), "SWAP", "", "", "", 10)
require.ErrorIs(t, err, errUniqueCodeRequired)
result, err := ok.GetLeadTraderLeadPositionHistory(contextGenerate(), "SWAP", leadTraderUniqueID, "", "", 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestPlaceSpreadOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &SpreadOrderParam{Tag: "tag-here"}
_, err = ok.PlaceSpreadOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errMissingInstrumentID)
arg.SpreadID = spreadTP.String()
_, err = ok.PlaceSpreadOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrTypeIsInvalid)
arg.OrderType = "limit"
_, err = ok.PlaceSpreadOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.Size = 1
_, err = ok.PlaceSpreadOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrPriceBelowMin)
arg.Price = 12345
_, err = ok.PlaceSpreadOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrSideIsInvalid)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{
InstrumentID: spreadTP.String(),
SpreadID: "1234",
ClientOrderID: "12354123523",
Side: order.Buy.Lower(),
OrderType: "limit",
Size: 1,
Price: 12345,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelSpreadOrder(t *testing.T) {
t.Parallel()
_, err := ok.CancelSpreadOrder(contextGenerate(), "", "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelSpreadOrder(contextGenerate(), "12345", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsCancelSpreadOrder(t *testing.T) {
t.Parallel()
_, err := ok.WsCancelSpreadOrder(contextGenerate(), "", "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsCancelSpreadOrder(contextGenerate(), "1234", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAllSpreadOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAllSpreadOrders(contextGenerate(), "123456")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsCancelAllSpreadOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsCancelAllSpreadOrders(contextGenerate(), "BTC-USDT_BTC-USDT-SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendSpreadOrder(t *testing.T) {
t.Parallel()
_, err := ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{NewSize: 2})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{OrderID: "2510789768709120"})
require.ErrorIs(t, err, errSizeOrPriceIsRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{
OrderID: "2510789768709120",
NewSize: 2,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsAmandSpreadOrder(t *testing.T) {
t.Parallel()
_, err := ok.WsAmandSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
_, err = ok.WsAmandSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{NewSize: 2})
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.WsAmandSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{OrderID: "2510789768709120"})
require.ErrorIs(t, err, errSizeOrPriceIsRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsAmandSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{
OrderID: "2510789768709120",
NewSize: 2,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSpreadOrderDetails(t *testing.T) {
t.Parallel()
_, err := ok.GetSpreadOrderDetails(contextGenerate(), "", "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSpreadOrderDetails(contextGenerate(), "1234567", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetActiveSpreadOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetActiveSpreadOrders(contextGenerate(), "", "post_only", "partially_filled", "", "", 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetCompletedSpreadOrdersLast7Days(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetCompletedSpreadOrdersLast7Days(contextGenerate(), "", "limit", "canceled", "", "", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSpreadTradesOfLast7Days(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetSpreadTradesOfLast7Days(contextGenerate(), "", "", "", "", "", time.Time{}, time.Time{}, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSpreads(t *testing.T) {
t.Parallel()
result, err := ok.GetPublicSpreads(contextGenerate(), "", "", "", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSpreadOrderBooks(t *testing.T) {
t.Parallel()
_, err := ok.GetPublicSpreadOrderBooks(contextGenerate(), "", 0)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetPublicSpreadOrderBooks(contextGenerate(), "BTC-USDT_BTC-USDT-SWAP", 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetSpreadTickers(t *testing.T) {
t.Parallel()
_, err := ok.GetPublicSpreadTickers(contextGenerate(), "")
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetPublicSpreadTickers(contextGenerate(), "BTC-USDT_BTC-USDT-SWAP")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPublicSpreadTrades(t *testing.T) {
t.Parallel()
result, err := ok.GetPublicSpreadTrades(contextGenerate(), "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOptionsTickBands(t *testing.T) {
t.Parallel()
_, err := ok.GetOptionsTickBands(contextGenerate(), "", "")
require.ErrorIs(t, err, errInvalidInstrumentType)
result, err := ok.GetOptionsTickBands(contextGenerate(), "OPTION", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestExtractIndexCandlestick(t *testing.T) {
t.Parallel()
data := `[ [ "1597026383085", "3.721", "3.743", "3.677", "3.708", "1" ], [ "1597026383085", "3.731", "3.799", "3.494", "3.72", "1" ]]`
var resp []CandlestickHistoryItem
err := json.Unmarshal([]byte(data), &resp)
require.NoError(t, err)
require.Len(t, resp, 2)
require.Equal(t, 3.743, resp[0].HighestPrice.Float64())
require.Equal(t, StateCompleted, resp[0].Confirm)
}
func TestGetHistoricIndexAndMarkPriceCandlesticks(t *testing.T) {
t.Parallel()
_, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), "", time.Time{}, time.Time{}, kline.FiveMin, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), "BTC-USD", time.Time{}, time.Time{}, kline.FiveMin, 10)
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.GetMarkPriceCandlestickHistory(contextGenerate(), "BTC-USD-SWAP", time.Time{}, time.Time{}, kline.FiveMin, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetEconomicCanendarData(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetEconomicCalendarData(contextGenerate(), "", "", time.Now(), time.Time{}, 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetDepositWithdrawalStatus(t *testing.T) {
t.Parallel()
_, err := ok.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "", "", "", "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
_, err = ok.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "", "1244", "", "")
require.ErrorIs(t, err, errMissingValidWithdrawalID)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "1244", "", "", "")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetPublicExchangeList(t *testing.T) {
t.Parallel()
result, err := ok.GetPublicExchangeList(contextGenerate())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestWsPlaceSpreadOrder(t *testing.T) {
t.Parallel()
_, err := ok.WsPlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{})
require.ErrorIs(t, err, common.ErrNilPointer)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.WsPlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{
SpreadID: "BTC-USDT_BTC-USDT-SWAP",
ClientOrderID: "b15",
Side: order.Buy.Lower(),
OrderType: "limit",
Price: 2.15,
Size: 2,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetInviteesDetail(t *testing.T) {
t.Parallel()
_, err := ok.GetInviteesDetail(contextGenerate(), "")
require.ErrorIs(t, err, errUserIDRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetInviteesDetail(contextGenerate(), "1234")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetUserAffilateRebateInformation(t *testing.T) {
t.Parallel()
_, err := ok.GetUserAffiliateRebateInformation(contextGenerate(), "")
require.ErrorIs(t, err, errInvalidAPIKey)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetUserAffiliateRebateInformation(contextGenerate(), "1234")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetOpenInterest(t *testing.T) {
t.Parallel()
_, err := ok.GetOpenInterest(contextGenerate(), key.PairAsset{
Base: currency.ETH.Item,
Quote: currency.USDT.Item,
Asset: asset.USDTMarginedFutures,
})
require.ErrorIs(t, err, asset.ErrNotSupported)
usdSwapCode := currency.NewCode("USD-SWAP")
resp, err := ok.GetOpenInterest(contextGenerate(), key.PairAsset{
Base: perpetualSwapTP.Base.Item,
Quote: perpetualSwapTP.Quote.Item,
Asset: asset.PerpetualSwap,
})
assert.NoError(t, err)
assert.NotEmpty(t, resp)
cp1 := currency.NewPair(currency.DOGE, usdSwapCode)
sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, ok, asset.PerpetualSwap, cp1)
resp, err = ok.GetOpenInterest(contextGenerate(),
key.PairAsset{
Base: currency.BTC.Item,
Quote: usdSwapCode.Item,
Asset: asset.PerpetualSwap,
},
key.PairAsset{
Base: cp1.Base.Item,
Quote: cp1.Quote.Item,
Asset: asset.PerpetualSwap,
},
)
assert.NoError(t, err)
assert.NotEmpty(t, resp)
resp, err = ok.GetOpenInterest(contextGenerate())
assert.NoError(t, err)
assert.NotEmpty(t, resp)
}
func TestGetCurrencyTradeURL(t *testing.T) {
t.Parallel()
testexch.UpdatePairsOnce(t, ok)
for _, a := range ok.GetAssetTypes(false) {
pairs, err := ok.CurrencyPairs.GetPairs(a, false)
assert.NoError(t, err)
assert.NotEmpty(t, pairs)
resp, err := ok.GetCurrencyTradeURL(contextGenerate(), a, pairs[0])
assert.NoError(t, err)
assert.NotEmpty(t, resp)
}
}
func TestPlaceLendingOrder(t *testing.T) {
t.Parallel()
_, err := ok.PlaceLendingOrder(contextGenerate(), &LendingOrderParam{})
require.ErrorIs(t, err, common.ErrEmptyParams)
arg := &LendingOrderParam{AutoRenewal: true}
_, err = ok.PlaceLendingOrder(contextGenerate(), arg)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
arg.Currency = currency.USDT
_, err = ok.PlaceLendingOrder(contextGenerate(), arg)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
arg.Amount = 1
_, err = ok.PlaceLendingOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errRateRequired)
arg.Rate = 0.01
_, err = ok.PlaceLendingOrder(contextGenerate(), arg)
require.ErrorIs(t, err, errLendingTermIsRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.PlaceLendingOrder(contextGenerate(), &LendingOrderParam{
Currency: currency.USDT,
Amount: 1,
Rate: 0.01,
Term: "30D",
AutoRenewal: true,
})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAmendLendingOrder(t *testing.T) {
t.Parallel()
_, err := ok.AmendLendingOrder(contextGenerate(), "", 0, 0, false)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.AmendLendingOrder(contextGenerate(), "12312312", 1., 2., true)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLendingOrders(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLendingOrders(contextGenerate(), "", "pending", currency.ETH, time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetLendingSubOrderList(t *testing.T) {
t.Parallel()
_, err := ok.GetLendingSubOrderList(contextGenerate(), "", "pending", time.Time{}, time.Time{}, 10)
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetLendingSubOrderList(contextGenerate(), "12345", "", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelAllSpreadOrdersAfterCountdown(t *testing.T) {
t.Parallel()
_, err := ok.CancelAllSpreadOrdersAfterCountdown(contextGenerate(), 2)
require.ErrorIs(t, err, errCountdownTimeoutRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CancelAllSpreadOrdersAfterCountdown(contextGenerate(), 12)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetContractsOpenInterestHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetFuturesContractsOpenInterestHistory(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetFuturesContractsOpenInterestHistory(contextGenerate(), futuresTP.String(), kline.FiveMin, time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFuturesContractTakerVolume(t *testing.T) {
t.Parallel()
_, err := ok.GetFuturesContractTakerVolume(contextGenerate(), "", kline.FiveMin, 1, 10, time.Time{}, time.Time{})
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetFuturesContractTakerVolume(contextGenerate(), futuresTP.String(), kline.FiveMin, 1, 10, time.Time{}, time.Time{})
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFuturesContractLongShortAccountRatio(t *testing.T) {
t.Parallel()
_, err := ok.GetFuturesContractLongShortAccountRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetFuturesContractLongShortAccountRatio(contextGenerate(), futuresTP.String(), kline.FiveMin, time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTopTradersFuturesContractLongShortRatio(t *testing.T) {
t.Parallel()
_, err := ok.GetTopTradersFuturesContractLongShortAccountRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetTopTradersFuturesContractLongShortAccountRatio(contextGenerate(), futuresTP.String(), kline.FiveMin, time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetTopTradersFuturesContractLongShortPositionRatio(t *testing.T) {
t.Parallel()
_, err := ok.GetTopTradersFuturesContractLongShortPositionRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetTopTradersFuturesContractLongShortPositionRatio(contextGenerate(), futuresTP.String(), kline.FiveMin, time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAccountInstruments(t *testing.T) {
t.Parallel()
_, err := ok.GetAccountInstruments(contextGenerate(), asset.Empty, "", "", spotTP.String())
require.ErrorIs(t, err, errInvalidInstrumentType)
_, err = ok.GetAccountInstruments(contextGenerate(), asset.Futures, "", "", spotTP.String())
require.ErrorIs(t, err, errInvalidUnderlying)
_, err = ok.GetAccountInstruments(contextGenerate(), asset.Options, "", "", spotTP.String())
require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetAccountInstruments(contextGenerate(), asset.Spot, "", "", spotTP.String())
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.GetAccountInstruments(contextGenerate(), asset.Options, "", "BTC-USD", optionsTP.String())
assert.NoError(t, err)
assert.NotNil(t, result)
result, err = ok.GetAccountInstruments(contextGenerate(), asset.Futures, "BTC-USD", "", futuresTP.String())
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestOrderTypeString(t *testing.T) {
t.Parallel()
var orderTypesToStringMap = map[order.Type]struct {
Expected string
Error error
}{
order.Market: {Expected: orderMarket},
order.Limit: {Expected: orderLimit},
order.PostOnly: {Expected: orderPostOnly},
order.FillOrKill: {Expected: orderFOK},
order.ImmediateOrCancel: {Expected: orderIOC},
order.OptimalLimitIOC: {Expected: orderOptimalLimitIOC},
order.MarketMakerProtection: {Expected: "mmp"},
order.MarketMakerProtectionAndPostOnly: {Expected: "mmp_and_post_only"},
order.Liquidation: {Error: order.ErrUnsupportedOrderType},
order.OCO: {Expected: "oco"},
order.TrailingStop: {Expected: "move_order_stop"},
order.Chase: {Expected: "chase"},
order.TWAP: {Expected: "twap"},
order.ConditionalStop: {Expected: "conditional"},
order.Trigger: {Expected: "trigger"},
}
for oType, val := range orderTypesToStringMap {
orderTypeString, err := orderTypeString(oType)
require.ErrorIs(t, err, val.Error)
assert.Equal(t, val.Expected, orderTypeString)
}
}
func TestGetMarkPriceCandlesticks(t *testing.T) {
t.Parallel()
_, err := ok.GetMarkPriceCandlesticks(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetMarkPriceCandlesticks(contextGenerate(), spotTP.String(), kline.FiveMin, time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetHistoricIndexCandlesticksHistory(t *testing.T) {
t.Parallel()
_, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), "", time.Time{}, time.Time{}, kline.TenMin, 10)
require.ErrorIs(t, err, errMissingInstrumentID)
result, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), spotTP.String(), time.Time{}, time.Time{}, kline.FiveMin, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestAssetTypeString(t *testing.T) {
t.Parallel()
_, err := assetTypeString(asset.LinearContract)
require.ErrorIs(t, err, asset.ErrNotSupported)
assetTypes := ok.GetAssetTypes(false)
for a := range assetTypes {
if assetTypes[a] == asset.Spread {
continue
}
_, err := assetTypeString(assetTypes[a])
assert.NoError(t, err)
}
}
func TestGetAnnouncements(t *testing.T) {
t.Parallel()
result, err := ok.GetAnnouncements(contextGenerate(), "", 0)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetAnnouncementTypes(t *testing.T) {
t.Parallel()
results, err := ok.GetAnnouncementTypes(contextGenerate())
require.NoError(t, err)
assert.NotEmpty(t, results)
}
func TestGetDepositOrderDetail(t *testing.T) {
t.Parallel()
_, err := ok.GetDepositOrderDetail(contextGenerate(), "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetDepositOrderDetail(contextGenerate(), "12312312")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFiatDepositOrderHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFiatDepositOrderHistory(contextGenerate(), currency.USDT, "TR_BANKS", "failed", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetWithdrawalOrderDetail(t *testing.T) {
t.Parallel()
_, err := ok.GetWithdrawalOrderDetail(contextGenerate(), "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetWithdrawalOrderDetail(contextGenerate(), "024041201450544699")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFiatWithdrawalOrderHistory(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFiatWithdrawalOrderHistory(contextGenerate(), currency.USDT, "SEPA", "failed", time.Time{}, time.Time{}, 10)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCancelWithdrawalOrder(t *testing.T) {
t.Parallel()
_, err := ok.CancelWithdrawalOrder(contextGenerate(), "")
require.ErrorIs(t, err, order.ErrOrderIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.CancelWithdrawalOrder(contextGenerate(), "124041201450544699")
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestCreateWithdrawalOrder(t *testing.T) {
t.Parallel()
_, err := ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000)
require.ErrorIs(t, err, errIDNotSet)
_, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.EMPTYCODE, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
_, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 0)
require.ErrorIs(t, err, order.ErrAmountBelowMin)
_, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "", "194a6975e98246538faeb0fab0d502df", 1000)
require.ErrorIs(t, err, errPaymentMethodRequired)
_, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "", 1000)
require.ErrorIs(t, err, errIDNotSet)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders)
result, err := ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFiatWithdrawalPaymentMethods(t *testing.T) {
t.Parallel()
_, err := ok.GetFiatWithdrawalPaymentMethods(contextGenerate(), currency.EMPTYCODE)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFiatWithdrawalPaymentMethods(contextGenerate(), currency.TRY)
require.NoError(t, err)
assert.NotNil(t, result)
}
func TestGetFiatDepositPaymentMethods(t *testing.T) {
t.Parallel()
_, err := ok.GetFiatDepositPaymentMethods(contextGenerate(), currency.EMPTYCODE)
require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
result, err := ok.GetFiatDepositPaymentMethods(contextGenerate(), currency.TRY)
require.NoError(t, err)
assert.NotNil(t, result)
}
func (ok *Okx) instrumentFamilyFromInstID(instrumentType, instID string) (string, error) {
ok.instrumentsInfoMapLock.Lock()
defer ok.instrumentsInfoMapLock.Unlock()
if instrumentType != "" {
insts, okay := ok.instrumentsInfoMap[instrumentType]
if !okay {
return "", errInvalidInstrumentType
}
for a := range insts {
if insts[a].InstrumentID == instID {
return insts[a].InstrumentFamily, nil
}
}
} else {
for _, insts := range ok.instrumentsInfoMap {
for a := range insts {
if insts[a].InstrumentID == instID {
return insts[a].InstrumentFamily, nil
}
}
}
}
return "", fmt.Errorf("instrument family not found for instrument %s", instID)
}
func TestGenerateSubscriptions(t *testing.T) {
t.Parallel()
ok.Websocket.SetCanUseAuthenticatedEndpoints(true)
subs, err := ok.generateSubscriptions()
require.NoError(t, err, "generateSubscriptions must not error")
exp := subscription.List{
{Channel: subscription.MyAccountChannel, QualifiedChannel: `{"channel":"account"}`, Authenticated: true},
}
var pairs currency.Pairs
for _, s := range ok.Features.Subscriptions {
for _, a := range ok.GetAssetTypes(true) {
if s.Asset != asset.All && s.Asset != a {
continue
}
pairs, err = ok.GetEnabledPairs(a)
require.NoErrorf(t, err, "GetEnabledPairs %s must not error", a)
pairs = common.SortStrings(pairs).Format(currency.PairFormat{Uppercase: true, Delimiter: "-"})
s := s.Clone() //nolint:govet // Intentional lexical scope shadow
s.Asset = a
name := channelName(s)
if isSymbolChannel(s) {
for i, p := range pairs {
s := s.Clone() //nolint:govet // Intentional lexical scope shadow
s.QualifiedChannel = fmt.Sprintf(`{"channel":%q,"instID":%q}`, name, p)
s.Pairs = pairs[i : i+1]
exp = append(exp, s)
}
} else {
s := s.Clone() //nolint:govet // Intentional lexical scope shadow
if isAssetChannel(s) {
s.QualifiedChannel = fmt.Sprintf(`{"channel":%q,"instType":%q}`, name, GetInstrumentTypeFromAssetItem(s.Asset))
} else {
s.QualifiedChannel = `{"channel":"` + name + `"}`
}
s.Pairs = pairs
exp = append(exp, s)
}
}
}
testsubs.EqualLists(t, exp, subs)
ok.Features.Subscriptions = subscription.List{{Channel: channelGridPositions, Params: map[string]any{"algoId": "42"}}}
subs, err = ok.generateSubscriptions()
require.NoError(t, err, "generateSubscriptions must not error")
exp = subscription.List{{Channel: channelGridPositions, Params: map[string]any{"algoId": "42"}, QualifiedChannel: `{"channel":"grid-positions","algoId":"42"}`}}
testsubs.EqualLists(t, exp, subs)
ok.Features.Subscriptions = subscription.List{{Channel: channelGridPositions}}
subs, err = ok.generateSubscriptions()
require.NoError(t, err, "generateSubscriptions must not error")
exp = subscription.List{{Channel: channelGridPositions, QualifiedChannel: `{"channel":"grid-positions"}`}}
testsubs.EqualLists(t, exp, subs)
}
const (
processSpreadOrderbookJSON = `{"arg":{"channel":"sprd-books5", "sprdId": "BTC-USDT_BTC-USDT-SWAP" }, "data": [ { "asks": [ ["111.06","55154","2"], ["111.07","53276","2"], ["111.08","72435","2"], ["111.09","70312","2"], ["111.1","67272","2"]], "bids": [ ["111.05","57745","2"], ["111.04","57109","2"], ["111.03","69563","2"], ["111.02","71248","2"], ["111.01","65090","2"]], "ts": "1670324386802"}]}`
wsProcessPublicSpreadTradesJSON = `{"arg":{"channel":"sprd-public-trades", "sprdId": "BTC-USDT_BTC-USDT-SWAP" }, "data": [ { "sprdId": "BTC-USDT_BTC-USDT-SWAP", "tradeId": "2499206329160695808", "px": "-10", "sz": "0.001", "side": "sell", "ts": "1726801105519"}]}`
okxSpreadPublicTickerJSON = `{"arg":{"channel":"sprd-tickers", "sprdId": "BTC-USDT_BTC-USDT-SWAP" }, "data": [ { "sprdId": "BTC-USDT_BTC-USDT-SWAP", "last": "4", "lastSz": "0.01", "askPx": "19.7", "askSz": "5.79", "bidPx": "5.9", "bidSz": "5.79", "open24h": "-7", "high24h": "19.6", "low24h": "-7", "vol24h": "9.87", "ts": "1715247061026"}]}`
wsProcessSpreadOrdersJSON = `{"arg":{"channel":"sprd-orders","sprdId": "BTC-USDT_BTC-USDT-SWAP", "uid": "614488474791936"}, "data": [{"sprdId": "BTC-USDT_BTC-UST-SWAP", "ordId": "312269865356374016", "clOrdId": "b1", "tag": "", "px": "999", "sz": "3", "ordType": "limit", "side": "buy", "fillSz": "0", "fillPx": "", "tradeId": "", "accFillSz": "0", "pendingFillSz": "2", "pendingSettleSz": "1", "canceledSz": "1", "state": "live", "avgPx": "0", "cancelSource": "", "uTime": "1597026383085", "cTime": "1597026383085", "code": "0", "msg": "", "reqId": "", "amendResult": ""}]}`
wsProcessSpreadTradesJSON = `{"arg":{"channel":"sprd-trades", "sprdId": "BTC-USDT_BTC-USDT-SWAP", "uid": "614488474791936" }, "data":[ { "sprdId":"BTC-USDT-SWAP_BTC-USDT-200329", "tradeId":"123", "ordId":"123445", "clOrdId": "b16", "tag":"", "fillPx":"999", "fillSz":"3", "state": "filled", "side":"buy", "execType":"M", "ts":"1597026383085", "legs": [ { "instId": "BTC-USDT-SWAP", "px": "20000", "sz": "3", "szCont": "0.03", "side": "buy", "fee": "", "feeCcy": "", "tradeId": "1232342342" }, { "instId": "BTC-USDT-200329", "px": "21000", "sz": "3", "szCont": "0.03", "side": "sell", "fee": "", "feeCcy": "", "tradeId": "5345646634" } ], "code": "", "msg":""}]}`
)
func TestWsProcessSpreadOrderbook(t *testing.T) {
t.Parallel()
err := ok.wsProcessSpreadOrderbook([]byte(processSpreadOrderbookJSON))
assert.NoError(t, err)
}
func TestWsProcessPublicSpreadTrades(t *testing.T) {
t.Parallel()
err := ok.wsProcessPublicSpreadTrades([]byte(wsProcessPublicSpreadTradesJSON))
assert.NoError(t, err)
}
func TestWsProcessPublicSpreadTicker(t *testing.T) {
t.Parallel()
err := ok.wsProcessPublicSpreadTicker([]byte(okxSpreadPublicTickerJSON))
assert.NoError(t, err)
}
func TestWsProcessSpreadOrders(t *testing.T) {
t.Parallel()
err := ok.wsProcessSpreadOrders([]byte(wsProcessSpreadOrdersJSON))
assert.NoError(t, err)
}
func TestWsProcessSpreadTradesJSON(t *testing.T) {
t.Parallel()
err := ok.wsProcessSpreadTrades([]byte(wsProcessSpreadTradesJSON))
assert.NoError(t, err)
}
func TestOrderTypeFromString(t *testing.T) {
t.Parallel()
orderTypeStrings := map[string]struct {
OType order.Type
Error error
}{
"market": {OType: order.Market},
"LIMIT": {OType: order.Limit},
"limit": {OType: order.Limit},
"post_only": {OType: order.PostOnly},
"fok": {OType: order.FillOrKill},
"ioc": {OType: order.ImmediateOrCancel},
"optimal_limit_ioc": {OType: order.OptimalLimitIOC},
"mmp": {OType: order.MarketMakerProtection},
"mmp_and_post_only": {OType: order.MarketMakerProtectionAndPostOnly},
"trigger": {OType: order.UnknownType, Error: order.ErrTypeIsInvalid},
"chase": {OType: order.Chase},
"move_order_stop": {OType: order.TrailingStop},
"twap": {OType: order.TWAP},
"abcd": {OType: order.UnknownType, Error: order.ErrTypeIsInvalid},
}
for a := range orderTypeStrings {
oType, err := orderTypeFromString(a)
assert.ErrorIs(t, err, orderTypeStrings[a].Error)
assert.Equal(t, oType, orderTypeStrings[a].OType)
}
}
func TestGetFee(t *testing.T) {
t.Parallel()
// CryptocurrencyWithdrawalFee Basic
feeBuilder := &exchange.FeeBuilder{
Amount: 1,
FeeType: exchange.CryptocurrencyWithdrawalFee,
Pair: spotTP,
PurchasePrice: 1,
}
_, err := ok.GetFee(contextGenerate(), feeBuilder)
require.ErrorIs(t, err, errFeeTypeUnsupported)
feeBuilder.FeeType = exchange.OfflineTradeFee
_, err = ok.GetFee(contextGenerate(), feeBuilder)
assert.NoError(t, err)
sharedtestvalues.SkipTestIfCredentialsUnset(t, ok)
feeBuilder.FeeType = exchange.CryptocurrencyTradeFee
_, err = ok.GetFee(contextGenerate(), feeBuilder)
require.NoError(t, err)
}
func TestPriceTypeString(t *testing.T) {
t.Parallel()
priceTypeToStringMap := map[order.PriceType]string{
order.LastPrice: "last",
order.IndexPrice: "index",
order.MarkPrice: "mark",
order.UnknownPriceType: "",
}
var priceTString string
for x := range priceTypeToStringMap {
priceTString = priceTypeString(x)
assert.Equal(t, priceTString, priceTypeToStringMap[x])
}
}
func TestMarginTypeToString(t *testing.T) {
t.Parallel()
marginTypeToStringMap := map[margin.Type]string{
margin.Isolated: "isolated",
margin.Multi: "cross",
margin.NoMargin: "cash",
margin.SpotIsolated: "spot_isolated",
margin.Unset: "",
}
var marginTypeString string
for m := range marginTypeToStringMap {
marginTypeString = ok.marginTypeToString(m)
assert.Equal(t, marginTypeString, marginTypeToStringMap[m])
}
}