Skip to content

Commit

Permalink
fixup! GateIO: Abstract GetOpenInterest
Browse files Browse the repository at this point in the history
  • Loading branch information
gbjk committed Jan 12, 2025
1 parent 36c97ef commit 1401f84
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 57 deletions.
4 changes: 2 additions & 2 deletions exchanges/gateio/gateio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3344,8 +3344,8 @@ func BenchmarkGetOpenInterestFutures(b *testing.B) {
require.Greater(b, len(availPairs), 5)
err = g.CurrencyPairs.StorePairs(a, availPairs[:5], true)
require.NoError(b, err)
keys := make([]key.PairAsset, 0, 5)
for i := range 5 {
keys := make([]key.PairAsset, 0, 2)
for i := range 1 {
keys = append(keys, key.PairAsset{
Asset: a,
Base: availPairs[i].Base.Item,
Expand Down
150 changes: 95 additions & 55 deletions exchanges/gateio/gateio_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2201,73 +2201,113 @@ func contractToFundingRate(name string, item asset.Item, fPair currency.Pair, co
// If no pairs are provided, all enabled assets and pairs will be used
func (g *Gateio) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([]futures.OpenInterest, error) {
var errs error
for _, a := range []asset.Item{asset.DeliveryFutures, asset.CoinMarginedFutures, asset.USDTMarginedFutures} {
pairs, err := g.GetEnabledPairs(a)
if err != nil {
continue
}
if len(keys) == 0 {
for _, p := range pairs {
keys = append(keys, key.PairAsset{
Asset: a,
Base: p.Base.Item,
Quote: p.Quote.Item,
})
}
} else {
for _, k := range keys {
if k.Asset == a {
if p := k.Pair(); !pairs.Contains(p, true) {
return nil, fmt.Errorf("%w: %s %s", currency.ErrPairNotEnabled, a, p)
}
}
resp := make([]futures.OpenInterest, 0, len(keys))
assets := asset.Items{}
if len(keys) == 0 {
assets = g.GetAssetTypes(true)
} else {
for _, k := range keys {
if !slices.Contains(assets, k.Asset) {
assets = append(assets, k.Asset)
}
}
}
resp := make([]futures.OpenInterest, 0, len(keys))
for _, k := range keys {
p, isEnabled, err := g.MatchSymbolCheckEnabled(k.Pair().String(), k.Asset, false)
if !isEnabled {
err = currency.ErrPairNotEnabled
for _, a := range assets {
var p currency.Pair
if len(keys) == 1 && a == keys[0].Asset {
if p, _, errs = g.MatchSymbolCheckEnabled(keys[0].Pair().String(), a, false); errs != nil {
return nil, errs
}
}
contracts, err := g.getOpenInterestContracts(ctx, a, p)
if err != nil {
errs = common.AppendError(errs, err)
err = fmt.Errorf("%w: %s", asset.ErrNotEnabled, k.Pair())
errs = common.AppendError(errs, fmt.Errorf("%w fetching %s", err, a))
continue
}
settlementCurrency := currency.USDT
var openInterest float64
switch k.Asset {
case asset.DeliveryFutures:
contractResp, err2 := g.GetDeliveryContract(ctx, currency.USDT, p)
err = err2
openInterest = contractResp.QuantoMultiplier.Float64() * float64(contractResp.PositionSize) * contractResp.IndexPrice.Float64()
case asset.CoinMarginedFutures:
settlementCurrency = currency.BTC
fallthrough
case asset.USDTMarginedFutures:
contractResp, err2 := g.GetFuturesContract(ctx, settlementCurrency, p.String())
err = err2
openInterest = contractResp.QuantoMultiplier.Float64() * float64(contractResp.PositionSize) * contractResp.IndexPrice.Float64()
default:
err = fmt.Errorf("%w %s %s", asset.ErrNotSupported, k.Asset, k.Pair())
}
if err != nil {
return nil, err
for _, c := range contracts {
if p == currency.EMPTYPAIR {
pN, isEnabled, err := g.MatchSymbolCheckEnabled(c.contractName(), a, true)
if err != nil && !errors.Is(err, currency.ErrPairNotFound) {
errs = common.AppendError(errs, fmt.Errorf("%w from %s contract %s", err, a, c.contractName()))
continue
}
if !isEnabled {
continue
}
if len(keys) > 1 {
wanted := slices.ContainsFunc(keys, func(k key.PairAsset) bool {
return a == k.Asset && k.Pair().Equal(p)
})
if !wanted {
continue
}
}
p = pN
}
resp = append(resp, futures.OpenInterest{
Key: key.ExchangePairAsset{
Exchange: g.Name,
Base: p.Base.Item,
Quote: p.Quote.Item,
Asset: a,
},
OpenInterest: c.openInterest(),
})
}
resp = append(resp, futures.OpenInterest{
Key: key.ExchangePairAsset{
Exchange: g.Name,
Base: k.Base,
Quote: k.Quote,
Asset: k.Asset,
},
OpenInterest: openInterest,
})
}
return slices.Clip(resp), errs
}

type openInterestContract interface {
openInterest() float64
contractName() string
}

func (c *FuturesContract) openInterest() float64 {
return c.QuantoMultiplier.Float64() * float64(c.PositionSize) * c.IndexPrice.Float64()
}
func (c *FuturesContract) contractName() string {
return c.Name
}
func (c *DeliveryContract) openInterest() float64 {
return c.QuantoMultiplier.Float64() * float64(c.PositionSize) * c.IndexPrice.Float64()
}
func (c *DeliveryContract) contractName() string {
return c.Name
}

func (g *Gateio) getOpenInterestContracts(ctx context.Context, a asset.Item, p currency.Pair) ([]openInterestContract, error) {
contracts := []openInterestContract{}
settlementCurrency := currency.USDT
switch a {
case asset.DeliveryFutures:
if p != currency.EMPTYPAIR {
d, err := g.GetDeliveryContract(ctx, currency.USDT, p)
return []openInterestContract{d}, err
}
d, err := g.GetAllDeliveryContracts(ctx, currency.USDT)
for _, c := range d {

Check failure on line 2289 in exchanges/gateio/gateio_wrapper.go

View workflow job for this annotation

GitHub Actions / lint

rangeValCopy: each iteration copies 384 bytes (consider pointers or indexing) (gocritic)
contracts = append(contracts, &c)

Check failure on line 2290 in exchanges/gateio/gateio_wrapper.go

View workflow job for this annotation

GitHub Actions / lint

exporting a pointer for the loop variable c (exportloopref)
}
return contracts, err
case asset.CoinMarginedFutures:
settlementCurrency = currency.BTC
case asset.USDTMarginedFutures:
// Continue
default:
return nil, fmt.Errorf("%w: %s", asset.ErrNotSupported, a)
}
if p != currency.EMPTYPAIR {
contract, err := g.GetFuturesContract(ctx, settlementCurrency, p.String())
return []openInterestContract{contract}, err
}
futures, err := g.GetAllFutureContracts(ctx, settlementCurrency)
for _, c := range futures {

Check failure on line 2305 in exchanges/gateio/gateio_wrapper.go

View workflow job for this annotation

GitHub Actions / lint

rangeValCopy: each iteration copies 424 bytes (consider pointers or indexing) (gocritic)
contracts = append(contracts, &c)

Check failure on line 2306 in exchanges/gateio/gateio_wrapper.go

View workflow job for this annotation

GitHub Actions / lint

exporting a pointer for the loop variable c (exportloopref)
}
return contracts, err
}

// getClientOrderIDFromText returns the client order ID from the text response
func getClientOrderIDFromText(text string) string {
if strings.HasPrefix(text, "t-") {
Expand Down

0 comments on commit 1401f84

Please sign in to comment.