Skip to content

Commit

Permalink
Merge pull request #1460 from c9s/c9s/fix-xnav-price-query
Browse files Browse the repository at this point in the history
FIX: fix and improve session UpdatePrice method
  • Loading branch information
c9s authored Dec 18, 2023
2 parents 3ba46f9 + 882c127 commit 49896bf
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 7 deletions.
2 changes: 1 addition & 1 deletion pkg/bbgo/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ func (session *ExchangeSession) getSessionSymbols(defaultSymbols ...string) ([]s
return defaultSymbols, nil
}

return session.FindPossibleSymbols()
return session.FindPossibleAssetSymbols()
}

func defaultSyncSinceTime() time.Time {
Expand Down
46 changes: 41 additions & 5 deletions pkg/bbgo/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ func (session *ExchangeSession) Market(symbol string) (market types.Market, ok b
return market, ok
}

func (session *ExchangeSession) Markets() map[string]types.Market {
func (session *ExchangeSession) Markets() types.MarketMap {
return session.markets
}

Expand Down Expand Up @@ -703,10 +703,15 @@ func (session *ExchangeSession) UpdatePrices(ctx context.Context, currencies []s
// return nil
// }

markets := session.Markets()
var symbols []string
for _, c := range currencies {
symbols = append(symbols, c+fiat) // BTC/USDT
symbols = append(symbols, fiat+c) // USDT/TWD
possibleSymbols := findPossibleMarketSymbols(markets, c, fiat)
symbols = append(symbols, possibleSymbols...)
}

if len(symbols) == 0 {
return nil
}

tickers, err := session.Exchange.QueryTickers(ctx, symbols...)
Expand All @@ -717,7 +722,17 @@ func (session *ExchangeSession) UpdatePrices(ctx context.Context, currencies []s
var lastTime time.Time
for k, v := range tickers {
// for {Crypto}/USDT markets
session.lastPrices[k] = v.Last
// map things like BTCUSDT = {price}
if market, ok := markets[k]; ok {
if types.IsFiatCurrency(market.BaseCurrency) {
session.lastPrices[k] = v.Last.Div(fixedpoint.One)
} else {
session.lastPrices[k] = v.Last
}
} else {
session.lastPrices[k] = v.Last
}

if v.Time.After(lastTime) {
lastTime = v.Time
}
Expand All @@ -727,7 +742,7 @@ func (session *ExchangeSession) UpdatePrices(ctx context.Context, currencies []s
return err
}

func (session *ExchangeSession) FindPossibleSymbols() (symbols []string, err error) {
func (session *ExchangeSession) FindPossibleAssetSymbols() (symbols []string, err error) {
// If the session is an isolated margin session, there will be only the isolated margin symbol
if session.Margin && session.IsolatedMargin {
return []string{
Expand Down Expand Up @@ -1011,3 +1026,24 @@ func (session *ExchangeSession) FormatOrders(orders []types.SubmitOrder) (format

return formattedOrders, err
}

func findPossibleMarketSymbols(markets types.MarketMap, c, fiat string) (symbols []string) {
var tries []string
// expand USD stable coin currencies
if types.IsUSDFiatCurrency(fiat) {
for _, usdFiat := range types.USDFiatCurrencies {
tries = append(tries, c+usdFiat, usdFiat+c)
}
} else {
tries = []string{c + fiat, fiat + c}
}

for _, try := range tries {
if markets.Has(try) {
symbols = append(symbols, try)
break
}
}

return symbols
}
44 changes: 44 additions & 0 deletions pkg/bbgo/session_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package bbgo

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/c9s/bbgo/pkg/types"
)

func Test_findPossibleMarketSymbols(t *testing.T) {
t.Run("btcusdt", func(t *testing.T) {
markets := types.MarketMap{
"BTCUSDT": types.Market{},
"BTCUSDC": types.Market{},
"BTCUSD": types.Market{},
"BTCBUSD": types.Market{},
}
symbols := findPossibleMarketSymbols(markets, "BTC", "USDT")
if assert.Len(t, symbols, 1) {
assert.Equal(t, "BTCUSDT", symbols[0])
}
})

t.Run("btcusd only", func(t *testing.T) {
markets := types.MarketMap{
"BTCUSD": types.Market{},
}
symbols := findPossibleMarketSymbols(markets, "BTC", "USDT")
if assert.Len(t, symbols, 1) {
assert.Equal(t, "BTCUSD", symbols[0])
}
})

t.Run("usd to stable coin", func(t *testing.T) {
markets := types.MarketMap{
"BTCUSDT": types.Market{},
}
symbols := findPossibleMarketSymbols(markets, "BTC", "USD")
if assert.Len(t, symbols, 1) {
assert.Equal(t, "BTCUSDT", symbols[0])
}
})
}
7 changes: 7 additions & 0 deletions pkg/types/currencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ var USD = wrapper{accounting.Accounting{Symbol: "$ ", Precision: 2}}
var BTC = wrapper{accounting.Accounting{Symbol: "BTC ", Precision: 8}}
var BNB = wrapper{accounting.Accounting{Symbol: "BNB ", Precision: 4}}

const (
USDT = "USDT"
USDC = "USDC"
BUSD = "BUSD"
)

var FiatCurrencies = []string{"USDC", "USDT", "USD", "TWD", "EUR", "GBP", "BUSD"}

// USDFiatCurrencies lists the USD stable coins
var USDFiatCurrencies = []string{"USDT", "USDC", "USD", "BUSD"}

func IsUSDFiatCurrency(currency string) bool {
Expand Down
9 changes: 8 additions & 1 deletion pkg/types/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ func (m Market) TruncateQuoteQuantity(quantity fixedpoint.Value) fixedpoint.Valu
// when side = buy, then available = quote balance
// The balance will be truncated first in order to calculate the minimal notional and minimal quantity
// The adjusted (truncated) order quantity will be returned
func (m Market) GreaterThanMinimalOrderQuantity(side SideType, price, available fixedpoint.Value) (fixedpoint.Value, bool) {
func (m Market) GreaterThanMinimalOrderQuantity(
side SideType, price, available fixedpoint.Value,
) (fixedpoint.Value, bool) {
switch side {
case SideTypeSell:
available = m.TruncateQuantity(available)
Expand Down Expand Up @@ -236,3 +238,8 @@ type MarketMap map[string]Market
func (m MarketMap) Add(market Market) {
m[market.Symbol] = market
}

func (m MarketMap) Has(symbol string) bool {
_, ok := m[symbol]
return ok
}

0 comments on commit 49896bf

Please sign in to comment.