mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 06:53:52 +00:00
track arbitrage orders
This commit is contained in:
parent
a95c3b94a0
commit
4975fb5498
|
@ -32,7 +32,12 @@ type State struct {
|
|||
FilledBuyGrids map[fixedpoint.Value]struct{} `json:"filledBuyGrids"`
|
||||
FilledSellGrids map[fixedpoint.Value]struct{} `json:"filledSellGrids"`
|
||||
Position *bbgo.Position `json:"position,omitempty"`
|
||||
ArbitrageProfit fixedpoint.Value `json:"totalProfit"`
|
||||
|
||||
ArbitrageProfit fixedpoint.Value `json:"arbitrageProfit"`
|
||||
|
||||
// any created orders for tracking trades
|
||||
// [source Order ID] -> arbitrage order
|
||||
ArbitrageOrders map[uint64]types.Order `json:"arbitrageOrders"`
|
||||
}
|
||||
|
||||
type Strategy struct {
|
||||
|
@ -93,9 +98,6 @@ type Strategy struct {
|
|||
// activeOrders is the locally maintained active order book of the maker orders.
|
||||
activeOrders *bbgo.LocalActiveOrderBook
|
||||
|
||||
// any created orders for tracking trades
|
||||
orders map[uint64]types.Order
|
||||
|
||||
// groupID is the group ID used for the strategy instance for canceling orders
|
||||
groupID int64
|
||||
}
|
||||
|
@ -344,7 +346,6 @@ func (s *Strategy) placeGridOrders(orderExecutor bbgo.OrderExecutor, session *bb
|
|||
log.Warn(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *Strategy) tradeUpdateHandler(trade types.Trade) {
|
||||
|
@ -367,15 +368,16 @@ func (s *Strategy) tradeUpdateHandler(trade types.Trade) {
|
|||
|
||||
profit, madeProfit := s.state.Position.AddTrade(trade)
|
||||
if madeProfit {
|
||||
s.Notify("position profit: %f", profit.Float64())
|
||||
s.Notify("average cost profit: %f", profit.Float64())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Strategy) submitReverseOrder(order types.Order) {
|
||||
var side = order.Side.Reverse()
|
||||
var price = order.Price
|
||||
var quantity = order.Quantity
|
||||
func (s *Strategy) handleFilledOrder(filledOrder types.Order) {
|
||||
// generate arbitrage order
|
||||
var side = filledOrder.Side.Reverse()
|
||||
var price = filledOrder.Price
|
||||
var quantity = filledOrder.Quantity
|
||||
|
||||
switch side {
|
||||
case types.SideTypeSell:
|
||||
|
@ -389,7 +391,7 @@ func (s *Strategy) submitReverseOrder(order types.Order) {
|
|||
} else if s.Long {
|
||||
// long = use the same amount to buy more quantity back
|
||||
// the original amount
|
||||
var amount = order.Price * order.Quantity
|
||||
var amount = filledOrder.Price * filledOrder.Quantity
|
||||
quantity = amount / price
|
||||
}
|
||||
|
||||
|
@ -403,7 +405,7 @@ func (s *Strategy) submitReverseOrder(order types.Order) {
|
|||
GroupID: s.groupID,
|
||||
}
|
||||
|
||||
log.Infof("submitting arbitrage order: %s against %s", submitOrder.String(), order.String())
|
||||
log.Infof("submitting arbitrage order: %s against filled order %s", submitOrder.String(), filledOrder.String())
|
||||
|
||||
createdOrders, err := s.OrderExecutor.SubmitOrders(context.Background(), submitOrder)
|
||||
if err != nil {
|
||||
|
@ -411,8 +413,51 @@ func (s *Strategy) submitReverseOrder(order types.Order) {
|
|||
return
|
||||
}
|
||||
|
||||
// create one-way link from the newly created orders
|
||||
for _, o := range createdOrders {
|
||||
s.state.ArbitrageOrders[o.OrderID] = filledOrder
|
||||
}
|
||||
|
||||
s.orderStore.Add(createdOrders...)
|
||||
s.activeOrders.Add(createdOrders...)
|
||||
|
||||
// calculate arbitrage profit
|
||||
if s.Long {
|
||||
switch filledOrder.Side {
|
||||
case types.SideTypeSell:
|
||||
if buyOrder, ok := s.state.ArbitrageOrders[filledOrder.OrderID]; ok {
|
||||
// use base asset quantity here
|
||||
baseProfit := buyOrder.Quantity - filledOrder.Quantity
|
||||
s.state.ArbitrageProfit += fixedpoint.NewFromFloat(baseProfit)
|
||||
s.Notify("grid arbitrage profit %f %s", baseProfit, s.Market.BaseCurrency)
|
||||
}
|
||||
|
||||
case types.SideTypeBuy:
|
||||
if sellOrder, ok := s.state.ArbitrageOrders[filledOrder.OrderID]; ok {
|
||||
// use base asset quantity here
|
||||
baseProfit := filledOrder.Quantity - sellOrder.Quantity
|
||||
s.state.ArbitrageProfit += fixedpoint.NewFromFloat(baseProfit)
|
||||
s.Notify("grid arbitrage profit %f %s", baseProfit, s.Market.BaseCurrency)
|
||||
}
|
||||
}
|
||||
} else if !s.Long && s.Quantity > 0 {
|
||||
switch filledOrder.Side {
|
||||
case types.SideTypeSell:
|
||||
if buyOrder, ok := s.state.ArbitrageOrders[filledOrder.OrderID]; ok {
|
||||
// use base asset quantity here
|
||||
quoteProfit := (filledOrder.Quantity * filledOrder.Price) - (buyOrder.Quantity * buyOrder.Price)
|
||||
s.state.ArbitrageProfit += fixedpoint.NewFromFloat(quoteProfit)
|
||||
s.Notify("grid arbitrage profit %f %s", quoteProfit, s.Market.BaseCurrency)
|
||||
}
|
||||
case types.SideTypeBuy:
|
||||
if sellOrder, ok := s.state.ArbitrageOrders[filledOrder.OrderID]; ok {
|
||||
// use base asset quantity here
|
||||
quoteProfit := (sellOrder.Quantity * sellOrder.Price) - (filledOrder.Quantity * filledOrder.Price)
|
||||
s.state.ArbitrageProfit += fixedpoint.NewFromFloat(quoteProfit)
|
||||
s.Notify("grid arbitrage profit %f %s", quoteProfit, s.Market.QuoteCurrency)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
|
||||
|
@ -464,10 +509,15 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
|||
s.state = &State{
|
||||
FilledBuyGrids: make(map[fixedpoint.Value]struct{}),
|
||||
FilledSellGrids: make(map[fixedpoint.Value]struct{}),
|
||||
ArbitrageOrders: make(map[uint64]types.Order),
|
||||
Position: position,
|
||||
}
|
||||
}
|
||||
|
||||
if s.state.ArbitrageOrders == nil {
|
||||
s.state.ArbitrageOrders = make(map[uint64]types.Order)
|
||||
}
|
||||
|
||||
s.Notify("current position %+v", s.state.Position)
|
||||
|
||||
instanceID := fmt.Sprintf("grid-%s-%d", s.Symbol, s.GridNum)
|
||||
|
@ -479,7 +529,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.
|
||||
s.activeOrders = bbgo.NewLocalActiveOrderBook()
|
||||
s.activeOrders.OnFilled(s.submitReverseOrder)
|
||||
s.activeOrders.OnFilled(s.handleFilledOrder)
|
||||
s.activeOrders.BindStream(session.Stream)
|
||||
|
||||
s.Graceful.OnShutdown(func(ctx context.Context, wg *sync.WaitGroup) {
|
||||
|
|
|
@ -167,7 +167,7 @@ func (o Order) Backup() SubmitOrder {
|
|||
}
|
||||
|
||||
func (o Order) String() string {
|
||||
return fmt.Sprintf("order %s %f/%f at %f -> %s", o.Side, o.ExecutedQuantity, o.Quantity, o.Price, o.Status)
|
||||
return fmt.Sprintf("order %s %s %f/%f at %f -> %s", o.Symbol, o.Side, o.ExecutedQuantity, o.Quantity, o.Price, o.Status)
|
||||
}
|
||||
|
||||
func (o Order) PlainText() string {
|
||||
|
|
Loading…
Reference in New Issue
Block a user