Skip to content

Commit

Permalink
Merge pull request #1710 from c9s/c9s/xmaker/stb-improvements
Browse files Browse the repository at this point in the history
IMPROVE: [xmaker] improve stability
  • Loading branch information
c9s authored Aug 26, 2024
2 parents 90bcd25 + 86cc821 commit 80949bf
Show file tree
Hide file tree
Showing 20 changed files with 204 additions and 87 deletions.
25 changes: 0 additions & 25 deletions .travis.yml

This file was deleted.

1 change: 1 addition & 0 deletions config/xmaker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ crossExchangeStrategies:
# 18002.00
pips: 10
circuitBreaker:
enabled: true
maximumConsecutiveTotalLoss: 36.0
maximumConsecutiveLossTimes: 10
maximumLossPerRound: 15.0
Expand Down
2 changes: 1 addition & 1 deletion examples/exchange-api/binance-book/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var rootCmd = &cobra.Command{
stream.SetPublicOnly()
stream.Subscribe(types.BookChannel, symbol, types.SubscribeOptions{})

streamBook := types.NewStreamBook(symbol)
streamBook := types.NewStreamBook(symbol, exchange.Name())
streamBook.BindStream(stream)

go func() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/bbgo/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ func (session *ExchangeSession) initSymbol(ctx context.Context, environ *Environ
for _, sub := range session.Subscriptions {
switch sub.Channel {
case types.BookChannel:
book := types.NewStreamBook(sub.Symbol)
book := types.NewStreamBook(sub.Symbol, session.ExchangeName)
book.BindStream(session.MarketDataStream)
session.orderBooks[sub.Symbol] = book

Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/orderbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ var orderbookCmd = &cobra.Command{
return fmt.Errorf("session %s not found", sessionName)
}

orderBook := types.NewMutexOrderBook(symbol)
orderBook := types.NewMutexOrderBook(symbol, session.Exchange.Name())

s := session.Exchange.NewStream()
s.SetPublicOnly()
Expand Down
18 changes: 9 additions & 9 deletions pkg/priceresolver/simple.go → pkg/pricesolver/simple.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package priceresolver
package pricesolver

import (
"sync"
Expand All @@ -9,8 +9,8 @@ import (
"github.com/c9s/bbgo/pkg/types"
)

// SimplePriceResolver implements a map-structure-based price index
type SimplePriceResolver struct {
// SimplePriceSolver implements a map-structure-based price index
type SimplePriceSolver struct {
// symbolPrices stores the latest trade price by mapping symbol to price
symbolPrices map[string]fixedpoint.Value
markets types.MarketMap
Expand All @@ -28,16 +28,16 @@ type SimplePriceResolver struct {
mu sync.Mutex
}

func NewSimplePriceResolver(markets types.MarketMap) *SimplePriceResolver {
return &SimplePriceResolver{
func NewSimplePriceResolver(markets types.MarketMap) *SimplePriceSolver {
return &SimplePriceSolver{
markets: markets,
symbolPrices: make(map[string]fixedpoint.Value),
pricesByBase: make(map[string]map[string]fixedpoint.Value),
pricesByQuote: make(map[string]map[string]fixedpoint.Value),
}
}

func (m *SimplePriceResolver) Update(symbol string, price fixedpoint.Value) {
func (m *SimplePriceSolver) Update(symbol string, price fixedpoint.Value) {
m.mu.Lock()
defer m.mu.Unlock()

Expand Down Expand Up @@ -65,11 +65,11 @@ func (m *SimplePriceResolver) Update(symbol string, price fixedpoint.Value) {
baseMap[market.BaseCurrency] = price
}

func (m *SimplePriceResolver) UpdateFromTrade(trade types.Trade) {
func (m *SimplePriceSolver) UpdateFromTrade(trade types.Trade) {
m.Update(trade.Symbol, trade.Price)
}

func (m *SimplePriceResolver) inferencePrice(asset string, assetPrice fixedpoint.Value, preferredFiats ...string) (fixedpoint.Value, bool) {
func (m *SimplePriceSolver) inferencePrice(asset string, assetPrice fixedpoint.Value, preferredFiats ...string) (fixedpoint.Value, bool) {
// log.Infof("inferencePrice %s = %f", asset, assetPrice.Float64())
quotePrices, ok := m.pricesByBase[asset]
if ok {
Expand Down Expand Up @@ -112,7 +112,7 @@ func (m *SimplePriceResolver) inferencePrice(asset string, assetPrice fixedpoint
return fixedpoint.Zero, false
}

func (m *SimplePriceResolver) ResolvePrice(asset string, preferredFiats ...string) (fixedpoint.Value, bool) {
func (m *SimplePriceSolver) ResolvePrice(asset string, preferredFiats ...string) (fixedpoint.Value, bool) {
m.mu.Lock()
defer m.mu.Unlock()
return m.inferencePrice(asset, fixedpoint.One, preferredFiats...)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package priceresolver
package pricesolver

import (
"testing"
Expand Down
23 changes: 13 additions & 10 deletions pkg/strategy/audacitymaker/orderflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package audacitymaker

import (
"context"

"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint"
Expand Down Expand Up @@ -38,7 +39,7 @@ func (s *PerTrade) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
position := orderExecutor.Position()
symbol := position.Symbol
// ger best bid/ask, not used yet
s.StreamBook = types.NewStreamBook(symbol)
s.StreamBook = types.NewStreamBook(symbol, session.ExchangeName)
s.StreamBook.BindStream(session.MarketDataStream)

// use queue to do time-series rolling
Expand All @@ -59,7 +60,7 @@ func (s *PerTrade) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener

session.MarketDataStream.OnMarketTrade(func(trade types.Trade) {

//log.Infof("%s trade @ %f", trade.Side, trade.Price.Float64())
// log.Infof("%s trade @ %f", trade.Side, trade.Price.Float64())

ctx := context.Background()

Expand All @@ -80,10 +81,10 @@ func (s *PerTrade) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
sellTradesNumber.Update(1)
}

//canceled := s.orderExecutor.GracefulCancel(ctx)
//if canceled != nil {
// canceled := s.orderExecutor.GracefulCancel(ctx)
// if canceled != nil {
// _ = s.orderExecutor.GracefulCancel(ctx)
//}
// }

sizeFraction := buyTradeSize.Sum() / sellTradeSize.Sum()
numberFraction := buyTradesNumber.Sum() / sellTradesNumber.Sum()
Expand Down Expand Up @@ -112,15 +113,15 @@ func (s *PerTrade) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
if outlier(orderFlowSizeMinMax.Tail(100), threshold) > 0 && outlier(orderFlowNumberMinMax.Tail(100), threshold) > 0 {
_ = s.orderExecutor.GracefulCancel(ctx)
log.Infof("long!!")
//_ = s.placeTrade(ctx, types.SideTypeBuy, s.Quantity, symbol)
// _ = s.placeTrade(ctx, types.SideTypeBuy, s.Quantity, symbol)
_ = s.placeOrder(ctx, types.SideTypeBuy, s.Quantity, bid.Price, symbol)
//_ = s.placeOrder(ctx, types.SideTypeSell, s.Quantity, ask.Price.Mul(fixedpoint.NewFromFloat(1.0005)), symbol)
// _ = s.placeOrder(ctx, types.SideTypeSell, s.Quantity, ask.Price.Mul(fixedpoint.NewFromFloat(1.0005)), symbol)
} else if outlier(orderFlowSizeMinMax.Tail(100), threshold) < 0 && outlier(orderFlowNumberMinMax.Tail(100), threshold) < 0 {
_ = s.orderExecutor.GracefulCancel(ctx)
log.Infof("short!!")
//_ = s.placeTrade(ctx, types.SideTypeSell, s.Quantity, symbol)
// _ = s.placeTrade(ctx, types.SideTypeSell, s.Quantity, symbol)
_ = s.placeOrder(ctx, types.SideTypeSell, s.Quantity, ask.Price, symbol)
//_ = s.placeOrder(ctx, types.SideTypeBuy, s.Quantity, bid.Price.Mul(fixedpoint.NewFromFloat(0.9995)), symbol)
// _ = s.placeOrder(ctx, types.SideTypeBuy, s.Quantity, bid.Price.Mul(fixedpoint.NewFromFloat(0.9995)), symbol)
}
}

Expand All @@ -138,7 +139,9 @@ func (s *PerTrade) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
}
}

func (s *PerTrade) placeOrder(ctx context.Context, side types.SideType, quantity fixedpoint.Value, price fixedpoint.Value, symbol string) error {
func (s *PerTrade) placeOrder(
ctx context.Context, side types.SideType, quantity fixedpoint.Value, price fixedpoint.Value, symbol string,
) error {
market, _ := s.session.Market(symbol)
_, err := s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{
Symbol: symbol,
Expand Down
2 changes: 1 addition & 1 deletion pkg/strategy/scmaker/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
s.Strategy.Initialize(ctx, s.Environment, session, s.Market, ID, s.InstanceID())

s.book = types.NewStreamBook(s.Symbol)
s.book = types.NewStreamBook(s.Symbol, session.Exchange.Name())
s.book.BindStream(session.MarketDataStream)

s.liquidityOrderBook = bbgo.NewActiveOrderBook(s.Symbol)
Expand Down
14 changes: 10 additions & 4 deletions pkg/strategy/tri/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,9 @@ func notifyUsdPnL(profit fixedpoint.Value) {
bbgo.Notify(title)
}

func (s *Strategy) iocOrderExecution(ctx context.Context, session *bbgo.ExchangeSession, orders [3]types.SubmitOrder, ratio float64) (types.OrderSlice, error) {
func (s *Strategy) iocOrderExecution(
ctx context.Context, session *bbgo.ExchangeSession, orders [3]types.SubmitOrder, ratio float64,
) (types.OrderSlice, error) {
service, ok := session.Exchange.(types.ExchangeOrderQueryService)
if !ok {
return nil, errors.New("exchange does not support ExchangeOrderQueryService")
Expand Down Expand Up @@ -700,7 +702,9 @@ func (s *Strategy) waitWebSocketOrderDone(ctx context.Context, orderID uint64, t
}
}

func (s *Strategy) waitOrdersAndCollectTrades(ctx context.Context, service types.ExchangeOrderQueryService, createdOrders types.OrderSlice) (map[uint64][]types.Trade, types.OrderSlice, error) {
func (s *Strategy) waitOrdersAndCollectTrades(
ctx context.Context, service types.ExchangeOrderQueryService, createdOrders types.OrderSlice,
) (map[uint64][]types.Trade, types.OrderSlice, error) {
var err error
var orderTrades = make(map[uint64][]types.Trade)
var updatedOrders types.OrderSlice
Expand Down Expand Up @@ -763,7 +767,9 @@ func (s *Strategy) analyzeOrders(orders types.OrderSlice) {
}
}

func (s *Strategy) buildArbMarkets(session *bbgo.ExchangeSession, symbols []string, separateStream bool, sigC sigchan.Chan) (map[string]*ArbMarket, error) {
func (s *Strategy) buildArbMarkets(
session *bbgo.ExchangeSession, symbols []string, separateStream bool, sigC sigchan.Chan,
) (map[string]*ArbMarket, error) {
markets := make(map[string]*ArbMarket)
// build market object
for _, symbol := range symbols {
Expand All @@ -790,7 +796,7 @@ func (s *Strategy) buildArbMarkets(session *bbgo.ExchangeSession, symbols []stri
Speed: types.SpeedHigh,
})

book := types.NewStreamBook(symbol)
book := types.NewStreamBook(symbol, session.ExchangeName)
priceUpdater := func(_ types.SliceOrderBook) {
bestBid, bestAsk, _ := book.BestBidAndAsk()
if bestAsk.Equals(m.bestAsk) && bestBid.Equals(m.bestBid) {
Expand Down
6 changes: 3 additions & 3 deletions pkg/strategy/xalign/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/core"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/priceresolver"
"github.com/c9s/bbgo/pkg/pricesolver"
"github.com/c9s/bbgo/pkg/types"
)

Expand Down Expand Up @@ -57,7 +57,7 @@ type Strategy struct {

faultBalanceRecords map[string][]TimeBalance

priceResolver *priceresolver.SimplePriceResolver
priceResolver *pricesolver.SimplePriceSolver

sessions map[string]*bbgo.ExchangeSession
orderBooks map[string]*bbgo.ActiveOrderBook
Expand Down Expand Up @@ -372,7 +372,7 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
// session.Market(symbol)
}

s.priceResolver = priceresolver.NewSimplePriceResolver(markets)
s.priceResolver = pricesolver.NewSimplePriceResolver(markets)

bbgo.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
Expand Down
2 changes: 1 addition & 1 deletion pkg/strategy/xdepthmaker/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ func (s *Strategy) CrossRun(
return err
}

s.pricingBook = types.NewStreamBook(s.HedgeSymbol)
s.pricingBook = types.NewStreamBook(s.HedgeSymbol, s.hedgeSession.ExchangeName)
s.pricingBook.BindStream(s.hedgeSession.MarketDataStream)

s.stopC = make(chan struct{})
Expand Down
2 changes: 1 addition & 1 deletion pkg/strategy/xdepthmaker/strategy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestStrategy_generateMakerOrders(t *testing.T) {
},
}

pricingBook := types.NewStreamBook("BTCUSDT")
pricingBook := types.NewStreamBook("BTCUSDT", types.ExchangeBinance)
pricingBook.Load(types.SliceOrderBook{
Symbol: "BTCUSDT",
Bids: types.PriceVolumeSlice{
Expand Down
4 changes: 2 additions & 2 deletions pkg/strategy/xgap/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
})

if s.SourceExchange != "" {
s.sourceBook = types.NewStreamBook(s.Symbol)
s.sourceBook = types.NewStreamBook(s.Symbol, sourceSession.ExchangeName)
s.sourceBook.BindStream(s.sourceSession.MarketDataStream)
}

s.tradingBook = types.NewStreamBook(s.Symbol)
s.tradingBook = types.NewStreamBook(s.Symbol, tradingSession.ExchangeName)
s.tradingBook.BindStream(s.tradingSession.MarketDataStream)

s.tradingSession.UserDataStream.OnTradeUpdate(func(trade types.Trade) {
Expand Down
43 changes: 43 additions & 0 deletions pkg/strategy/xmaker/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package xmaker

import "github.com/prometheus/client_golang/prometheus"

var openOrderBidExposureInUsdMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "xmaker_open_order_bid_exposure_in_usd",
Help: "",
}, []string{"strategy_type", "strategy_id", "exchange", "symbol"})

var openOrderAskExposureInUsdMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "xmaker_open_order_ask_exposure_in_usd",
Help: "",
}, []string{"strategy_type", "strategy_id", "exchange", "symbol"})

var makerBestBidPriceMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "xmaker_maker_best_bid_price",
Help: "",
}, []string{"strategy_type", "strategy_id", "exchange", "symbol"})

var makerBestAskPriceMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "xmaker_maker_best_ask_price",
Help: "",
}, []string{"strategy_type", "strategy_id", "exchange", "symbol"})

var numOfLayersMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "xmaker_num_of_layers",
Help: "",
}, []string{"strategy_type", "strategy_id", "exchange", "symbol"})

func init() {
prometheus.MustRegister(
openOrderBidExposureInUsdMetrics,
openOrderAskExposureInUsdMetrics,
makerBestBidPriceMetrics,
makerBestAskPriceMetrics,
numOfLayersMetrics,
)
}
Loading

0 comments on commit 80949bf

Please sign in to comment.