1+ using Newtonsoft . Json ;
2+ using Newtonsoft . Json . Linq ;
13using System ;
24using System . Collections . Generic ;
35using System . Linq ;
4- using System . Net . Http ;
5- using System . Text ;
66using System . Threading ;
77using System . Threading . Tasks ;
8- using Newtonsoft . Json . Linq ;
98
109namespace ExchangeSharp
1110{
1211 public partial class ExchangeDigifinexAPI : ExchangeAPI
1312 {
1413 private string [ ] Urls =
1514 {
16- "openapi.digifinex.com" ,
17- "openapi.digifinex.vip" , // these other URLs don't work anymore
15+ "openapi.digifinex.com" ,
16+ "openapi.digifinex.vip" , // these other URLs don't work anymore
1817 "openapi.digifinex.xyz" ,
19- } ;
18+ } ;
2019
2120 private string fastestUrl = null ;
2221 private int failedUrlCount ;
@@ -85,7 +84,7 @@ protected override async Task OnGetNonceOffset()
8584 var timeFaster = now - serverDate ;
8685 timeWindow = "30" ; // max latency of 30s
8786 NonceOffset = now - serverDate ; // how much time to substract from Nonce when making a request
88- //Console.WriteLine($"NonceOffset {GetHashCode()}: {NonceOffset}");
87+ //Console.WriteLine($"NonceOffset {GetHashCode()}: {NonceOffset}");
8988 }
9089 catch
9190 {
@@ -169,9 +168,7 @@ private async Task<ExchangeMarket> ParseExchangeMarketAsync(JToken x)
169168 } ;
170169 }
171170
172- protected internal override async Task <
173- IEnumerable < ExchangeMarket >
174- > OnGetMarketSymbolsMetadataAsync ( )
171+ protected internal override async Task < IEnumerable < ExchangeMarket > > OnGetMarketSymbolsMetadataAsync ( )
175172 {
176173 await inited . Task ;
177174 JToken obj = await MakeJsonRequestAsync < JToken > ( "markets" ) ;
@@ -189,9 +186,8 @@ protected override async Task<IEnumerable<string>> OnGetMarketSymbolsAsync()
189186 return ( await GetMarketSymbolsMetadataAsync ( ) ) . Select ( x => x . MarketSymbol ) ;
190187 }
191188
192- private async Task < ExchangeTicker > ParseTickerAsync ( JToken x )
189+ private async Task < ExchangeTicker > ParseTickerAsync ( JToken t , JToken dateStr )
193190 {
194- var t = x [ "ticker" ] [ 0 ] ;
195191 var symbol = t [ "symbol" ] . ToStringUpperInvariant ( ) ;
196192 var ( baseCurrency , quoteCurrency ) = await ExchangeMarketSymbolToCurrenciesAsync ( symbol ) ;
197193
@@ -210,16 +206,34 @@ private async Task<ExchangeTicker> ParseTickerAsync(JToken x)
210206 QuoteCurrencyVolume = t [ "base_vol" ] . ConvertInvariant < decimal > ( ) ,
211207 BaseCurrencyVolume = t [ "vol" ] . ConvertInvariant < decimal > ( ) ,
212208 Timestamp = CryptoUtility . UnixTimeStampToDateTimeSeconds (
213- x [ "date" ] . ConvertInvariant < long > ( )
209+ //t["date"].ConvertInvariant<long>()
210+ dateStr . ConvertInvariant < long > ( )
214211 ) ,
215212 } ,
216213 } ;
217214 }
218215
216+ protected override async Task < IEnumerable < KeyValuePair < string , ExchangeTicker > > > OnGetTickersAsync ( )
217+ {
218+ List < KeyValuePair < string , ExchangeTicker > > tickers = new List < KeyValuePair < string , ExchangeTicker > > ( ) ;
219+ JToken token = await MakeJsonRequestAsync < JToken > ( "/ticker" ) ;
220+ foreach ( JToken tick in token [ "ticker" ] )
221+ {
222+ string marketSymbol = tick [ "symbol" ] . ToStringInvariant ( ) ;
223+ tickers . Add (
224+ new KeyValuePair < string , ExchangeTicker > (
225+ marketSymbol ,
226+ await ParseTickerAsync ( tick , token [ "date" ] )
227+ )
228+ ) ;
229+ }
230+ return tickers ;
231+ }
232+
219233 protected override async Task < ExchangeTicker > OnGetTickerAsync ( string marketSymbol )
220234 {
221235 JToken obj = await MakeJsonRequestAsync < JToken > ( $ "/ticker?symbol={ marketSymbol } ") ;
222- return await ParseTickerAsync ( obj ) ;
236+ return await ParseTickerAsync ( obj [ "ticker" ] [ 0 ] , obj [ "date" ] ) ;
223237 }
224238
225239 protected override async Task < ExchangeOrderBook > OnGetOrderBookAsync (
@@ -388,9 +402,10 @@ protected override async Task<IEnumerable<ExchangeOrderResult>> OnGetOpenOrderDe
388402 ) ;
389403 }
390404
391- protected override async Task <
392- IEnumerable < ExchangeOrderResult >
393- > OnGetCompletedOrderDetailsAsync ( string marketSymbol = null , DateTime ? afterDate = null )
405+ protected override async Task < IEnumerable < ExchangeOrderResult > > OnGetCompletedOrderDetailsAsync (
406+ string marketSymbol = null ,
407+ DateTime ? afterDate = null
408+ )
394409 {
395410 Dictionary < string , object > payload = await GetNoncePayloadAsync ( ) ;
396411 var url = "/spot/mytrades?limit=500" ;
@@ -443,7 +458,7 @@ protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(
443458 $ "/spot/order?order_id={ orderId } ",
444459 payload : payload
445460 ) ;
446- var x = token [ "data" ] ;
461+ var x = token [ "data" ] [ 0 ] ;
447462 return new ExchangeOrderResult
448463 {
449464 MarketSymbol = x [ "symbol" ] . ToStringUpperInvariant ( ) ,
@@ -458,7 +473,7 @@ protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(
458473 AveragePrice = x [ "avg_price" ] . ConvertInvariant < decimal > ( ) ,
459474 Amount = x [ "amount" ] . ConvertInvariant < decimal > ( ) ,
460475 AmountFilled = x [ "executed_amount" ] . ConvertInvariant < decimal > ( ) ,
461- IsBuy = x [ "type" ] . ToStringLowerInvariant ( ) == "buy " ,
476+ IsBuy = x [ "type" ] . ToStringLowerInvariant ( ) == "buy_market " ,
462477 Result = ParseOrderStatus ( x [ "status" ] ) ,
463478 } ;
464479 }
@@ -563,10 +578,86 @@ protected override async Task OnCancelOrderAsync(
563578
564579 #region WebSocket APIs
565580
566- protected override async Task < IWebSocket > OnGetTradesWebSocketAsync (
567- Func < KeyValuePair < string , ExchangeTrade > , Task > callback ,
581+ protected override async Task < IWebSocket > OnGetTickersWebSocketAsync (
582+ Action < IReadOnlyCollection < KeyValuePair < string , ExchangeTicker > > > callback ,
568583 params string [ ] marketSymbols
569584 )
585+ {
586+ await inited . Task ;
587+ if ( callback == null )
588+ {
589+ return null ;
590+ }
591+ else if ( marketSymbols == null || marketSymbols . Length == 0 )
592+ {
593+ marketSymbols = ( await GetMarketSymbolsAsync ( ) ) . Take ( 30 ) . ToArray ( ) ;
594+ Logger . Warn ( "subscribing to the first 30 symbols" ) ;
595+ }
596+ return await ConnectPublicWebSocketAsync (
597+ string . Empty ,
598+ async ( _socket , msg ) =>
599+ {
600+ JToken token = JToken . Parse (
601+ CryptoUtility
602+ . DecompressDeflate (
603+ ( new ArraySegment < byte > ( msg , 2 , msg . Length - 2 ) ) . ToArray ( )
604+ )
605+ . ToStringFromUTF8 ( )
606+ ) ;
607+ // doesn't send error msgs - just disconnects
608+ if ( token [ "method" ] . ToStringLowerInvariant ( ) == "all_ticker.update" )
609+ {
610+ var args = token [ "params" ] ;
611+ var x = args as JArray ;
612+ var tickers = new List < KeyValuePair < string , ExchangeTicker > > ( ) ;
613+
614+ for ( int i = 0 ; i < x . Count ; i ++ )
615+ {
616+ var tick = x [ i ] ;
617+ var symbol = tick [ "symbol" ] . ToStringUpperInvariant ( ) ;
618+ tickers . Add ( new KeyValuePair < string , ExchangeTicker > (
619+ symbol ,
620+ await this . ParseTickerWebSocketAsync ( symbol , tick )
621+ )
622+ ) ;
623+ }
624+ callback ( tickers ) ;
625+ }
626+ } ,
627+ async ( _socket2 ) =>
628+ {
629+ var id = Interlocked . Increment ( ref websocketMessageId ) ;
630+ await _socket2 . SendMessageAsync (
631+ new
632+ {
633+ id ,
634+ method = "all_ticker.subscribe" ,
635+ @params = marketSymbols
636+ }
637+ ) ;
638+ }
639+ ) ;
640+ }
641+
642+ private async Task < ExchangeTicker > ParseTickerWebSocketAsync ( string symbol , JToken token )
643+ {
644+ return await this . ParseTickerAsync (
645+ token ,
646+ symbol ,
647+ askKey : "best_ask" ,
648+ bidKey : "best_bid" ,
649+ lastKey : "last" ,
650+ baseVolumeKey : "base_volume_24h" ,
651+ quoteVolumeKey : "quote_volume_24h" ,
652+ timestampKey : "timestamp" ,
653+ TimestampType . UnixMilliseconds
654+ ) ;
655+ }
656+
657+ protected override async Task < IWebSocket > OnGetTradesWebSocketAsync (
658+ Func < KeyValuePair < string , ExchangeTrade > , Task > callback ,
659+ params string [ ] marketSymbols
660+ )
570661 {
571662 await inited . Task ;
572663 if ( callback == null )
@@ -601,12 +692,12 @@ params string[] marketSymbols
601692 // "id": null
602693 // }
603694 JToken token = JToken . Parse (
604- CryptoUtility
605- . DecompressDeflate (
606- ( new ArraySegment < byte > ( msg , 2 , msg . Length - 2 ) ) . ToArray ( )
607- )
608- . ToStringFromUTF8 ( )
609- ) ;
695+ CryptoUtility
696+ . DecompressDeflate (
697+ ( new ArraySegment < byte > ( msg , 2 , msg . Length - 2 ) ) . ToArray ( )
698+ )
699+ . ToStringFromUTF8 ( )
700+ ) ;
610701 // doesn't send error msgs - just disconnects
611702 if ( token [ "method" ] . ToStringLowerInvariant ( ) == "trades.update" )
612703 {
@@ -658,13 +749,13 @@ await callback.Invoke(
658749 {
659750 var id = Interlocked . Increment ( ref websocketMessageId ) ;
660751 await _socket2 . SendMessageAsync (
661- new
662- {
663- id ,
664- method = "trades.subscribe" ,
665- @params = marketSymbols
666- }
667- ) ;
752+ new
753+ {
754+ id ,
755+ method = "trades.subscribe" ,
756+ @params = marketSymbols
757+ }
758+ ) ;
668759 }
669760 ) ;
670761 }
@@ -716,12 +807,12 @@ params string[] marketSymbols
716807 // "id": null
717808 //}
718809 JToken token = JToken . Parse (
719- CryptoUtility
720- . DecompressDeflate (
721- ( new ArraySegment < byte > ( msg , 2 , msg . Length - 2 ) ) . ToArray ( )
722- )
723- . ToStringFromUTF8 ( )
724- ) ;
810+ CryptoUtility
811+ . DecompressDeflate (
812+ ( new ArraySegment < byte > ( msg , 2 , msg . Length - 2 ) ) . ToArray ( )
813+ )
814+ . ToStringFromUTF8 ( )
815+ ) ;
725816 if ( token [ "method" ] . ToStringLowerInvariant ( ) == "depth.update" )
726817 {
727818 var args = token [ "params" ] ;
@@ -757,17 +848,42 @@ params string[] marketSymbols
757848 {
758849 var id = Interlocked . Increment ( ref websocketMessageId ) ;
759850 await _socket . SendMessageAsync (
760- new
761- {
762- id ,
763- method = "depth.subscribe" ,
764- @params = marketSymbols
765- }
766- ) ;
851+ new
852+ {
853+ id ,
854+ method = "depth.subscribe" ,
855+ @params = marketSymbols
856+ }
857+ ) ;
767858 }
768859 ) ;
769860 }
770861
862+ private static async Task SubscribeToChannel (
863+ IWebSocket socket ,
864+ int id ,
865+ string channel ,
866+ string [ ] marketSymbols
867+ )
868+ {
869+ if ( marketSymbols . Length == 0 )
870+ {
871+ marketSymbols = new [ ] { "all" } ;
872+ }
873+
874+ var payload = JsonConvert . SerializeObject (
875+ new
876+ {
877+ Id = id ,
878+ method = channel ,
879+ @params = marketSymbols
880+ } ,
881+ SerializerSettings
882+ ) ;
883+
884+ await socket . SendMessageAsync ( payload ) ;
885+ }
886+
771887 #endregion WebSocket APIs
772888 }
773889
0 commit comments