xmaker: improve balance checking

This commit is contained in:
c9s 2021-03-21 12:43:41 +08:00
parent 948e555f51
commit 814a77ea39
7 changed files with 36 additions and 10 deletions

View File

@ -72,7 +72,7 @@ riskControls:
crossExchangeStrategies:
- mobydick:
- xmaker:
symbol: BTCUSDT
sourceExchange: binance
makerExchange: max

View File

@ -63,11 +63,11 @@ riskControls:
crossExchangeStrategies:
- mobydick:
- xmaker:
symbol: ETHUSDT
sourceExchange: binance
makerExchange: max
updateInterval: 1s
updateInterval: 2s
# disableHedge disables the hedge orders on the source exchange
# disableHedge: true
@ -78,7 +78,7 @@ crossExchangeStrategies:
askMargin: 0.004
bidMargin: 0.004
quantity: 0.1
quantity: 0.01
quantityMultiplier: 2
# numLayers means how many order we want to place on each side. 3 means we want 3 bid orders and 3 ask orders

View File

@ -49,7 +49,7 @@ sessions:
crossExchangeStrategies:
- mobydick:
- xmaker:
symbol: "BTCUSDT"
sourceExchange: binance
makerExchange: max

View File

@ -173,6 +173,8 @@ func (trader *Trader) Subscribe() {
for _, strategy := range strategies {
if subscriber, ok := strategy.(ExchangeSessionSubscriber); ok {
subscriber.Subscribe(session)
} else {
log.Errorf("strategy %s does not implement ExchangeSessionSubscriber", strategy.ID())
}
}
}
@ -180,6 +182,8 @@ func (trader *Trader) Subscribe() {
for _, strategy := range trader.crossExchangeStrategies {
if subscriber, ok := strategy.(CrossExchangeSessionSubscriber); ok {
subscriber.CrossSubscribe(trader.environment.sessions)
} else {
log.Errorf("strategy %s does not implement CrossExchangeSessionSubscriber", strategy.ID())
}
}
}

View File

@ -11,5 +11,6 @@ import (
_ "github.com/c9s/bbgo/pkg/strategy/support"
_ "github.com/c9s/bbgo/pkg/strategy/swing"
_ "github.com/c9s/bbgo/pkg/strategy/trailingstop"
_ "github.com/c9s/bbgo/pkg/strategy/xmaker"
_ "github.com/c9s/bbgo/pkg/strategy/xpuremaker"
)

View File

@ -501,7 +501,7 @@ func (r *CreateOrderRequest) Do(ctx context.Context) (order *Order, err error) {
payload["group_id"] = r.groupID
}
req, err := r.client.newAuthenticatedRequest("POST", "v2/orders", &payload)
req, err := r.client.newAuthenticatedRequest("POST", "v2/orders", payload)
if err != nil {
return order, errors.Wrapf(err, "order create error")
}

View File

@ -82,11 +82,16 @@ type Strategy struct {
func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) {
sourceSession, ok := sessions[s.SourceExchange]
if !ok {
panic(fmt.Errorf("source exchange %s is not defined", s.SourceExchange))
panic(fmt.Errorf("source session %s is not defined", s.SourceExchange))
}
log.Infof("subscribing %s from %s", s.Symbol, s.SourceExchange)
sourceSession.Subscribe(types.BookChannel, s.Symbol, types.SubscribeOptions{})
makerSession, ok := sessions[s.MakerExchange]
if !ok {
panic(fmt.Errorf("maker session %s is not defined", s.MakerExchange))
}
makerSession.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: "1m"})
}
func (s *Strategy) updateQuote(ctx context.Context) {
@ -104,7 +109,7 @@ func (s *Strategy) updateQuote(ctx context.Context) {
}
if valid, err := sourceBook.IsValid(); !valid {
log.WithError(err).Error("invalid order book: %v", err)
log.WithError(err).Errorf("invalid order book: %v", err)
return
}
@ -131,9 +136,18 @@ func (s *Strategy) updateQuote(ctx context.Context) {
makerQuota := &bbgo.QuotaTransaction{}
if b, ok := makerBalances[s.makerMarket.BaseCurrency]; ok {
makerQuota.BaseAsset.Add(b.Available)
if b.Available.Float64() <= s.makerMarket.MinQuantity {
disableMakerAsk = true
}
}
if b, ok := makerBalances[s.makerMarket.QuoteCurrency]; ok {
makerQuota.QuoteAsset.Add(b.Available)
if b.Available.Float64() <= s.makerMarket.MinNotional {
disableMakerBid = true
}
}
hedgeBalances := s.sourceSession.Account.Balances()
@ -141,6 +155,7 @@ func (s *Strategy) updateQuote(ctx context.Context) {
if b, ok := hedgeBalances[s.sourceMarket.BaseCurrency]; ok {
hedgeQuota.BaseAsset.Add(b.Available)
// to make bid orders, we need enough base asset in the foreign exchange,
// if the base asset balance is not enough for selling
if b.Available.Float64() <= s.sourceMarket.MinQuantity {
disableMakerBid = true
@ -150,12 +165,18 @@ func (s *Strategy) updateQuote(ctx context.Context) {
if b, ok := hedgeBalances[s.sourceMarket.QuoteCurrency]; ok {
hedgeQuota.QuoteAsset.Add(b.Available)
// to make ask orders, we need enough quote asset in the foreign exchange,
// if the quote asset balance is not enough for buying
if b.Available.Float64() <= s.sourceMarket.MinNotional {
disableMakerAsk = true
}
}
if disableMakerAsk && disableMakerBid {
log.Warn("maker is disabled due to insufficient balances")
return
}
for i := 0; i < s.NumLayers; i++ {
// for maker bid orders
if !disableMakerBid {
@ -376,7 +397,7 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
}
// restore state
instanceID := fmt.Sprintf("%s-%s-%s", ID, s.Symbol)
instanceID := fmt.Sprintf("%s-%s", ID, s.Symbol)
s.groupID = generateGroupID(instanceID)
log.Infof("using group id %d from fnv(%s)", s.groupID, instanceID)