From edc8c132d55b7bcca2b76064541c84a2dc634b1a Mon Sep 17 00:00:00 2001 From: c9s Date: Thu, 8 Sep 2022 23:17:35 +0800 Subject: [PATCH 1/4] pivotshort: print stopEMA protection --- pkg/strategy/pivotshort/failedbreakhigh.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/strategy/pivotshort/failedbreakhigh.go b/pkg/strategy/pivotshort/failedbreakhigh.go index d34415cbe..72e07afff 100644 --- a/pkg/strategy/pivotshort/failedbreakhigh.go +++ b/pkg/strategy/pivotshort/failedbreakhigh.go @@ -199,6 +199,7 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg // stop EMA protection if s.StopEMA != nil { if !s.StopEMA.Allowed(closePrice) { + bbgo.Notify("stopEMA protection: close price %f %s", kline.Close.Float64(), s.StopEMA.String()) return } } From 90f3727d68581114926f1f55efe1ab4435962b86 Mon Sep 17 00:00:00 2001 From: c9s Date: Thu, 8 Sep 2022 23:19:14 +0800 Subject: [PATCH 2/4] pivotshort: log submit order error --- pkg/strategy/pivotshort/failedbreakhigh.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pkg/strategy/pivotshort/failedbreakhigh.go b/pkg/strategy/pivotshort/failedbreakhigh.go index 72e07afff..21574679d 100644 --- a/pkg/strategy/pivotshort/failedbreakhigh.go +++ b/pkg/strategy/pivotshort/failedbreakhigh.go @@ -220,8 +220,8 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg } if s.MarketOrder { - bbgo.Notify("%s price %f failed breaking the previous high %f with ratio %f, submitting market sell to open a short position", symbol, kline.Close.Float64(), previousHigh.Float64(), s.Ratio.Float64()) - _, _ = s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{ + bbgo.Notify("%s price %f failed breaking the previous high %f with ratio %f, submitting market sell %f to open a short position", symbol, kline.Close.Float64(), previousHigh.Float64(), s.Ratio.Float64(), quantity.Float64()) + _, err := s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{ Symbol: s.Symbol, Side: types.SideTypeSell, Type: types.OrderTypeMarket, @@ -229,12 +229,15 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg MarginSideEffect: types.SideEffectTypeMarginBuy, Tag: "FailedBreakHighMarket", }) + if err != nil { + bbgo.Notify(err.Error()) + } } else { sellPrice := previousHigh bbgo.Notify("%s price %f failed breaking the previous high %f with ratio %f, submitting limit sell @ %f", symbol, kline.Close.Float64(), previousHigh.Float64(), s.Ratio.Float64(), sellPrice.Float64()) - _, _ = s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{ + _, err := s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{ Symbol: kline.Symbol, Side: types.SideTypeSell, Type: types.OrderTypeLimit, @@ -243,6 +246,10 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg MarginSideEffect: types.SideEffectTypeMarginBuy, Tag: "FailedBreakHighLimit", }) + + if err != nil { + bbgo.Notify(err.Error()) + } } })) } From 2e9524668722904a2786d61c55e97ab51bd1b042 Mon Sep 17 00:00:00 2001 From: c9s Date: Fri, 9 Sep 2022 13:57:39 +0800 Subject: [PATCH 3/4] bbgo: add OpenPosition method --- pkg/bbgo/order_executor_general.go | 92 +++++++++++++++++++++++++++++ pkg/risk/account_value.go | 8 ++- pkg/strategy/supertrend/strategy.go | 2 +- 3 files changed, 98 insertions(+), 4 deletions(-) diff --git a/pkg/bbgo/order_executor_general.go b/pkg/bbgo/order_executor_general.go index d8d8347ff..da679e8b4 100644 --- a/pkg/bbgo/order_executor_general.go +++ b/pkg/bbgo/order_executor_general.go @@ -2,12 +2,14 @@ package bbgo import ( "context" + "errors" "fmt" "strings" log "github.com/sirupsen/logrus" "github.com/c9s/bbgo/pkg/fixedpoint" + "github.com/c9s/bbgo/pkg/risk" "github.com/c9s/bbgo/pkg/types" ) @@ -128,6 +130,96 @@ func (e *GeneralOrderExecutor) SubmitOrders(ctx context.Context, submitOrders .. return createdOrders, err } +type OpenPositionOptions struct { + // Long is for open a long position + // Long or Short must be set + Long bool + + // Short is for open a short position + // Long or Short must be set + Short bool + + // Leverage is used for leveraged position and account + Leverage fixedpoint.Value + + Quantity fixedpoint.Value + MarketOrder bool + LimitOrder bool + LimitTakerRatio fixedpoint.Value + CurrentPrice fixedpoint.Value + Tag string +} + +func (e *GeneralOrderExecutor) OpenPosition(ctx context.Context, options OpenPositionOptions) error { + price := options.CurrentPrice + submitOrder := types.SubmitOrder{ + Symbol: e.position.Symbol, + Type: types.OrderTypeMarket, + MarginSideEffect: types.SideEffectTypeMarginBuy, + Tag: options.Tag, + } + + if !options.LimitTakerRatio.IsZero() { + if options.Long { + // use higher price to buy (this ensures that our order will be filled) + price = price.Mul(one.Add(options.LimitTakerRatio)) + } else if options.Short { + // use lower price to sell (this ensures that our order will be filled) + price = price.Mul(one.Sub(options.LimitTakerRatio)) + } + } + + if options.MarketOrder { + submitOrder.Type = types.OrderTypeMarket + } else if options.LimitOrder { + submitOrder.Type = types.OrderTypeLimit + submitOrder.Price = price + } + + quantity := options.Quantity + + if options.Long { + if quantity.IsZero() { + quoteQuantity, err := risk.CalculateQuoteQuantity(ctx, e.session, e.position.QuoteCurrency, options.Leverage) + if err != nil { + return err + } + + quantity = quoteQuantity.Div(price) + } + + submitOrder.Side = types.SideTypeBuy + submitOrder.Quantity = quantity + + createdOrder, err2 := e.SubmitOrders(ctx, submitOrder) + if err2 != nil { + return err2 + } + _ = createdOrder + return nil + } else if options.Short { + if quantity.IsZero() { + var err error + quantity, err = risk.CalculateBaseQuantity(e.session, e.position.Market, price, quantity, options.Leverage) + if err != nil { + return err + } + } + + submitOrder.Side = types.SideTypeSell + submitOrder.Quantity = quantity + + createdOrder, err2 := e.SubmitOrders(ctx, submitOrder) + if err2 != nil { + return err2 + } + _ = createdOrder + return nil + } + + return errors.New("options Long or Short must be set") +} + // GracefulCancelActiveOrderBook cancels the orders from the active orderbook. func (e *GeneralOrderExecutor) GracefulCancelActiveOrderBook(ctx context.Context, activeOrders *ActiveOrderBook) error { if activeOrders.NumOfOrders() == 0 { diff --git a/pkg/risk/account_value.go b/pkg/risk/account_value.go index 2f17f9fe2..d8c4f718a 100644 --- a/pkg/risk/account_value.go +++ b/pkg/risk/account_value.go @@ -16,6 +16,8 @@ var log = logrus.WithField("risk", "AccountValueCalculator") var one = fixedpoint.One +var defaultLeverage = fixedpoint.NewFromInt(3) + var maxLeverage = fixedpoint.NewFromInt(10) type AccountValueCalculator struct { @@ -191,7 +193,7 @@ func (c *AccountValueCalculator) MarginLevel(ctx context.Context) (fixedpoint.Va func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) { // default leverage guard if leverage.IsZero() { - leverage = fixedpoint.NewFromInt(3) + leverage = defaultLeverage } baseBalance, _ := session.Account.Balance(market.BaseCurrency) @@ -271,10 +273,10 @@ func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, p return quantity, fmt.Errorf("quantity is zero, can not submit sell order, please check your settings") } -func CalculateQuoteQuantity(session *bbgo.ExchangeSession, ctx context.Context, quoteCurrency string, leverage fixedpoint.Value) (fixedpoint.Value, error) { +func CalculateQuoteQuantity(ctx context.Context, session *bbgo.ExchangeSession, quoteCurrency string, leverage fixedpoint.Value) (fixedpoint.Value, error) { // default leverage guard if leverage.IsZero() { - leverage = fixedpoint.NewFromInt(3) + leverage = defaultLeverage } quoteBalance, _ := session.Account.Balance(quoteCurrency) diff --git a/pkg/strategy/supertrend/strategy.go b/pkg/strategy/supertrend/strategy.go index bc4f632dc..1c70be8fb 100644 --- a/pkg/strategy/supertrend/strategy.go +++ b/pkg/strategy/supertrend/strategy.go @@ -389,7 +389,7 @@ func (s *Strategy) calculateQuantity(ctx context.Context, currentPrice fixedpoin return balance.Available.Mul(fixedpoint.Min(s.Leverage, fixedpoint.One)) } else { // Using leverage or spot buy - quoteQty, err := risk.CalculateQuoteQuantity(s.session, ctx, s.Market.QuoteCurrency, s.Leverage) + quoteQty, err := risk.CalculateQuoteQuantity(ctx, s.session, s.Market.QuoteCurrency, s.Leverage) if err != nil { log.WithError(err).Errorf("can not update %s quote balance from exchange", s.Symbol) return fixedpoint.Zero From 8dca24e9eeda4cb8f05c0b5d88b6b5fbd95ae280 Mon Sep 17 00:00:00 2001 From: c9s Date: Fri, 9 Sep 2022 17:40:17 +0800 Subject: [PATCH 4/4] all: solve cyclic import --- pkg/bbgo/environment.go | 6 +-- pkg/bbgo/log.go | 1 + pkg/bbgo/order_executor_general.go | 5 +-- pkg/{risk/account_value.go => bbgo/risk.go} | 37 +++++++++---------- .../risk_test.go} | 9 ++--- pkg/strategy/pivotshort/breaklow.go | 5 +-- pkg/strategy/pivotshort/failedbreakhigh.go | 5 +-- pkg/strategy/pivotshort/resistance.go | 3 +- pkg/strategy/supertrend/strategy.go | 13 +++---- 9 files changed, 38 insertions(+), 46 deletions(-) create mode 100644 pkg/bbgo/log.go rename pkg/{risk/account_value.go => bbgo/risk.go} (81%) rename pkg/{risk/account_value_test.go => bbgo/risk_test.go} (95%) diff --git a/pkg/bbgo/environment.go b/pkg/bbgo/environment.go index cc85b13e4..76426b756 100644 --- a/pkg/bbgo/environment.go +++ b/pkg/bbgo/environment.go @@ -21,7 +21,7 @@ import ( "github.com/spf13/viper" "gopkg.in/tucnak/telebot.v2" - exchange2 "github.com/c9s/bbgo/pkg/exchange" + "github.com/c9s/bbgo/pkg/exchange" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/interact" "github.com/c9s/bbgo/pkg/notifier/slacknotifier" @@ -223,12 +223,12 @@ func (environ *Environment) ConfigureExchangeSessions(userConfig *Config) error func (environ *Environment) AddExchangesByViperKeys() error { for _, n := range types.SupportedExchanges { if viper.IsSet(string(n) + "-api-key") { - exchange, err := exchange2.NewWithEnvVarPrefix(n, "") + ex, err := exchange.NewWithEnvVarPrefix(n, "") if err != nil { return err } - environ.AddExchange(n.String(), exchange) + environ.AddExchange(n.String(), ex) } } diff --git a/pkg/bbgo/log.go b/pkg/bbgo/log.go new file mode 100644 index 000000000..f30d11b65 --- /dev/null +++ b/pkg/bbgo/log.go @@ -0,0 +1 @@ +package bbgo diff --git a/pkg/bbgo/order_executor_general.go b/pkg/bbgo/order_executor_general.go index da679e8b4..64c07d7db 100644 --- a/pkg/bbgo/order_executor_general.go +++ b/pkg/bbgo/order_executor_general.go @@ -9,7 +9,6 @@ import ( log "github.com/sirupsen/logrus" "github.com/c9s/bbgo/pkg/fixedpoint" - "github.com/c9s/bbgo/pkg/risk" "github.com/c9s/bbgo/pkg/types" ) @@ -180,7 +179,7 @@ func (e *GeneralOrderExecutor) OpenPosition(ctx context.Context, options OpenPos if options.Long { if quantity.IsZero() { - quoteQuantity, err := risk.CalculateQuoteQuantity(ctx, e.session, e.position.QuoteCurrency, options.Leverage) + quoteQuantity, err := CalculateQuoteQuantity(ctx, e.session, e.position.QuoteCurrency, options.Leverage) if err != nil { return err } @@ -200,7 +199,7 @@ func (e *GeneralOrderExecutor) OpenPosition(ctx context.Context, options OpenPos } else if options.Short { if quantity.IsZero() { var err error - quantity, err = risk.CalculateBaseQuantity(e.session, e.position.Market, price, quantity, options.Leverage) + quantity, err = CalculateBaseQuantity(e.session, e.position.Market, price, quantity, options.Leverage) if err != nil { return err } diff --git a/pkg/risk/account_value.go b/pkg/bbgo/risk.go similarity index 81% rename from pkg/risk/account_value.go rename to pkg/bbgo/risk.go index d8c4f718a..a28617f53 100644 --- a/pkg/risk/account_value.go +++ b/pkg/bbgo/risk.go @@ -1,34 +1,30 @@ -package risk +package bbgo import ( "context" "fmt" "time" - "github.com/sirupsen/logrus" + log "github.com/sirupsen/logrus" - "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" + "github.com/c9s/bbgo/pkg/risk" "github.com/c9s/bbgo/pkg/types" ) -var log = logrus.WithField("risk", "AccountValueCalculator") - -var one = fixedpoint.One - var defaultLeverage = fixedpoint.NewFromInt(3) var maxLeverage = fixedpoint.NewFromInt(10) type AccountValueCalculator struct { - session *bbgo.ExchangeSession + session *ExchangeSession quoteCurrency string prices map[string]fixedpoint.Value tickers map[string]types.Ticker updateTime time.Time } -func NewAccountValueCalculator(session *bbgo.ExchangeSession, quoteCurrency string) *AccountValueCalculator { +func NewAccountValueCalculator(session *ExchangeSession, quoteCurrency string) *AccountValueCalculator { return &AccountValueCalculator{ session: session, quoteCurrency: quoteCurrency, @@ -190,7 +186,7 @@ func (c *AccountValueCalculator) MarginLevel(ctx context.Context) (fixedpoint.Va return marginLevel, nil } -func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) { +func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) { // default leverage guard if leverage.IsZero() { leverage = defaultLeverage @@ -205,7 +201,7 @@ func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, p balance, hasBalance := session.Account.Balance(market.BaseCurrency) if hasBalance { if quantity.IsZero() { - logrus.Warnf("sell quantity is not set, using all available base balance: %v", balance) + log.Warnf("sell quantity is not set, using all available base balance: %v", balance) if !balance.Available.IsZero() { return balance.Available, nil } @@ -222,7 +218,7 @@ func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, p } // using leverage -- starts from here - logrus.Infof("calculating available leveraged base quantity: base balance = %+v, quote balance = %+v", baseBalance, quoteBalance) + log.Infof("calculating available leveraged base quantity: base balance = %+v, quote balance = %+v", baseBalance, quoteBalance) // calculate the quantity automatically if session.Margin || session.IsolatedMargin { @@ -232,22 +228,22 @@ func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, p // avoid using all account value since there will be some trade loss for interests and the fee accountValue = accountValue.Mul(one.Sub(fixedpoint.NewFromFloat(0.01))) - logrus.Infof("calculated account value %f %s", accountValue.Float64(), market.QuoteCurrency) + log.Infof("calculated account value %f %s", accountValue.Float64(), market.QuoteCurrency) if session.IsolatedMargin { originLeverage := leverage leverage = fixedpoint.Min(leverage, maxLeverage) - logrus.Infof("using isolated margin, maxLeverage=10 originalLeverage=%f currentLeverage=%f", + log.Infof("using isolated margin, maxLeverage=10 originalLeverage=%f currentLeverage=%f", originLeverage.Float64(), leverage.Float64()) } // spot margin use the equity value, so we use the total quote balance here - maxPosition := CalculateMaxPosition(price, accountValue, leverage) + maxPosition := risk.CalculateMaxPosition(price, accountValue, leverage) debt := baseBalance.Debt() maxQuantity := maxPosition.Sub(debt) - logrus.Infof("margin leverage: calculated maxQuantity=%f maxPosition=%f debt=%f price=%f accountValue=%f %s leverage=%f", + log.Infof("margin leverage: calculated maxQuantity=%f maxPosition=%f debt=%f price=%f accountValue=%f %s leverage=%f", maxQuantity.Float64(), maxPosition.Float64(), debt.Float64(), @@ -261,8 +257,8 @@ func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, p if session.Futures || session.IsolatedFutures { // TODO: get mark price here - maxPositionQuantity := CalculateMaxPosition(price, quoteBalance.Available, leverage) - requiredPositionCost := CalculatePositionCost(price, price, maxPositionQuantity, leverage, types.SideTypeSell) + maxPositionQuantity := risk.CalculateMaxPosition(price, quoteBalance.Available, leverage) + requiredPositionCost := risk.CalculatePositionCost(price, price, maxPositionQuantity, leverage, types.SideTypeSell) if quoteBalance.Available.Compare(requiredPositionCost) < 0 { return maxPositionQuantity, fmt.Errorf("available margin %f %s is not enough, can not submit order", quoteBalance.Available.Float64(), market.QuoteCurrency) } @@ -273,7 +269,7 @@ func CalculateBaseQuantity(session *bbgo.ExchangeSession, market types.Market, p return quantity, fmt.Errorf("quantity is zero, can not submit sell order, please check your settings") } -func CalculateQuoteQuantity(ctx context.Context, session *bbgo.ExchangeSession, quoteCurrency string, leverage fixedpoint.Value) (fixedpoint.Value, error) { +func CalculateQuoteQuantity(ctx context.Context, session *ExchangeSession, quoteCurrency string, leverage fixedpoint.Value) (fixedpoint.Value, error) { // default leverage guard if leverage.IsZero() { leverage = defaultLeverage @@ -294,7 +290,8 @@ func CalculateQuoteQuantity(ctx context.Context, session *bbgo.ExchangeSession, log.WithError(err).Errorf("can not update available quote") return fixedpoint.Zero, err } - logrus.Infof("calculating available leveraged quote quantity: account available quote = %+v", availableQuote) + + log.Infof("calculating available leveraged quote quantity: account available quote = %+v", availableQuote) return availableQuote.Mul(leverage), nil } diff --git a/pkg/risk/account_value_test.go b/pkg/bbgo/risk_test.go similarity index 95% rename from pkg/risk/account_value_test.go rename to pkg/bbgo/risk_test.go index 940ae0b45..fcd9f532b 100644 --- a/pkg/risk/account_value_test.go +++ b/pkg/bbgo/risk_test.go @@ -1,4 +1,4 @@ -package risk +package bbgo import ( "context" @@ -8,7 +8,6 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types/mocks" @@ -40,7 +39,7 @@ func TestAccountValueCalculator_NetValue(t *testing.T) { "BTCUSDT": newTestTicker(), }, nil) - session := bbgo.NewExchangeSession("test", mockEx) + session := NewExchangeSession("test", mockEx) session.Account.UpdateBalances(types.BalanceMap{ "BTC": { Currency: "BTC", @@ -81,7 +80,7 @@ func TestAccountValueCalculator_NetValue(t *testing.T) { "BTCUSDT": newTestTicker(), }, nil) - session := bbgo.NewExchangeSession("test", mockEx) + session := NewExchangeSession("test", mockEx) session.Account.UpdateBalances(types.BalanceMap{ "BTC": { Currency: "BTC", @@ -123,7 +122,7 @@ func TestNewAccountValueCalculator_MarginLevel(t *testing.T) { "BTCUSDT": newTestTicker(), }, nil) - session := bbgo.NewExchangeSession("test", mockEx) + session := NewExchangeSession("test", mockEx) session.Account.UpdateBalances(types.BalanceMap{ "BTC": { Currency: "BTC", diff --git a/pkg/strategy/pivotshort/breaklow.go b/pkg/strategy/pivotshort/breaklow.go index cecc56c86..3f52deead 100644 --- a/pkg/strategy/pivotshort/breaklow.go +++ b/pkg/strategy/pivotshort/breaklow.go @@ -6,7 +6,6 @@ import ( "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/indicator" - "github.com/c9s/bbgo/pkg/risk" "github.com/c9s/bbgo/pkg/types" ) @@ -197,7 +196,7 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener // graceful cancel all active orders _ = orderExecutor.GracefulCancel(ctx) - quantity, err := risk.CalculateBaseQuantity(s.session, s.Market, closePrice, s.Quantity, s.Leverage) + quantity, err := bbgo.CalculateBaseQuantity(s.session, s.Market, closePrice, s.Quantity, s.Leverage) if err != nil { log.WithError(err).Errorf("quantity calculation error") } @@ -241,7 +240,7 @@ func (s *BreakLow) pilotQuantityCalculation() { s.Quantity.Float64(), s.Leverage.Float64()) - quantity, err := risk.CalculateBaseQuantity(s.session, s.Market, s.lastLow, s.Quantity, s.Leverage) + quantity, err := bbgo.CalculateBaseQuantity(s.session, s.Market, s.lastLow, s.Quantity, s.Leverage) if err != nil { log.WithError(err).Errorf("quantity calculation error") } diff --git a/pkg/strategy/pivotshort/failedbreakhigh.go b/pkg/strategy/pivotshort/failedbreakhigh.go index 21574679d..58562976e 100644 --- a/pkg/strategy/pivotshort/failedbreakhigh.go +++ b/pkg/strategy/pivotshort/failedbreakhigh.go @@ -6,7 +6,6 @@ import ( "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/indicator" - "github.com/c9s/bbgo/pkg/risk" "github.com/c9s/bbgo/pkg/types" ) @@ -209,7 +208,7 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg // graceful cancel all active orders _ = orderExecutor.GracefulCancel(ctx) - quantity, err := risk.CalculateBaseQuantity(s.session, s.Market, closePrice, s.Quantity, s.Leverage) + quantity, err := bbgo.CalculateBaseQuantity(s.session, s.Market, closePrice, s.Quantity, s.Leverage) if err != nil { log.WithError(err).Errorf("quantity calculation error") } @@ -260,7 +259,7 @@ func (s *FailedBreakHigh) pilotQuantityCalculation() { s.Quantity.Float64(), s.Leverage.Float64()) - quantity, err := risk.CalculateBaseQuantity(s.session, s.Market, s.lastHigh, s.Quantity, s.Leverage) + quantity, err := bbgo.CalculateBaseQuantity(s.session, s.Market, s.lastHigh, s.Quantity, s.Leverage) if err != nil { log.WithError(err).Errorf("quantity calculation error") } diff --git a/pkg/strategy/pivotshort/resistance.go b/pkg/strategy/pivotshort/resistance.go index 8ee4c2c5d..1a7c04ae0 100644 --- a/pkg/strategy/pivotshort/resistance.go +++ b/pkg/strategy/pivotshort/resistance.go @@ -7,7 +7,6 @@ import ( "github.com/c9s/bbgo/pkg/datatype/floats" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/indicator" - "github.com/c9s/bbgo/pkg/risk" "github.com/c9s/bbgo/pkg/types" ) @@ -128,7 +127,7 @@ func (s *ResistanceShort) updateResistanceOrders(closePrice fixedpoint.Value) { } func (s *ResistanceShort) placeResistanceOrders(ctx context.Context, resistancePrice fixedpoint.Value) { - totalQuantity, err := risk.CalculateBaseQuantity(s.session, s.Market, resistancePrice, s.Quantity, s.Leverage) + totalQuantity, err := bbgo.CalculateBaseQuantity(s.session, s.Market, resistancePrice, s.Quantity, s.Leverage) if err != nil { log.WithError(err).Errorf("quantity calculation error") } diff --git a/pkg/strategy/supertrend/strategy.go b/pkg/strategy/supertrend/strategy.go index 1c70be8fb..ae99aadfe 100644 --- a/pkg/strategy/supertrend/strategy.go +++ b/pkg/strategy/supertrend/strategy.go @@ -6,13 +6,12 @@ import ( "os" "sync" - "github.com/c9s/bbgo/pkg/data/tsv" - "github.com/c9s/bbgo/pkg/datatype/floats" - "github.com/c9s/bbgo/pkg/risk" - "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/c9s/bbgo/pkg/data/tsv" + "github.com/c9s/bbgo/pkg/datatype/floats" + "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/indicator" @@ -173,7 +172,7 @@ type Strategy struct { Leverage fixedpoint.Value `json:"leverage"` // Quantity sets the fixed order qty, takes precedence over Leverage Quantity fixedpoint.Value `json:"quantity"` - AccountValueCalculator *risk.AccountValueCalculator + AccountValueCalculator *bbgo.AccountValueCalculator // TakeProfitAtrMultiplier TP according to ATR multiple, 0 to disable this TakeProfitAtrMultiplier float64 `json:"takeProfitAtrMultiplier"` @@ -389,7 +388,7 @@ func (s *Strategy) calculateQuantity(ctx context.Context, currentPrice fixedpoin return balance.Available.Mul(fixedpoint.Min(s.Leverage, fixedpoint.One)) } else { // Using leverage or spot buy - quoteQty, err := risk.CalculateQuoteQuantity(ctx, s.session, s.Market.QuoteCurrency, s.Leverage) + quoteQty, err := bbgo.CalculateQuoteQuantity(ctx, s.session, s.Market.QuoteCurrency, s.Leverage) if err != nil { log.WithError(err).Errorf("can not update %s quote balance from exchange", s.Symbol) return fixedpoint.Zero @@ -449,7 +448,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se s.orderExecutor.Bind() // AccountValueCalculator - s.AccountValueCalculator = risk.NewAccountValueCalculator(s.session, s.Market.QuoteCurrency) + s.AccountValueCalculator = bbgo.NewAccountValueCalculator(s.session, s.Market.QuoteCurrency) // Accumulated profit report if bbgo.IsBackTesting {