currency: Adds matching lookup table built from available pairs (#1312)

* currency: Add pair matching update (cherry-pick)

* exchange/currency: Add tests and update func

* linter fix, also if using json unmarshal functionality stop usage of string conversion without delimiter

* gemini: fix test

* currency/manager: potential optimisation

* exchanges: purge derive from wrapper cases and add warning comment

* glorious: nits

* glorious: nits

* linter: fix

* glorious: nits

* whoops

* whoops

* glorious: nits continued

* glorious: diff THANKS!

* hitbtc: fix update tradable pairs strings splitting. continue if not enabled tickers update pair.

* glorious: nits

* linter: fix

* Update exchanges/exmo/exmo_wrapper.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* bitstamp: fix test when 32 biterinos architecturinos

* capture more strings for speed

* swapsies because whos running 32bit \0/?

---------

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
Co-authored-by: Scott <gloriousCode@users.noreply.github.com>
This commit is contained in:
Ryan O'Hara-Reid
2023-10-18 11:57:27 +11:00
committed by GitHub
parent d3bf4a460a
commit ceef7a14e0
32 changed files with 621 additions and 264 deletions

View File

@@ -2,6 +2,7 @@ package bybit
import (
"context"
"errors"
"fmt"
"sort"
"strconv"
@@ -416,16 +417,6 @@ func (by *Bybit) UpdateTradablePairs(ctx context.Context, forceUpdate bool) erro
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error {
avail, err := by.GetAvailablePairs(assetType)
if err != nil {
return err
}
enabled, err := by.GetEnabledPairs(assetType)
if err != nil {
return err
}
switch assetType {
case asset.Spot:
ticks, err := by.GetTickersV5(ctx, "spot", "", "")
@@ -434,17 +425,19 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error
}
for x := range ticks.List {
pair, err := avail.DeriveFrom(ticks.List[x].Symbol)
pair, enabled, err := by.MatchSymbolCheckEnabled(ticks.List[x].Symbol, assetType, false)
if err != nil {
// These symbols below do not have a spot market but are in fact
// perpetuals.
if ticks.List[x].Symbol == "ZECUSDT" || ticks.List[x].Symbol == "DASHUSDT" {
continue
}
return err
if !errors.Is(err, currency.ErrPairNotFound) {
return err
}
}
if !enabled.Contains(pair, true) {
if !enabled {
continue
}
@@ -465,6 +458,11 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error
}
}
case asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.Futures:
enabled, err := by.GetEnabledPairs(assetType)
if err != nil {
return err
}
tick, err := by.GetFuturesSymbolPriceTicker(ctx, currency.EMPTYPAIR)
if err != nil {
return err
@@ -480,7 +478,8 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error
if tick[y].Symbol != formattedPair.String() {
continue
}
cp, err := by.extractCurrencyPair(tick[y].Symbol, assetType)
// Don't need to check if this pair is enabled due to call above.
cp, err := by.MatchSymbolWithAvailablePairs(tick[y].Symbol, assetType, false)
if err != nil {
return err
}
@@ -501,6 +500,11 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error
}
}
case asset.USDCMarginedFutures:
enabled, err := by.GetEnabledPairs(assetType)
if err != nil {
return err
}
for x := range enabled {
formattedPair, err := by.FormatExchangeCurrency(enabled[x], assetType)
if err != nil {
@@ -512,7 +516,8 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error
return err
}
cp, err := by.extractCurrencyPair(tick.Symbol, assetType)
// Don't need to check if this pair is enabled due to call above.
cp, err := by.MatchSymbolWithAvailablePairs(tick.Symbol, assetType, false)
if err != nil {
return err
}
@@ -551,10 +556,13 @@ func (by *Bybit) UpdateTicker(ctx context.Context, p currency.Pair, assetType as
}
for y := range tick {
cp, err := by.extractCurrencyPair(tick[y].Symbol, assetType)
cp, enabled, err := by.MatchSymbolCheckEnabled(tick[y].Symbol, assetType, false)
if err != nil {
return nil, err
}
if !enabled {
continue
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice.Float64(),
High: tick[y].HighPrice.Float64(),
@@ -572,7 +580,6 @@ func (by *Bybit) UpdateTicker(ctx context.Context, p currency.Pair, assetType as
return nil, err
}
}
case asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.Futures:
tick, err := by.GetFuturesSymbolPriceTicker(ctx, formattedPair)
if err != nil {
@@ -580,10 +587,13 @@ func (by *Bybit) UpdateTicker(ctx context.Context, p currency.Pair, assetType as
}
for y := range tick {
cp, err := by.extractCurrencyPair(tick[y].Symbol, assetType)
cp, enabled, err := by.MatchSymbolCheckEnabled(tick[y].Symbol, assetType, false)
if err != nil {
return nil, err
}
if !enabled {
continue
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice.Float64(),
High: tick[y].HighPrice24h.Float64(),
@@ -606,10 +616,13 @@ func (by *Bybit) UpdateTicker(ctx context.Context, p currency.Pair, assetType as
return nil, err
}
cp, err := by.extractCurrencyPair(tick.Symbol, assetType)
cp, enabled, err := by.MatchSymbolCheckEnabled(tick.Symbol, assetType, false)
if err != nil {
return nil, err
}
if !enabled {
return nil, fmt.Errorf("%v %v not enabled", formattedPair, assetType)
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick.LastPrice.Float64(),
High: tick.High24h.Float64(),
@@ -2097,30 +2110,12 @@ func (by *Bybit) GetServerTime(ctx context.Context, a asset.Item) (time.Time, er
return time.Time{}, fmt.Errorf("%s %w", a, asset.ErrNotSupported)
}
func (by *Bybit) extractCurrencyPair(symbol string, item asset.Item) (currency.Pair, error) {
pairs, err := by.CurrencyPairs.GetPairs(item, true)
if err != nil {
return currency.EMPTYPAIR, err
}
pair, err := pairs.DeriveFrom(symbol)
if err != nil {
return currency.EMPTYPAIR, err
}
return pair, nil
}
// UpdateOrderExecutionLimits sets exchange executions for a required asset type
func (by *Bybit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error {
avail, err := by.GetAvailablePairs(a)
if err != nil {
return err
}
var limits []order.MinMaxLevel
switch a {
case asset.Spot:
var pairsData []PairData
pairsData, err = by.GetAllSpotPairs(ctx)
pairsData, err := by.GetAllSpotPairs(ctx)
if err != nil {
return err
}
@@ -2128,11 +2123,15 @@ func (by *Bybit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e
limits = make([]order.MinMaxLevel, 0, len(pairsData))
for x := range pairsData {
var pair currency.Pair
pair, err = avail.DeriveFrom(pairsData[x].Name)
var enabled bool
pair, enabled, err = by.MatchSymbolCheckEnabled(pairsData[x].Name, a, false)
if err != nil {
log.Warnf(log.ExchangeSys, "%s unable to load limits for %v, pair data missing", by.Name, pairsData[x].Name)
continue
}
if !enabled {
continue
}
limits = append(limits, order.MinMaxLevel{
Asset: a,