Skip to content

Commit 0beccc0

Browse files
authored
Merge pull request #2394 from anywhy/binance-algo-order-ws
FIX: [binance] suppport binance ws algo order event update
2 parents 729d8a5 + 6b204bb commit 0beccc0

File tree

6 files changed

+470
-4
lines changed

6 files changed

+470
-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+
}

0 commit comments

Comments
 (0)