mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
pivotshort: improve useQuantityOrBaseBalance
This commit is contained in:
parent
0ba529cb45
commit
6c91af2392
|
@ -2,10 +2,12 @@ package pivotshort
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/bbgo"
|
"github.com/c9s/bbgo/pkg/bbgo"
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
"github.com/c9s/bbgo/pkg/indicator"
|
"github.com/c9s/bbgo/pkg/indicator"
|
||||||
|
"github.com/c9s/bbgo/pkg/risk"
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -168,7 +170,16 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
|
||||||
// graceful cancel all active orders
|
// graceful cancel all active orders
|
||||||
_ = orderExecutor.GracefulCancel(ctx)
|
_ = orderExecutor.GracefulCancel(ctx)
|
||||||
|
|
||||||
quantity := s.useQuantityOrBaseBalance(s.Quantity)
|
leverage := fixedpoint.NewFromInt(5)
|
||||||
|
quantity, err := useQuantityOrBaseBalance(s.session, s.Market, closePrice, s.Quantity, leverage)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Errorf("quantity calculation error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if quantity.IsZero() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if s.MarketOrder {
|
if s.MarketOrder {
|
||||||
bbgo.Notify("%s price %f breaks the previous low %f with ratio %f, submitting market sell to open a short position", symbol, kline.Close.Float64(), previousLow.Float64(), s.Ratio.Float64())
|
bbgo.Notify("%s price %f breaks the previous low %f with ratio %f, submitting market sell to open a short position", symbol, kline.Close.Float64(), previousLow.Float64(), s.Ratio.Float64())
|
||||||
_, _ = s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{
|
_, _ = s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{
|
||||||
|
@ -204,24 +215,58 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BreakLow) useQuantityOrBaseBalance(quantity fixedpoint.Value) fixedpoint.Value {
|
func useQuantityOrBaseBalance(session *bbgo.ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) {
|
||||||
if s.session.Margin || s.session.IsolatedMargin || s.session.Futures || s.session.IsolatedFutures {
|
usingLeverage := session.Margin || session.IsolatedMargin || session.Futures || session.IsolatedFutures
|
||||||
return quantity
|
if usingLeverage {
|
||||||
|
if !quantity.IsZero() {
|
||||||
|
return quantity, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// quantity is zero, we need to calculate the quantity
|
||||||
|
baseBalance, _ := session.Account.Balance(market.BaseCurrency)
|
||||||
|
quoteBalance, _ := session.Account.Balance(market.QuoteCurrency)
|
||||||
|
|
||||||
|
// calculate the quantity automatically
|
||||||
|
if session.Margin || session.IsolatedMargin {
|
||||||
|
baseBalanceValue := baseBalance.Total().Mul(price)
|
||||||
|
accountValue := baseBalanceValue.Add(quoteBalance.Total())
|
||||||
|
|
||||||
|
// spot margin use the equity value, so we use the total quote balance here
|
||||||
|
maxPositionQuantity := risk.CalculateMaxPosition(price, accountValue, leverage)
|
||||||
|
|
||||||
|
log.Infof("margin leverage: calculated maxPositionQuantity=%f price=%f accountValue=%f %s leverage=%f",
|
||||||
|
maxPositionQuantity.Float64(),
|
||||||
|
price.Float64(),
|
||||||
|
accountValue.Float64(),
|
||||||
|
market.QuoteCurrency,
|
||||||
|
leverage.Float64())
|
||||||
|
|
||||||
|
return maxPositionQuantity, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if session.Futures || session.IsolatedFutures {
|
||||||
|
// TODO: get mark price here
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxPositionQuantity, nil
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
balance, hasBalance := s.session.Account.Balance(s.Market.BaseCurrency)
|
// For spot, we simply sell the base currency
|
||||||
|
balance, hasBalance := session.Account.Balance(market.BaseCurrency)
|
||||||
if hasBalance {
|
if hasBalance {
|
||||||
if quantity.IsZero() {
|
if quantity.IsZero() {
|
||||||
bbgo.Notify("sell quantity is not set, submitting sell with all base balance: %s", balance.Available.String())
|
log.Warnf("sell quantity is not set, submitting sell with all base balance: %s", balance.Available.String())
|
||||||
quantity = balance.Available
|
quantity = balance.Available
|
||||||
} else {
|
} else {
|
||||||
quantity = fixedpoint.Min(quantity, balance.Available)
|
quantity = fixedpoint.Min(quantity, balance.Available)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if quantity.IsZero() {
|
return quantity, fmt.Errorf("quantity is zero, can not submit sell order, please check your settings")
|
||||||
log.Errorf("quantity is zero, can not submit sell order, please check settings")
|
|
||||||
}
|
|
||||||
|
|
||||||
return quantity
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user