mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
bbgo: add OpenPosition method
This commit is contained in:
parent
90f3727d68
commit
2e95246687
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user