Strumienie WebSocket
Przekroczono limit czasu połączenia
- Serwer zamyka połączenie WebSocket po 60 sekundach bezczynności (Connection Keep-Alive)
- Bezczynność jest definiowana jako brak żądań wysłanych przez klienta
Utrzymywanie połączenia
Aby utrzymać połączenie WebSocket aktywne, należy
- Wysyłaj okresowe żądania co 50 sekund
- Prawidłowo obsługuj potencjalne rozłączenia w logice swojej aplikacji
Upoważnienie
Wstęp
Przed podpisaniem jakichkolwiek żądań WebSocket musisz utworzyć klucz API na swoim koncie osobistym Cryptomus
Szczegółowe instrukcje dotyczące tworzenia klucza API są dostępne Tutaj
Uzyskanie jednorazowego tokena do połączenia
Przed połączeniem się z serwerem WebSocket należy uzyskać jednorazowy token uwierzytelniający
Możesz uzyskać token wysyłając odpowiednie żądanie
Token jest ważny przez 5 minut lub do czasu pierwszego udanego połączenia
Łączenie się z serwerem WebSocket
Aby połączyć się z serwerem WebSocket
1. Uzyskaj jednorazową token uwierzytelniający
2. Określ token w parametrze zapytania token podczas nawiązywania połączenia
Przykład adresu URL połączenia: wss://api-ws.cryptomus.com/ws?token=b0b1cacd26993392ecf072155bd1686c96e380ad12cefa564aa6665c85c77334
Token można użyć tylko raz. Przy każdym nowym połączeniu należy poprosić o nowy token.
Po pomyślnej weryfikacji tokena połączenie zostanie nawiązane i będziesz mógł subskrybować dostępne kanały
Uzyskiwanie jednorazowego tokena uwierzytelniającego dla połączenia WebSocket
Umożliwia wygenerowanie jednorazowego tokena uwierzytelniającego do połączenia z serwerem WebSocket. Token jest ważny do pierwszego udanego połączenia lub do jego wygaśnięcia (5 minut).
Nagłówki autoryzacji
Dostępne są pełne informacje o wymaganych nagłówkach autoryzacyjnych Tutaj
Odpowiedź
{ "token": "168b34a3a12370740ff1654f0d0c4726ff1bba8c4675edc0d7553f15e5a2a094" }
KopiaMożliwe kody
200: Zamówienie zostało pomyślnie utworzone
404: Nie znaleziono użytkownika lub zasobu
500: Wewnętrzny błąd serwera
Symbole skali głębokości
Wniosek
Odpowiedź
1{
2 "status": "success",
3 "message": "success",
4 "data": [
5 {
6 "scale": "0.01",
7 "index": 0 // index
8 },
9 ...
10 ]
11}
KopiaLista rynkowa
Wniosek
Odpowiedź
1{
2 "result": [
3 {
4 "id": "01HSBPVS17CT2GN2FV34K3AMP9",
5 "symbol": "BTC_USDT",
6 "baseCurrency": "BTC",
7 "quoteCurrency": "USDT",
8 "baseMinSize": "0.0000100000000000",
9 "quoteMinSize": "0.1000000000000000",
10 "baseMaxSize": "10000000000.0000000000000000",
11 "quoteMaxSize": "99999999.0000000000000000",
12 "basePrec": "8",
13 "quotePrec": "6",
14 "baseCurrencyFullName": "Bitcoin",
15 "quoteCurrencyFullName": "Tether USD"
16 },
17 ...
18 ]
19}
KopiaPrzykładowa implementacja
Node.js
1const WebSocket = require('ws');
2
3class CryptomusWebSocket {
4 constructor(token) {
5 this.token = token;
6 this.socket = new WebSocket('wss://api-ws.cryptomus.com/ws?token=${this.token}');
7 this.setupConnection();
8 }
9
10 setupConnection() {
11 this.socket.on('open', () => {
12 console.log('Connected to Cryptomus WebSocket');
13 this.startPing();
14 });
15
16 this.socket.on('message', (data) => {
17 console.log('Received:', data.toString());
18 });
19 }
20
21 ping() {
22 if (this.socket.readyState === WebSocket.OPEN) {
23 this.socket.send(JSON.stringify({
24 id: 0,
25 method: "ping",
26 params: []
27 }));
28 }
29 }
30
31 startPing() {
32 setInterval(() => {
33 this.ping();
34 }, 50 * 1000); // Every 50 seconds
35 }
36}
37
38// Usage
39const token = "your_auth_token_here";
40const client = new CryptomusWebSocket(token);
41
KopiaPython
1import asyncio
2import websockets
3import json
4
5class CryptomusWebSocket:
6 def __init__(self, token):
7 self.token = token
8 self.socket = None
9
10 async def connect(self):
11 self.socket = await websockets.connect(f"wss://api-ws.cryptomus.com/ws?token={self.token}")
12 print('Connected to Cryptomus WebSocket')
13
14 async def ping(self):
15 await self.socket.send(json.dumps({
16 "id": 0,
17 "method": "ping",
18 "params": []
19 }))
20
21 async def start_ping(self):
22 while True:
23 await asyncio.sleep(50) # Every 50 seconds
24 await self.ping()
25
26 async def listen(self):
27 async for message in self.socket:
28 print(f"Received: {message}")
29
30 async def run(self):
31 await self.connect()
32
33 # Start ping task
34 ping_task = asyncio.create_task(self.start_ping())
35
36 # Listen for messages
37 await self.listen()
38
39# Usage
40token = "your_auth_token_here"
41client = CryptomusWebSocket(token)
42asyncio.run(client.run())
43
KopiaWszystkie punkty końcowe zwracają czas w formacie znacznika czasu Unix
Struktura wiadomości żądania
Nazwa | Typ parametru | Definicja |
---|---|---|
id | Integer | Powinien być unikalny, aby przetworzyć odpowiedź na Twoje żądanie |
method | String | Nazwa żądania |
params | Array | Przekaż tutaj parametry metody |
Typ parametru
IntegerDefinicja
Powinien być unikalny, aby przetworzyć odpowiedź na Twoje żądanieTyp parametru
StringDefinicja
Nazwa żądaniaTyp parametru
ArrayDefinicja
Przekaż tutaj parametry metody
Połączenie WebSocket zostanie zakończone, jeśli zostanie wysłany nieprawidłowy kod JSON
Typy wiadomości i żądań
- Żądanie (`ping`, `candles_request` itd.)
- Subskrypcja (`candles_subscribe`, `lastprice_subscribe` itd.). Ponowna subskrypcja tego samego typu danych zostanie anulowana.
Wiadomość odpowiedzi
Nazwa | Typ parametru | Definicja |
---|---|---|
id | Integer | Identyfikator żądania |
data | Null | Jeśli żądanie się nie powiedzie. Jeśli się powiedzie, struktura odpowiedzi dla każdej metody jest pokazana poniżej. |
error | Null | jeśli się powiedzie. Jeśli wystąpi błąd |
message | String | |
code | Integer | Kod błędu |
Typ parametru
IntegerDefinicja
Identyfikator żądaniaTyp parametru
NullDefinicja
Jeśli żądanie się nie powiedzie. Jeśli się powiedzie, struktura odpowiedzi dla każdej metody jest pokazana poniżej.Typ parametru
NullDefinicja
jeśli się powiedzie. Jeśli wystąpi błądTyp parametru
IntegerDefinicja
Kod błędu
Kod: 1. Wiadomość: Nieprawidłowy format wiadomości
Kod: 2. Komunikat: Inne błędy
Typy wiadomości odpowiedzi
- Wynik zapytania
- Status subskrypcji (powodzenie/niepowodzenie)
- Aktualizuj wydarzenia
Ping-pong
Świst
1{
2 "id": 0,
3 "method": "ping",
4 "params": []
5}
6
KopiaPong odpowiedzi
1{
2 "id": 0,
3 "method": "pong",
4 "data": null,
5 "error": null
6}
7
KopiaPrzykłady subskrypcji
Wniosek
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "params": [
5 "BTC_USDT"
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
KopiaAktualizacja wydarzenia
1{
2 "id": 0,
3 "method": "trade_update",
4 "data": [], // See structure for each method below
5 "error": null
6}
7
KopiaOstatnia cena
Prenumerata
1{
2 "id": 0,
3 "method": "lastprice_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "BTC_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
KopiaZapisz się na wszystkie wydarzenia lastprice_subscribe
1{
2 "id": 0,
3 "method": "lastprice_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "method": "lastprice_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
KopiaWydarzenie
1{
2 "id": 0,
3 "method": "lastprice_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750953362,
7 "price": "107152.55"
8 },
9 "error": null
10}
11
KopiaAnulowanie subskrypcji
Wniosek
1{
2 "id": 0,
3 "method": "lastprice_unsubscribe",
4 "params": [
5 "BTC_USDT",
6 "ETH_USDT",
7 ...
8 ]
9}
10
KopiaAnuluj subskrypcję wszystkich wydarzeń lastprice_unsubscribe
1{
2 "id": 0,
3 "method": "lastprice_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
KopiaGłębokość
Prenumerata
Najpierw musisz uzyskać wskaźnik skali rynku jak zdobyć
1{
2 "id": 0,
3 "method": "depth_subscribe",
4 "params": [
5 "BTC_USDT:0", // market:scale_index
6 "BTC_USDT:1",
7 "ETH_USDT:1",
8 ...
9 ]
10}
11
KopiaZapisz się na wszystkie wydarzenia depth_subscribe
1{
2 "id": 0,
3 "method": "depth_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "method": "depth_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
KopiaWydarzenie
1{
2 "id": 0,
3 "method": "depth_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750952911,
7 "full_reload": false, // If false, it is a partial update, if true, it is a fully updated orderbook.
8 "scale_index": 0,
9 "asks": [
10 [
11 "107043.93", // price
12 "0.304313" // value
13 ]
14 ],
15 "bids": [
16 [
17 "106976.11",
18 "0" // for partial update - finished orders will be 0
19 ]
20 ]
21 },
22 "error": null
23}
24
KopiaAnulowanie subskrypcji
Wniosek
1{
2 "id": 0,
3 "method": "depth_unsubscribe",
4 "params": [
5 "BTC_USDT:0", // market:scale_index
6 "ETH_USDT:1",
7 ...
8 ]
9}
10
KopiaAnuluj subskrypcję wszystkich wydarzeń depth_unsubscribe
1{
2 "id": 0,
3 "method": "depth_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
KopiaSerce
Prenumerata
1{
2 "id": 0,
3 "method": "ticker_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "BTC_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
KopiaZapisz się na wszystkie wydarzenia ticker_subscribe
1{
2 "id": 0,
3 "method": "ticker_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "method": "ticker_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
KopiaWydarzenie
1{
2 "id": 0,
3 "method": "ticker_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750953144,
7 "price": "107090.35",
8 "open": "107042.21",
9 "high": "108248.15",
10 "low": "106573.19",
11 "volume": "1531.027982",
12 "quote_volume": "164564314.80174687",
13 "price_change": "0.04"
14 },
15 "error": null
16}
17
KopiaAnulowanie subskrypcji
Wniosek
1{
2 "id": 0,
3 "method": "ticker_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "ETH_USDT",
7 ...
8 ]
9}
10
KopiaAnuluj subskrypcję wszystkich wydarzeń ticker_unsubscribe
1{
2 "id": 0,
3 "method": "ticker_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
KopiaTransakcje
Prenumerata
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "BTC_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
KopiaZapisz się na wszystkie wydarzenia trade_subscribe
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
KopiaWydarzenie
1{
2 "id": 0,
3 "method": "trade_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750953177,
7 "trades": [
8 {
9 "price": 107100.01,
10 "quantity": 0.000254,
11 "timestamp": 1750953177,
12 "direction": "buy"
13 },
14 ...
15 ]
16 },
17 "error": null
18}
19
KopiaAnulowanie subskrypcji
Wniosek
1{
2 "id": 0,
3 "method": "trade_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "ETH_USDT",
7 ...
8 ]
9}
10
KopiaAnuluj subskrypcję wszystkich wydarzeń trade_unsubscribe
1{
2 "id": 0,
3 "method": "trade_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
KopiaŚwięcenia
Prenumerata
1{
2 "id": 0,
3 "method": "order_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "TRX_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
KopiaZapisz się na wszystkie wydarzenia order_subscribe
1{
2 "id": 0,
3 "method": "order_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "method": "order_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
KopiaWydarzenia
Zamówienie utworzone
1{
2 "id": "1",
3 "method": "order_update",
4 "data": {
5 "type": "created",
6 "info": {
7 "id": "01JYET5DQ772MPYHHE417FQF1J",
8 "symbol": "TRX_USDT",
9 "orderType": "limit",
10 "direction": "sell",
11 "price": "0.2200000000000000",
12 "quantity": "50.0000000000000000",
13 "value": "11.0000000000000000",
14 "filledQuantity": "0.0000000000000000",
15 "filledValue": "0.0000000000000000",
16 "clientOid": null,
17 "createTs": 1750696376
18 }
19 },
20 "error": null
21}
22
KopiaZamówienie zaktualizowane
1{
2 "id": "3",
3 "method": "order_update",
4 "data": {
5 "type": "updated",
6 "info": {
7 "id": "01JYET5DQ772MPYHHE417FQF1J",
8 "symbol": "TRX_USDT",
9 "orderType": "limit",
10 "direction": "sell",
11 "price": "0.2200000000000000",
12 "quantity": "50.0000000000000000",
13 "value": "11.0000000000000000",
14 "filledQuantity": "20.0000000000000000",
15 "filledValue": "4.4000000000000000",
16 "clientOid": null,
17 "createTs": 1750696376,
18 "updateTs": 1750696487,
19 }
20 },
21 "error": null
22}
23
KopiaZamówienie zakończone
1{
2 "id": "3",
3 "method": "order_update",
4 "data": {
5 "type": "finished",
6 "info": {
7 "id": "01JYET5DQ772MPYHHE417FQF1J",
8 "symbol": "TRX_USDT",
9 "orderType": "limit",
10 "direction": "sell",
11 "price": "0.2200000000000000",
12 "quantity": "50.0000000000000000",
13 "value": "11.0000000000000000",
14 "filledQuantity": "50.0000000000000000",
15 "filledValue": "11.0000000000000000",
16 "clientOid": null,
17 "createTs": 1750696376,
18 "finishTs": 1750696417,
19 "state": "completed""internalState": "filled"
20 }
21 },
22 "error": null
23}
24
KopiaAnuluj subskrypcję aktualizacji
Z określonych rynków
1{
2 "id": 0,
3 "method": "order_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "ETH_USDT",
7 ...
8 ]
9}
10
KopiaZe wszystkich rynków
1{
2 "id": 0,
3 "method": "order_unsubscribe",
4 "params": [
5 "all" // Optional, will also work if an empty array is passed in
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
KopiaSalda
Prenumerata
Waluta bazowa z lista rynkowa
1{
2 "id": 0,
3 "method": "balance_subscribe",
4 "params": [
5 "BTC", // BaseCurrency from market list
6 "TRX,
7 "ETH",
8 ...
9 ]
10}
11
KopiaZapisz się na wszystkie wydarzenia balance_subscribe
1{
2 "id": 0,
3 "method": "balance_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "method": "balance_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
KopiaWydarzenia
1{
2 "id": "4",
3 "method": "balance_update",
4 "data": {
5 "info": {
6 "walletId": "01J7E836F6K5KCX5DP2W0F6FAG",
7 "currencyCode": "USDT",
8 "amount": "50.0000000000000000",
9 "oldBalance": "40000.0000000000000000",
10 "newBalance": "39950.00000000"
11 }
12 },
13 "error": null
14}
15
KopiaAnuluj subskrypcję wydarzeń
Z określonych walut
Waluta bazowa z market-list
1{
2 "id": 0,
3 "method": "balance_unsubscribe",
4 "params": [
5 "BTC", // BaseCurrency from market list
6 "ETH",
7 ...
8 ]
9}
10
KopiaZe wszystkich walut
1{
2 "id": 0,
3 "method": "balance_unsubscribe",
4 "params": [
5 "all" // Optional, will also work if an empty array is passed in
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
KopiaOferty
Prenumerata
1{
2 "id": 0,
3 "method": "deal_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "TRX_USDT,
7 "ETH_USDT",
8 ...
9 ]
10}
11
KopiaZapisz się na wszystkie wydarzenia deal_subscribe
1{
2 "id": 0,
3 "method": "deal_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
KopiaWydarzenia
1{
2 "id": "4",
3 "method": "deal_update",
4 "data": {
5 "info": {
6 "dealId": "01JYH50V5VWPP3QTYGM6CPZ0AR",
7 "symbol": "TRX_USDT",
8 "dealState": "completed",
9 "transactionId": "01JYH50V5YM8M3943KJ9HY2VXM",
10 "filledPrice": "0.2726960000000000",
11 "filledQuantity": "100.0000000000000000",
12 "filledValue": "27.2696000000000000",
13 "fee": "1.0907840000000000",
14 "feeCurrency": "USDT",
15 "tradeRole": "taker",
16 "committedAt": 1750774869
17 }
18 },
19 "error": null
20}
21
KopiaAnuluj subskrypcję aktualizacji
Z określonych rynków
1{
2 "id": 0,
3 "method": "deal_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "TRX_USDT,
7 ...
8 ]
9}
10
KopiaZe wszystkich rynków
1{
2 "id": 0,
3 "method": "deal_unsubscribe",
4 "params": [
5 "all" // Optional, will also work if an empty array is passed in
6 ]
7}
8
KopiaOdpowiedź
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
Kopia