تدفقات WebSocket

مهلة الاتصال

    - يقوم الخادم بإغلاق اتصال WebSocket بعد 60 ثانية من عدم النشاط (Connection Keep-Alive)

    - يتم تعريف الخمول على أنه عدم وجود طلبات يرسلها العميل

الحفاظ على الاتصال

للحفاظ على اتصال WebSocket نشطًا، تحتاج إلى

    - إرسال طلبات دورية كل 50 ثانية

    - التعامل بشكل صحيح مع الانقطاعات المحتملة في منطق تطبيقك

التفويض

مقدمة

قبل توقيع أي طلبات WebSocket، يجب عليك إنشاء مفتاح API في حسابك الشخصي في Cryptomus

تتوفر تعليمات مفصلة لإنشاء مفتاح API هنا

الحصول على رمز لمرة واحدة للاتصال

قبل الاتصال بخادم WebSocket، تحتاج إلى الحصول على رمز مصادقة لمرة واحدة

يمكنك الحصول على الرمز عن طريق الإرسال الطلب المقابل

الرمز صالح لمدة 5 دقائق أو حتى الاتصال الناجح الأول

الاتصال بخادم WebSocket

للاتصال بخادم WebSocket

1. احصل على لمرة واحدة رمز المصادقة

2. حدد الرمز في معلمة الاستعلام الرمز عند إنشاء الاتصال

مثال على عنوان URL للاتصال: wss://api-ws.cryptomus.com/ws?token=b0b1cacd26993392ecf072155bd1686c96e380ad12cefa564aa6665c85c77334

لا يمكن استخدام الرمز إلا مرة واحدة. لكل اتصال جديد، يجب عليك طلب رمز جديد.

بعد التحقق الناجح من الرمز، سيتم إنشاء الاتصال ويمكنك الاشتراك في القنوات المتاحة

الحصول على رمز مصادقة لمرة واحدة لاتصال WebSocket

يسمح بإنشاء رمز مصادقة لمرة واحدة للاتصال بخادم WebSocket. يبقى الرمز صالحًا حتى أول اتصال ناجح أو حتى انتهاء صلاحيته (5 دقائق).

GET
/v2/user-api/exchange/account/web-socket/token
ينسخ

رؤوس التفويض

المعلومات الكاملة حول رؤوس التفويض المطلوبة متاحة هنا

إجابة

{ "token": "168b34a3a12370740ff1654f0d0c4726ff1bba8c4675edc0d7553f15e5a2a094" }
ينسخ

الرموز الممكنة

200: تم إنشاء الطلب بنجاح

404: لم يتم العثور على المستخدم أو المورد

500: خطأ داخلي في الخادم

رموز مقياس العمق

طلب

GET
https://exchange-ws.cryptomus.com/api/v2/symbol-scales?symbol={symbol}
ينسخ

إجابة


1{
2  "status": "success",
3  "message": "success",
4  "data": [
5    {
6      "scale": "0.01",
7      "index": 0 // index
8    },
9    ...
10  ]
11}
ينسخ

قائمة السوق

طلب

GET
https://api-app.cryptomus.com/v1/exchange/market
ينسخ

إجابة


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}
ينسخ

مثال على التنفيذ

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            
ينسخ

Python


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            
ينسخ

تعيد جميع نقاط النهاية الوقت بتنسيق الطابع الزمني الخاص بـ Unix

هيكل رسالة الطلب

اسمنوع المعلمةتعريف
idIntegerيجب أن تكون فريدة لمعالجة الاستجابة لطلبك
methodStringاسم الطلب
paramsArrayمرر المعلمات للطريقة هنا

نوع المعلمة

Integer

تعريف

يجب أن تكون فريدة لمعالجة الاستجابة لطلبك

نوع المعلمة

String

تعريف

اسم الطلب

نوع المعلمة

Array

تعريف

مرر المعلمات للطريقة هنا

سيتم إنهاء اتصال WebSocket إذا تم إرسال JSON غير صالح

أنواع الرسائل والطلبات

- الطلب (`ping`، `candles_request`، إلخ.)

- الاشتراك (`candles_subscribe`، `lastprice_subscribe`، إلخ.). سيتم إلغاء إعادة الاشتراك في نفس نوع البيانات.

رسالة الرد

اسمنوع المعلمةتعريف
idIntegerمعرف الطلب
dataNullإذا فشل الطلب. في حال نجاحه، يظهر أدناه هيكل الاستجابة لكل طريقة.
errorNullإذا نجح الأمر. إذا كان هناك خطأ
messageString
codeIntegerرمز الخطأ

نوع المعلمة

Integer

تعريف

معرف الطلب

نوع المعلمة

Null

تعريف

إذا فشل الطلب. في حال نجاحه، يظهر أدناه هيكل الاستجابة لكل طريقة.

نوع المعلمة

Null

تعريف

إذا نجح الأمر. إذا كان هناك خطأ

نوع المعلمة

Integer

تعريف

رمز الخطأ

الرمز: 1. الرسالة: تنسيق الرسالة غير صالح

الرمز: 2. الرسالة: أخطاء أخرى

أنواع رسائل الاستجابة

- نتيجة الاستعلام

- حالة الاشتراك (نجاح/فشل)

- تحديث الأحداث

تنس الطاولة

بينغ


1{    
2  "id": 0,   
3  "method": "ping",   
4  "params": []
5} 
6          
ينسخ

استجابة بونغ


1{
2  "id": 0,
3  "method": "pong",
4  "data": null,
5  "error": null
6}         
7          
ينسخ

أمثلة على الاشتراكات

طلب


1{    
2  "id": 0,    
3  "method": "trade_subscribe",    
4  "params": [  
5      "BTC_USDT"    
6  ]
7}            
8          
ينسخ

إجابة


1{    
2  "id": 0,    
3  "method": "trade_subscribe",  
4  "data": {       
5	  "status": "success"    
6  },    
7  "error": null  
8} 
9          
ينسخ

تحديث الحدث


1{    
2  "id": 0,    
3  "method": "trade_update",    
4  "data": [], // See structure for each method below  
5  "error": null
6}  
7          
ينسخ

السعر الأخير

الاشتراك


1{   
2  "id": 0,   
3  "method": "lastprice_subscribe",   
4  "params": [   
5    "BTC_USDT",  // Market
6    "BTC_USDT",       
7    "ETH_USDT",      
8    ...    
9  ]
10}       
11          
ينسخ
اشترك في جميع الأحداث lastprice_subscribe

1{    
2  "id": 0,   
3  "method": "lastprice_subscribe",   
4  "params": [  
5    "all" // This also works for other events    
6  ]
7}
8            
ينسخ

إجابة


1{    
2  "id": 0,    
3  "method": "lastprice_subscribe",  
4  "data": {       
5    "status": "success"    
6  },    
7  "error": null  
8}   
9          
ينسخ

حدث


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          
ينسخ

إلغاء الاشتراك

طلب

1{    
2  "id": 0,   
3  "method": "lastprice_unsubscribe",   
4  "params": [  
5    "BTC_USDT",       
6    "ETH_USDT",       
7    ...    
8  ]
9}             
10            
ينسخ
إلغاء الاشتراك في جميع الأحداث lastprice_unsubscribe

1{    
2  "id": 0,   
3  "method": "lastprice_unsubscribe",   
4  "params": [  
5    "all" // This also works for other events   
6  ]
7}  
8            
ينسخ

إجابة


1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null  
7}
ينسخ

عمق

الاشتراك

أولاً، عليك الحصول على مؤشر مقياس السوق كيفية الحصول عليها


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          
ينسخ
اشترك في جميع الأحداث depth_subscribe

1{    
2  "id": 0,   
3  "method": "depth_subscribe",   
4  "params": [  
5    "all" // This also works for other events    
6  ]
7}  
8            
ينسخ

إجابة


1{    
2  "id": 0,    
3  "method": "depth_subscribe",  
4  "data": {       
5    "status": "success"    
6  },    
7  "error": null  
8} 
9            
ينسخ

حدث


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            
ينسخ

إلغاء الاشتراك

طلب

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              
ينسخ
إلغاء الاشتراك في جميع الأحداث depth_unsubscribe

1{    
2  "id": 0,   
3  "method": "depth_unsubscribe",   
4  "params": [  
5    "all" // This also works for other events    
6  ]
7}  
8              
ينسخ
إجابة

1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null  
7}  
8              
ينسخ

شريط الأخبار

الاشتراك


1{   
2  "id": 0,   
3  "method": "ticker_subscribe",   
4  "params": [   
5    "BTC_USDT",  // Market
6    "BTC_USDT",       
7    "ETH_USDT",      
8    ...    
9  ]
10}  
11          
ينسخ
اشترك في جميع الأحداث ticker_subscribe

1{    
2  "id": 0,   
3  "method": "ticker_subscribe",   
4  "params": [  
5    "all" // This also works for other events    
6  ]
7} 
8          
ينسخ

إجابة


1{    
2  "id": 0,    
3  "method": "ticker_subscribe",  
4  "data": {       
5    "status": "success"    
6  },    
7  "error": null  
8}  
9          
ينسخ

حدث


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          
ينسخ

إلغاء الاشتراك

طلب

1{    
2  "id": 0,   
3  "method": "ticker_unsubscribe",   
4  "params": [  
5    "BTC_USDT",      // Market 
6    "ETH_USDT",       
7    ...    
8  ]
9} 
10            
ينسخ
إلغاء الاشتراك في جميع الأحداث ticker_unsubscribe

1{    
2  "id": 0,   
3  "method": "ticker_unsubscribe",   
4  "params": [  
5    "all" // This also works for other events    
6  ]
7} 
8            
ينسخ
إجابة

1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null  
7}  
8            
ينسخ

الصفقات

الاشتراك


1{   
2  "id": 0,   
3  "method": "trade_subscribe",   
4  "params": [   
5    "BTC_USDT",  // Market
6    "BTC_USDT",       
7    "ETH_USDT",      
8    ...    
9  ]
10}  
11          
ينسخ
اشترك في جميع الأحداث trade_subscribe

1{    
2  "id": 0,   
3  "method": "trade_subscribe",   
4  "params": [  
5    "all" // This also works for other events    
6  ]
7}  
8          
ينسخ

إجابة


1{    
2  "id": 0,    
3  "method": "trade_subscribe",  
4  "data": {       
5    "status": "success"    
6  },    
7  "error": null  
8}  
9          
ينسخ

حدث


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          
ينسخ

إلغاء الاشتراك

طلب

1{    
2  "id": 0,   
3  "method": "trade_unsubscribe",   
4  "params": [  
5    "BTC_USDT",    // Market   
6    "ETH_USDT",       
7    ...    
8  ]
9}  
10            
ينسخ
إلغاء الاشتراك في جميع الأحداث trade_unsubscribe

1{    
2  "id": 0,   
3  "method": "trade_unsubscribe",   
4  "params": [  
5    "all" // This also works for other events    
6  ]
7}  
8            
ينسخ
إجابة

1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null  
7}  
8            
ينسخ

طلبات

الاشتراك


1{   
2  "id": 0,   
3  "method": "order_subscribe",   
4  "params": [   
5    "BTC_USDT",  // Market
6    "TRX_USDT",       
7    "ETH_USDT",       
8    ...    
9  ]
10}  
11          
ينسخ

اشترك في جميع الأحداث order_subscribe


1{    
2  "id": 0,  
3  "method": "order_subscribe",    
4  "params": [      
5    "all" // This also works for other events    
6  ]
7}  
8          
ينسخ

إجابة


1{    
2  "id": 0,    
3  "method": "order_subscribe",  
4  "data": {      
5    "status": "success"    
6  },    
7  "error": null 
8} 
9          
ينسخ

الأحداث

تم إنشاء الطلب

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            
ينسخ
تم تحديث الطلب

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            
ينسخ
تم الانتهاء من الطلب

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            
ينسخ

إلغاء الاشتراك في التحديثات

من أسواق محددة

1{    
2  "id": 0,   
3  "method": "order_unsubscribe",   
4  "params": [  
5    "BTC_USDT",   // Market    
6    "ETH_USDT",       
7    ...    
8  ]
9} 
10            
ينسخ
من جميع الأسواق

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            
ينسخ
إجابة

1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null   
7} 
8            
ينسخ

الأرصدة

الاشتراك

العملة الأساسية من قائمة السوق


1{   
2  "id": 0,   
3  "method": "balance_subscribe",   
4  "params": [   
5    "BTC",  // BaseCurrency from market list
6    "TRX,      
7    "ETH",       
8    ...    
9  ]
10}  
11          
ينسخ

اشترك في جميع الأحداث balance_subscribe


1{    
2  "id": 0,  
3  "method": "balance_subscribe",    
4  "params": [       
5    "all" // This also works for other events    
6  ]
7}  
8          
ينسخ

إجابة


1{    
2  "id": 0,    
3  "method": "balance_subscribe",  
4  "data": {      
5    "status": "success"    
6  },    
7  "error": null   
8}  
9          
ينسخ

الأحداث


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          
ينسخ

إلغاء الاشتراك في الأحداث

من عملات محددة

العملة الأساسية من market-list


1{    
2  "id": 0,   
3  "method": "balance_unsubscribe",   
4  "params": [  
5    "BTC",       // BaseCurrency from market list
6    "ETH",       
7    ...    
8  ]
9}     
10            
ينسخ
من جميع العملات

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            
ينسخ
إجابة

1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null   
7}  
8            
ينسخ

العروض

الاشتراك


1{   
2  "id": 0,   
3  "method": "deal_subscribe",   
4  "params": [   
5    "BTC_USDT",   // Market
6    "TRX_USDT,       
7    "ETH_USDT",       
8    ...   
9  ]
10} 
11          
ينسخ

اشترك في جميع الأحداث deal_subscribe


1{    
2  "id": 0,  
3  "method": "deal_subscribe",    
4  "params": [       
5    "all" // This also works for other events    
6  ]
7}  
8          
ينسخ

إجابة


1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null  
7}
8          
ينسخ

الأحداث


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          
ينسخ

إلغاء الاشتراك في التحديثات

من أسواق محددة

1{    
2  "id": 0,   
3  "method": "deal_unsubscribe",   
4  "params": [  
5    "BTC_USDT",   // Market
6    "TRX_USDT,       
7    ...    
8  ]
9} 
10            
ينسخ
من جميع الأسواق

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            
ينسخ
إجابة

1{    
2  "id": 0,    
3  "data": {      
4    "status": "success"    
5  },    
6  "error": null   
7} 
8            
ينسخ