Skip to content

Commit c32f30c

Browse files
committed
support place algo order via websocket api
1 parent e3b4ad3 commit c32f30c

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed

v2/algo_order_place_service_ws.go

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
package binance
2+
3+
import (
4+
"encoding/json"
5+
"time"
6+
7+
"github.com/adshao/go-binance/v2/common"
8+
"github.com/adshao/go-binance/v2/common/websocket"
9+
"github.com/adshao/go-binance/v2/futures"
10+
)
11+
12+
// AlgoOrderPlaceWsService creates algo order using WebSocket API
13+
type AlgoOrderPlaceWsService struct {
14+
c websocket.Client
15+
ApiKey string
16+
SecretKey string
17+
KeyType string
18+
TimeOffset int64
19+
}
20+
21+
// NewAlgoOrderPlaceWsService init AlgoOrderPlaceWsService
22+
func NewAlgoOrderPlaceWsService(apiKey, secretKey string) (*AlgoOrderPlaceWsService, error) {
23+
conn, err := websocket.NewConnection(futures.WsApiInitReadWriteConn, futures.WebsocketKeepalive, futures.WebsocketTimeoutReadWriteConnection)
24+
if err != nil {
25+
return nil, err
26+
}
27+
28+
client, err := websocket.NewClient(conn)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
return &AlgoOrderPlaceWsService{
34+
c: client,
35+
ApiKey: apiKey,
36+
SecretKey: secretKey,
37+
KeyType: common.KeyTypeHmac,
38+
}, nil
39+
}
40+
41+
// AlgoOrderPlaceWsRequest parameters for 'algoOrder.place' websocket API
42+
type AlgoOrderPlaceWsRequest struct {
43+
algoType futures.OrderAlgoType
44+
symbol string
45+
side futures.SideType
46+
_type futures.AlgoOrderType
47+
positionSide *futures.PositionSideType
48+
timeInForce *futures.TimeInForceType
49+
quantity *string
50+
price *string
51+
triggerPrice string
52+
workingType *futures.WorkingType
53+
closePosition *bool
54+
reduceOnly *bool
55+
newClientOrderID *string
56+
newOrderRespType futures.NewOrderRespType
57+
recvWindow *int64
58+
}
59+
60+
// NewAlgoOrderPlaceWsRequest init AlgoOrderPlaceWsRequest
61+
func NewAlgoOrderPlaceWsRequest() *AlgoOrderPlaceWsRequest {
62+
return &AlgoOrderPlaceWsRequest{
63+
algoType: futures.OrderAlgoTypeConditional,
64+
newOrderRespType: futures.NewOrderRespTypeRESULT,
65+
}
66+
}
67+
68+
// Symbol set symbol
69+
func (s *AlgoOrderPlaceWsRequest) Symbol(symbol string) *AlgoOrderPlaceWsRequest {
70+
s.symbol = symbol
71+
return s
72+
}
73+
74+
// Side set side
75+
func (s *AlgoOrderPlaceWsRequest) Side(side futures.SideType) *AlgoOrderPlaceWsRequest {
76+
s.side = side
77+
return s
78+
}
79+
80+
// Type set type
81+
func (s *AlgoOrderPlaceWsRequest) Type(_type futures.AlgoOrderType) *AlgoOrderPlaceWsRequest {
82+
s._type = _type
83+
return s
84+
}
85+
86+
// PositionSide set positionSide
87+
func (s *AlgoOrderPlaceWsRequest) PositionSide(positionSide futures.PositionSideType) *AlgoOrderPlaceWsRequest {
88+
s.positionSide = &positionSide
89+
return s
90+
}
91+
92+
// TimeInForce set timeInForce
93+
func (s *AlgoOrderPlaceWsRequest) TimeInForce(timeInForce futures.TimeInForceType) *AlgoOrderPlaceWsRequest {
94+
s.timeInForce = &timeInForce
95+
return s
96+
}
97+
98+
// Quantity set quantity
99+
func (s *AlgoOrderPlaceWsRequest) Quantity(quantity string) *AlgoOrderPlaceWsRequest {
100+
s.quantity = &quantity
101+
return s
102+
}
103+
104+
// Price set price
105+
func (s *AlgoOrderPlaceWsRequest) Price(price string) *AlgoOrderPlaceWsRequest {
106+
s.price = &price
107+
return s
108+
}
109+
110+
// TriggerPrice set triggerPrice
111+
func (s *AlgoOrderPlaceWsRequest) TriggerPrice(triggerPrice string) *AlgoOrderPlaceWsRequest {
112+
s.triggerPrice = triggerPrice
113+
return s
114+
}
115+
116+
// WorkingType set workingType
117+
func (s *AlgoOrderPlaceWsRequest) WorkingType(workingType futures.WorkingType) *AlgoOrderPlaceWsRequest {
118+
s.workingType = &workingType
119+
return s
120+
}
121+
122+
// ClosePosition set closePosition
123+
func (s *AlgoOrderPlaceWsRequest) ClosePosition(closePosition bool) *AlgoOrderPlaceWsRequest {
124+
s.closePosition = &closePosition
125+
return s
126+
}
127+
128+
// ReduceOnly set reduceOnly
129+
func (s *AlgoOrderPlaceWsRequest) ReduceOnly(reduceOnly bool) *AlgoOrderPlaceWsRequest {
130+
s.reduceOnly = &reduceOnly
131+
return s
132+
}
133+
134+
// NewClientOrderID set newClientOrderID
135+
func (s *AlgoOrderPlaceWsRequest) NewClientOrderID(newClientOrderID string) *AlgoOrderPlaceWsRequest {
136+
s.newClientOrderID = &newClientOrderID
137+
return s
138+
}
139+
140+
// NewOrderResponseType set newOrderResponseType
141+
func (s *AlgoOrderPlaceWsRequest) NewOrderResponseType(newOrderResponseType futures.NewOrderRespType) *AlgoOrderPlaceWsRequest {
142+
s.newOrderRespType = newOrderResponseType
143+
return s
144+
}
145+
146+
// RecvWindow set recvWindow
147+
func (s *AlgoOrderPlaceWsRequest) RecvWindow(recvWindow int64) *AlgoOrderPlaceWsRequest {
148+
s.recvWindow = &recvWindow
149+
return s
150+
}
151+
152+
// buildParams builds params
153+
func (s *AlgoOrderPlaceWsRequest) buildParams() map[string]interface{} {
154+
m := map[string]interface{}{
155+
"algoType": s.algoType,
156+
"symbol": s.symbol,
157+
"side": s.side,
158+
"type": s._type,
159+
"triggerPrice": s.triggerPrice,
160+
"newOrderRespType": s.newOrderRespType,
161+
}
162+
163+
if s.positionSide != nil {
164+
m["positionSide"] = *s.positionSide
165+
}
166+
if s.timeInForce != nil {
167+
m["timeInForce"] = *s.timeInForce
168+
}
169+
if s.quantity != nil {
170+
m["quantity"] = *s.quantity
171+
}
172+
if s.price != nil {
173+
m["price"] = *s.price
174+
}
175+
if s.workingType != nil {
176+
m["workingType"] = *s.workingType
177+
}
178+
if s.closePosition != nil {
179+
m["closePosition"] = *s.closePosition
180+
}
181+
if s.reduceOnly != nil {
182+
m["reduceOnly"] = *s.reduceOnly
183+
}
184+
if s.newClientOrderID != nil {
185+
m["newClientOrderId"] = *s.newClientOrderID
186+
}
187+
if s.recvWindow != nil {
188+
m["recvWindow"] = *s.recvWindow
189+
}
190+
191+
return m
192+
}
193+
194+
// CreateAlgoOrderResult define algo order creation result
195+
type CreateAlgoOrderResult struct {
196+
AlgoId int64 `json:"algoId"`
197+
ClientAlgoId string `json:"clientAlgoId"`
198+
}
199+
200+
// CreateAlgoOrderWsResponse define 'algoOrder.place' websocket API response
201+
type CreateAlgoOrderWsResponse struct {
202+
Id string `json:"id"`
203+
Status int `json:"status"`
204+
Result CreateAlgoOrderResult `json:"result"`
205+
206+
// error response
207+
Error *common.APIError `json:"error,omitempty"`
208+
}
209+
210+
// SyncDo - sends 'algoOrder.place' request and receives response
211+
func (s *AlgoOrderPlaceWsService) SyncDo(requestID string, request *AlgoOrderPlaceWsRequest) (*CreateAlgoOrderWsResponse, error) {
212+
// Use custom method "algoOrder.place"
213+
method := websocket.WsApiMethodType("algoOrder.place")
214+
215+
rawData, err := websocket.CreateRequest(
216+
websocket.NewRequestData(
217+
requestID,
218+
s.ApiKey,
219+
s.SecretKey,
220+
s.TimeOffset,
221+
s.KeyType,
222+
),
223+
method,
224+
request.buildParams(),
225+
)
226+
if err != nil {
227+
return nil, err
228+
}
229+
230+
response, err := s.c.WriteSync(requestID, rawData, websocket.WriteSyncWsTimeout)
231+
if err != nil {
232+
return nil, err
233+
}
234+
235+
createAlgoOrderWsResponse := &CreateAlgoOrderWsResponse{}
236+
if err := json.Unmarshal(response, createAlgoOrderWsResponse); err != nil {
237+
return nil, err
238+
}
239+
240+
return createAlgoOrderWsResponse, nil
241+
}
242+
243+
// ReceiveAllDataBeforeStop waits until all responses will be received from websocket until timeout expired
244+
func (s *AlgoOrderPlaceWsService) ReceiveAllDataBeforeStop(timeout time.Duration) {
245+
s.c.Wait(timeout)
246+
}
247+
248+
// GetReadChannel returns channel with API response data (including API errors)
249+
func (s *AlgoOrderPlaceWsService) GetReadChannel() <-chan []byte {
250+
return s.c.GetReadChannel()
251+
}
252+
253+
// GetReadErrorChannel returns channel with errors which are occurred while reading websocket connection
254+
func (s *AlgoOrderPlaceWsService) GetReadErrorChannel() <-chan error {
255+
return s.c.GetReadErrorChannel()
256+
}
257+
258+
// GetReconnectCount returns count of reconnect attempts by client
259+
func (s *AlgoOrderPlaceWsService) GetReconnectCount() int64 {
260+
return s.c.GetReconnectCount()
261+
}
262+
263+

0 commit comments

Comments
 (0)