mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-03 15:10:49 +00:00
exchanges: Fix GateIO/Coinbase test failures and OKX race (#1753)
* exchanges: Fix gateio/coinbase test failures * OKX: Fix TestGetAssetsFromInstrumentTypeOrID race * GateIO: Add/improve comments * GateIO: Rid additional API call for FetchTradablePairs and provide additional context for test * GateIO: Prompt test reviewers to take action if BTC settlement is supported again
This commit is contained in:
@@ -10,7 +10,6 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -2792,7 +2791,7 @@ func (g *Gateio) GetSingleDeliveryPosition(ctx context.Context, settle currency.
|
||||
|
||||
// UpdateDeliveryPositionMargin updates position margin
|
||||
func (g *Gateio) UpdateDeliveryPositionMargin(ctx context.Context, settle currency.Code, change float64, contract currency.Pair) (*Position, error) {
|
||||
if !slices.Contains(settlementCurrencies, settle) {
|
||||
if settle.IsEmpty() {
|
||||
return nil, errEmptyOrInvalidSettlementCurrency
|
||||
}
|
||||
if contract.IsInvalid() {
|
||||
@@ -2809,7 +2808,7 @@ func (g *Gateio) UpdateDeliveryPositionMargin(ctx context.Context, settle curren
|
||||
|
||||
// UpdateDeliveryPositionLeverage updates position leverage
|
||||
func (g *Gateio) UpdateDeliveryPositionLeverage(ctx context.Context, settle currency.Code, contract currency.Pair, leverage float64) (*Position, error) {
|
||||
if !slices.Contains(settlementCurrencies, settle) {
|
||||
if settle.IsEmpty() {
|
||||
return nil, errEmptyOrInvalidSettlementCurrency
|
||||
}
|
||||
if contract.IsInvalid() {
|
||||
@@ -2827,7 +2826,7 @@ func (g *Gateio) UpdateDeliveryPositionLeverage(ctx context.Context, settle curr
|
||||
|
||||
// UpdateDeliveryPositionRiskLimit update position risk limit
|
||||
func (g *Gateio) UpdateDeliveryPositionRiskLimit(ctx context.Context, settle currency.Code, contract currency.Pair, riskLimit uint64) (*Position, error) {
|
||||
if !slices.Contains(settlementCurrencies, settle) {
|
||||
if settle.IsEmpty() {
|
||||
return nil, errEmptyOrInvalidSettlementCurrency
|
||||
}
|
||||
if contract.IsInvalid() {
|
||||
@@ -2920,7 +2919,7 @@ func (g *Gateio) CancelMultipleDeliveryOrders(ctx context.Context, contract curr
|
||||
// GetSingleDeliveryOrder Get a single order
|
||||
// Zero-filled order cannot be retrieved 10 minutes after order cancellation
|
||||
func (g *Gateio) GetSingleDeliveryOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) {
|
||||
if !slices.Contains(settlementCurrencies, settle) {
|
||||
if settle.IsEmpty() {
|
||||
return nil, errEmptyOrInvalidSettlementCurrency
|
||||
}
|
||||
if orderID == "" {
|
||||
|
||||
@@ -1142,22 +1142,18 @@ func TestCancelMultipleDeliveryOrders(t *testing.T) {
|
||||
|
||||
func TestGetSingleDeliveryOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetSingleDeliveryOrder(context.Background(), currency.USD, "123456")
|
||||
_, err := g.GetSingleDeliveryOrder(context.Background(), currency.EMPTYCODE, "123456")
|
||||
assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency, "GetSingleDeliveryOrder should return errEmptyOrInvalidSettlementCurrency")
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, g)
|
||||
for _, settle := range settlementCurrencies {
|
||||
_, err := g.GetSingleDeliveryOrder(context.Background(), settle, "123456")
|
||||
assert.NoErrorf(t, err, "GetSingleDeliveryOrder %s should not error", settle)
|
||||
}
|
||||
_, err = g.GetSingleDeliveryOrder(context.Background(), currency.USDT, "123456")
|
||||
assert.NoError(t, err, "GetSingleDeliveryOrder should not error")
|
||||
}
|
||||
|
||||
func TestCancelSingleDeliveryOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
|
||||
for _, settle := range settlementCurrencies {
|
||||
_, err := g.CancelSingleDeliveryOrder(context.Background(), settle, "123456")
|
||||
assert.NoErrorf(t, err, "CancelSingleDeliveryOrder %s should not error", settle)
|
||||
}
|
||||
_, err := g.CancelSingleDeliveryOrder(context.Background(), currency.USDT, "123456")
|
||||
assert.NoError(t, err, "CancelSingleDeliveryOrder should not error")
|
||||
}
|
||||
|
||||
func TestGetDeliveryPersonalTradingHistory(t *testing.T) {
|
||||
@@ -1225,7 +1221,7 @@ func TestCancelAllDeliveryPriceTriggeredOrder(t *testing.T) {
|
||||
func TestGetSingleDeliveryPriceTriggeredOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, g)
|
||||
_, err := g.GetSingleDeliveryPriceTriggeredOrder(context.Background(), currency.BTC, "12345")
|
||||
_, err := g.GetSingleDeliveryPriceTriggeredOrder(context.Background(), currency.USDT, "12345")
|
||||
assert.NoError(t, err, "GetSingleDeliveryPriceTriggeredOrder should not error")
|
||||
}
|
||||
|
||||
@@ -1450,8 +1446,15 @@ func TestCancelAllFuturesOpenOrders(t *testing.T) {
|
||||
|
||||
func TestGetAllDeliveryContracts(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetAllDeliveryContracts(context.Background(), currency.USDT)
|
||||
assert.NoError(t, err, "GetAllDeliveryContracts should not error")
|
||||
r, err := g.GetAllDeliveryContracts(context.Background(), currency.USDT)
|
||||
require.NoError(t, err, "GetAllDeliveryContracts must not error")
|
||||
assert.NotEmpty(t, r, "GetAllDeliveryContracts should return data")
|
||||
r, err = g.GetAllDeliveryContracts(context.Background(), currency.BTC)
|
||||
require.NoError(t, err, "GetAllDeliveryContracts must not error")
|
||||
// The test below will fail if support for BTC settlement is added. This is intentional, as it ensures we are alerted when it's time to reintroduce support
|
||||
if !assert.Empty(t, r, "GetAllDeliveryContracts should not return any data with unsupported settlement currency BTC") {
|
||||
t.Error("BTC settlement for delivery futures appears to be supported again by the API. Please raise an issue to reintroduce BTC support for this exchange")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSingleDeliveryContracts(t *testing.T) {
|
||||
@@ -1527,6 +1530,8 @@ func TestGetSingleDeliveryPosition(t *testing.T) {
|
||||
|
||||
func TestUpdateDeliveryPositionMargin(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.UpdateDeliveryPositionMargin(context.Background(), currency.EMPTYCODE, 0.001, currency.Pair{})
|
||||
assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
|
||||
settle, err := getSettlementFromCurrency(getPair(t, asset.DeliveryFutures))
|
||||
require.NoError(t, err, "getSettlementFromCurrency must not error")
|
||||
@@ -1536,15 +1541,19 @@ func TestUpdateDeliveryPositionMargin(t *testing.T) {
|
||||
|
||||
func TestUpdateDeliveryPositionLeverage(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.UpdateDeliveryPositionLeverage(context.Background(), currency.EMPTYCODE, currency.Pair{}, 0.001)
|
||||
assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
|
||||
_, err := g.UpdateDeliveryPositionLeverage(context.Background(), currency.USDT, getPair(t, asset.DeliveryFutures), 0.001)
|
||||
_, err = g.UpdateDeliveryPositionLeverage(context.Background(), currency.USDT, getPair(t, asset.DeliveryFutures), 0.001)
|
||||
assert.NoError(t, err, "UpdateDeliveryPositionLeverage should not error")
|
||||
}
|
||||
|
||||
func TestUpdateDeliveryPositionRiskLimit(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.UpdateDeliveryPositionRiskLimit(context.Background(), currency.EMPTYCODE, currency.Pair{}, 0)
|
||||
assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders)
|
||||
_, err := g.UpdateDeliveryPositionRiskLimit(context.Background(), currency.USDT, getPair(t, asset.DeliveryFutures), 30)
|
||||
_, err = g.UpdateDeliveryPositionRiskLimit(context.Background(), currency.USDT, getPair(t, asset.DeliveryFutures), 30)
|
||||
assert.NoError(t, err, "UpdateDeliveryPositionRiskLimit should not error")
|
||||
}
|
||||
|
||||
|
||||
@@ -520,21 +520,16 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency
|
||||
}
|
||||
return pairs, nil
|
||||
case asset.DeliveryFutures:
|
||||
btcContracts, err := g.GetAllDeliveryContracts(ctx, currency.BTC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
usdtContracts, err := g.GetAllDeliveryContracts(ctx, currency.USDT)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
btcContracts = append(btcContracts, usdtContracts...)
|
||||
pairs := make([]currency.Pair, 0, len(btcContracts))
|
||||
for x := range btcContracts {
|
||||
if btcContracts[x].InDelisting {
|
||||
pairs := make([]currency.Pair, 0, len(usdtContracts))
|
||||
for x := range usdtContracts {
|
||||
if usdtContracts[x].InDelisting {
|
||||
continue
|
||||
}
|
||||
p := strings.ToUpper(btcContracts[x].Name)
|
||||
p := strings.ToUpper(usdtContracts[x].Name)
|
||||
if !g.IsValidPairString(p) {
|
||||
continue
|
||||
}
|
||||
@@ -633,6 +628,11 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
var tickers []FuturesTicker
|
||||
var ticks []FuturesTicker
|
||||
for _, settle := range settlementCurrencies {
|
||||
// All delivery futures are settled in USDT only, despite the API accepting a settlement currency parameter for all delivery futures endpoints
|
||||
if a == asset.DeliveryFutures && !settle.Equal(currency.USDT) {
|
||||
continue
|
||||
}
|
||||
|
||||
if a == asset.Futures {
|
||||
ticks, err = g.GetFuturesTickers(ctx, settle, currency.EMPTYPAIR)
|
||||
} else {
|
||||
@@ -828,6 +828,11 @@ func (g *Gateio) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.H
|
||||
case asset.Futures, asset.DeliveryFutures:
|
||||
currencies := make([]account.Balance, 0, 2)
|
||||
for x := range settlementCurrencies {
|
||||
// All delivery futures are settled in USDT only, despite the API accepting a settlement currency parameter for all delivery futures endpoints
|
||||
if a == asset.DeliveryFutures && !settlementCurrencies[x].Equal(currency.USDT) {
|
||||
continue
|
||||
}
|
||||
|
||||
var balance *FuturesAccount
|
||||
if a == asset.Futures {
|
||||
balance, err = g.QueryFuturesAccount(ctx, settlementCurrencies[x])
|
||||
@@ -1721,6 +1726,11 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque
|
||||
}
|
||||
|
||||
for settlement := range settlements {
|
||||
// All delivery futures are settled in USDT only, despite the API accepting a settlement currency parameter for all delivery futures endpoints
|
||||
if req.AssetType == asset.DeliveryFutures && !settlement.Equal(currency.USDT) {
|
||||
continue
|
||||
}
|
||||
|
||||
var futuresOrders []Order
|
||||
if req.AssetType == asset.Futures {
|
||||
futuresOrders, err = g.GetFuturesOrders(ctx, currency.EMPTYPAIR, "open", "", settlement, 0, 0, 0)
|
||||
@@ -2112,58 +2122,56 @@ func (g *Gateio) GetFuturesContractDetails(ctx context.Context, item asset.Item)
|
||||
return resp, nil
|
||||
case asset.DeliveryFutures:
|
||||
var resp []futures.Contract
|
||||
for k := range settlementCurrencies {
|
||||
contracts, err := g.GetAllDeliveryContracts(ctx, settlementCurrencies[k])
|
||||
contracts, err := g.GetAllDeliveryContracts(ctx, currency.USDT)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contractsToAdd := make([]futures.Contract, len(contracts))
|
||||
for j := range contracts {
|
||||
var name, underlying currency.Pair
|
||||
name, err = currency.NewPairFromString(contracts[j].Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contractsToAdd := make([]futures.Contract, len(contracts))
|
||||
for j := range contracts {
|
||||
var name, underlying currency.Pair
|
||||
name, err = currency.NewPairFromString(contracts[j].Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
underlying, err = currency.NewPairFromString(contracts[j].Underlying)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ct futures.ContractType
|
||||
// no start information, inferring it based on contract type
|
||||
// gateio also reuses contracts for kline data, cannot use a lookup to see the first trade
|
||||
var s, e time.Time
|
||||
e = contracts[j].ExpireTime.Time()
|
||||
switch contracts[j].Cycle {
|
||||
case "WEEKLY":
|
||||
ct = futures.Weekly
|
||||
s = e.Add(-kline.OneWeek.Duration())
|
||||
case "BI-WEEKLY":
|
||||
ct = futures.Fortnightly
|
||||
s = e.Add(-kline.TwoWeek.Duration())
|
||||
case "QUARTERLY":
|
||||
ct = futures.Quarterly
|
||||
s = e.Add(-kline.ThreeMonth.Duration())
|
||||
case "BI-QUARTERLY":
|
||||
ct = futures.HalfYearly
|
||||
s = e.Add(-kline.SixMonth.Duration())
|
||||
default:
|
||||
ct = futures.LongDated
|
||||
}
|
||||
contractsToAdd[j] = futures.Contract{
|
||||
Exchange: g.Name,
|
||||
Name: name,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: s,
|
||||
EndDate: e,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: !contracts[j].InDelisting,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{settlementCurrencies[k]},
|
||||
MarginCurrency: currency.Code{},
|
||||
Multiplier: contracts[j].QuantoMultiplier.Float64(),
|
||||
MaxLeverage: contracts[j].LeverageMax.Float64(),
|
||||
}
|
||||
underlying, err = currency.NewPairFromString(contracts[j].Underlying)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ct futures.ContractType
|
||||
// no start information, inferring it based on contract type
|
||||
// gateio also reuses contracts for kline data, cannot use a lookup to see the first trade
|
||||
var s, e time.Time
|
||||
e = contracts[j].ExpireTime.Time()
|
||||
switch contracts[j].Cycle {
|
||||
case "WEEKLY":
|
||||
ct = futures.Weekly
|
||||
s = e.Add(-kline.OneWeek.Duration())
|
||||
case "BI-WEEKLY":
|
||||
ct = futures.Fortnightly
|
||||
s = e.Add(-kline.TwoWeek.Duration())
|
||||
case "QUARTERLY":
|
||||
ct = futures.Quarterly
|
||||
s = e.Add(-kline.ThreeMonth.Duration())
|
||||
case "BI-QUARTERLY":
|
||||
ct = futures.HalfYearly
|
||||
s = e.Add(-kline.SixMonth.Duration())
|
||||
default:
|
||||
ct = futures.LongDated
|
||||
}
|
||||
contractsToAdd[j] = futures.Contract{
|
||||
Exchange: g.Name,
|
||||
Name: name,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: s,
|
||||
EndDate: e,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: !contracts[j].InDelisting,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{currency.USDT},
|
||||
MarginCurrency: currency.Code{},
|
||||
Multiplier: contracts[j].QuantoMultiplier.Float64(),
|
||||
MaxLeverage: contracts[j].LeverageMax.Float64(),
|
||||
}
|
||||
resp = append(resp, contractsToAdd...)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user