Skip to content

Commit 1d9ef07

Browse files
committed
Expose symbol dictionary method
Allow getting a dictionary of string to exchange market, handy for fast lookups and cached by default for performance
1 parent 5e51514 commit 1d9ef07

File tree

3 files changed

+45
-22
lines changed

3 files changed

+45
-22
lines changed

ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,11 @@ protected async override Task<IEnumerable<KeyValuePair<string, ExchangeTicker>>>
207207
List<KeyValuePair<string, ExchangeTicker>> tickers = new List<KeyValuePair<string, ExchangeTicker>>();
208208
string symbol;
209209
JToken obj = await MakeJsonRequestAsync<JToken>("/market/tickers", BaseUrl, null);
210+
Dictionary<string, ExchangeMarket> markets = await this.GetExchangeMarketDictionaryFromCacheAsync();
210211
foreach (JToken child in obj)
211212
{
212213
symbol = child["symbol"].ToStringInvariant();
213-
if (symbol != "hb10" && symbol != "huobi10") // WTF...
214+
if (markets.ContainsKey(symbol))
214215
{
215216
tickers.Add(new KeyValuePair<string, ExchangeTicker>(symbol, this.ParseTicker(child, symbol, null, null, "close", "amount", "vol")));
216217
}
@@ -431,7 +432,6 @@ protected override async Task<ExchangeOrderBook> OnGetOrderBookAsync(string mark
431432
[7990, 1.9970],
432433
[7995, 0.88],
433434
*/
434-
ExchangeOrderBook orders = new ExchangeOrderBook();
435435
JToken obj = await MakeJsonRequestAsync<JToken>("/market/depth?symbol=" + marketSymbol + "&type=step0", BaseUrl, null);
436436
return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj["tick"], sequence: "ts", maxCount: maxCount);
437437
}

ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -547,32 +547,17 @@ public virtual async Task<ExchangeMarket> GetExchangeMarketFromCacheAsync(string
547547
// TODO: Add not found dictionary, or some mechanism to mitigate this risk
548548
// not sure if this is needed, but adding it just in case
549549
await new SynchronizationContextRemover();
550-
CachedItem<Dictionary<string, ExchangeMarket>> cacheResult = await Cache.Get<Dictionary<string, ExchangeMarket>>(nameof(GetExchangeMarketFromCacheAsync), null);
551-
if (cacheResult.Found && cacheResult.Value.TryGetValue(marketSymbol, out ExchangeMarket market))
550+
Dictionary<string, ExchangeMarket> lookup = await this.GetExchangeMarketDictionaryFromCacheAsync();
551+
if (lookup != null && lookup.TryGetValue(marketSymbol, out ExchangeMarket market))
552552
{
553553
return market;
554554
}
555555

556556
// try again with a fresh request
557-
Cache.Remove(nameof(GetExchangeMarketFromCacheAsync));
558557
Cache.Remove(nameof(GetMarketSymbolsMetadataAsync));
559-
cacheResult = await Cache.Get<Dictionary<string, ExchangeMarket>>(nameof(GetExchangeMarketFromCacheAsync), async () =>
560-
{
561-
Dictionary<string, ExchangeMarket> symbolsMetadataDictionary = new Dictionary<string, ExchangeMarket>(StringComparer.OrdinalIgnoreCase);
562-
IEnumerable<ExchangeMarket> symbolsMetadata = await GetMarketSymbolsMetadataAsync();
563-
564-
// build a new lookup dictionary
565-
foreach (ExchangeMarket symbolMetadata in symbolsMetadata)
566-
{
567-
symbolsMetadataDictionary[symbolMetadata.MarketSymbol] = symbolMetadata;
568-
}
569-
570-
// return the cached dictionary for 4 hours
571-
return new CachedItem<Dictionary<string, ExchangeMarket>>(symbolsMetadataDictionary, CryptoUtility.UtcNow.AddHours(4.0));
572-
});
573-
574-
// attempt to lookup one more time in the dictionary
575-
if (cacheResult.Found && cacheResult.Value.TryGetValue(marketSymbol, out market))
558+
Cache.Remove(nameof(ExchangeAPIExtensions.GetExchangeMarketDictionaryFromCacheAsync));
559+
lookup = await this.GetExchangeMarketDictionaryFromCacheAsync();
560+
if (lookup != null && lookup.TryGetValue(marketSymbol, out market))
576561
{
577562
return market;
578563
}

ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,44 @@ async Task innerCallback(ExchangeOrderBook newOrderBook)
194194
return socket;
195195
}
196196

197+
/// <summary>
198+
/// Get cache of symbols metadata and put into a dictionary. This method looks in the cache first, and if found, returns immediately, otherwise makes a network request and puts it in the cache
199+
/// </summary>
200+
/// <param name="api">Exchange API</param>
201+
/// <returns>Dictionary of symbol name and market, or null if there was an error</returns>
202+
public static async Task<Dictionary<string, ExchangeMarket>> GetExchangeMarketDictionaryFromCacheAsync(this ExchangeAPI api)
203+
{
204+
await new SynchronizationContextRemover();
205+
CachedItem<Dictionary<string, ExchangeMarket>> cacheResult = await api.Cache.Get<Dictionary<string, ExchangeMarket>>(nameof(GetExchangeMarketDictionaryFromCacheAsync), async () =>
206+
{
207+
try
208+
{
209+
Dictionary<string, ExchangeMarket> symbolsMetadataDictionary = new Dictionary<string, ExchangeMarket>(StringComparer.OrdinalIgnoreCase);
210+
IEnumerable<ExchangeMarket> symbolsMetadata = await api.GetMarketSymbolsMetadataAsync();
211+
212+
// build a new lookup dictionary
213+
foreach (ExchangeMarket symbolMetadata in symbolsMetadata)
214+
{
215+
symbolsMetadataDictionary[symbolMetadata.MarketSymbol] = symbolMetadata;
216+
}
217+
218+
// return the cached dictionary for 4 hours
219+
return new CachedItem<Dictionary<string, ExchangeMarket>>(symbolsMetadataDictionary, CryptoUtility.UtcNow.AddHours(4.0));
220+
}
221+
catch// (Exception ex)
222+
{
223+
// if the network goes down this could log quite a lot of exceptions...
224+
//Logger.Error(ex);
225+
return new CachedItem<Dictionary<string, ExchangeMarket>>();
226+
}
227+
});
228+
if (cacheResult.Found)
229+
{
230+
return cacheResult.Value;
231+
}
232+
return null;
233+
}
234+
197235
/// <summary>
198236
/// Place a limit order by first querying the order book and then placing the order for a threshold below the bid or above the ask that would fully fulfill the amount.
199237
/// The order book is scanned until an amount of bids or asks that will fulfill the order is found and then the order is placed at the lowest bid or highest ask price multiplied

0 commit comments

Comments
 (0)