exchanges: Add UpdateTickers method and reserve UpdateTicker for single ticker symbol update requests (if supported) (#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
This commit is contained in:
Luis Rascão
2021-08-27 03:31:34 +01:00
committed by GitHub
parent 4851e94eba
commit c9ab0b1164
52 changed files with 931 additions and 267 deletions

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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())

View File

@@ -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")

View File

@@ -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,
@@ -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,
@@ -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,
@@ -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 ticker.GetTicker(b.Name, p, assetType)
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, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -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()

View File

@@ -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) {
@@ -353,18 +353,27 @@ 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
}
@@ -372,7 +381,7 @@ func (b *Bitfinex) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.P
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
}

View File

@@ -139,23 +139,23 @@ func (b *Bitflyer) Run() {
}
// FetchTradablePairs returns a list of the exchanges tradable pairs
func (b *Bitflyer) FetchTradablePairs(assetType asset.Item) ([]string, error) {
func (b *Bitflyer) FetchTradablePairs(a asset.Item) ([]string, error) {
pairs, err := b.GetMarkets()
if err != nil {
return nil, err
}
format, err := b.GetPairFormat(assetType, false)
format, err := b.GetPairFormat(a, false)
if err != nil {
return nil, err
}
var products []string
for i := range pairs {
if pairs[i].Alias != "" && assetType == asset.Futures {
if pairs[i].Alias != "" && a == asset.Futures {
products = append(products, pairs[i].Alias)
} else if pairs[i].Alias == "" &&
assetType == asset.Spot &&
a == asset.Spot &&
strings.Contains(pairs[i].ProductCode,
format.Delimiter) {
products = append(products, pairs[i].ProductCode)
@@ -187,9 +187,14 @@ func (b *Bitflyer) UpdateTradablePairs(forceUpdate bool) error {
return nil
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *Bitflyer) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bitflyer) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
fPair, err := b.FormatExchangeCurrency(p, assetType)
func (b *Bitflyer) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
fPair, err := b.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
@@ -206,12 +211,12 @@ func (b *Bitflyer) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.
Last: tickerNew.Last,
Volume: tickerNew.Volume,
ExchangeName: b.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
}
return ticker.GetTicker(b.Name, fPair, assetType)
return ticker.GetTicker(b.Name, fPair, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -242,6 +242,13 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateTickers(t *testing.T) {
err := b.UpdateTickers(asset.Spot)
if err != nil {
t.Fatal(err)
}
}
func setFeeBuilder() *exchange.FeeBuilder {
return &exchange.FeeBuilder{
Amount: 1,

View File

@@ -251,24 +251,23 @@ func (b *Bithumb) UpdateTradablePairs(forceUpdate bool) error {
return b.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bithumb) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *Bithumb) UpdateTickers(a asset.Item) error {
tickers, err := b.GetAllTickers()
if err != nil {
return nil, err
return err
}
pairs, err := b.GetEnabledPairs(assetType)
pairs, err := b.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range pairs {
curr := pairs[i].Base.String()
t, ok := tickers[curr]
if !ok {
return nil,
fmt.Errorf("enabled pair %s [%s] not found in returned ticker map %v",
pairs[i], pairs, tickers)
return fmt.Errorf("enabled pair %s [%s] not found in returned ticker map %v",
pairs[i], pairs, tickers)
}
err = ticker.ProcessTicker(&ticker.Price{
High: t.MaxPrice,
@@ -278,20 +277,29 @@ func (b *Bithumb) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.P
Close: t.ClosingPrice,
Pair: pairs[i],
ExchangeName: b.Name,
AssetType: assetType,
AssetType: a,
})
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 *Bithumb) 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 *Bithumb) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
tickerNew, err := ticker.GetTicker(b.Name, p, assetType)
func (b *Bithumb) FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
tickerNew, err := ticker.GetTicker(b.Name, p, a)
if err != nil {
return b.UpdateTicker(p, assetType)
return b.UpdateTicker(p, a)
}
return tickerNew, nil
}

View File

@@ -1090,3 +1090,18 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
cp := currency.NewPair(currency.ETH, currency.USD)
_, err := b.UpdateTicker(cp, asset.PerpetualContract)
if err != nil {
t.Fatal(err)
}
}
func TestUpdateTickers(t *testing.T) {
err := b.UpdateTickers(asset.Spot)
if err != nil {
t.Fatal(err)
}
}

View File

@@ -279,21 +279,16 @@ func (b *Bitmex) UpdateTradablePairs(forceUpdate bool) error {
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bitmex) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
fPair, err := b.FormatExchangeCurrency(p, assetType)
if err != nil {
return nil, err
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *Bitmex) UpdateTickers(a asset.Item) error {
tick, err := b.GetActiveAndIndexInstruments()
if err != nil {
return nil, err
return err
}
pairs, err := b.GetEnabledPairs(assetType)
pairs, err := b.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for j := range tick {
@@ -312,12 +307,27 @@ func (b *Bitmex) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr
Pair: tick[j].Symbol,
LastUpdated: tick[j].Timestamp,
ExchangeName: b.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
return ticker.GetTicker(b.Name, fPair, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bitmex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := b.UpdateTickers(a)
if err != nil {
return nil, err
}
fPair, err := b.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
return ticker.GetTicker(b.Name, fPair, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -304,9 +304,14 @@ func (b *Bitstamp) UpdateTradablePairs(forceUpdate bool) error {
return b.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *Bitstamp) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bitstamp) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
fPair, err := b.FormatExchangeCurrency(p, assetType)
func (b *Bitstamp) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
fPair, err := b.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
@@ -327,12 +332,12 @@ func (b *Bitstamp) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.
Pair: fPair,
LastUpdated: time.Unix(tick.Timestamp, 0),
ExchangeName: b.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
}
return ticker.GetTicker(b.Name, fPair, assetType)
return ticker.GetTicker(b.Name, fPair, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -275,9 +275,14 @@ func (b *Bittrex) UpdateTradablePairs(forceUpdate bool) error {
return b.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *Bittrex) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *Bittrex) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
formattedPair, err := b.FormatExchangeCurrency(p, assetType)
func (b *Bittrex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
formattedPair, err := b.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
@@ -297,14 +302,14 @@ func (b *Bittrex) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.P
return nil, err
}
tickerPrice := b.constructTicker(t, &s, pair, assetType)
tickerPrice := b.constructTicker(t, &s, pair, a)
err = ticker.ProcessTicker(tickerPrice)
if err != nil {
return nil, err
}
return ticker.GetTicker(b.Name, p, assetType)
return ticker.GetTicker(b.Name, p, a)
}
// constructTicker constructs a ticker price from the underlying data

View File

@@ -495,6 +495,14 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := b.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestGetActiveOrders(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {

View File

@@ -287,27 +287,27 @@ func (b *BTCMarkets) UpdateTradablePairs(forceUpdate bool) error {
return b.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *BTCMarkets) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
allPairs, err := b.GetEnabledPairs(assetType)
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *BTCMarkets) UpdateTickers(a asset.Item) error {
allPairs, err := b.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
tickers, err := b.GetTickers(allPairs)
if err != nil {
return nil, err
return err
}
if len(allPairs) != len(tickers) {
return nil, errors.New("enabled pairs differ from returned tickers")
return errors.New("enabled pairs differ from returned tickers")
}
for x := range tickers {
var newP currency.Pair
newP, err = currency.NewPairFromString(tickers[x].MarketID)
if err != nil {
return nil, err
return err
}
err = ticker.ProcessTicker(&ticker.Price{
@@ -320,13 +320,22 @@ func (b *BTCMarkets) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticke
Volume: tickers[x].Volume,
LastUpdated: time.Now(),
ExchangeName: b.Name,
AssetType: assetType,
AssetType: a,
})
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 *BTCMarkets) 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

View File

@@ -256,6 +256,20 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := b.UpdateTickers(asset.Spot)
if err != nil {
t.Fatal(err)
}
err = b.UpdateTickers(asset.Futures)
if err != nil {
t.Fatal(err)
}
}
func TestGetServerTime(t *testing.T) {
t.Parallel()
_, err := b.GetServerTime()

View File

@@ -284,17 +284,17 @@ func (b *BTSE) UpdateTradablePairs(forceUpdate bool) error {
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (b *BTSE) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
tickers, err := b.GetMarketSummary("", assetType == asset.Spot)
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (b *BTSE) UpdateTickers(a asset.Item) error {
tickers, err := b.GetMarketSummary("", a == asset.Spot)
if err != nil {
return nil, err
return err
}
for x := range tickers {
var pair currency.Pair
pair, err = currency.NewPairFromString(tickers[x].Symbol)
if err != nil {
return nil, err
return err
}
err = ticker.ProcessTicker(&ticker.Price{
@@ -306,13 +306,22 @@ func (b *BTSE) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pric
Volume: tickers[x].Volume,
High: tickers[x].High24Hr,
ExchangeName: b.Name,
AssetType: assetType})
AssetType: a})
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 *BTSE) 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

View File

@@ -353,9 +353,14 @@ func (c *CoinbasePro) FetchAccountInfo(assetType asset.Item) (account.Holdings,
return acc, nil
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (c *CoinbasePro) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (c *CoinbasePro) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
fpair, err := c.FormatExchangeCurrency(p, assetType)
func (c *CoinbasePro) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
fpair, err := c.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
@@ -380,14 +385,14 @@ func (c *CoinbasePro) UpdateTicker(p currency.Pair, assetType asset.Item) (*tick
Pair: p,
LastUpdated: tick.Time,
ExchangeName: c.Name,
AssetType: assetType}
AssetType: a}
err = ticker.ProcessTicker(tickerPrice)
if err != nil {
return tickerPrice, err
}
return ticker.GetTicker(c.Name, p, assetType)
return ticker.GetTicker(c.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -244,6 +244,21 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateTickers(t *testing.T) {
// TODO: fix Coinbene rate limiting that will allow to uncomment the next line
// and enable parallel testing
// t.Parallel()
err := c.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
err = c.UpdateTickers(asset.PerpetualSwap)
if err != nil {
t.Error(err)
}
}
func TestGetAccountInfo(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {

View File

@@ -297,30 +297,29 @@ func (c *Coinbene) UpdateTradablePairs(forceUpdate bool) error {
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (c *Coinbene) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
if !c.SupportsAsset(assetType) {
return nil,
fmt.Errorf("%s does not support asset type %s", c.Name, assetType)
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (c *Coinbene) UpdateTickers(a asset.Item) error {
if !c.SupportsAsset(a) {
return fmt.Errorf("%s does not support asset type %s", c.Name, a)
}
allPairs, err := c.GetEnabledPairs(assetType)
allPairs, err := c.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
switch assetType {
switch a {
case asset.Spot:
tickers, err := c.GetTickers()
if err != nil {
return nil, err
return err
}
for i := range tickers {
var newP currency.Pair
newP, err = currency.NewPairFromString(tickers[i].Symbol)
if err != nil {
return nil, err
return err
}
if !allPairs.Contains(newP, true) {
@@ -336,21 +335,21 @@ func (c *Coinbene) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.
Ask: tickers[i].BestAsk,
Volume: tickers[i].DailyVolume,
ExchangeName: c.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
case asset.PerpetualSwap:
tickers, err := c.GetSwapTickers()
if err != nil {
return nil, err
return err
}
for x := range allPairs {
fpair, err := c.FormatExchangeCurrency(allPairs[x], assetType)
fpair, err := c.FormatExchangeCurrency(allPairs[x], a)
if err != nil {
return nil, err
return err
}
tick, ok := tickers[fpair.String()]
@@ -371,13 +370,22 @@ func (c *Coinbene) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.
Volume: tick.Volume24Hour,
LastUpdated: tick.Timestamp,
ExchangeName: c.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
return ticker.GetTicker(c.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (c *Coinbene) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := c.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(c.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -402,14 +402,19 @@ func (c *COINUT) FetchAccountInfo(assetType asset.Item) (account.Holdings, error
return acc, nil
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (c *COINUT) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (c *COINUT) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
func (c *COINUT) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := c.loadInstrumentsIfNotLoaded()
if err != nil {
return nil, err
}
fpair, err := c.FormatExchangeCurrency(p, assetType)
fpair, err := c.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
@@ -434,12 +439,12 @@ func (c *COINUT) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr
Pair: p,
LastUpdated: time.Unix(0, tick.Timestamp),
ExchangeName: c.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
}
return ticker.GetTicker(c.Name, p, assetType)
return ticker.GetTicker(c.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -457,3 +457,22 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BTC_USD")
if err != nil {
t.Fatal(err)
}
_, err = e.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
err := e.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -182,18 +182,15 @@ func (e *EXMO) UpdateTradablePairs(forceUpdate bool) error {
return e.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (e *EXMO) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (e *EXMO) UpdateTickers(a asset.Item) error {
result, err := e.GetTicker()
if err != nil {
return nil, err
return err
}
if _, ok := result[p.String()]; !ok {
return nil, err
}
pairs, err := e.GetEnabledPairs(assetType)
pairs, err := e.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range pairs {
for j := range result {
@@ -210,13 +207,22 @@ func (e *EXMO) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pric
Low: result[j].Low,
Volume: result[j].Volume,
ExchangeName: e.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
return ticker.GetTicker(e.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (e *EXMO) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := e.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(e.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -935,6 +935,14 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := f.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestGetActiveOrders(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {

View File

@@ -94,6 +94,7 @@ func (f *FTX) SetDefaults() {
Websocket: true,
RESTCapabilities: protocol.Features{
TickerFetching: true,
TickerBatching: true,
KlineFetching: true,
TradeFetching: true,
OrderbookFetching: true,
@@ -299,25 +300,21 @@ func (f *FTX) UpdateTradablePairs(forceUpdate bool) error {
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (f *FTX) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
allPairs, err := f.GetEnabledPairs(assetType)
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (f *FTX) UpdateTickers(a asset.Item) error {
allPairs, err := f.GetEnabledPairs(a)
if err != nil {
return nil, err
}
if !allPairs.Contains(p, true) {
allPairs = append(allPairs, p)
return err
}
markets, err := f.GetMarkets()
if err != nil {
return nil, err
return err
}
for a := range allPairs {
formattedPair, err := f.FormatExchangeCurrency(allPairs[a], assetType)
for p := range allPairs {
formattedPair, err := f.FormatExchangeCurrency(allPairs[p], a)
if err != nil {
return nil, err
return err
}
for x := range markets {
@@ -327,21 +324,52 @@ func (f *FTX) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price
var resp ticker.Price
resp.Pair, err = currency.NewPairFromString(markets[x].Name)
if err != nil {
return nil, err
return err
}
resp.Last = markets[x].Last
resp.Bid = markets[x].Bid
resp.Ask = markets[x].Ask
resp.LastUpdated = time.Now()
resp.AssetType = assetType
resp.AssetType = a
resp.ExchangeName = f.Name
err = ticker.ProcessTicker(&resp)
if err != nil {
return nil, err
return err
}
}
}
return ticker.GetTicker(f.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (f *FTX) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
formattedPair, err := f.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
market, err := f.GetMarket(formattedPair.String())
if err != nil {
return nil, err
}
var resp ticker.Price
resp.Pair, err = currency.NewPairFromString(market.Name)
if err != nil {
return nil, err
}
resp.Last = market.Last
resp.Bid = market.Bid
resp.Ask = market.Ask
resp.LastUpdated = time.Now()
resp.AssetType = a
resp.ExchangeName = f.Name
err = ticker.ProcessTicker(&resp)
if err != nil {
return nil, err
}
return ticker.GetTicker(f.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -834,3 +834,22 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("btc_usdt")
if err != nil {
t.Fatal(err)
}
_, err = g.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
err := g.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -230,19 +230,19 @@ func (g *Gateio) UpdateTradablePairs(forceUpdate bool) error {
return g.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (g *Gateio) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (g *Gateio) UpdateTickers(a asset.Item) error {
result, err := g.GetTickers()
if err != nil {
return nil, err
return err
}
pairs, err := g.GetEnabledPairs(assetType)
pairs, err := g.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range pairs {
for p := range pairs {
for k := range result {
if !strings.EqualFold(k, pairs[i].String()) {
if !strings.EqualFold(k, pairs[p].String()) {
continue
}
@@ -254,16 +254,25 @@ func (g *Gateio) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr
QuoteVolume: result[k].QuoteVolume,
Open: result[k].Open,
Close: result[k].Close,
Pair: pairs[i],
Pair: pairs[p],
ExchangeName: g.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
return ticker.GetTicker(g.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (g *Gateio) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := g.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(g.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -343,9 +343,14 @@ func (g *Gemini) FetchAccountInfo(assetType asset.Item) (account.Holdings, error
return acc, nil
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (g *Gemini) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (g *Gemini) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
fPair, err := g.FormatExchangeCurrency(p, assetType)
func (g *Gemini) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
fPair, err := g.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
@@ -364,12 +369,12 @@ func (g *Gemini) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr
Close: tick.Close,
Pair: fPair,
ExchangeName: g.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
}
return ticker.GetTicker(g.Name, fPair, assetType)
return ticker.GetTicker(g.Name, fPair, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -161,6 +161,13 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateTickers(t *testing.T) {
err := h.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestGetAllTickers(t *testing.T) {
_, err := h.GetTickers()
if err != nil {

View File

@@ -305,21 +305,21 @@ func (h *HitBTC) UpdateTradablePairs(forceUpdate bool) error {
return h.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (h *HitBTC) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (h *HitBTC) UpdateTickers(a asset.Item) error {
tick, err := h.GetTickers()
if err != nil {
return nil, err
return err
}
pairs, err := h.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range pairs {
for j := range tick {
pairFmt, err := h.FormatExchangeCurrency(pairs[i], a)
if err != nil {
return nil, err
return err
}
if tick[j].Symbol != pairFmt.String() {
@@ -348,10 +348,19 @@ func (h *HitBTC) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err
ExchangeName: h.Name,
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (h *HitBTC) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := h.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(h.Name, p, a)
}

View File

@@ -431,12 +431,17 @@ func (h *HUOBI) UpdateTradablePairs(forceUpdate bool) error {
return h.UpdatePairs(cp, asset.CoinMarginedFutures, false, forceUpdate)
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (h *HUOBI) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (h *HUOBI) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
if !h.SupportsAsset(assetType) {
return nil, fmt.Errorf("asset type of %s is not supported by %s", assetType, h.Name)
func (h *HUOBI) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
if !h.SupportsAsset(a) {
return nil, fmt.Errorf("asset type of %s is not supported by %s", a, h.Name)
}
switch assetType {
switch a {
case asset.Spot:
tickerData, err := h.Get24HrMarketSummary(p)
if err != nil {
@@ -478,7 +483,7 @@ func (h *HUOBI) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pri
Bid: marketData.Tick.Bid[0],
Ask: marketData.Tick.Ask[0],
ExchangeName: h.Name,
AssetType: assetType,
AssetType: a,
})
if err != nil {
return nil, err
@@ -499,13 +504,13 @@ func (h *HUOBI) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pri
Bid: marketData.Tick.Bid[0],
Ask: marketData.Tick.Ask[0],
ExchangeName: h.Name,
AssetType: assetType,
AssetType: a,
})
if err != nil {
return nil, err
}
}
return ticker.GetTicker(h.Name, p, assetType)
return ticker.GetTicker(h.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -29,6 +29,7 @@ type IBotExchange interface {
ValidateCredentials(a asset.Item) error
FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error)
UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error)
UpdateTickers(a asset.Item) error
FetchOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error)
UpdateOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error)
FetchTradablePairs(a asset.Item) ([]string, error)

View File

@@ -139,9 +139,14 @@ func (i *ItBit) UpdateTradablePairs(forceUpdate bool) error {
return common.ErrFunctionNotSupported
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (i *ItBit) UpdateTickers(a asset.Item) error {
return common.ErrFunctionNotSupported
}
// UpdateTicker updates and returns the ticker for a currency pair
func (i *ItBit) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
fpair, err := i.FormatExchangeCurrency(p, assetType)
func (i *ItBit) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
fpair, err := i.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
@@ -162,12 +167,12 @@ func (i *ItBit) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pri
Pair: p,
LastUpdated: tick.ServertimeUTC,
ExchangeName: i.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
}
return ticker.GetTicker(i.Name, p, assetType)
return ticker.GetTicker(i.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -95,6 +95,19 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := k.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
err = k.UpdateTickers(asset.Futures)
if err != nil {
t.Error(err)
}
}
func TestUpdateOrderbook(t *testing.T) {
t.Parallel()
sp, err := currency.NewPairFromString("BTCEUR")

View File

@@ -406,28 +406,28 @@ func (k *Kraken) UpdateTradablePairs(forceUpdate bool) error {
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (k *Kraken) 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 (k *Kraken) UpdateTickers(a asset.Item) error {
switch a {
case asset.Spot:
pairs, err := k.GetEnabledPairs(assetType)
pairs, err := k.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
pairsCollated, err := k.FormatExchangeCurrencies(pairs, assetType)
pairsCollated, err := k.FormatExchangeCurrencies(pairs, a)
if err != nil {
return nil, err
return err
}
tickers, err := k.GetTickers(pairsCollated)
if err != nil {
return nil, err
return err
}
for i := range pairs {
for c, t := range tickers {
pairFmt, err := k.FormatExchangeCurrency(pairs[i], assetType)
pairFmt, err := k.FormatExchangeCurrency(pairs[i], a)
if err != nil {
return nil, err
return err
}
if !strings.EqualFold(pairFmt.String(), c) {
altCurrency := assetTranslator.LookupAltname(c)
@@ -449,21 +449,21 @@ func (k *Kraken) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr
Open: t.Open,
Pair: pairs[i],
ExchangeName: k.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
case asset.Futures:
t, err := k.GetFuturesTickers()
if err != nil {
return nil, err
return err
}
for x := range t.Tickers {
pair, err := currency.NewPairFromString(t.Tickers[x].Symbol)
if err != nil {
return nil, err
return err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: t.Tickers[x].Last,
@@ -473,15 +473,24 @@ func (k *Kraken) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr
Open: t.Tickers[x].Open24H,
Pair: pair,
ExchangeName: k.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 ticker.GetTicker(k.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (k *Kraken) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := k.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(k.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -513,3 +513,23 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("eth_btc")
if err != nil {
t.Fatal(err)
}
_, err = l.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := l.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -188,15 +188,15 @@ func (l *Lbank) UpdateTradablePairs(forceUpdate bool) error {
return l.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (l *Lbank) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (l *Lbank) UpdateTickers(a asset.Item) error {
tickerInfo, err := l.GetTickers()
if err != nil {
return nil, err
return err
}
pairs, err := l.GetEnabledPairs(assetType)
pairs, err := l.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range pairs {
for j := range tickerInfo {
@@ -212,13 +212,22 @@ func (l *Lbank) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pri
Pair: tickerInfo[j].Symbol,
LastUpdated: time.Unix(0, tickerInfo[j].Timestamp),
ExchangeName: l.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
return ticker.GetTicker(l.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (l *Lbank) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := l.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(l.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -436,3 +436,23 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BTCUSD")
if err != nil {
t.Fatal(err)
}
_, err = l.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := l.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -165,16 +165,16 @@ func (l *LocalBitcoins) UpdateTradablePairs(forceUpdate bool) error {
return l.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (l *LocalBitcoins) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (l *LocalBitcoins) UpdateTickers(a asset.Item) error {
tick, err := l.GetTicker()
if err != nil {
return nil, err
return err
}
pairs, err := l.GetEnabledPairs(assetType)
pairs, err := l.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range pairs {
curr := pairs[i].Quote.String()
@@ -186,15 +186,23 @@ func (l *LocalBitcoins) UpdateTicker(p currency.Pair, assetType asset.Item) (*ti
tp.Last = tick[curr].Avg24h
tp.Volume = tick[curr].VolumeBTC
tp.ExchangeName = l.Name
tp.AssetType = assetType
tp.AssetType = a
err = ticker.ProcessTicker(&tp)
if err != nil {
return nil, err
return err
}
}
return nil
}
return ticker.GetTicker(l.Name, p, assetType)
// UpdateTicker updates and returns the ticker for a currency pair
func (l *LocalBitcoins) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := l.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(l.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -1132,3 +1132,23 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BTC-USD")
if err != nil {
t.Fatal(err)
}
_, err = o.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := o.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -271,16 +271,16 @@ func (o *OKCoin) UpdateTradablePairs(forceUpdate bool) error {
return o.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (o *OKCoin) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
if assetType == asset.Spot {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (o *OKCoin) UpdateTickers(a asset.Item) error {
if a == asset.Spot {
resp, err := o.GetSpotAllTokenPairsInformation()
if err != nil {
return nil, err
return err
}
pairs, err := o.GetEnabledPairs(assetType)
pairs, err := o.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range pairs {
for j := range resp {
@@ -300,14 +300,23 @@ func (o *OKCoin) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr
Pair: pairs[i],
LastUpdated: resp[j].Timestamp,
ExchangeName: o.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
}
return ticker.GetTicker(o.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (o *OKCoin) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := o.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(o.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -2250,3 +2250,23 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("EOS-USDT")
if err != nil {
t.Fatal(err)
}
_, err = o.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := o.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -424,19 +424,18 @@ func (o *OKEX) UpdateTradablePairs(forceUpdate bool) error {
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (o *OKEX) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
tickerPrice := new(ticker.Price)
switch assetType {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (o *OKEX) UpdateTickers(a asset.Item) error {
switch a {
case asset.Spot:
resp, err := o.GetSpotAllTokenPairsInformation()
if err != nil {
return tickerPrice, err
return err
}
enabled, err := o.GetEnabledPairs(asset.Spot)
if err != nil {
return nil, err
return err
}
for j := range resp {
@@ -456,21 +455,21 @@ func (o *OKEX) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pric
Pair: resp[j].InstrumentID,
LastUpdated: resp[j].Timestamp,
ExchangeName: o.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
case asset.PerpetualSwap:
resp, err := o.GetAllSwapTokensInformation()
if err != nil {
return nil, err
return err
}
enabled, err := o.GetEnabledPairs(asset.PerpetualSwap)
if err != nil {
return nil, err
return err
}
for j := range resp {
@@ -492,21 +491,21 @@ func (o *OKEX) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pric
Pair: nC,
LastUpdated: resp[j].Timestamp,
ExchangeName: o.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
case asset.Futures:
resp, err := o.GetAllFuturesTokenInfo()
if err != nil {
return nil, err
return err
}
enabled, err := o.GetEnabledPairs(asset.Futures)
if err != nil {
return nil, err
return err
}
for j := range resp {
@@ -528,14 +527,23 @@ func (o *OKEX) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pric
Pair: nC,
LastUpdated: resp[j].Timestamp,
ExchangeName: o.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
}
return ticker.GetTicker(o.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (o *OKEX) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := o.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(o.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -1006,3 +1006,23 @@ func TestGetCompleteBalances(t *testing.T) {
t.Fatal(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("BTC_LTC")
if err != nil {
t.Fatal(err)
}
_, err = p.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := p.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -270,21 +270,21 @@ func (p *Poloniex) UpdateTradablePairs(forceUpgrade bool) error {
return p.UpdatePairs(ps, asset.Spot, false, forceUpgrade)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (p *Poloniex) UpdateTicker(currencyPair currency.Pair, assetType asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (p *Poloniex) UpdateTickers(a asset.Item) error {
tick, err := p.GetTicker()
if err != nil {
return nil, err
return err
}
enabledPairs, err := p.GetEnabledPairs(assetType)
enabledPairs, err := p.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for i := range enabledPairs {
fpair, err := p.FormatExchangeCurrency(enabledPairs[i], assetType)
fpair, err := p.FormatExchangeCurrency(enabledPairs[i], a)
if err != nil {
return nil, err
return err
}
curr := fpair.String()
if _, ok := tick[curr]; !ok {
@@ -301,12 +301,21 @@ func (p *Poloniex) UpdateTicker(currencyPair currency.Pair, assetType asset.Item
Volume: tick[curr].BaseVolume,
QuoteVolume: tick[curr].QuoteVolume,
ExchangeName: p.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
return ticker.GetTicker(p.Name, currencyPair, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (p *Poloniex) UpdateTicker(currencyPair currency.Pair, a asset.Item) (*ticker.Price, error) {
err := p.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(p.Name, currencyPair, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -51,6 +51,10 @@ func (c *CustomEx) FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, er
return nil, nil
}
func (c *CustomEx) UpdateTickers(a asset.Item) error {
return nil
}
func (c *CustomEx) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
return nil, nil
}

View File

@@ -513,3 +513,23 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("ETH_BTC")
if err != nil {
t.Fatal(err)
}
_, err = y.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := y.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -174,26 +174,26 @@ func (y *Yobit) UpdateTradablePairs(forceUpdate bool) error {
return y.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (y *Yobit) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
enabledPairs, err := y.GetEnabledPairs(assetType)
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (y *Yobit) UpdateTickers(a asset.Item) error {
enabledPairs, err := y.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
pairsCollated, err := y.FormatExchangeCurrencies(enabledPairs, assetType)
pairsCollated, err := y.FormatExchangeCurrencies(enabledPairs, a)
if err != nil {
return nil, err
return err
}
result, err := y.GetTicker(pairsCollated)
if err != nil {
return nil, err
return err
}
for i := range enabledPairs {
fpair, err := y.FormatExchangeCurrency(enabledPairs[i], assetType)
fpair, err := y.FormatExchangeCurrency(enabledPairs[i], a)
if err != nil {
return nil, err
return err
}
curr := fpair.Lower().String()
if _, ok := result[curr]; !ok {
@@ -210,13 +210,22 @@ func (y *Yobit) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Pri
QuoteVolume: resultCurr.VolumeCurrent,
Volume: resultCurr.Vol,
ExchangeName: y.Name,
AssetType: assetType,
AssetType: a,
})
if err != nil {
return nil, err
return err
}
}
return ticker.GetTicker(y.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (y *Yobit) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := y.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(y.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -1000,3 +1000,23 @@ func TestGetHistoricTrades(t *testing.T) {
t.Error(err)
}
}
func TestUpdateTicker(t *testing.T) {
t.Parallel()
cp, err := currency.NewPairFromString("ETH_USDT")
if err != nil {
t.Fatal(err)
}
_, err = z.UpdateTicker(cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestUpdateTickers(t *testing.T) {
t.Parallel()
err := z.UpdateTickers(asset.Spot)
if err != nil {
t.Error(err)
}
}

View File

@@ -243,16 +243,16 @@ func (z *ZB) UpdateTradablePairs(forceUpdate bool) error {
return z.UpdatePairs(p, asset.Spot, false, forceUpdate)
}
// UpdateTicker updates and returns the ticker for a currency pair
func (z *ZB) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) {
// UpdateTickers updates the ticker for all currency pairs of a given asset type
func (z *ZB) UpdateTickers(a asset.Item) error {
result, err := z.GetTickers()
if err != nil {
return nil, err
return err
}
enabledPairs, err := z.GetEnabledPairs(assetType)
enabledPairs, err := z.GetEnabledPairs(a)
if err != nil {
return nil, err
return err
}
for x := range enabledPairs {
// We can't use either pair format here, so format it to lower-
@@ -271,13 +271,22 @@ func (z *ZB) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price,
Low: result[curr].Low,
Volume: result[curr].Volume,
ExchangeName: z.Name,
AssetType: assetType})
AssetType: a})
if err != nil {
return nil, err
return err
}
}
return ticker.GetTicker(z.Name, p, assetType)
return nil
}
// UpdateTicker updates and returns the ticker for a currency pair
func (z *ZB) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) {
err := z.UpdateTickers(a)
if err != nil {
return nil, err
}
return ticker.GetTicker(z.Name, p, a)
}
// FetchTicker returns the ticker for a currency pair

View File

@@ -143032,6 +143032,34 @@
"bodyParams": "",
"headers": {}
},
{
"data": {
"askPrice": "0.04103400",
"askQty": "1.89600000",
"bidPrice": "0.04103300",
"bidQty": "43.77800000",
"closeTime": 1611715404283,
"count": 460443,
"firstId": 221265272,
"highPrice": "0.04223600",
"lastId": 221725714,
"lastPrice": "0.04103400",
"lastQty": "1.06900000",
"lowPrice": "0.04007400",
"openPrice": "0.04176800",
"openTime": 1611629004283,
"prevClosePrice": "0.04176800",
"priceChange": "-0.00073400",
"priceChangePercent": "-1.757",
"quoteVolume": "16980.13811233",
"symbol": "ETHBTC",
"volume": "410969.51200000",
"weightedAvgPrice": "0.04131727"
},
"queryString": "symbol=ETHBTC",
"bodyParams": "",
"headers": {}
},
{
"data": [
{
@@ -310430,4 +310458,4 @@
]
}
}
}
}