19 using System.Collections.Generic;
20 using System.Runtime.CompilerServices;
32 private static readonly Dictionary<string, Symbol> Symbols =
new(StringComparer.OrdinalIgnoreCase);
33 private static readonly Dictionary<Symbol, string> Tickers =
new();
40 public static void Set(
string ticker,
Symbol symbol)
44 Symbols[ticker] = symbol;
45 Tickers[symbol] = ticker;
47 var index = ticker.IndexOf(
'.');
50 var related = ticker.Substring(0, index);
51 if (Symbols.TryGetValue(related, out symbol) && symbol is
null)
53 Symbols.Remove(related);
83 symbol = result.Item2;
96 return Tickers.TryGetValue(symbol, out var ticker) ? ticker : symbol.
ID.
ToString();
110 return Tickers.TryGetValue(symbol, out ticker);
124 return Tickers.Remove(symbol, out var ticker) && Symbols.Remove(ticker, out symbol);
138 return Symbols.Remove(ticker, out var symbol) && Tickers.Remove(symbol, out ticker);
155 [MethodImpl(MethodImplOptions.AggressiveInlining)]
156 private static Tuple<bool, Symbol, InvalidOperationException>
TryGetSymbol(
string ticker)
160 if (!TryGetSymbolCached(ticker, out var symbol))
164 var search = $
"{ticker}.";
165 var match = Symbols.Where(kvp => kvp.Key.StartsWith(search, StringComparison.InvariantCultureIgnoreCase) && kvp.Value is not
null).ToList();
167 if (match.Count == 0)
170 Symbols[ticker] =
null;
171 return new(
false,
null,
null);
173 else if (match.Count == 1)
176 Symbols[ticker] = match[0].Value;
177 return new(
true, match[0].Value,
null);
179 else if (match.Count > 1)
182 return new(
false,
null,
new InvalidOperationException(
183 Messages.SymbolCache.MultipleMatchingTickersLocated(match.Select(kvp => kvp.Key))));
186 return new(symbol is not
null, symbol,
null);
197 [MethodImpl(MethodImplOptions.AggressiveInlining)]
198 private static bool TryGetSymbolCached(
string ticker, out Symbol symbol)
200 if (Symbols.TryGetValue(ticker, out symbol))
204 if (SecurityIdentifier.TryParse(ticker, out var sid))
206 symbol =
new Symbol(sid, sid.Symbol);