Skip to content

Commit f18ff02

Browse files
feat: Add functionality to public.websocket.all-liquidation (#210)
* added allLiquidation websocket handler * updated README * Update v5_ws_public_allliquidation.go * Update v5_ws_public_allliquidation.go --------- Co-authored-by: hirokisan <expsharetoworld@gmail.com>
1 parent f0b9b88 commit f18ff02

File tree

5 files changed

+213
-14
lines changed

5 files changed

+213
-14
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ The following API endpoints have been implemented
354354
- [Kline](https://bybit-exchange.github.io/docs/v5/websocket/public/kline)
355355
- [Ticker](https://bybit-exchange.github.io/docs/v5/websocket/public/ticker)
356356
- [Trade](https://bybit-exchange.github.io/docs/v5/websocket/public/trade)
357-
- [Liquidation](https://bybit-exchange.github.io/docs/v5/websocket/public/liquidation)
357+
- [Liquidation (Deprecated)](https://bybit-exchange.github.io/docs/v5/websocket/public/liquidation)
358+
- [AllLiquidation](https://bybit-exchange.github.io/docs/v5/websocket/public/all-liquidation)
358359

359360
#### Private Topics V5
360361

v5_client_web_socket_service.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ func (s *V5WebsocketService) Public(category CategoryV5) (V5WebsocketPublicServi
3030
return nil, err
3131
}
3232
return &V5WebsocketPublicService{
33-
client: s.client,
34-
connection: c,
35-
category: category,
36-
paramOrderBookMap: make(map[V5WebsocketPublicOrderBookParamKey]func(V5WebsocketPublicOrderBookResponse) error),
37-
paramKlineMap: make(map[V5WebsocketPublicKlineParamKey]func(V5WebsocketPublicKlineResponse) error),
38-
paramTickerMap: make(map[V5WebsocketPublicTickerParamKey]func(V5WebsocketPublicTickerResponse) error),
39-
paramTradeMap: make(map[V5WebsocketPublicTradeParamKey]func(V5WebsocketPublicTradeResponse) error),
40-
paramLiquidationMap: make(map[V5WebsocketPublicLiquidationParamKey]func(V5WebsocketPublicLiquidationResponse) error),
33+
client: s.client,
34+
connection: c,
35+
category: category,
36+
paramOrderBookMap: make(map[V5WebsocketPublicOrderBookParamKey]func(V5WebsocketPublicOrderBookResponse) error),
37+
paramKlineMap: make(map[V5WebsocketPublicKlineParamKey]func(V5WebsocketPublicKlineResponse) error),
38+
paramTickerMap: make(map[V5WebsocketPublicTickerParamKey]func(V5WebsocketPublicTickerResponse) error),
39+
paramTradeMap: make(map[V5WebsocketPublicTradeParamKey]func(V5WebsocketPublicTradeResponse) error),
40+
paramLiquidationMap: make(map[V5WebsocketPublicLiquidationParamKey]func(V5WebsocketPublicLiquidationResponse) error),
41+
paramAllLiquidationMap: make(map[V5WebsocketPublicAllLiquidationParamKey]func(V5WebsocketPublicAllLiquidationResponse) error),
4142
}, nil
4243
}
4344

v5_ws_public.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ type V5WebsocketPublicServiceI interface {
5454
V5WebsocketPublicLiquidationParamKey,
5555
func(V5WebsocketPublicLiquidationResponse) error,
5656
) (func() error, error)
57+
SubscribeAllLiquidation(
58+
V5WebsocketPublicAllLiquidationParamKey,
59+
func(V5WebsocketPublicAllLiquidationResponse) error,
60+
) (func() error, error)
5761
}
5862

5963
// V5WebsocketPublicService :
@@ -64,11 +68,12 @@ type V5WebsocketPublicService struct {
6468

6569
mu sync.Mutex
6670

67-
paramOrderBookMap map[V5WebsocketPublicOrderBookParamKey]func(V5WebsocketPublicOrderBookResponse) error
68-
paramKlineMap map[V5WebsocketPublicKlineParamKey]func(V5WebsocketPublicKlineResponse) error
69-
paramTickerMap map[V5WebsocketPublicTickerParamKey]func(V5WebsocketPublicTickerResponse) error
70-
paramTradeMap map[V5WebsocketPublicTradeParamKey]func(V5WebsocketPublicTradeResponse) error
71-
paramLiquidationMap map[V5WebsocketPublicLiquidationParamKey]func(V5WebsocketPublicLiquidationResponse) error
71+
paramOrderBookMap map[V5WebsocketPublicOrderBookParamKey]func(V5WebsocketPublicOrderBookResponse) error
72+
paramKlineMap map[V5WebsocketPublicKlineParamKey]func(V5WebsocketPublicKlineResponse) error
73+
paramTickerMap map[V5WebsocketPublicTickerParamKey]func(V5WebsocketPublicTickerResponse) error
74+
paramTradeMap map[V5WebsocketPublicTradeParamKey]func(V5WebsocketPublicTradeResponse) error
75+
paramLiquidationMap map[V5WebsocketPublicLiquidationParamKey]func(V5WebsocketPublicLiquidationResponse) error
76+
paramAllLiquidationMap map[V5WebsocketPublicAllLiquidationParamKey]func(V5WebsocketPublicAllLiquidationResponse) error
7277
}
7378

7479
const (
@@ -99,6 +104,9 @@ const (
99104

100105
// V5WebsocketPublicTopicLiquidation :
101106
V5WebsocketPublicTopicLiquidation = V5WebsocketPublicTopic("liquidation")
107+
108+
// V5WebsocketPublicTopicAllLiquidation :
109+
V5WebsocketPublicTopicAllLiquidation = V5WebsocketPublicTopic("allLiquidation")
102110
)
103111

104112
func (t V5WebsocketPublicTopic) String() string {
@@ -123,6 +131,8 @@ func (s *V5WebsocketPublicService) judgeTopic(respBody []byte) (V5WebsocketPubli
123131
return V5WebsocketPublicTopicTrade, nil
124132
case strings.Contains(topic, V5WebsocketPublicTopicLiquidation.String()):
125133
return V5WebsocketPublicTopicLiquidation, nil
134+
case strings.Contains(topic, V5WebsocketPublicTopicAllLiquidation.String()):
135+
return V5WebsocketPublicTopicAllLiquidation, nil
126136
}
127137
}
128138
return "", nil
@@ -281,6 +291,18 @@ func (s *V5WebsocketPublicService) Run() error {
281291
return err
282292
}
283293

294+
if err := f(resp); err != nil {
295+
return err
296+
}
297+
case V5WebsocketPublicTopicAllLiquidation:
298+
var resp V5WebsocketPublicAllLiquidationResponse
299+
if err := s.parseResponse(message, &resp); err != nil {
300+
return err
301+
}
302+
f, err := s.retrieveAllLiquidationFunc(resp.Key())
303+
if err != nil {
304+
return err
305+
}
284306
if err := f(resp); err != nil {
285307
return err
286308
}

v5_ws_public_allliquidation.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package bybit
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
"strings"
8+
9+
"github.com/gorilla/websocket"
10+
)
11+
12+
// SubscribeAllLiquidation :
13+
func (s *V5WebsocketPublicService) SubscribeAllLiquidation(
14+
key V5WebsocketPublicAllLiquidationParamKey,
15+
f func(V5WebsocketPublicAllLiquidationResponse) error,
16+
) (func() error, error) {
17+
if err := s.addParamAllLiquidationFunc(key, f); err != nil {
18+
return nil, err
19+
}
20+
param := struct {
21+
Op string `json:"op"`
22+
Args []interface{} `json:"args"`
23+
}{
24+
Op: "subscribe",
25+
Args: []interface{}{key.Topic()},
26+
}
27+
buf, err := json.Marshal(param)
28+
if err != nil {
29+
return nil, err
30+
}
31+
if err := s.writeMessage(websocket.TextMessage, buf); err != nil {
32+
return nil, err
33+
}
34+
return func() error {
35+
param := struct {
36+
Op string `json:"op"`
37+
Args []interface{} `json:"args"`
38+
}{
39+
Op: "unsubscribe",
40+
Args: []interface{}{key.Topic()},
41+
}
42+
buf, err := json.Marshal(param)
43+
if err != nil {
44+
return err
45+
}
46+
if err := s.writeMessage(websocket.TextMessage, []byte(buf)); err != nil {
47+
return err
48+
}
49+
s.removeParamAllLiquidationFunc(key)
50+
return nil
51+
}, nil
52+
}
53+
54+
// V5WebsocketPublicAllLiquidationParamKey :
55+
type V5WebsocketPublicAllLiquidationParamKey struct {
56+
Symbol SymbolV5
57+
}
58+
59+
// Topic :
60+
func (k *V5WebsocketPublicAllLiquidationParamKey) Topic() string {
61+
return fmt.Sprintf("%s.%s", V5WebsocketPublicTopicAllLiquidation, k.Symbol)
62+
}
63+
64+
// V5WebsocketPublicAllLiquidationResponse :
65+
type V5WebsocketPublicAllLiquidationResponse struct {
66+
Topic string `json:"topic"`
67+
Type string `json:"type"`
68+
TimeStamp int64 `json:"ts"`
69+
Data []V5WebsocketPublicAllLiquidationData `json:"data"`
70+
}
71+
72+
// V5WebsocketPublicAllLiquidationData :
73+
type V5WebsocketPublicAllLiquidationData struct {
74+
UpdatedTime uint64 `json:"T"` // The updated timestamp (ms)
75+
Symbol SymbolV5 `json:"s"` // Symbol name
76+
Side Side `json:"S"` // Position side. Buy,Sell. When you receive a Buy update, this means that a long position has been liquidated
77+
Size string `json:"v"` // Executed size
78+
Price string `json:"p"` // Bankruptcy price
79+
}
80+
81+
// Key :
82+
func (r *V5WebsocketPublicAllLiquidationResponse) Key() V5WebsocketPublicAllLiquidationParamKey {
83+
topic := r.Topic
84+
arr := strings.Split(topic, ".")
85+
if arr[0] != V5WebsocketPublicTopicAllLiquidation.String() || len(arr) != 2 {
86+
return V5WebsocketPublicAllLiquidationParamKey{}
87+
}
88+
89+
return V5WebsocketPublicAllLiquidationParamKey{
90+
Symbol: SymbolV5(arr[1]),
91+
}
92+
}
93+
94+
// addParamAllLiquidationFunc :
95+
func (s *V5WebsocketPublicService) addParamAllLiquidationFunc(key V5WebsocketPublicAllLiquidationParamKey, f func(V5WebsocketPublicAllLiquidationResponse) error) error {
96+
if _, exist := s.paramAllLiquidationMap[key]; exist {
97+
return errors.New("already registered for this key")
98+
}
99+
s.paramAllLiquidationMap[key] = f
100+
return nil
101+
}
102+
103+
// removeParamAllLiquidationFunc :
104+
func (s *V5WebsocketPublicService) removeParamAllLiquidationFunc(key V5WebsocketPublicAllLiquidationParamKey) {
105+
delete(s.paramAllLiquidationMap, key)
106+
}
107+
108+
// retrieveAllLiquidationFunc :
109+
func (s *V5WebsocketPublicService) retrieveAllLiquidationFunc(key V5WebsocketPublicAllLiquidationParamKey) (func(V5WebsocketPublicAllLiquidationResponse) error, error) {
110+
f, exist := s.paramAllLiquidationMap[key]
111+
if !exist {
112+
return nil, errors.New("func not found")
113+
}
114+
return f, nil
115+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package bybit
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/hirokisan/bybit/v2/testhelper"
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestWebsocketV5Public_AllLiquidation(t *testing.T) {
13+
data := []map[string]interface{}{
14+
{
15+
"p": "25844.48",
16+
"S": "Buy",
17+
"v": "2.8",
18+
"s": "BTCUSDT",
19+
"T": 1673251091822,
20+
},
21+
}
22+
respBody := map[string]interface{}{
23+
"topic": "allLiquidation.BTCUSDT",
24+
"type": "snapshot",
25+
"ts": 1673251091822,
26+
"data": data,
27+
}
28+
bytesBody, err := json.Marshal(respBody)
29+
require.NoError(t, err)
30+
31+
category := CategoryV5Linear
32+
33+
server, teardown := testhelper.NewWebsocketServer(
34+
testhelper.WithWebsocketHandlerOption(V5WebsocketPublicPathFor(category), bytesBody),
35+
)
36+
defer teardown()
37+
38+
wsClient := NewTestWebsocketClient().
39+
WithBaseURL(server.URL)
40+
41+
svc, err := wsClient.V5().Public(category)
42+
require.NoError(t, err)
43+
44+
{
45+
_, err := svc.SubscribeAllLiquidation(
46+
V5WebsocketPublicAllLiquidationParamKey{
47+
Symbol: SymbolV5BTCUSDT,
48+
},
49+
func(response V5WebsocketPublicAllLiquidationResponse) error {
50+
assert.Equal(t, respBody["topic"], response.Topic)
51+
return nil
52+
},
53+
)
54+
require.NoError(t, err)
55+
}
56+
57+
assert.NoError(t, svc.Run())
58+
assert.NoError(t, svc.Ping())
59+
assert.NoError(t, svc.Close())
60+
}

0 commit comments

Comments
 (0)