mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
bbgo: refactor order executor with max retries
This commit is contained in:
parent
2a927dc34d
commit
a838b4991a
|
@ -54,7 +54,7 @@ func (e *ExchangeOrderExecutionRouter) SubmitOrdersTo(ctx context.Context, sessi
|
|||
return nil, err
|
||||
}
|
||||
|
||||
createdOrders, _, err := BatchPlaceOrder(ctx, es.Exchange, formattedOrders...)
|
||||
createdOrders, _, err := BatchPlaceOrder(ctx, es.Exchange, nil, formattedOrders...)
|
||||
return createdOrders, err
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ func (e *ExchangeOrderExecutor) SubmitOrders(ctx context.Context, orders ...type
|
|||
log.Infof("submitting order: %s", order.String())
|
||||
}
|
||||
|
||||
createdOrders, _, err := BatchPlaceOrder(ctx, e.Session.Exchange, formattedOrders...)
|
||||
createdOrders, _, err := BatchPlaceOrder(ctx, e.Session.Exchange, nil, formattedOrders...)
|
||||
return createdOrders, err
|
||||
}
|
||||
|
||||
|
@ -297,10 +297,13 @@ func (c *BasicRiskController) ProcessOrders(session *ExchangeSession, orders ...
|
|||
return outOrders, nil
|
||||
}
|
||||
|
||||
type OrderCallback func(order types.Order)
|
||||
|
||||
// BatchPlaceOrder
|
||||
func BatchPlaceOrder(ctx context.Context, exchange types.Exchange, submitOrders ...types.SubmitOrder) (types.OrderSlice, []int, error) {
|
||||
func BatchPlaceOrder(ctx context.Context, exchange types.Exchange, orderCallback OrderCallback, submitOrders ...types.SubmitOrder) (types.OrderSlice, []int, error) {
|
||||
var createdOrders types.OrderSlice
|
||||
var err error
|
||||
|
||||
var errIndexes []int
|
||||
for i, submitOrder := range submitOrders {
|
||||
createdOrder, err2 := exchange.SubmitOrder(ctx, submitOrder)
|
||||
|
@ -309,6 +312,11 @@ func BatchPlaceOrder(ctx context.Context, exchange types.Exchange, submitOrders
|
|||
errIndexes = append(errIndexes, i)
|
||||
} else if createdOrder != nil {
|
||||
createdOrder.Tag = submitOrder.Tag
|
||||
|
||||
if orderCallback != nil {
|
||||
orderCallback(*createdOrder)
|
||||
}
|
||||
|
||||
createdOrders = append(createdOrders, *createdOrder)
|
||||
}
|
||||
}
|
||||
|
@ -316,8 +324,6 @@ func BatchPlaceOrder(ctx context.Context, exchange types.Exchange, submitOrders
|
|||
return createdOrders, errIndexes, err
|
||||
}
|
||||
|
||||
type OrderCallback func(order types.Order)
|
||||
|
||||
// BatchRetryPlaceOrder places the orders and retries the failed orders
|
||||
func BatchRetryPlaceOrder(ctx context.Context, exchange types.Exchange, errIdx []int, orderCallback OrderCallback, logger log.FieldLogger, submitOrders ...types.SubmitOrder) (types.OrderSlice, []int, error) {
|
||||
if logger == nil {
|
||||
|
@ -329,26 +335,12 @@ func BatchRetryPlaceOrder(ctx context.Context, exchange types.Exchange, errIdx [
|
|||
|
||||
// if the errIdx is nil, then we should iterate all the submit orders
|
||||
// allocate a variable for new error index
|
||||
var errIdxNext []int
|
||||
if len(errIdx) == 0 {
|
||||
for i, submitOrder := range submitOrders {
|
||||
createdOrder, err2 := exchange.SubmitOrder(ctx, submitOrder)
|
||||
if err2 != nil {
|
||||
werr = multierr.Append(werr, err2)
|
||||
errIdxNext = append(errIdxNext, i)
|
||||
} else if createdOrder != nil {
|
||||
// if the order is successfully created, than we should copy the order tag
|
||||
createdOrder.Tag = submitOrder.Tag
|
||||
|
||||
if orderCallback != nil {
|
||||
orderCallback(*createdOrder)
|
||||
}
|
||||
|
||||
createdOrders = append(createdOrders, *createdOrder)
|
||||
}
|
||||
var err2 error
|
||||
createdOrders, errIdx, err2 = BatchPlaceOrder(ctx, exchange, orderCallback, submitOrders...)
|
||||
if err2 != nil {
|
||||
werr = multierr.Append(werr, err2)
|
||||
}
|
||||
|
||||
errIdx = errIdxNext
|
||||
}
|
||||
|
||||
timeoutCtx, cancelTimeout := context.WithTimeout(ctx, DefaultSubmitOrderRetryTimeout)
|
||||
|
@ -359,6 +351,7 @@ func BatchRetryPlaceOrder(ctx context.Context, exchange types.Exchange, errIdx [
|
|||
|
||||
// set backoff max retries to 101 because https://ja.wikipedia.org/wiki/101%E5%9B%9E%E7%9B%AE%E3%81%AE%E3%83%97%E3%83%AD%E3%83%9D%E3%83%BC%E3%82%BA
|
||||
backoffMaxRetries := uint64(101)
|
||||
var errIdxNext []int
|
||||
batchRetryOrder:
|
||||
for retryRound := 0; len(errIdx) > 0 && retryRound < 10; retryRound++ {
|
||||
// sleep for 200 millisecond between each retry
|
||||
|
|
|
@ -40,6 +40,7 @@ type GeneralOrderExecutor struct {
|
|||
|
||||
marginBaseMaxBorrowable, marginQuoteMaxBorrowable fixedpoint.Value
|
||||
|
||||
maxRetries uint
|
||||
disableNotify bool
|
||||
closing int64
|
||||
}
|
||||
|
@ -73,6 +74,10 @@ func (e *GeneralOrderExecutor) DisableNotify() {
|
|||
e.disableNotify = true
|
||||
}
|
||||
|
||||
func (e *GeneralOrderExecutor) SetMaxRetries(maxRetries uint) {
|
||||
e.maxRetries = maxRetries
|
||||
}
|
||||
|
||||
func (e *GeneralOrderExecutor) startMarginAssetUpdater(ctx context.Context) {
|
||||
marginService, ok := e.session.Exchange.(types.MarginBorrowRepayService)
|
||||
if !ok {
|
||||
|
@ -194,10 +199,12 @@ func (e *GeneralOrderExecutor) FastSubmitOrders(ctx context.Context, submitOrder
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
createdOrders, errIdx, err := BatchPlaceOrder(ctx, e.session.Exchange, formattedOrders...)
|
||||
|
||||
createdOrders, errIdx, err := BatchPlaceOrder(ctx, e.session.Exchange, nil, formattedOrders...)
|
||||
if len(errIdx) > 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if IsBackTesting {
|
||||
e.orderStore.Add(createdOrders...)
|
||||
e.activeMakerOrders.Add(createdOrders...)
|
||||
|
@ -229,6 +236,11 @@ func (e *GeneralOrderExecutor) SubmitOrders(ctx context.Context, submitOrders ..
|
|||
e.tradeCollector.Process()
|
||||
}
|
||||
|
||||
if e.maxRetries == 0 {
|
||||
createdOrders, _, err := BatchPlaceOrder(ctx, e.session.Exchange, orderCreateCallback, formattedOrders...)
|
||||
return createdOrders, err
|
||||
}
|
||||
|
||||
createdOrders, _, err := BatchRetryPlaceOrder(ctx, e.session.Exchange, nil, orderCreateCallback, e.logger, formattedOrders...)
|
||||
return createdOrders, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user