mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 00:35:15 +00:00
FEATURE: cancel maker orders and open take profit order
This commit is contained in:
parent
f90ef3372d
commit
092d5cfb07
|
@ -9,6 +9,10 @@ import (
|
|||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type cancelOrdersByGroupIDApi interface {
|
||||
CancelOrdersByGroupID(ctx context.Context, groupID int64) ([]types.Order, error)
|
||||
}
|
||||
|
||||
func (s *Strategy) placeOpenPositionOrders(ctx context.Context) error {
|
||||
s.logger.Infof("[DCA] start placing open position orders")
|
||||
price, err := getBestPriceUntilSuccess(ctx, s.Session.Exchange, s.Symbol, s.Short)
|
||||
|
@ -111,3 +115,24 @@ func calculateNotionalAndNum(market types.Market, short bool, budget fixedpoint.
|
|||
|
||||
return fixedpoint.Zero, 0
|
||||
}
|
||||
|
||||
func (s *Strategy) cancelOpenPositionOrders(ctx context.Context) error {
|
||||
s.logger.Info("[DCA] cancel open position orders")
|
||||
e, ok := s.Session.Exchange.(cancelOrdersByGroupIDApi)
|
||||
if ok {
|
||||
cancelledOrders, err := e.CancelOrdersByGroupID(ctx, int64(s.OrderGroupID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cancelledOrder := range cancelledOrders {
|
||||
s.logger.Info("CANCEL ", cancelledOrder.String())
|
||||
}
|
||||
} else {
|
||||
if err := s.OrderExecutor.ActiveMakerOrders().GracefulCancel(ctx, s.Session.Exchange); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -32,9 +32,13 @@ func newTestStrategy(va ...string) *Strategy {
|
|||
|
||||
market := newTestMarket()
|
||||
s := &Strategy{
|
||||
logger: logrus.NewEntry(logrus.New()),
|
||||
Symbol: symbol,
|
||||
Market: market,
|
||||
logger: logrus.NewEntry(logrus.New()),
|
||||
Symbol: symbol,
|
||||
Market: market,
|
||||
Short: false,
|
||||
TakeProfitRatio: Number("10%"),
|
||||
makerSide: types.SideTypeBuy,
|
||||
takeProfitSide: types.SideTypeSell,
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
42
pkg/strategy/dca2/takeProfit.go
Normal file
42
pkg/strategy/dca2/takeProfit.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package dca2
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func (s *Strategy) openTakeProfitOrders(ctx context.Context) error {
|
||||
s.logger.Info("[DCA] open take profit orders")
|
||||
takeProfitOrder := s.generateTakeProfitOrder(s.Short, s.Position)
|
||||
createdOrders, err := s.OrderExecutor.SubmitOrders(ctx, takeProfitOrder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, createdOrder := range createdOrders {
|
||||
s.logger.Info("SUBMIT TAKE PROFIT ORDER ", createdOrder.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Strategy) generateTakeProfitOrder(short bool, position *types.Position) types.SubmitOrder {
|
||||
takeProfitRatio := s.TakeProfitRatio
|
||||
if s.Short {
|
||||
takeProfitRatio = takeProfitRatio.Neg()
|
||||
}
|
||||
takeProfitPrice := s.Market.TruncatePrice(position.AverageCost.Mul(fixedpoint.One.Add(takeProfitRatio)))
|
||||
return types.SubmitOrder{
|
||||
Symbol: s.Symbol,
|
||||
Market: s.Market,
|
||||
Type: types.OrderTypeLimit,
|
||||
Price: takeProfitPrice,
|
||||
Side: s.takeProfitSide,
|
||||
TimeInForce: types.TimeInForceGTC,
|
||||
Quantity: position.GetBase().Abs(),
|
||||
Tag: orderTag,
|
||||
GroupID: s.OrderGroupID,
|
||||
}
|
||||
}
|
47
pkg/strategy/dca2/takeProfit_test.go
Normal file
47
pkg/strategy/dca2/takeProfit_test.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package dca2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/c9s/bbgo/pkg/testing/testhelper"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGenerateTakeProfitOrder(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
strategy := newTestStrategy()
|
||||
|
||||
position := types.NewPositionFromMarket(strategy.Market)
|
||||
position.AddTrade(types.Trade{
|
||||
Symbol: "BTCUSDT",
|
||||
Side: types.SideTypeBuy,
|
||||
Price: Number("28500"),
|
||||
Quantity: Number("1"),
|
||||
QuoteQuantity: Number("28500"),
|
||||
Fee: Number("0.0015"),
|
||||
FeeCurrency: strategy.Market.BaseCurrency,
|
||||
})
|
||||
|
||||
o := strategy.generateTakeProfitOrder(false, position)
|
||||
assert.Equal(Number("31397.09"), o.Price)
|
||||
assert.Equal(Number("0.9985"), o.Quantity)
|
||||
assert.Equal(types.SideTypeSell, o.Side)
|
||||
assert.Equal(strategy.Symbol, o.Symbol)
|
||||
|
||||
position.AddTrade(types.Trade{
|
||||
Side: types.SideTypeBuy,
|
||||
Price: Number("27000"),
|
||||
Quantity: Number("0.5"),
|
||||
QuoteQuantity: Number("13500"),
|
||||
Fee: Number("0.00075"),
|
||||
FeeCurrency: strategy.Market.BaseCurrency,
|
||||
})
|
||||
o = strategy.generateTakeProfitOrder(false, position)
|
||||
assert.Equal(Number("30846.26"), o.Price)
|
||||
assert.Equal(Number("1.49775"), o.Quantity)
|
||||
assert.Equal(types.SideTypeSell, o.Side)
|
||||
assert.Equal(strategy.Symbol, o.Symbol)
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user