bbgo_origin/pkg/bbgo/order_execution.go

87 lines
2.7 KiB
Go
Raw Normal View History

package bbgo
import (
"context"
"github.com/pkg/errors"
2020-10-26 10:17:18 +00:00
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
type ExchangeOrderExecutionRouter struct {
Notifiability
sessions map[string]*ExchangeSession
}
func (e *ExchangeOrderExecutionRouter) SubmitOrdersTo(ctx context.Context, session string, orders ...types.SubmitOrder) ([]types.Order, error) {
es, ok := e.sessions[session]
if !ok {
return nil, errors.Errorf("exchange session %s not found", session)
}
2020-10-26 10:17:18 +00:00
formattedOrders, err := formatOrders(orders, es)
if err != nil {
return nil, err
}
// e.Notify(":memo: Submitting order to %s %s %s %s with quantity: %s", session, order.Symbol, order.Type, order.Side, order.QuantityString, order)
return es.Exchange.SubmitOrders(ctx, formattedOrders...)
}
// ExchangeOrderExecutor is an order executor wrapper for single exchange instance.
type ExchangeOrderExecutor struct {
2020-10-26 10:17:18 +00:00
Notifiability `json:"-"`
2020-10-26 10:17:18 +00:00
session *ExchangeSession `json:"-"`
}
2020-10-26 10:17:18 +00:00
func (e *ExchangeOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) ([]types.Order, error) {
formattedOrders, err := formatOrders(orders, e.session)
if err != nil {
return nil, err
}
// e.Notify(":memo: Submitting %s %s %s order with quantity: %s", order.Symbol, order.Type, order.Side, order.QuantityString, order)
return e.session.Exchange.SubmitOrders(ctx, formattedOrders...)
}
2020-10-26 10:17:18 +00:00
type RiskControlOrderExecutor struct {
Notifiability `json:"-"`
MinQuoteBalance fixedpoint.Value `json:"minQuoteBalance,omitempty"`
MaxAssetBalance fixedpoint.Value `json:"maxBaseAssetBalance,omitempty"`
MinAssetBalance fixedpoint.Value `json:"minBaseAssetBalance,omitempty"`
MaxOrderAmount fixedpoint.Value `json:"maxOrderAmount,omitempty"`
session *ExchangeSession `json:"-"`
}
func (e *RiskControlOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) ([]types.Order, error) {
formattedOrders, err := formatOrders(orders, e.session)
if err != nil {
return nil, err
}
// e.Notify(":memo: Submitting %s %s %s order with quantity: %s", order.Symbol, order.Type, order.Side, order.QuantityString, order)
return e.session.Exchange.SubmitOrders(ctx, formattedOrders...)
}
func formatOrders(orders []types.SubmitOrder, session *ExchangeSession) (formattedOrders []types.SubmitOrder, err error) {
for _, order := range orders {
2020-10-26 10:17:18 +00:00
market, ok := session.Market(order.Symbol)
if !ok {
2020-10-26 10:17:18 +00:00
return formattedOrders, errors.Errorf("market is not defined: %s", order.Symbol)
}
order.Market = market
order.PriceString = market.FormatPrice(order.Price)
order.QuantityString = market.FormatVolume(order.Quantity)
formattedOrders = append(formattedOrders, order)
}
2020-10-26 10:17:18 +00:00
return formattedOrders, err
}