private async Task <PairRate> CreateExchangeRate(KeyValuePair <string, ExchangeTicker> ticker)
        {
            if (notFoundSymbols.TryGetValue(ticker.Key, out _))
            {
                return(null);
            }
            try
            {
                var tickerName = await _ExchangeAPI.ExchangeMarketSymbolToGlobalMarketSymbolAsync(ticker.Key);

                if (!CurrencyPair.TryParse(tickerName, out var pair))
                {
                    notFoundSymbols.TryAdd(ticker.Key, ticker.Key);
                    return(null);
                }
                if (ReverseCurrencyPair)
                {
                    pair = new CurrencyPair(pair.Right, pair.Left);
                }
                return(new PairRate(pair, new BidAsk(ticker.Value.Bid, ticker.Value.Ask)));
            }
            catch (ArgumentException)
            {
                notFoundSymbols.TryAdd(ticker.Key, ticker.Key);
                return(null);
            }
        }
        public async Task <Tuple <DateTime, DateTime> > CacheAllData(ExchangeAPI api, Exchange exchange)
        {
            Global.Logger.Information($"Starting CacheAllData");
            var watch1 = System.Diagnostics.Stopwatch.StartNew();

            var exchangeCoins = api.GetMarketSymbolsMetadataAsync().Result.Where(m => m.BaseCurrency == Global.Configuration.TradeOptions.QuoteCurrency);

            // If there are items on the only trade list remove the rest
            if (Global.Configuration.TradeOptions.OnlyTradeList.Count > 0)
            {
                exchangeCoins = exchangeCoins.Where(m => Global.Configuration.TradeOptions.OnlyTradeList.Any(c => c.Contains(m.MarketSymbol))).ToList();
            }

            var currentExchangeOption = Global.Configuration.ExchangeOptions.FirstOrDefault();

            IExchangeAPI realExchange = ExchangeAPI.GetExchangeAPI(api.Name);

            var returns = new Tuple <DateTime, DateTime>(DateTime.MinValue, DateTime.MinValue);

            foreach (var coin in exchangeCoins)
            {
                var symbol = coin.MarketSymbol;

                if (realExchange is ExchangeBinanceAPI)
                {
                    symbol = await api.ExchangeMarketSymbolToGlobalMarketSymbolAsync(symbol);
                }

                var backtestOptions = new BacktestOptions
                {
                    DataFolder   = Global.DataPath,
                    Exchange     = exchange,
                    Coin         = symbol,
                    CandlePeriod = Int32.Parse(currentExchangeOption.SimulationCandleSize)
                };

                var key1  = api.Name + backtestOptions.Coin + backtestOptions.CandlePeriod;
                var data1 = Global.AppCache.Get <List <Candle> >(key1);
                if (data1 != null)
                {
                    returns = new Tuple <DateTime, DateTime>(data1.First().Timestamp, data1.Last().Timestamp);
                    continue;
                }

                Candle databaseFirstCandle = Global.DataStoreBacktest.GetBacktestFirstCandle(backtestOptions).Result;
                Candle databaseLastCandle  = Global.DataStoreBacktest.GetBacktestLastCandle(backtestOptions).Result;

                if (databaseFirstCandle == null || databaseLastCandle == null)
                {
                    continue;
                }

                backtestOptions.StartDate = databaseFirstCandle.Timestamp;
                backtestOptions.EndDate   = databaseLastCandle.Timestamp;

                var candleProvider = new DatabaseCandleProvider();
                var _candle15      = candleProvider.GetCandles(backtestOptions, Global.DataStoreBacktest).Result;
                _candle15 = await _candle15.FillCandleGaps((Period)Enum.Parse(typeof(Period), backtestOptions.CandlePeriod.ToString(), true));

                Global.AppCache.Remove(backtestOptions.Coin + backtestOptions.CandlePeriod);
                Global.AppCache.Add(api.Name + backtestOptions.Coin + backtestOptions.CandlePeriod, _candle15, new MemoryCacheEntryOptions());

                Global.Logger.Information($"   Cached {key1}");

                backtestOptions.CandlePeriod = 1;

                var key2 = api.Name + backtestOptions.Coin + backtestOptions.CandlePeriod;
                if (Global.AppCache.Get <List <Candle> >(key2) != null)
                {
                    continue;
                }

                Candle database1FirstCandle = Global.DataStoreBacktest.GetBacktestFirstCandle(backtestOptions).Result;
                Candle database1LastCandle  = Global.DataStoreBacktest.GetBacktestLastCandle(backtestOptions).Result;

                if (database1FirstCandle == null || database1LastCandle == null)
                {
                    continue;
                }

                backtestOptions.StartDate = database1FirstCandle.Timestamp;
                backtestOptions.EndDate   = database1LastCandle.Timestamp;

                var _candle1 = candleProvider.GetCandles(backtestOptions, Global.DataStoreBacktest).Result;
                _candle1 = await _candle1.FillCandleGaps((Period)Enum.Parse(typeof(Period), backtestOptions.CandlePeriod.ToString(), true));

                Global.AppCache.Remove(backtestOptions.Coin + backtestOptions.CandlePeriod);
                Global.AppCache.Add(api.Name + backtestOptions.Coin + backtestOptions.CandlePeriod, _candle1, new MemoryCacheEntryOptions());

                Global.Logger.Information($"   Cached {key2}");

                returns = new Tuple <DateTime, DateTime>(backtestOptions.StartDate, backtestOptions.EndDate);
            }

            watch1.Stop();
            Global.Logger.Warning($"Ended CacheAllData in #{watch1.Elapsed.TotalSeconds} seconds");

            return(returns);
        }