1
- using System ;
1
+ using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
4
using System . Threading . Tasks ;
5
5
using ExchangeSharp . Models ;
6
+ using Newtonsoft . Json ;
6
7
using Newtonsoft . Json . Linq ;
8
+ using ExchangeSharp . API . Exchanges . MEXC . Models ;
7
9
8
10
namespace ExchangeSharp
9
11
{
@@ -21,6 +23,7 @@ private ExchangeMEXCAPI()
21
23
MarketSymbolSeparator = string . Empty ;
22
24
MarketSymbolIsUppercase = true ;
23
25
RateLimit = new RateGate ( 20 , TimeSpan . FromSeconds ( 2 ) ) ;
26
+ WebSocketOrderBookType = WebSocketOrderBookType . FullBookFirstThenDeltas ;
24
27
}
25
28
26
29
public override Task < string > ExchangeMarketSymbolToGlobalMarketSymbolAsync ( string marketSymbol )
@@ -369,6 +372,110 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy
369
372
await MakeJsonRequestAsync < JToken > ( "/order" , BaseUrl , payload , "DELETE" ) ;
370
373
}
371
374
375
+ protected override async Task < IWebSocket > OnGetDeltaOrderBookWebSocketAsync (
376
+ Action < ExchangeOrderBook > callback ,
377
+ int maxCount = 20 ,
378
+ params string [ ] marketSymbols
379
+ )
380
+ {
381
+ if ( marketSymbols == null || marketSymbols . Length == 0 )
382
+ {
383
+ marketSymbols = ( await GetMarketSymbolsAsync ( ) ) . ToArray ( ) ;
384
+ }
385
+
386
+ var initialSequenceIds = new Dictionary < string , long > ( ) ;
387
+
388
+ return await ConnectPublicWebSocketAsync (
389
+ string . Empty ,
390
+ ( _socket , msg ) =>
391
+ {
392
+ var json = msg . ToStringFromUTF8 ( ) ;
393
+
394
+ MarketDepthDiffUpdate update = null ;
395
+ try
396
+ {
397
+ update = JsonConvert . DeserializeObject < MarketDepthDiffUpdate > ( json , SerializerSettings ) ;
398
+ }
399
+ catch
400
+ {
401
+ }
402
+
403
+ if ( update == null || string . IsNullOrWhiteSpace ( update . Channel ) || update . Details == null )
404
+ {
405
+ return Task . CompletedTask ;
406
+ }
407
+
408
+ if ( update . Details . Version < initialSequenceIds [ update . Symbol ] )
409
+ {
410
+ // A deprecated update should be ignored
411
+ return Task . CompletedTask ;
412
+ }
413
+
414
+ var eventTimeDateTime = update . EventTime . UnixTimeStampToDateTimeMilliseconds ( ) ;
415
+
416
+ var orderBook = new ExchangeOrderBook
417
+ {
418
+ IsFromSnapshot = false ,
419
+ ExchangeName = Name ,
420
+ SequenceId = update . Details . Version ,
421
+ MarketSymbol = update . Symbol ,
422
+ LastUpdatedUtc = eventTimeDateTime ,
423
+ } ;
424
+
425
+ if ( update . Details . Asks != null )
426
+ {
427
+ foreach ( var ask in update . Details . Asks )
428
+ {
429
+ orderBook . Asks [ ask . Price ] = new ExchangeOrderPrice
430
+ {
431
+ Price = ask . Price ,
432
+ Amount = ask . Volume ,
433
+ } ;
434
+ }
435
+ }
436
+
437
+ if ( update . Details . Bids != null )
438
+ {
439
+ foreach ( var bid in update . Details . Bids )
440
+ {
441
+ orderBook . Bids [ bid . Price ] = new ExchangeOrderPrice
442
+ {
443
+ Price = bid . Price ,
444
+ Amount = bid . Volume ,
445
+ } ;
446
+ }
447
+ }
448
+
449
+ callback ( orderBook ) ;
450
+
451
+ return Task . CompletedTask ;
452
+ } ,
453
+ async ( _socket ) =>
454
+ {
455
+ foreach ( var marketSymbol in marketSymbols ) // "Every websocket connection maximum support 30 subscriptions at one time." - API docs
456
+ {
457
+ var initialBook = await OnGetOrderBookAsync ( marketSymbol , maxCount ) ;
458
+ initialBook . IsFromSnapshot = true ;
459
+
460
+ callback ( initialBook ) ;
461
+
462
+ initialSequenceIds [ marketSymbol ] = initialBook . SequenceId ;
463
+
464
+ var subscriptionParams = new List < string >
465
+ {
466
+ $ "[email protected] @{ marketSymbol } "
467
+ } ;
468
+
469
+ await _socket . SendMessageAsync ( new WebSocketSubscription
470
+ {
471
+ Method = "SUBSCRIPTION" ,
472
+ Params = subscriptionParams ,
473
+ } ) ;
474
+ }
475
+ }
476
+ ) ;
477
+ }
478
+
372
479
private async Task < JToken > GetBalance ( )
373
480
{
374
481
var token = await MakeJsonRequestAsync < JToken > ( "/account" , payload : await GetNoncePayloadAsync ( ) ) ;
0 commit comments