From d85da78e17b2976fec5441da81cb5594c6cea9c9 Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 1 Sep 2024 00:58:50 +0800 Subject: [PATCH 1/6] xmaker: improve hedge account credit calculation --- pkg/strategy/xmaker/strategy.go | 49 ++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/pkg/strategy/xmaker/strategy.go b/pkg/strategy/xmaker/strategy.go index 680c910f0..8c3478ee7 100644 --- a/pkg/strategy/xmaker/strategy.go +++ b/pkg/strategy/xmaker/strategy.go @@ -503,6 +503,10 @@ func (s *Strategy) updateQuote(ctx context.Context) { !hedgeAccount.MarginLevel.IsZero() { if hedgeAccount.MarginLevel.Compare(s.MinMarginLevel) < 0 { + s.logger.Infof("hedge account margin level %s is less then the min margin level %s, calculating the borrowed positions", + hedgeAccount.MarginLevel.String(), + s.MinMarginLevel.String()) + if quote, ok := hedgeAccount.Balance(s.sourceMarket.QuoteCurrency); ok { quoteDebt := quote.Debt() if quoteDebt.Sign() > 0 { @@ -517,22 +521,41 @@ func (s *Strategy) updateQuote(ctx context.Context) { } } } else { - // credit buffer - creditBufferRatio := fixedpoint.NewFromFloat(1.2) - if quote, ok := hedgeAccount.Balance(s.sourceMarket.QuoteCurrency); ok { - netQuote := quote.Net() - if netQuote.Sign() > 0 { - hedgeQuota.QuoteAsset.Add(netQuote.Mul(creditBufferRatio)) - } - } + s.logger.Infof("hedge account margin level %s is greater than the min margin level %s, calculating the net value", + hedgeAccount.MarginLevel.String(), + s.MinMarginLevel.String()) - if base, ok := hedgeAccount.Balance(s.sourceMarket.BaseCurrency); ok { - netBase := base.Net() - if netBase.Sign() > 0 { - hedgeQuota.BaseAsset.Add(netBase.Mul(creditBufferRatio)) + netValueInUsd, calcErr := s.accountValueCalculator.NetValue(ctx) + if calcErr != nil { + s.logger.WithError(calcErr).Errorf("unable to calculate the net value") + } else { + // calculate credit buffer + s.logger.Infof("hedge account net value in usd: %f", netValueInUsd.Float64()) + + if quote, ok := hedgeAccount.Balance(s.sourceMarket.QuoteCurrency); ok { + debt := quote.Debt() + quota := netValueInUsd.Sub(debt) + + s.logger.Infof("hedge account quote balance: %s, debt: %s, quota: %s", + quote.String(), + debt.String(), + quota.String()) + + hedgeQuota.QuoteAsset.Add(quota) + } + + if base, ok := hedgeAccount.Balance(s.sourceMarket.BaseCurrency); ok { + debt := base.Debt() + quota := netValueInUsd.Div(bestAsk.Price).Sub(debt) + + s.logger.Infof("hedge account base balance: %s, debt: %s, quota: %s", + base.String(), + debt.String(), + quota.String()) + + hedgeQuota.BaseAsset.Add(quota) } } - // netValueInUsd, err := s.accountValueCalculator.NetValue(ctx) } } else { From 8b1306a6a6bc38634632a06eb78a164c1196f4fc Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 1 Sep 2024 01:31:50 +0800 Subject: [PATCH 2/6] xmaker: calculate maximum leveraged account value --- pkg/strategy/xmaker/strategy.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/strategy/xmaker/strategy.go b/pkg/strategy/xmaker/strategy.go index 8c3478ee7..098c222d4 100644 --- a/pkg/strategy/xmaker/strategy.go +++ b/pkg/strategy/xmaker/strategy.go @@ -532,6 +532,11 @@ func (s *Strategy) updateQuote(ctx context.Context) { // calculate credit buffer s.logger.Infof("hedge account net value in usd: %f", netValueInUsd.Float64()) + maximumHedgeAccountLeverage := fixedpoint.NewFromFloat(1.2) + netValueInUsd = netValueInUsd.Mul(maximumHedgeAccountLeverage) + + s.logger.Infof("hedge account maximum leveraged value in usd: %f", netValueInUsd.Float64()) + if quote, ok := hedgeAccount.Balance(s.sourceMarket.QuoteCurrency); ok { debt := quote.Debt() quota := netValueInUsd.Sub(debt) From ad6056834ee81cb9b71b1d71ab68a9e94ef7d4dd Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 1 Sep 2024 01:34:25 +0800 Subject: [PATCH 3/6] xmaker: separate maximumValueInUsd in a new var --- pkg/strategy/xmaker/strategy.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/strategy/xmaker/strategy.go b/pkg/strategy/xmaker/strategy.go index 098c222d4..fd58422bc 100644 --- a/pkg/strategy/xmaker/strategy.go +++ b/pkg/strategy/xmaker/strategy.go @@ -533,13 +533,13 @@ func (s *Strategy) updateQuote(ctx context.Context) { s.logger.Infof("hedge account net value in usd: %f", netValueInUsd.Float64()) maximumHedgeAccountLeverage := fixedpoint.NewFromFloat(1.2) - netValueInUsd = netValueInUsd.Mul(maximumHedgeAccountLeverage) + maximumValueInUsd := netValueInUsd.Mul(maximumHedgeAccountLeverage) - s.logger.Infof("hedge account maximum leveraged value in usd: %f", netValueInUsd.Float64()) + s.logger.Infof("hedge account maximum leveraged value in usd: %f", maximumValueInUsd.Float64()) if quote, ok := hedgeAccount.Balance(s.sourceMarket.QuoteCurrency); ok { debt := quote.Debt() - quota := netValueInUsd.Sub(debt) + quota := maximumValueInUsd.Sub(debt) s.logger.Infof("hedge account quote balance: %s, debt: %s, quota: %s", quote.String(), @@ -551,7 +551,7 @@ func (s *Strategy) updateQuote(ctx context.Context) { if base, ok := hedgeAccount.Balance(s.sourceMarket.BaseCurrency); ok { debt := base.Debt() - quota := netValueInUsd.Div(bestAsk.Price).Sub(debt) + quota := maximumValueInUsd.Div(bestAsk.Price).Sub(debt) s.logger.Infof("hedge account base balance: %s, debt: %s, quota: %s", base.String(), From ed073264f18df8b1b7ede34c90f3a67b65302be9 Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 1 Sep 2024 15:42:36 +0800 Subject: [PATCH 4/6] xmaker: add MaxHedgeAccountLeverage option --- pkg/strategy/xmaker/strategy.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/strategy/xmaker/strategy.go b/pkg/strategy/xmaker/strategy.go index fd58422bc..f78a434ca 100644 --- a/pkg/strategy/xmaker/strategy.go +++ b/pkg/strategy/xmaker/strategy.go @@ -119,6 +119,8 @@ type Strategy struct { // MaxExposurePosition defines the unhedged quantity of stop MaxExposurePosition fixedpoint.Value `json:"maxExposurePosition"` + MaxHedgeAccountLeverage fixedpoint.Value `json:"maxHedgeAccountLeverage"` + DisableHedge bool `json:"disableHedge"` NotifyTrade bool `json:"notifyTrade"` @@ -532,10 +534,9 @@ func (s *Strategy) updateQuote(ctx context.Context) { // calculate credit buffer s.logger.Infof("hedge account net value in usd: %f", netValueInUsd.Float64()) - maximumHedgeAccountLeverage := fixedpoint.NewFromFloat(1.2) - maximumValueInUsd := netValueInUsd.Mul(maximumHedgeAccountLeverage) + maximumValueInUsd := netValueInUsd.Mul(s.MaxHedgeAccountLeverage) - s.logger.Infof("hedge account maximum leveraged value in usd: %f", maximumValueInUsd.Float64()) + s.logger.Infof("hedge account maximum leveraged value in usd: %f (%f x)", maximumValueInUsd.Float64(), s.MaxHedgeAccountLeverage.Float64()) if quote, ok := hedgeAccount.Balance(s.sourceMarket.QuoteCurrency); ok { debt := quote.Debt() @@ -562,7 +563,6 @@ func (s *Strategy) updateQuote(ctx context.Context) { } } } - } else { if b, ok := hedgeBalances[s.sourceMarket.BaseCurrency]; ok { // to make bid orders, we need enough base asset in the foreign exchange, @@ -1037,6 +1037,10 @@ func (s *Strategy) Defaults() error { s.MinMarginLevel = fixedpoint.NewFromFloat(3.0) } + if s.MaxHedgeAccountLeverage.IsZero() { + s.MaxHedgeAccountLeverage = fixedpoint.NewFromFloat(1.2) + } + if s.BidMargin.IsZero() { if !s.Margin.IsZero() { s.BidMargin = s.Margin From a4833524cf0c8c006e147ece186c177531883eec Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 1 Sep 2024 16:41:16 +0800 Subject: [PATCH 5/6] xmaker: add more logs --- pkg/strategy/xmaker/strategy.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkg/strategy/xmaker/strategy.go b/pkg/strategy/xmaker/strategy.go index f78a434ca..3f88a40ee 100644 --- a/pkg/strategy/xmaker/strategy.go +++ b/pkg/strategy/xmaker/strategy.go @@ -481,6 +481,7 @@ func (s *Strategy) updateQuote(ctx context.Context) { makerQuota.BaseAsset.Add(b.Available) } else { disableMakerAsk = true + s.logger.Infof("%s maker ask disabled: insufficient base balance %s", s.Symbol, b.String()) } } @@ -489,6 +490,7 @@ func (s *Strategy) updateQuote(ctx context.Context) { makerQuota.QuoteAsset.Add(b.Available) } else { disableMakerBid = true + s.logger.Infof("%s maker bid disabled: insufficient quote balance %s", s.Symbol, b.String()) } } @@ -572,13 +574,13 @@ func (s *Strategy) updateQuote(ctx context.Context) { if b.Available.Compare(minAvailable) > 0 { hedgeQuota.BaseAsset.Add(b.Available.Sub(minAvailable)) } else { - s.logger.Warnf("%s maker bid disabled: insufficient base balance %s", s.Symbol, b.String()) + s.logger.Warnf("%s maker bid disabled: insufficient hedge base balance %s", s.Symbol, b.String()) disableMakerBid = true } } else if b.Available.Compare(s.sourceMarket.MinQuantity) > 0 { hedgeQuota.BaseAsset.Add(b.Available) } else { - s.logger.Warnf("%s maker bid disabled: insufficient base balance %s", s.Symbol, b.String()) + s.logger.Warnf("%s maker bid disabled: insufficient hedge base balance %s", s.Symbol, b.String()) disableMakerBid = true } } @@ -591,17 +593,16 @@ func (s *Strategy) updateQuote(ctx context.Context) { if b.Available.Compare(minAvailable) > 0 { hedgeQuota.QuoteAsset.Add(b.Available.Sub(minAvailable)) } else { - s.logger.Warnf("%s maker ask disabled: insufficient quote balance %s", s.Symbol, b.String()) + s.logger.Warnf("%s maker ask disabled: insufficient hedge quote balance %s", s.Symbol, b.String()) disableMakerAsk = true } } else if b.Available.Compare(s.sourceMarket.MinNotional) > 0 { hedgeQuota.QuoteAsset.Add(b.Available) } else { - s.logger.Warnf("%s maker ask disabled: insufficient quote balance %s", s.Symbol, b.String()) + s.logger.Warnf("%s maker ask disabled: insufficient hedge quote balance %s", s.Symbol, b.String()) disableMakerAsk = true } } - } // if max exposure position is configured, we should not: From 4d1c357c3d092afb8dfa5cd7a35911771ed6a03a Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 1 Sep 2024 17:54:32 +0800 Subject: [PATCH 6/6] xmaker: reuse makerMarket field --- pkg/strategy/xmaker/strategy.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/strategy/xmaker/strategy.go b/pkg/strategy/xmaker/strategy.go index 3f88a40ee..948b5bf65 100644 --- a/pkg/strategy/xmaker/strategy.go +++ b/pkg/strategy/xmaker/strategy.go @@ -1300,9 +1300,8 @@ func (s *Strategy) CrossRun( return errors.New("tradesSince time can not be zero") } - makerMarket, _ := makerSession.Market(s.Symbol) - position := types.NewPositionFromMarket(makerMarket) - profitStats := types.NewProfitStats(makerMarket) + position := types.NewPositionFromMarket(s.makerMarket) + profitStats := types.NewProfitStats(s.makerMarket) fixer := common.NewProfitFixer() // fixer.ConverterManager = s.ConverterManager @@ -1317,7 +1316,7 @@ func (s *Strategy) CrossRun( fixer.AddExchange(sourceSession.Name, ss) } - if err2 := fixer.Fix(ctx, makerMarket.Symbol, + if err2 := fixer.Fix(ctx, s.makerMarket.Symbol, s.ProfitFixerConfig.TradesSince.Time(), time.Now(), profitStats,