Skip to content

Commit

Permalink
exchanges: Add UpdateTickers method and reserve UpdateTicker for sing…
Browse files Browse the repository at this point in the history
…le ticker symbol update requests (if supported) (thrasher-corp#764)

* exchanges: add an UpdateTickers method to the main exchange interface

This method will fetch all currency pair tickers of a given asset type
and update them internally, does nothing for now.

* exchanges: refactor UpdateTicker on all exchanges

Keep the exact previous behaviour but implement the UpdateTickers
method and refactor UpdateTicker by using it where applicable.

* sync_manager: update all tickers when batching is enabled

* binance: UpdateTicker to fetch single ticker symbol

* ftx: UpdateTicker to fetch single ticker symbol
  • Loading branch information
lrascao authored Aug 27, 2021
1 parent 4851e94 commit c9ab0b1
Show file tree
Hide file tree
Showing 52 changed files with 931 additions and 267 deletions.
35 changes: 35 additions & 0 deletions cmd/exchange_template/wrapper_file.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,41 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(p currency.Pair, assetType a
return ticker.GetTicker({{.Variable}}.Name, p, assetType)
}

// UpdateTickers updates all currency pairs of a given asset type
func ({{.Variable}} *{{.CapitalName}}) UpdateTickers(assetType asset.Item) error {
// NOTE: EXAMPLE FOR GETTING TICKER PRICE
/*
tick, err := {{.Variable}}.GetTickers()
if err != nil {
return err
}
for y := range tick {
cp, err := currency.NewPairFromString(tick[y].Symbol)
if err != nil {
return err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice,
High: tick[y].HighPrice,
Low: tick[y].LowPrice,
Bid: tick[y].BidPrice,
Ask: tick[y].AskPrice,
Volume: tick[y].Volume,
QuoteVolume: tick[y].QuoteVolume,
Open: tick[y].OpenPrice,
Close: tick[y].PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: assetType,
})
if err != nil {
return err
}
}
*/
return nil
}

// FetchTicker returns the ticker for a currency pair
func ({{.Variable}} *{{.CapitalName}}) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
tickerNew, err := ticker.GetTicker({{.Variable}}.Name, p, assetType)
Expand Down
5 changes: 4 additions & 1 deletion engine/sync_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,10 @@ func (m *syncManager) worker() {
if m.config.Verbose {
log.Debugf(log.SyncMgr, "Initialising %s REST ticker batching", exchangeName)
}
result, err = exchanges[x].UpdateTicker(c.Pair, c.AssetType)
err = exchanges[x].UpdateTickers(c.AssetType)
if err == nil {
result, err = exchanges[x].FetchTicker(c.Pair, c.AssetType)
}
m.tickerBatchLastRequested[exchangeName] = time.Now()
m.mux.Unlock()
} else {
Expand Down
5 changes: 5 additions & 0 deletions exchanges/alphapoint/alphapoint_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ func (a *Alphapoint) FetchAccountInfo(assetType asset.Item) (account.Holdings, e
return acc, nil
}

// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (a *Alphapoint) UpdateTickers(assetType asset.Item) error {
return common.ErrFunctionNotSupported
}

// UpdateTicker updates and returns the ticker for a currency pair
func (a *Alphapoint) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
tick, err := a.GetTicker(p.String())
Expand Down
17 changes: 17 additions & 0 deletions exchanges/binance/binance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,23 @@ func TestUpdateTicker(t *testing.T) {
}
}

func TestUpdateTickers(t *testing.T) {
err := b.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}

err = b.UpdateTickers(asset.CoinMarginedFutures)
if err != nil {
t.Error(err)
}

err = b.UpdateTickers(asset.USDTMarginedFutures)
if err != nil {
t.Error(err)
}
}

func TestUpdateOrderbook(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BTCUSDT")
Expand Down
118 changes: 101 additions & 17 deletions exchanges/binance/binance_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,18 +422,18 @@ func (b *Binance) UpdateTradablePairs(forceUpdate bool) error {
return nil
}

// UpdateTicker updates and returns the ticker for a currency pair
func (b *Binance) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
switch assetType {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *Binance) UpdateTickers(a asset.Item) error {
switch a {
case asset.Spot, asset.Margin:
tick, err := b.GetTickers()
if err != nil {
return nil, err
return err
}
for y := range tick {
cp, err := currency.NewPairFromString(tick[y].Symbol)
if err != nil {
return nil, err
return err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice,
Expand All @@ -447,22 +447,22 @@ func (b *Binance) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.P
Close: tick[y].PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: assetType,
AssetType: a,
})
if err != nil {
return nil, err
return err
}
}
case asset.USDTMarginedFutures:
tick, err := b.U24HTickerPriceChangeStats(currency.Pair{})
if err != nil {
return nil, err
return err
}

for y := range tick {
cp, err := currency.NewPairFromString(tick[y].Symbol)
if err != nil {
return nil, err
return err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice,
Expand All @@ -474,22 +474,22 @@ func (b *Binance) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.P
Close: tick[y].PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: assetType,
AssetType: a,
})
if err != nil {
return nil, err
return err
}
}
case asset.CoinMarginedFutures:
tick, err := b.GetFuturesSwapTickerChangeStats(currency.Pair{}, "")
if err != nil {
return nil, err
return err
}

for y := range tick {
cp, err := currency.NewPairFromString(tick[y].Symbol)
if err != nil {
return nil, err
return err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice,
Expand All @@ -501,16 +501,100 @@ func (b *Binance) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.P
Close: tick[y].PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: assetType,
AssetType: a,
})
if err != nil {
return nil, err
return err
}
}
default:
return nil, fmt.Errorf("assetType not supported: %v", assetType)
return fmt.Errorf("assetType not supported: %v", a)
}
return nil
}

// UpdateTicker updates and returns the ticker for a currency pair
func (b *Binance) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
switch a {
case asset.Spot, asset.Margin:
tick, err := b.GetPriceChangeStats(p)
if err != nil {
return nil, err
}
cp, err := currency.NewPairFromString(tick.Symbol)
if err != nil {
return nil, err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick.LastPrice,
High: tick.HighPrice,
Low: tick.LowPrice,
Bid: tick.BidPrice,
Ask: tick.AskPrice,
Volume: tick.Volume,
QuoteVolume: tick.QuoteVolume,
Open: tick.OpenPrice,
Close: tick.PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: a,
})
if err != nil {
return nil, err
}
case asset.USDTMarginedFutures:
tick, err := b.U24HTickerPriceChangeStats(p)
if err != nil {
return nil, err
}
cp, err := currency.NewPairFromString(tick[0].Symbol)
if err != nil {
return nil, err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[0].LastPrice,
High: tick[0].HighPrice,
Low: tick[0].LowPrice,
Volume: tick[0].Volume,
QuoteVolume: tick[0].QuoteVolume,
Open: tick[0].OpenPrice,
Close: tick[0].PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: a,
})
if err != nil {
return nil, err
}
case asset.CoinMarginedFutures:
tick, err := b.GetFuturesSwapTickerChangeStats(p, "")
if err != nil {
return nil, err
}
cp, err := currency.NewPairFromString(tick[0].Symbol)
if err != nil {
return nil, err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[0].LastPrice,
High: tick[0].HighPrice,
Low: tick[0].LowPrice,
Volume: tick[0].Volume,
QuoteVolume: tick[0].QuoteVolume,
Open: tick[0].OpenPrice,
Close: tick[0].PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: a,
})
if err != nil {
return nil, err
}

default:
return nil, fmt.Errorf("assetType not supported: %v", a)
}
return ticker.GetTicker(b.Name, p, assetType)
return ticker.GetTicker(b.Name, p, a)
}

// FetchTicker returns the ticker for a currency pair
Expand Down
7 changes: 7 additions & 0 deletions exchanges/bitfinex/bitfinex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,13 @@ func TestUpdateTicker(t *testing.T) {
}
}

func TestUpdateTickers(t *testing.T) {
err := b.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

func TestNewOrderMulti(t *testing.T) {
if !b.ValidateAPICredentials() {
t.SkipNow()
Expand Down
33 changes: 21 additions & 12 deletions exchanges/bitfinex/bitfinex_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,22 +323,22 @@ func (b *Bitfinex) UpdateTradablePairs(forceUpdate bool) error {
return nil
}

// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bitfinex) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
enabledPairs, err := b.GetEnabledPairs(assetType)
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *Bitfinex) UpdateTickers(a asset.Item) error {
enabledPairs, err := b.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}

tickerNew, err := b.GetTickerBatch()
if err != nil {
return nil, err
return err
}

for k, v := range tickerNew {
pair, err := currency.NewPairFromString(k[1:]) // Remove prefix
if err != nil {
return nil, err
return err
}

if !enabledPairs.Contains(pair, true) {
Expand All @@ -353,26 +353,35 @@ func (b *Bitfinex) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.
Ask: v.Ask,
Volume: v.Volume,
Pair: pair,
AssetType: assetType,
AssetType: a,
ExchangeName: b.Name})
if err != nil {
return nil, err
return err
}
}
return ticker.GetTicker(b.Name, p, assetType)
return nil
}

// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bitfinex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := b.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(b.Name, p, a)
}

// FetchTicker returns the ticker for a currency pair
func (b *Bitfinex) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
fPair, err := b.FormatExchangeCurrency(p, assetType)
func (b *Bitfinex) FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
fPair, err := b.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}

b.appendOptionalDelimiter(&fPair)
tick, err := ticker.GetTicker(b.Name, fPair, asset.Spot)
if err != nil {
return b.UpdateTicker(fPair, assetType)
return b.UpdateTicker(fPair, a)
}
return tick, nil
}
Expand Down
Loading

0 comments on commit c9ab0b1

Please sign in to comment.