public ResizeableArray <TradeInfoItem> DownloadTradeHistory(TickerInputInfo info, DateTime time)
        {
            info.CheckUpdateTime();

            CachedTradeHistory savedData = new CachedTradeHistory()
            {
                Exchange = info.Exchange, TickerName = info.TickerName, StartDate = info.StartDate, EndDate = info.EndDate, BaseCurrency = info.Ticker.BaseCurrency, MarketCurrency = info.Ticker.MarketCurrency
            };
            CachedTradeHistory cachedData = CachedTradeHistory.FromFile(CachedTradeHistory.Directory + "\\" + ((ISupportSerialization)savedData).FileName);

            if (cachedData != null && cachedData.Items.Count > 0)
            {
                if (info.StartDate != DateTime.MinValue && info.StartDate == cachedData.Items[0].Time.Date && info.EndDate.AddDays(-1) <= cachedData.Items.Last().Time.Date)
                {
                    LogManager.Default.Add(LogType.Log, this, "" + info.Exchange + ":" + info.TickerName, "load cached trade history", cachedData.StartDate + "-" + cachedData.EndDate + ": " + cachedData.Items.Count + " items");
                    return(cachedData.Items);
                }
            }

            DateTime start             = info.StartDate.Date;
            int      intervalInSeconds = info.KlineIntervalMin * 60;
            DateTime origin            = start;
            DateTime end = info.EndDate.Date.AddHours(12);

            if (end > DateTime.Now)
            {
                end = DateTime.Now.AddHours(-1);
            }
            ResizeableArray <TradeInfoItem> res = new ResizeableArray <TradeInfoItem>();

            DownloadProgress = 0.0;
            DownloadText     = "Donwloading Trade History Data for " + info.Exchange + ":" + info.TickerName;

            while (start < end)
            {
                DateTime localEnd = start.AddDays(1);
                if (localEnd > end)
                {
                    localEnd = end;
                }
                ResizeableArray <TradeInfoItem> data = info.Ticker.Exchange.GetTrades(info.Ticker, start, localEnd);
                if (data == null || data.Count == 0)
                {
                    LogManager.Default.Add(LogType.Error, this, info.TickerName, "cannot download trade history", start + "-" + localEnd);
                    start = start.AddDays(1);
                    continue;
                }
                localEnd         = data.Last().Time;
                DownloadProgress = (data.Last().Time - origin).TotalMinutes / (DateTime.UtcNow - origin).TotalMinutes * 100;
                var args = RaiseDownloadProgressChanged();
                if (args != null && args.Cancel)
                {
                    return(null);
                }
                //Thread.Sleep(300);
                LogManager.Default.Add(LogType.Success, this, info.TickerName, "trade history downloaded", start + "-" + localEnd);
                if (res.Last() != null && res.Last().Time == data[0].Time)
                {
                    DownloadProgress = 100;
                    break;
                }
                start = data.Last().Time.AddSeconds(+1);
                res.AddRange(data);
            }

            RaiseDownloadProgressChanged();

            for (int i = 0; i < res.Count - 1; i++)
            {
                if (res[i].Time > res[i + 1].Time)
                {
                    LogManager.Default.Add(LogType.Success, this, info.TickerName, "trade history timing error", start + "-" + end);
                    throw new Exception("TradeHistory Timing Error!");
                }
            }

            cachedData       = savedData;
            cachedData.Items = res;
            if (savedData.Items.Count > 0)
            {
                savedData.StartDate = savedData.Items[0].Time;
                savedData.EndDate   = savedData.Items.Last().Time;
            }
            cachedData.Save();

            return(res);
        }
        public virtual ResizeableArray <CandleStickData> DownloadCandleStickData(TickerInputInfo info)
        {
            CachedCandleStickData savedData = new CachedCandleStickData()
            {
                Exchange = info.Exchange, TickerName = info.TickerName, IntervalMin = info.KlineIntervalMin, StartDate = info.StartDate, EndDate = info.EndDate, BaseCurrency = info.Ticker.BaseCurrency, MarketCurrency = info.Ticker.MarketCurrency
            };
            CachedCandleStickData cachedData = CachedCandleStickData.FromFile(CachedCandleStickData.Directory + "\\" + ((ISupportSerialization)savedData).FileName);

            info.CheckUpdateTime();
            if (cachedData != null)
            {
                if (info.StartDate != DateTime.MinValue && info.StartDate == cachedData.Items[0].Time.Date && info.EndDate == cachedData.Items.Last().Time.Date)
                {
                    return(cachedData.Items);
                }
            }

            DateTime start                        = info.StartDate;
            int      intervalInSeconds            = info.KlineIntervalMin * 60;
            ResizeableArray <CandleStickData> res = new ResizeableArray <CandleStickData>();
            int  deltaCount                       = 500;
            long minCount         = (long)(SettingsStore.Default.SimulationSettings.KLineHistoryIntervalDays) * 24 * 60;
            long candleStickCount = minCount / info.KlineIntervalMin;
            long pageCount        = candleStickCount / deltaCount;
            int  pageIndex        = 0;

            DownloadProgress = 0.0;
            DownloadText     = "Donwloading CandleStick Data for " + info.Exchange + ":" + info.TickerName;

            if (!info.Ticker.Exchange.SupportCandleSticksRange)
            {
                ResizeableArray <CandleStickData> data = info.Ticker.GetCandleStickData(info.KlineIntervalMin, start, intervalInSeconds * deltaCount);
                if (data == null)
                {
                    return(null);
                }
                DownloadProgress = 100;
                var args = RaiseDownloadProgressChanged();
                if (args.Cancel)
                {
                    return(null);
                }

                cachedData       = savedData;
                cachedData.Items = data;
                cachedData.Save();
                return(data);
            }

            while (start.Date < info.EndDate.Date)
            {
                ResizeableArray <CandleStickData> data = info.Ticker.GetCandleStickData(info.KlineIntervalMin, start, intervalInSeconds * deltaCount);
                if (data == null || data.Count == 0)
                {
                    start = start.AddSeconds(intervalInSeconds * deltaCount);
                    continue;
                }
                res.AddRange(data);
                pageIndex++;
                DownloadProgress = pageIndex * 100 / pageCount;
                RaiseDownloadProgressChanged();
                Thread.Sleep(300);
                start = start.AddSeconds(intervalInSeconds * deltaCount);
            }
            cachedData       = savedData;
            cachedData.Items = res;
            cachedData.Save();
            return(res);
        }
        protected virtual ResizeableArray <CandleStickData> DownloadCandleStickData(TickerInputInfo info)
        {
            CachedCandleStickData savedData = new CachedCandleStickData()
            {
                Exchange = info.Exchange, TickerName = info.TickerName, IntervalMin = info.KlineIntervalMin
            };
            CachedCandleStickData cachedData = CachedCandleStickData.FromFile(CachedCandleStickData.Directory + "\\" + ((ISupportSerialization)savedData).FileName);

            if (cachedData != null)
            {
                // outdated
                if (SettingsStore.Default.SimulationSettings.StartTime.Date == cachedData.Items[0].Time.Date)
                {
                    return(cachedData.Items);
                }
            }

            DateTime start             = DateTime.UtcNow.Date;
            int      intervalInSeconds = info.KlineIntervalMin * 60;

            //int candleStickCount = 10000;
            start = start.AddDays(-SettingsStore.Default.SimulationSettings.KLineHistoryIntervalDays);// .AddSeconds(-intervalInSeconds * candleStickCount);
            ResizeableArray <CandleStickData> res = new ResizeableArray <CandleStickData>();
            //List<ResizeableArray<CandleStickData>> splitData = new List<ResizeableArray<CandleStickData>>();
            int  deltaCount       = 500;
            long minCount         = (long)(SettingsStore.Default.SimulationSettings.KLineHistoryIntervalDays) * 24 * 60;
            long candleStickCount = minCount / info.KlineIntervalMin;
            long pageCount        = candleStickCount / deltaCount;
            int  pageIndex        = 0;

            DownloadProgress = 0.0;

            if (!info.Ticker.Exchange.SupportCandleSticksRange)
            {
                ResizeableArray <CandleStickData> data = info.Ticker.GetCandleStickData(info.KlineIntervalMin, start, intervalInSeconds * deltaCount);
                if (data == null)
                {
                    return(null);
                }
                DownloadProgress = 100;
                RaiseDownloadProgressChanged();

                cachedData       = savedData;
                cachedData.Items = data;
                cachedData.Save();
                return(data);
            }

            //for(int i = 0; i < candleStickCount / deltaCount; i++) {
            while (start.Date < DateTime.Now.Date)
            {
                ResizeableArray <CandleStickData> data = info.Ticker.GetCandleStickData(info.KlineIntervalMin, start, intervalInSeconds * deltaCount);
                if (data == null || data.Count == 0)
                {
                    start = start.AddSeconds(intervalInSeconds * deltaCount);
                    continue;
                }
                res.AddRange(data);
                pageIndex++;
                DownloadProgress = pageIndex * 100 / pageCount;
                RaiseDownloadProgressChanged();
                Thread.Sleep(300);
                start = start.AddSeconds(intervalInSeconds * deltaCount);
            }
            cachedData       = savedData;
            cachedData.Items = res;
            cachedData.Save();
            return(res);
        }