Skip to content

Commit c842e93

Browse files
committed
fix binance ws algo order event update
1 parent 6fd452b commit c842e93

File tree

5 files changed

+142
-4
lines changed

5 files changed

+142
-4
lines changed

pkg/bbgo/activeorderbook.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ func (b *ActiveOrderBook) Update(order types.Order) {
373373
}
374374

375375
switch order.Status {
376-
case types.OrderStatusFilled:
376+
case types.OrderStatusFilled, types.OrderStatusFinished:
377377
// make sure we have the order and we remove it
378378
removed := b.orders.Remove(order.OrderID)
379379
b.mu.Unlock()
@@ -405,6 +405,10 @@ func (b *ActiveOrderBook) Update(order types.Order) {
405405
}
406406
b.C.Emit()
407407

408+
case types.OrderStatusTriggering, types.OrderStatusTriggered:
409+
b.orders.Update(order)
410+
b.mu.Unlock()
411+
408412
default:
409413
b.mu.Unlock()
410414
b.logger.Warnf("[ActiveOrderBook] unhandled order status: %s", order.Status)

pkg/exchange/binance/parse.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,11 @@ func parseWebSocketEvent(message []byte) (interface{}, error) {
494494
err = json.Unmarshal([]byte(message), &event)
495495
return &event, err
496496

497+
case "ALGO_UPDATE":
498+
var event AlgoOrderUpdateEvent
499+
err = json.Unmarshal([]byte(message), &event)
500+
return &event, err
501+
497502
default:
498503
id := val.GetInt("id")
499504
if id > 0 {
@@ -1266,3 +1271,99 @@ type OrderTradeLiteUpdateEvent struct {
12661271
TradeID int64 `json:"t"`
12671272
OrderID int64 `json:"i"`
12681273
}
1274+
1275+
/*
1276+
{
1277+
"e":"ALGO_UPDATE", // Event Type
1278+
"T":1750515742297, // Transaction Time
1279+
"E":1750515742303, // Event Time
1280+
"o":{
1281+
"caid":"Q5xaq5EGKgXXa0fD7fs0Ip", // Client Algo Id
1282+
"aid":2148719, // Algo Id
1283+
"at":"CONDITIONAL", // Algo Type
1284+
"o":"TAKE_PROFIT", //Order Type
1285+
"s":"BNBUSDT", //Symbol
1286+
"S":"SELL", //Side
1287+
"ps":"BOTH", //Position Side
1288+
"f":"GTC", //Time in force
1289+
"q":"0.01", //quantity
1290+
"X":"CANCELED", //Algo status
1291+
"ai":"", // order id
1292+
"ap": "0.00000", // avg fill price in matching engine, only display when order is triggered and placed in matching engine
1293+
"aq": "0.00000", // execuated quantity in matching engine, only display when order is triggered and placed in matching engine
1294+
"act": "0", // actual order type in matching engine, only display when order is triggered and placed in matching engine
1295+
"tp":"750", //Trigger price
1296+
"p":"750", //Order Price
1297+
"V":"EXPIRE_MAKER", //STP mode
1298+
"wt":"CONTRACT_PRICE", //Working type
1299+
"pm":"NONE", // Price match mode
1300+
"cp":false, //If Close-All
1301+
"pP":false, //If price protection is turned on
1302+
"R":false, // Is this reduce only
1303+
"tt":0, //Trigger time
1304+
"gtd":0, // good till time for GTD time in force
1305+
"rm": "Reduce Only reject" // algo order failed reason
1306+
}
1307+
}
1308+
*/
1309+
type AlgoOrderUpdateEvent struct {
1310+
EventBase
1311+
1312+
TransactionTime types.MillisecondTimestamp `json:"T"`
1313+
AlgoOrder AlgoOrder `json:"o"`
1314+
}
1315+
1316+
type AlgoOrder struct {
1317+
ClientAlgoId string `json:"caid"`
1318+
AlgoId int `json:"aid"`
1319+
AlgoType string `json:"at"`
1320+
OrderType string `json:"o"`
1321+
Symbol string `json:"s"`
1322+
Side string `json:"S"`
1323+
PositionSide string `json:"ps"`
1324+
TimeInForce string `json:"f"`
1325+
Quantity fixedpoint.Value `json:"q"`
1326+
Price fixedpoint.Value `json:"p"`
1327+
TriggerPrice fixedpoint.Value `json:"tp"`
1328+
StopPrice fixedpoint.Value `json:"sp"`
1329+
Status string `json:"X"`
1330+
OrderId string `json:"ai"`
1331+
AvgFillPrice fixedpoint.Value `json:"ap"`
1332+
ExecutedQuantity fixedpoint.Value `json:"aq"`
1333+
ActualOrderType string `json:"act"`
1334+
STPMode string `json:"V"`
1335+
WorkingType string `json:"wt"`
1336+
PriceMatchMode string `json:"pm"`
1337+
CloseAll bool `json:"cp"`
1338+
PriceProtection bool `json:"pP"`
1339+
TriggerTime int64 `json:"tt"`
1340+
GoodTillTime int64 `json:"gtd"`
1341+
ReduceOnly bool `json:"R"`
1342+
FailedReason string `json:"rm"`
1343+
}
1344+
1345+
func (e *AlgoOrderUpdateEvent) OrderFutures() (*types.Order, error) {
1346+
switch e.AlgoOrder.Status {
1347+
case "NEW", "CANCELED", "EXPIRED", "REJECTED", "TRIGGERING", "TRIGGERED", "FINISHED":
1348+
default:
1349+
return nil, errors.New("algo update event type is not for futures order")
1350+
}
1351+
1352+
return &types.Order{
1353+
Exchange: types.ExchangeBinance,
1354+
SubmitOrder: types.SubmitOrder{
1355+
Symbol: e.AlgoOrder.Symbol,
1356+
ClientOrderID: e.AlgoOrder.ClientAlgoId,
1357+
Side: toGlobalFuturesSideType(futures.SideType(e.AlgoOrder.Side)),
1358+
Type: toGlobalFuturesOrderType(futures.AlgoOrderType(e.AlgoOrder.OrderType)),
1359+
Quantity: e.AlgoOrder.Quantity,
1360+
Price: e.AlgoOrder.Price,
1361+
StopPrice: e.AlgoOrder.TriggerPrice,
1362+
TimeInForce: types.TimeInForce(e.AlgoOrder.TimeInForce),
1363+
},
1364+
OrderID: uint64(e.AlgoOrder.AlgoId),
1365+
Status: toGlobalFuturesOrderStatus(futures.OrderStatusType(e.AlgoOrder.Status)),
1366+
ExecutedQuantity: e.AlgoOrder.ExecutedQuantity,
1367+
UpdateTime: types.Time(e.TransactionTime.Time()),
1368+
}, nil
1369+
}

pkg/exchange/binance/stream.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ type Stream struct {
105105
accountConfigUpdateEventCallbacks []func(e *AccountConfigUpdateEvent)
106106
marginCallEventCallbacks []func(e *MarginCallEvent)
107107
listenKeyExpiredCallbacks []func(e *ListenKeyExpired)
108+
algoOrderUpdateEventCallbacks []func(e *AlgoOrderUpdateEvent)
108109

109110
errorCallbacks []func(e *ErrorEvent)
110111

@@ -190,6 +191,8 @@ func NewStream(ex *Exchange, client *binance.Client, futuresClient *futures.Clie
190191
// ===================================
191192
// Event type ACCOUNT_UPDATE from user data stream updates Balance and FuturesPosition.
192193
stream.OnOrderTradeUpdateEvent(stream.handleOrderTradeUpdateEvent)
194+
// Event type ALGO_UPDATE from user data stream updates AlgoOrder.
195+
stream.OnAlgoOrderUpdateEvent(stream.handleAlgoOrderUpdateEvent)
193196
// ===================================
194197

195198
if debugMode {
@@ -653,6 +656,8 @@ func (s *Stream) dispatchEvent(e interface{}) {
653656

654657
case *ForceOrderEvent:
655658
s.EmitForceOrderEvent(e)
659+
case *AlgoOrderUpdateEvent:
660+
s.EmitAlgoOrderUpdateEvent(e)
656661

657662
case *MarginCallEvent:
658663
}
@@ -864,3 +869,13 @@ func (s *Stream) listenKeyKeepAlive(ctx context.Context, listenKey string) {
864869
}
865870
}
866871
}
872+
873+
func (s *Stream) handleAlgoOrderUpdateEvent(e *AlgoOrderUpdateEvent) {
874+
order, err := e.OrderFutures()
875+
if err != nil {
876+
log.WithError(err).Error("algo order convert error")
877+
return
878+
}
879+
880+
s.EmitOrderUpdate(*order)
881+
}

pkg/exchange/binance/stream_callbacks.go

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/types/order.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,23 @@ const (
133133

134134
// OrderStatusExpired means the order is expired, it's an end state.
135135
OrderStatusExpired OrderStatus = "EXPIRED"
136+
137+
// OrderStatusTriggering means the algo order is triggering.
138+
OrderStatusTriggering OrderStatus = "TRIGGERING"
139+
140+
// OrderStatusTriggered means the algo order is triggered.
141+
OrderStatusTriggered OrderStatus = "TRIGGERED"
142+
143+
// OrderStatusFinished means the algo order is finished, it's an end state.
144+
OrderStatusFinished OrderStatus = "FINISHED"
136145
)
137146

138147
func (o OrderStatus) Closed() bool {
139148
return o == OrderStatusFilled ||
140149
o == OrderStatusCanceled ||
141150
o == OrderStatusRejected ||
142-
o == OrderStatusExpired
151+
o == OrderStatusExpired ||
152+
o == OrderStatusFinished
143153
}
144154

145155
type SubmitOrder struct {

0 commit comments

Comments
 (0)