@@ -332,7 +332,7 @@ protected override async Task<ExchangeOrderBook> OnGetOrderBookAsync(string mark
332332 return ExchangeAPIExtensions . ParseOrderBookFromJTokenArrays ( obj , sequence : "lastUpdateId" , maxCount : maxCount ) ;
333333 }
334334
335- protected override async Task OnGetHistoricalTradesAsync ( Func < IEnumerable < ExchangeTrade > , bool > callback , string marketSymbol , DateTime ? startDate = null , DateTime ? endDate = null )
335+ protected override async Task OnGetHistoricalTradesAsync ( Func < IEnumerable < ExchangeTrade > , bool > callback , string marketSymbol , DateTime ? startDate = null , DateTime ? endDate = null , int ? limit = null )
336336 {
337337 /* [ {
338338 "a": 26129, // Aggregate tradeId
@@ -345,17 +345,44 @@ protected override async Task OnGetHistoricalTradesAsync(Func<IEnumerable<Exchan
345345 "M": true // Was the trade the best price match?
346346 } ] */
347347
348- ExchangeHistoricalTradeHelper state = new ExchangeHistoricalTradeHelper ( this )
348+ //if(startDate == null && endDate == null) {
349+ // await OnGetRecentTradesAsync(marketSymbol, limit);
350+ //}
351+ //else {
352+ //System.Windows.Forms.MessageBox.Show("Duplicate MessageId " + MessageId, "HMMMM RETURN?");
353+
354+
355+ ExchangeHistoricalTradeHelper state = new ExchangeHistoricalTradeHelper ( this )
349356 {
350- Callback = callback ,
351- EndDate = endDate ,
352- ParseFunction = ( JToken token ) => token . ParseTrade ( "q" , "p" , "m" , "T" , TimestampType . UnixMilliseconds , "a" , "false" ) ,
353- StartDate = startDate ,
354- MarketSymbol = marketSymbol ,
355- TimestampFunction = ( DateTime dt ) => ( ( long ) CryptoUtility . UnixTimestampFromDateTimeMilliseconds ( dt ) ) . ToStringInvariant ( ) ,
356- Url = "/aggTrades?symbol=[marketSymbol]&startTime={0}&endTime={1}" ,
357- } ;
358- await state . ProcessHistoricalTrades ( ) ;
357+ Callback = callback ,
358+ EndDate = endDate ,
359+ ParseFunction = ( JToken token ) => token . ParseTrade ( "q" , "p" , "m" , "T" , TimestampType . UnixMilliseconds , "a" , "false" ) ,
360+ StartDate = startDate ,
361+ MarketSymbol = marketSymbol ,
362+ TimestampFunction = ( DateTime dt ) => ( ( long ) CryptoUtility . UnixTimestampFromDateTimeMilliseconds ( dt ) ) . ToStringInvariant ( ) ,
363+ Url = "/aggTrades?symbol=[marketSymbol]&startTime={0}&endTime={1}" ,
364+ } ;
365+ await state . ProcessHistoricalTrades ( ) ;
366+ //}
367+ }
368+
369+ protected override async Task < IEnumerable < ExchangeTrade > > OnGetRecentTradesAsync ( string marketSymbol , int ? limit = null )
370+ {
371+ List < ExchangeTrade > trades = new List < ExchangeTrade > ( ) ;
372+ //var maxRequestLimit = 1000; //hard coded for now, should add limit as an argument
373+ //https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list
374+ int maxRequestLimit = ( limit == null || limit < 1 || limit > 1000 ) ? 1000 : ( int ) limit ;
375+
376+ JToken obj = await MakeJsonRequestAsync < JToken > ( $ "/aggTrades?symbol={ marketSymbol } &limit={ maxRequestLimit } ") ;
377+ //JToken obj = await MakeJsonRequestAsync<JToken>("/public/trades/" + marketSymbol + "?limit=" + maxRequestLimit + "?sort=DESC");
378+ if ( obj . HasValues ) { //
379+ foreach ( JToken token in obj ) {
380+ var trade = token . ParseTrade ( "q" , "p" , "m" , "T" , TimestampType . UnixMilliseconds , "a" , "false" ) ;
381+ trades . Add ( trade ) ;
382+ }
383+ }
384+ return trades . AsEnumerable ( ) . Reverse ( ) ; //Descending order (ie newest trades first)
385+ //return trades;
359386 }
360387
361388 public async Task OnGetHistoricalTradesAsync ( Func < IEnumerable < ExchangeTrade > , bool > callback , string marketSymbol , long startId , long ? endId = null )
@@ -407,6 +434,56 @@ public async Task OnGetHistoricalTradesAsync(Func<IEnumerable<ExchangeTrade>, bo
407434 } while ( callback ( trades ) && trades . Count > 0 ) ;
408435 }
409436
437+ public async Task OnGetHistoricalTradesAsync ( Func < IEnumerable < ExchangeTrade > , bool > callback , string marketSymbol , int limit = 100 )
438+ {
439+ /* [ {
440+ "a": 26129, // Aggregate tradeId
441+ "p": "0.01633102", // Price
442+ "q": "4.70443515", // Quantity
443+ "f": 27781, // First tradeId
444+ "l": 27781, // Last tradeId
445+ "T": 1498793709153, // Timestamp
446+ "m": true, // Was the buyer the maker?
447+ "M": true // Was the trade the best price match?
448+ } ] */
449+
450+ // TODO : Refactor into a common layer once more Exchanges implement this pattern
451+ // https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list
452+ if ( limit > 1000 ) limit = 1000 ; //Binance max = 1000
453+ var maxRequestLimit = 1000 ;
454+ var trades = new List < ExchangeTrade > ( ) ;
455+ var processedIds = new HashSet < long > ( ) ;
456+ marketSymbol = NormalizeMarketSymbol ( marketSymbol ) ;
457+
458+ do {
459+ //if(fromId > endId)
460+ // break;
461+
462+ trades . Clear ( ) ;
463+ //var limit = Math.Min(endId - fromId ?? maxRequestLimit, maxRequestLimit);
464+ var obj = await MakeJsonRequestAsync < JToken > ( $ "/aggTrades?symbol={ marketSymbol } &limit={ limit } ") ;
465+
466+ foreach ( var token in obj ) {
467+ var trade = token . ParseTrade ( "q" , "p" , "m" , "T" , TimestampType . UnixMilliseconds , "a" , "false" ) ;
468+ //long tradeId = (long)trade.Id.ConvertInvariant<ulong>();
469+ //if(tradeId < fromId)
470+ // continue;
471+ //if(tradeId > endId)
472+ // continue;
473+ //if(!processedIds.Add(tradeId))
474+ // continue;
475+
476+ trades . Add ( trade ) ;
477+ //fromId = tradeId;
478+ }
479+
480+ //fromId++;
481+ } while ( callback ( trades ) && trades . Count > 0 ) ;
482+ }
483+
484+
485+
486+
410487 protected override async Task < IEnumerable < MarketCandle > > OnGetCandlesAsync ( string marketSymbol , int periodSeconds , DateTime ? startDate = null , DateTime ? endDate = null , int ? limit = null )
411488 {
412489 /* [
0 commit comments