mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 14:55:16 +00:00
xmaker: improve balance checking
This commit is contained in:
parent
948e555f51
commit
814a77ea39
|
@ -72,7 +72,7 @@ riskControls:
|
||||||
|
|
||||||
crossExchangeStrategies:
|
crossExchangeStrategies:
|
||||||
|
|
||||||
- mobydick:
|
- xmaker:
|
||||||
symbol: BTCUSDT
|
symbol: BTCUSDT
|
||||||
sourceExchange: binance
|
sourceExchange: binance
|
||||||
makerExchange: max
|
makerExchange: max
|
||||||
|
|
|
@ -63,11 +63,11 @@ riskControls:
|
||||||
|
|
||||||
crossExchangeStrategies:
|
crossExchangeStrategies:
|
||||||
|
|
||||||
- mobydick:
|
- xmaker:
|
||||||
symbol: ETHUSDT
|
symbol: ETHUSDT
|
||||||
sourceExchange: binance
|
sourceExchange: binance
|
||||||
makerExchange: max
|
makerExchange: max
|
||||||
updateInterval: 1s
|
updateInterval: 2s
|
||||||
|
|
||||||
# disableHedge disables the hedge orders on the source exchange
|
# disableHedge disables the hedge orders on the source exchange
|
||||||
# disableHedge: true
|
# disableHedge: true
|
||||||
|
@ -78,7 +78,7 @@ crossExchangeStrategies:
|
||||||
askMargin: 0.004
|
askMargin: 0.004
|
||||||
bidMargin: 0.004
|
bidMargin: 0.004
|
||||||
|
|
||||||
quantity: 0.1
|
quantity: 0.01
|
||||||
quantityMultiplier: 2
|
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
|
# numLayers means how many order we want to place on each side. 3 means we want 3 bid orders and 3 ask orders
|
||||||
|
|
|
@ -49,7 +49,7 @@ sessions:
|
||||||
|
|
||||||
crossExchangeStrategies:
|
crossExchangeStrategies:
|
||||||
|
|
||||||
- mobydick:
|
- xmaker:
|
||||||
symbol: "BTCUSDT"
|
symbol: "BTCUSDT"
|
||||||
sourceExchange: binance
|
sourceExchange: binance
|
||||||
makerExchange: max
|
makerExchange: max
|
||||||
|
|
|
@ -173,6 +173,8 @@ func (trader *Trader) Subscribe() {
|
||||||
for _, strategy := range strategies {
|
for _, strategy := range strategies {
|
||||||
if subscriber, ok := strategy.(ExchangeSessionSubscriber); ok {
|
if subscriber, ok := strategy.(ExchangeSessionSubscriber); ok {
|
||||||
subscriber.Subscribe(session)
|
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 {
|
for _, strategy := range trader.crossExchangeStrategies {
|
||||||
if subscriber, ok := strategy.(CrossExchangeSessionSubscriber); ok {
|
if subscriber, ok := strategy.(CrossExchangeSessionSubscriber); ok {
|
||||||
subscriber.CrossSubscribe(trader.environment.sessions)
|
subscriber.CrossSubscribe(trader.environment.sessions)
|
||||||
|
} else {
|
||||||
|
log.Errorf("strategy %s does not implement CrossExchangeSessionSubscriber", strategy.ID())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,6 @@ import (
|
||||||
_ "github.com/c9s/bbgo/pkg/strategy/support"
|
_ "github.com/c9s/bbgo/pkg/strategy/support"
|
||||||
_ "github.com/c9s/bbgo/pkg/strategy/swing"
|
_ "github.com/c9s/bbgo/pkg/strategy/swing"
|
||||||
_ "github.com/c9s/bbgo/pkg/strategy/trailingstop"
|
_ "github.com/c9s/bbgo/pkg/strategy/trailingstop"
|
||||||
|
_ "github.com/c9s/bbgo/pkg/strategy/xmaker"
|
||||||
_ "github.com/c9s/bbgo/pkg/strategy/xpuremaker"
|
_ "github.com/c9s/bbgo/pkg/strategy/xpuremaker"
|
||||||
)
|
)
|
||||||
|
|
|
@ -501,7 +501,7 @@ func (r *CreateOrderRequest) Do(ctx context.Context) (order *Order, err error) {
|
||||||
payload["group_id"] = r.groupID
|
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 {
|
if err != nil {
|
||||||
return order, errors.Wrapf(err, "order create error")
|
return order, errors.Wrapf(err, "order create error")
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,11 +82,16 @@ type Strategy struct {
|
||||||
func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) {
|
func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) {
|
||||||
sourceSession, ok := sessions[s.SourceExchange]
|
sourceSession, ok := sessions[s.SourceExchange]
|
||||||
if !ok {
|
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{})
|
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) {
|
func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
|
@ -104,7 +109,7 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid, err := sourceBook.IsValid(); !valid {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,9 +136,18 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
makerQuota := &bbgo.QuotaTransaction{}
|
makerQuota := &bbgo.QuotaTransaction{}
|
||||||
if b, ok := makerBalances[s.makerMarket.BaseCurrency]; ok {
|
if b, ok := makerBalances[s.makerMarket.BaseCurrency]; ok {
|
||||||
makerQuota.BaseAsset.Add(b.Available)
|
makerQuota.BaseAsset.Add(b.Available)
|
||||||
|
|
||||||
|
if b.Available.Float64() <= s.makerMarket.MinQuantity {
|
||||||
|
disableMakerAsk = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if b, ok := makerBalances[s.makerMarket.QuoteCurrency]; ok {
|
if b, ok := makerBalances[s.makerMarket.QuoteCurrency]; ok {
|
||||||
makerQuota.QuoteAsset.Add(b.Available)
|
makerQuota.QuoteAsset.Add(b.Available)
|
||||||
|
|
||||||
|
if b.Available.Float64() <= s.makerMarket.MinNotional {
|
||||||
|
disableMakerBid = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hedgeBalances := s.sourceSession.Account.Balances()
|
hedgeBalances := s.sourceSession.Account.Balances()
|
||||||
|
@ -141,6 +155,7 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
if b, ok := hedgeBalances[s.sourceMarket.BaseCurrency]; ok {
|
if b, ok := hedgeBalances[s.sourceMarket.BaseCurrency]; ok {
|
||||||
hedgeQuota.BaseAsset.Add(b.Available)
|
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 the base asset balance is not enough for selling
|
||||||
if b.Available.Float64() <= s.sourceMarket.MinQuantity {
|
if b.Available.Float64() <= s.sourceMarket.MinQuantity {
|
||||||
disableMakerBid = true
|
disableMakerBid = true
|
||||||
|
@ -150,12 +165,18 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
if b, ok := hedgeBalances[s.sourceMarket.QuoteCurrency]; ok {
|
if b, ok := hedgeBalances[s.sourceMarket.QuoteCurrency]; ok {
|
||||||
hedgeQuota.QuoteAsset.Add(b.Available)
|
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 the quote asset balance is not enough for buying
|
||||||
if b.Available.Float64() <= s.sourceMarket.MinNotional {
|
if b.Available.Float64() <= s.sourceMarket.MinNotional {
|
||||||
disableMakerAsk = true
|
disableMakerAsk = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if disableMakerAsk && disableMakerBid {
|
||||||
|
log.Warn("maker is disabled due to insufficient balances")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < s.NumLayers; i++ {
|
for i := 0; i < s.NumLayers; i++ {
|
||||||
// for maker bid orders
|
// for maker bid orders
|
||||||
if !disableMakerBid {
|
if !disableMakerBid {
|
||||||
|
@ -376,7 +397,7 @@ func (s *Strategy) CrossRun(ctx context.Context, _ bbgo.OrderExecutionRouter, se
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore state
|
// restore state
|
||||||
instanceID := fmt.Sprintf("%s-%s-%s", ID, s.Symbol)
|
instanceID := fmt.Sprintf("%s-%s", ID, s.Symbol)
|
||||||
s.groupID = generateGroupID(instanceID)
|
s.groupID = generateGroupID(instanceID)
|
||||||
log.Infof("using group id %d from fnv(%s)", s.groupID, instanceID)
|
log.Infof("using group id %d from fnv(%s)", s.groupID, instanceID)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user