@@ -326,29 +326,31 @@ protected override async Task<IReadOnlyDictionary<string, ExchangeCurrency>> OnG
326
326
327
327
protected override async Task < IEnumerable < string > > OnGetMarketSymbolsAsync ( )
328
328
{
329
- List < string > symbols = new List < string > ( ) ;
330
- var tickers = await GetTickersAsync ( ) ;
331
- foreach ( var kv in tickers )
332
- {
333
- symbols . Add ( kv . Key ) ;
334
- }
335
- return symbols ;
329
+ return ( await GetMarketSymbolsMetadataAsync ( ) ) . Where ( x => x . IsActive . Value ) . Select ( x => x . MarketSymbol ) ;
336
330
}
337
331
338
332
protected internal override async Task < IEnumerable < ExchangeMarket > > OnGetMarketSymbolsMetadataAsync ( )
339
333
{
340
- //https://poloniex.com/public?command=returnOrderBook¤cyPair=all&depth=0
341
- /*
342
- * "BTC_CLAM": {
343
- "asks": [],
344
- "bids": [],
345
- "isFrozen": "0",
346
- "seq": 37268918
347
- }, ...
334
+ //https://docs.poloniex.com/#returnticker
335
+ /*
336
+ {
337
+ "BTC_BTS": {
338
+ "id": 14,
339
+ "last": "0.00000090",
340
+ "lowestAsk": "0.00000091",
341
+ "highestBid": "0.00000089",
342
+ "percentChange": "-0.02173913",
343
+ "baseVolume": "0.28698296",
344
+ "quoteVolume": "328356.84081156",
345
+ "isFrozen": "0",
346
+ "postOnly": "0",
347
+ "high24hr": "0.00000093",
348
+ "low24hr": "0.00000087"
349
+ },...
348
350
*/
349
351
350
- var markets = new List < ExchangeMarket > ( ) ;
351
- Dictionary < string , JToken > lookup = await MakeJsonRequestAsync < Dictionary < string , JToken > > ( "/public?command=returnOrderBook¤cyPair=all&depth=0 " ) ;
352
+ var markets = new List < ExchangeMarket > ( ) ;
353
+ Dictionary < string , JToken > lookup = await MakeJsonRequestAsync < Dictionary < string , JToken > > ( "/public?command=returnTicker " ) ;
352
354
// StepSize is 8 decimal places for both price and amount on everything at Polo
353
355
const decimal StepSize = 0.00000001m ;
354
356
const decimal minTradeSize = 0.0001m ;
@@ -357,16 +359,18 @@ protected internal override async Task<IEnumerable<ExchangeMarket>> OnGetMarketS
357
359
{
358
360
var market = new ExchangeMarket { MarketSymbol = kvp . Key , IsActive = false } ;
359
361
360
- string isFrozen = kvp . Value [ "isFrozen" ] . ToStringInvariant ( ) ;
361
- if ( string . Equals ( isFrozen , "0" ) )
362
+ string isFrozen = kvp . Value [ "isFrozen" ] . ToStringInvariant ( ) ;
363
+ string postOnly = kvp . Value [ "postOnly" ] . ToStringInvariant ( ) ;
364
+ if ( string . Equals ( isFrozen , "0" ) && string . Equals ( postOnly , "0" ) )
362
365
{
363
366
market . IsActive = true ;
364
367
}
365
368
366
369
string [ ] pairs = kvp . Key . Split ( '_' ) ;
367
370
if ( pairs . Length == 2 )
368
371
{
369
- market . QuoteCurrency = pairs [ 0 ] ;
372
+ market . MarketId = kvp . Value [ "id" ] . ToStringLowerInvariant ( ) ;
373
+ market . QuoteCurrency = pairs [ 0 ] ;
370
374
market . BaseCurrency = pairs [ 1 ] ;
371
375
market . PriceStepSize = StepSize ;
372
376
market . QuantityStepSize = StepSize ;
@@ -440,10 +444,19 @@ protected override async Task<IWebSocket> OnGetTickersWebSocketAsync(Action<IRea
440
444
441
445
protected override async Task < IWebSocket > OnGetTradesWebSocketAsync ( Func < KeyValuePair < string , ExchangeTrade > , Task > callback , params string [ ] marketSymbols )
442
446
{
443
- Dictionary < int , Tuple < string , long > > messageIdToSymbol = new Dictionary < int , Tuple < string , long > > ( ) ;
447
+ Dictionary < int , string > messageIdToSymbol = new Dictionary < int , string > ( ) ;
448
+ Dictionary < string , int > symbolToMessageId = new Dictionary < string , int > ( ) ;
449
+ var symMeta = await GetMarketSymbolsMetadataAsync ( ) ;
450
+ foreach ( var symbol in symMeta )
451
+ {
452
+ messageIdToSymbol . Add ( int . Parse ( symbol . MarketId ) , symbol . MarketSymbol ) ;
453
+ symbolToMessageId . Add ( symbol . MarketSymbol , int . Parse ( symbol . MarketId ) ) ;
454
+ }
444
455
return await ConnectPublicWebSocketAsync ( string . Empty , async ( _socket , msg ) =>
445
456
{
446
457
JToken token = JToken . Parse ( msg . ToStringFromUTF8 ( ) ) ;
458
+ if ( token . Type == JTokenType . Object && token [ "error" ] != null )
459
+ throw new APIException ( $ "Exchange returned error: { token [ "error" ] . ToStringInvariant ( ) } ") ;
447
460
int msgId = token [ 0 ] . ConvertInvariant < int > ( ) ;
448
461
449
462
if ( msgId == 1010 || token . Count ( ) == 2 ) // "[7,2]"
@@ -459,18 +472,17 @@ protected override async Task<IWebSocket> OnGetTradesWebSocketAsync(Func<KeyValu
459
472
var dataType = data [ 0 ] . ToStringInvariant ( ) ;
460
473
if ( dataType == "i" )
461
474
{
462
- var marketInfo = data [ 1 ] ;
463
- var market = marketInfo [ "currencyPair" ] . ToStringInvariant ( ) ;
464
- messageIdToSymbol [ msgId ] = new Tuple < string , long > ( market , 0 ) ;
475
+ // can also populate messageIdToSymbol from here
476
+ continue ;
465
477
}
466
478
else if ( dataType == "t" )
467
479
{
468
- if ( messageIdToSymbol . TryGetValue ( msgId , out Tuple < string , long > symbol ) )
469
- { // 0 1 2 3 4 5
470
- // ["t", "<trade id>", <1 for buy 0 for sell>, "<price>", "<size>", <timestamp>]
471
- ExchangeTrade trade = data . ParseTrade ( amountKey : 4 , priceKey : 3 , typeKey : 2 , timestampKey : 5 ,
472
- timestampType : TimestampType . UnixSeconds , idKey : 1 , typeKeyIsBuyValue : "1" ) ;
473
- await callback ( new KeyValuePair < string , ExchangeTrade > ( symbol . Item1 , trade ) ) ;
480
+ if ( messageIdToSymbol . TryGetValue ( msgId , out string symbol ) )
481
+ { // 0 1 2 3 4 5 6
482
+ // ["t", "<trade id>", <1 for buy 0 for sell>, "<price>", "<size>", <timestamp>, "<epoch_ms>" ]
483
+ ExchangeTrade trade = data . ParseTrade ( amountKey : 4 , priceKey : 3 , typeKey : 2 , timestampKey : 6 ,
484
+ timestampType : TimestampType . UnixMilliseconds , idKey : 1 , typeKeyIsBuyValue : "1" ) ;
485
+ await callback ( new KeyValuePair < string , ExchangeTrade > ( symbol , trade ) ) ;
474
486
}
475
487
}
476
488
else if ( dataType == "o" )
@@ -484,14 +496,19 @@ protected override async Task<IWebSocket> OnGetTradesWebSocketAsync(Func<KeyValu
484
496
}
485
497
} , async ( _socket ) =>
486
498
{
499
+ IEnumerable < int > marketIDs = null ;
487
500
if ( marketSymbols == null || marketSymbols . Length == 0 )
488
501
{
489
- marketSymbols = ( await GetMarketSymbolsAsync ( ) ) . ToArray ( ) ;
502
+ marketIDs = messageIdToSymbol . Keys ;
503
+ }
504
+ else
505
+ {
506
+ marketIDs = marketSymbols . Select ( s => symbolToMessageId [ s ] ) ;
490
507
}
491
508
// subscribe to order book and trades channel for each symbol
492
- foreach ( var sym in marketSymbols )
509
+ foreach ( var id in marketIDs )
493
510
{
494
- await _socket . SendMessageAsync ( new { command = "subscribe" , channel = NormalizeMarketSymbol ( sym ) } ) ;
511
+ await _socket . SendMessageAsync ( new { command = "subscribe" , channel = id } ) ;
495
512
}
496
513
} ) ;
497
514
}
0 commit comments