Merge pull request #1823 from c9s/c9s/fix-xgap-symbol

IMPROVE: [xgap] customize source symbol
This commit is contained in:
c9s 2024-11-16 00:00:03 +08:00 committed by GitHub
commit 2f0932c40c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 24 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/c9s/bbgo/pkg/strategy/common" "github.com/c9s/bbgo/pkg/strategy/common"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"github.com/c9s/bbgo/pkg/util/timejitter" "github.com/c9s/bbgo/pkg/util/timejitter"
"github.com/c9s/bbgo/pkg/util/tradingutil"
) )
const ID = "xgap" const ID = "xgap"
@ -34,7 +35,7 @@ func (s *Strategy) ID() string {
} }
func (s *Strategy) InstanceID() string { func (s *Strategy) InstanceID() string {
return fmt.Sprintf("%s:%s", ID, s.Symbol) return fmt.Sprintf("%s:%s:%s", ID, s.TradingExchange, s.Symbol)
} }
type Strategy struct { type Strategy struct {
@ -43,12 +44,15 @@ type Strategy struct {
Environment *bbgo.Environment Environment *bbgo.Environment
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
SourceExchange string `json:"sourceExchange"` TradingExchange string `json:"tradingExchange"`
TradingExchange string `json:"tradingExchange"`
MinSpread fixedpoint.Value `json:"minSpread"` SourceSymbol string `json:"sourceSymbol"`
Quantity fixedpoint.Value `json:"quantity"` SourceExchange string `json:"sourceExchange"`
DryRun bool `json:"dryRun"`
MinSpread fixedpoint.Value `json:"minSpread"`
Quantity fixedpoint.Value `json:"quantity"`
DryRun bool `json:"dryRun"`
DailyMaxVolume fixedpoint.Value `json:"dailyMaxVolume,omitempty"` DailyMaxVolume fixedpoint.Value `json:"dailyMaxVolume,omitempty"`
DailyTargetVolume fixedpoint.Value `json:"dailyTargetVolume,omitempty"` DailyTargetVolume fixedpoint.Value `json:"dailyTargetVolume,omitempty"`
@ -63,6 +67,8 @@ type Strategy struct {
lastSourceKLine, lastTradingKLine types.KLine lastSourceKLine, lastTradingKLine types.KLine
sourceBook, tradingBook *types.StreamOrderBook sourceBook, tradingBook *types.StreamOrderBook
logger logrus.FieldLogger
stopC chan struct{} stopC chan struct{}
} }
@ -74,6 +80,12 @@ func (s *Strategy) Initialize() error {
if s.FeeBudget == nil { if s.FeeBudget == nil {
s.FeeBudget = &common.FeeBudget{} s.FeeBudget = &common.FeeBudget{}
} }
s.logger = logrus.WithFields(logrus.Fields{
"strategy": ID,
"strategy_instance": s.InstanceID(),
"symbol": s.Symbol,
})
return nil return nil
} }
@ -85,17 +97,24 @@ func (s *Strategy) Defaults() error {
if s.UpdateInterval == 0 { if s.UpdateInterval == 0 {
s.UpdateInterval = types.Duration(time.Second) s.UpdateInterval = types.Duration(time.Second)
} }
if s.SourceSymbol == "" {
s.SourceSymbol = s.Symbol
}
return nil return nil
} }
func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) { func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) {
sourceSession, ok := sessions[s.SourceExchange] if len(s.SourceExchange) > 0 && len(s.SourceSymbol) > 0 {
if !ok { sourceSession, ok := sessions[s.SourceExchange]
panic(fmt.Errorf("source session %s is not defined", s.SourceExchange)) if !ok {
} panic(fmt.Errorf("source session %s is not defined", s.SourceExchange))
}
sourceSession.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: "1m"}) sourceSession.Subscribe(types.KLineChannel, s.SourceSymbol, types.SubscribeOptions{Interval: "1m"})
sourceSession.Subscribe(types.BookChannel, s.Symbol, types.SubscribeOptions{Depth: types.DepthLevel5}) sourceSession.Subscribe(types.BookChannel, s.SourceSymbol, types.SubscribeOptions{Depth: types.DepthLevel5})
}
tradingSession, ok := sessions[s.TradingExchange] tradingSession, ok := sessions[s.TradingExchange]
if !ok { if !ok {
@ -136,24 +155,26 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
bbgo.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) { bbgo.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
if err := tradingutil.UniversalCancelAllOrders(ctx, s.tradingSession.Exchange, s.Symbol, nil); err != nil {
s.logger.WithError(err).Errorf("cancel all orders error")
}
close(s.stopC) close(s.stopC)
bbgo.Sync(ctx, s) bbgo.Sync(ctx, s)
}) })
// from here, set data binding // from here, set data binding
s.sourceSession.MarketDataStream.OnKLine(func(kline types.KLine) { sourceKLineHandler := func(kline types.KLine) {
s.mu.Lock() s.mu.Lock()
s.lastSourceKLine = kline s.lastSourceKLine = kline
s.mu.Unlock() s.mu.Unlock()
}) }
s.tradingSession.MarketDataStream.OnKLine(func(kline types.KLine) { s.sourceSession.MarketDataStream.OnKLine(sourceKLineHandler)
s.mu.Lock() s.tradingSession.MarketDataStream.OnKLine(sourceKLineHandler)
s.lastTradingKLine = kline
s.mu.Unlock()
})
if s.SourceExchange != "" { if s.SourceExchange != "" && s.SourceSymbol != "" {
s.sourceBook = types.NewStreamBook(s.Symbol, sourceSession.ExchangeName) s.sourceBook = types.NewStreamBook(s.SourceSymbol, sourceSession.ExchangeName)
s.sourceBook.BindStream(s.sourceSession.MarketDataStream) s.sourceBook.BindStream(s.sourceSession.MarketDataStream)
} }
@ -193,7 +214,6 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
} }
s.placeOrders(ctx) s.placeOrders(ctx)
s.cancelOrders(ctx) s.cancelOrders(ctx)
} }
} }

View File

@ -195,7 +195,8 @@ func getExplorerURL(network string, txID string) string {
switch strings.ToUpper(network) { switch strings.ToUpper(network) {
case "BTC": case "BTC":
return getBitcoinNetworkExplorerURL(txID) return getBitcoinNetworkExplorerURL(txID)
case "BSC": case "BSC", "BSC-BEP20":
// MAX uses "BSC-BEP20"
return getBscNetworkExplorerURL(txID) return getBscNetworkExplorerURL(txID)
case "ETH", "ETHEREUM": case "ETH", "ETHEREUM":
// binance uses "ETH" // binance uses "ETH"