mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
pull out active order book to the types package
This commit is contained in:
parent
1eb263de23
commit
14abe3fb7e
|
@ -17,7 +17,7 @@ type ExchangeOrderExecutionRouter struct {
|
|||
sessions map[string]*ExchangeSession
|
||||
}
|
||||
|
||||
func (e *ExchangeOrderExecutionRouter) SubmitOrdersTo(ctx context.Context, session string, orders ...types.SubmitOrder) ([]types.Order, error) {
|
||||
func (e *ExchangeOrderExecutionRouter) SubmitOrdersTo(ctx context.Context, session string, orders ...types.SubmitOrder) (types.OrderSlice, error) {
|
||||
es, ok := e.sessions[session]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("exchange session %s not found", session)
|
||||
|
@ -51,7 +51,7 @@ func (e *ExchangeOrderExecutor) notifySubmitOrders(orders ...types.SubmitOrder)
|
|||
}
|
||||
}
|
||||
|
||||
func (e *ExchangeOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) ([]types.Order, error) {
|
||||
func (e *ExchangeOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (types.OrderSlice, error) {
|
||||
formattedOrders, err := formatOrders(orders, e.session)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -81,7 +81,7 @@ type BasicRiskControlOrderExecutor struct {
|
|||
MaxOrderAmount fixedpoint.Value `json:"maxOrderAmount,omitempty"`
|
||||
}
|
||||
|
||||
func (e *BasicRiskControlOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) ([]types.Order, error) {
|
||||
func (e *BasicRiskControlOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (types.OrderSlice, error) {
|
||||
var formattedOrders []types.SubmitOrder
|
||||
for _, order := range orders {
|
||||
currentPrice, ok := e.session.LastPrice(order.Symbol)
|
||||
|
|
|
@ -17,7 +17,7 @@ type RiskControlOrderExecutors struct {
|
|||
BySymbol map[string]*SymbolBasedOrderExecutor `json:"bySymbol,omitempty" yaml:"bySymbol,omitempty"`
|
||||
}
|
||||
|
||||
func (e *RiskControlOrderExecutors) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) ([]types.Order, error) {
|
||||
func (e *RiskControlOrderExecutors) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (types.OrderSlice, error) {
|
||||
var symbolOrders = make(map[string][]types.SubmitOrder, len(orders))
|
||||
for _, order := range orders {
|
||||
symbolOrders[order.Symbol] = append(symbolOrders[order.Symbol], order)
|
||||
|
|
|
@ -295,10 +295,10 @@ func (trader *Trader) ReportPnL() *PnLReporterManager {
|
|||
}
|
||||
|
||||
type OrderExecutor interface {
|
||||
SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders []types.Order, err error)
|
||||
SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders types.OrderSlice, err error)
|
||||
}
|
||||
|
||||
type OrderExecutionRouter interface {
|
||||
// SubmitOrderTo submit order to a specific exchange session
|
||||
SubmitOrdersTo(ctx context.Context, session string, orders ...types.SubmitOrder) (createdOrders []types.Order, err error)
|
||||
SubmitOrdersTo(ctx context.Context, session string, orders ...types.SubmitOrder) (createdOrders types.OrderSlice, err error)
|
||||
}
|
||||
|
|
|
@ -310,7 +310,7 @@ func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) (err
|
|||
return err2
|
||||
}
|
||||
|
||||
func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders []types.Order, err error) {
|
||||
func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders types.OrderSlice, err error) {
|
||||
for _, order := range orders {
|
||||
orderType, err := toLocalOrderType(order.Type)
|
||||
if err != nil {
|
||||
|
|
|
@ -111,7 +111,7 @@ func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) (err
|
|||
return err2
|
||||
}
|
||||
|
||||
func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders []types.Order, err error) {
|
||||
func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders types.OrderSlice, err error) {
|
||||
for _, order := range orders {
|
||||
orderType, err := toLocalOrderType(order.Type)
|
||||
if err != nil {
|
||||
|
|
|
@ -64,8 +64,7 @@ type Strategy struct {
|
|||
|
||||
BaseQuantity float64 `json:"baseQuantity"`
|
||||
|
||||
activeBidOrders *types.SyncOrderMap
|
||||
activeAskOrders *types.SyncOrderMap
|
||||
activeOrders *types.LocalActiveOrderBook
|
||||
|
||||
boll *indicator.BOLL
|
||||
}
|
||||
|
@ -84,7 +83,7 @@ func (s *Strategy) updateBidOrders(orderExecutor bbgo.OrderExecutor, session *bb
|
|||
return
|
||||
}
|
||||
|
||||
var numOrders = s.GridNum - s.activeBidOrders.Len()
|
||||
var numOrders = s.GridNum - s.activeOrders.NumOfBids()
|
||||
if numOrders <= 0 {
|
||||
return
|
||||
}
|
||||
|
@ -113,10 +112,7 @@ func (s *Strategy) updateBidOrders(orderExecutor bbgo.OrderExecutor, session *bb
|
|||
return
|
||||
}
|
||||
|
||||
for _, o := range orders {
|
||||
log.Infof("adding order %d to the active bid order pool...", o.OrderID)
|
||||
s.activeBidOrders.Add(o)
|
||||
}
|
||||
s.activeOrders.Add(orders...)
|
||||
}
|
||||
|
||||
func (s *Strategy) updateAskOrders(orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) {
|
||||
|
@ -128,7 +124,7 @@ func (s *Strategy) updateAskOrders(orderExecutor bbgo.OrderExecutor, session *bb
|
|||
return
|
||||
}
|
||||
|
||||
var numOrders = s.GridNum - s.activeAskOrders.Len()
|
||||
var numOrders = s.GridNum - s.activeOrders.NumOfAsks()
|
||||
if numOrders <= 0 {
|
||||
return
|
||||
}
|
||||
|
@ -157,30 +153,22 @@ func (s *Strategy) updateAskOrders(orderExecutor bbgo.OrderExecutor, session *bb
|
|||
return
|
||||
}
|
||||
|
||||
for _, o := range orders {
|
||||
log.Infof("adding order %d to the active ask order pool...", o.OrderID)
|
||||
s.activeAskOrders.Add(o)
|
||||
}
|
||||
log.Infof("adding orders to the active ask order pool...")
|
||||
s.activeOrders.Add(orders...)
|
||||
}
|
||||
|
||||
func (s *Strategy) updateOrders(orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) {
|
||||
log.Infof("checking grid orders, bids=%d asks=%d", s.activeBidOrders.Len(), s.activeAskOrders.Len())
|
||||
log.Infof("checking grid orders, bids=%d asks=%d", s.activeOrders.Bids.Len(), s.activeOrders.Asks.Len())
|
||||
|
||||
for _, o := range s.activeBidOrders.Orders() {
|
||||
log.Infof("bid order: %d -> %s", o.OrderID, o.Status)
|
||||
}
|
||||
s.activeOrders.Print()
|
||||
|
||||
for _, o := range s.activeAskOrders.Orders() {
|
||||
log.Infof("ask order: %d -> %s", o.OrderID, o.Status)
|
||||
}
|
||||
|
||||
if s.activeBidOrders.Len() < s.GridNum {
|
||||
log.Infof("active bid orders not enough: %d < %d, updating...", s.activeBidOrders.Len(), s.GridNum)
|
||||
if s.activeOrders.Bids.Len() < s.GridNum {
|
||||
log.Infof("active bid orders not enough: %d < %d, updating...", s.activeOrders.Bids.Len(), s.GridNum)
|
||||
s.updateBidOrders(orderExecutor, session)
|
||||
}
|
||||
|
||||
if s.activeAskOrders.Len() < s.GridNum {
|
||||
log.Infof("active ask orders not enough: %d < %d, updating...", s.activeAskOrders.Len(), s.GridNum)
|
||||
if s.activeOrders.Asks.Len() < s.GridNum {
|
||||
log.Infof("active ask orders not enough: %d < %d, updating...", s.activeOrders.Asks.Len(), s.GridNum)
|
||||
s.updateAskOrders(orderExecutor, session)
|
||||
}
|
||||
}
|
||||
|
@ -196,9 +184,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
|||
})
|
||||
|
||||
// we don't persist orders so that we can not clear the previous orders for now. just need time to support this.
|
||||
// TODO: pull this map out and add mutex lock
|
||||
s.activeBidOrders = types.NewSyncOrderMap()
|
||||
s.activeAskOrders = types.NewSyncOrderMap()
|
||||
s.activeOrders = types.NewLocalActiveOrderBook()
|
||||
|
||||
session.Stream.OnOrderUpdate(func(order types.Order) {
|
||||
log.Infof("received order update: %+v", order)
|
||||
|
@ -208,43 +194,16 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
|||
}
|
||||
|
||||
switch order.Status {
|
||||
|
||||
case types.OrderStatusFilled:
|
||||
switch order.Side {
|
||||
case types.SideTypeSell:
|
||||
// find the filled bid to remove
|
||||
if filledOrder, ok := s.activeBidOrders.AnyFilled(); ok {
|
||||
s.activeBidOrders.Delete(filledOrder.OrderID)
|
||||
s.activeAskOrders.Delete(order.OrderID)
|
||||
}
|
||||
|
||||
case types.SideTypeBuy:
|
||||
// find the filled ask order to remove
|
||||
if filledOrder, ok := s.activeAskOrders.AnyFilled(); ok {
|
||||
s.activeAskOrders.Delete(filledOrder.OrderID)
|
||||
s.activeBidOrders.Delete(order.OrderID)
|
||||
}
|
||||
}
|
||||
s.activeOrders.WriteOff(order)
|
||||
|
||||
case types.OrderStatusCanceled, types.OrderStatusRejected:
|
||||
log.Infof("order status %s, removing %d from the active order pool...", order.Status, order.OrderID)
|
||||
|
||||
switch order.Side {
|
||||
case types.SideTypeSell:
|
||||
s.activeAskOrders.Delete(order.OrderID)
|
||||
case types.SideTypeBuy:
|
||||
s.activeBidOrders.Delete(order.OrderID)
|
||||
|
||||
}
|
||||
s.activeOrders.Delete(order)
|
||||
|
||||
default:
|
||||
log.Infof("order status %s, updating %d to the active order pool...", order.Status, order.OrderID)
|
||||
switch order.Side {
|
||||
case types.SideTypeSell:
|
||||
s.activeAskOrders.Add(order)
|
||||
case types.SideTypeBuy:
|
||||
s.activeBidOrders.Add(order)
|
||||
}
|
||||
s.activeOrders.Add(order)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -255,13 +214,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
|||
s.updateOrders(orderExecutor, session)
|
||||
|
||||
defer func() {
|
||||
for _, o := range s.activeBidOrders.Orders() {
|
||||
_ = session.Exchange.CancelOrders(context.Background(), o)
|
||||
}
|
||||
|
||||
for _, o := range s.activeAskOrders.Orders() {
|
||||
_ = session.Exchange.CancelOrders(context.Background(), o)
|
||||
}
|
||||
_ = session.Exchange.CancelOrders(context.Background(), s.activeOrders.Orders()...)
|
||||
}()
|
||||
|
||||
for {
|
||||
|
|
90
pkg/types/active_book.go
Normal file
90
pkg/types/active_book.go
Normal file
|
@ -0,0 +1,90 @@
|
|||
package types
|
||||
|
||||
import log "github.com/sirupsen/logrus"
|
||||
|
||||
// LocalActiveOrderBook manages the local active order books.
|
||||
type LocalActiveOrderBook struct {
|
||||
Bids *SyncOrderMap
|
||||
Asks *SyncOrderMap
|
||||
}
|
||||
|
||||
func NewLocalActiveOrderBook() *LocalActiveOrderBook {
|
||||
return &LocalActiveOrderBook{
|
||||
Bids: NewSyncOrderMap(),
|
||||
Asks: NewSyncOrderMap(),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *LocalActiveOrderBook) Print() {
|
||||
for _, o := range b.Bids.Orders() {
|
||||
log.Infof("bid order: %d -> %s", o.OrderID, o.Status)
|
||||
}
|
||||
|
||||
for _, o := range b.Asks.Orders() {
|
||||
log.Infof("ask order: %d -> %s", o.OrderID, o.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *LocalActiveOrderBook) Add(orders ...Order) {
|
||||
for _, order := range orders {
|
||||
switch order.Side {
|
||||
case SideTypeBuy:
|
||||
b.Bids.Add(order)
|
||||
|
||||
case SideTypeSell:
|
||||
b.Asks.Add(order)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *LocalActiveOrderBook) NumOfBids() int {
|
||||
return b.Bids.Len()
|
||||
}
|
||||
|
||||
func (b *LocalActiveOrderBook) NumOfAsks() int {
|
||||
return b.Asks.Len()
|
||||
}
|
||||
|
||||
func (b *LocalActiveOrderBook) Delete(order Order) {
|
||||
switch order.Side {
|
||||
case SideTypeBuy:
|
||||
b.Bids.Delete(order.OrderID)
|
||||
|
||||
case SideTypeSell:
|
||||
b.Asks.Delete(order.OrderID)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// WriteOff writes off the filled order on the opposite side.
|
||||
// This method does not write off order by order amount or order quantity.
|
||||
func (b *LocalActiveOrderBook) WriteOff(order Order) bool {
|
||||
if order.Status != OrderStatusFilled {
|
||||
return false
|
||||
}
|
||||
|
||||
switch order.Side {
|
||||
case SideTypeSell:
|
||||
// find the filled bid to remove
|
||||
if filledOrder, ok := b.Bids.AnyFilled(); ok {
|
||||
b.Bids.Delete(filledOrder.OrderID)
|
||||
b.Asks.Delete(order.OrderID)
|
||||
return true
|
||||
}
|
||||
|
||||
case SideTypeBuy:
|
||||
// find the filled ask order to remove
|
||||
if filledOrder, ok := b.Asks.AnyFilled(); ok {
|
||||
b.Asks.Delete(filledOrder.OrderID)
|
||||
b.Bids.Delete(order.OrderID)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *LocalActiveOrderBook) Orders() OrderSlice {
|
||||
return append(b.Asks.Orders(), b.Bids.Orders()...)
|
||||
}
|
|
@ -54,7 +54,7 @@ type Exchange interface {
|
|||
|
||||
QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []Withdraw, err error)
|
||||
|
||||
SubmitOrders(ctx context.Context, orders ...SubmitOrder) (createdOrders []Order, err error)
|
||||
SubmitOrders(ctx context.Context, orders ...SubmitOrder) (createdOrders OrderSlice, err error)
|
||||
|
||||
QueryOpenOrders(ctx context.Context, symbol string) (orders []Order, err error)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user