/// <summary> /// Асинхронная загрузка исторических данных /// </summary> /// <param name="toDate">Загрузка по эту дату включительно</param> /// <param name="isLastDirty">Данные за последний день неполные</param> /// <param name="progress">Объект управления фоновой задачей</param> /// <param name="cancel">Отмена длительной операции</param> /// <returns>Асинхронная задача загрузки</returns> public Task DownloadAllAsync(DateTime toDate, bool isLastDirty, BgTaskProgress progress, CancellationToken cancel) { return(Task.Run(() => { try { _logger.LogInformation("DownloadAll to {date}", toDate.ToString("yyyy-MM-dd")); var insStores = _insStoreBL.GetActiveInsStores(); int count = insStores.Count(); int idx = 1; if (progress != null) { progress.OnStart(count > 1); } Dictionary <CommonData.InsStore, BgTaskProgress> progresses = new Dictionary <CommonData.InsStore, BgTaskProgress>(); if (progress != null) { foreach (var ss in insStores) { string name = ""; var instrum = _instrumBL.GetInstrumByID(ss.InsID); if (instrum != null) { name = instrum.ShortName; } var child = progress.AddChildProgress(name); progresses.Add(ss, child); } } foreach (var insStore in insStores) { if (cancel.IsCancellationRequested) { if (progress != null) { progress.OnAbort(); } break; } var ssCal = _insStoreBL.GetInsStoreCalendar(insStore.InsStoreID); if (ssCal == null || ssCal.Periods == null) { continue; } DateTime fromDate; if (ssCal.Periods.Count() > 0) { var lastPeriod = ssCal.Periods.Last(); fromDate = lastPeriod.IsLastDirty ? lastPeriod.EndDate : lastPeriod.EndDate.AddDays(1); } else { fromDate = _insStoreBL.GetDefaultStartHistoryDate(toDate, insStore.Tf); } var p = progresses.ContainsKey(insStore) ? progresses[insStore] : null; DownloadAsync(insStore, fromDate, toDate, isLastDirty, true, p, cancel).Wait(); if (progress != null) { progress.OnProgress((double)idx++ / count * 100); } } if (progress != null) { if (cancel.IsCancellationRequested) { progress.OnAbort(); } else { progress.OnComplete(); } } _logger.LogInformation("DownloadAll complete."); } catch (Exception ex) { _logger.LogError(ex, "DownloadAll error."); if (progress != null) { progress.OnFault(ex); } } })); }
/// <summary> /// Загрузка тиковых данных для всех инструментов /// </summary> /// <returns>Общее кол-во загруженных тиков</returns> public async Task <int> LoadDataAsync() { lock (_ticks) { _ticks.Clear(); } _synTicksCount = _realDays = _synDays = 0; _insID_lastTick.Clear(); foreach (var instrum in _instrums) { if (Timeframe != Timeframes.Tick) { var barRow = new BarRow(Timeframe, instrum.InsID); await _insStoreBL.LoadHistoryAsync(barRow, instrum.InsID, StartDate, EndDate); await Task.Run(() => { foreach (var bar in barRow.Bars) { lock (_ticks) { int v = bar.Volume < int.MaxValue ? (int)bar.Volume : int.MaxValue; _ticks.Add(new Tick(0, bar.Time, instrum.InsID, 0, bar.Open)); _ticks.Add(new Tick(0, bar.Time, instrum.InsID, 0, bar.High)); _ticks.Add(new Tick(0, bar.Time, instrum.InsID, 0, bar.Low)); _ticks.Add(new Tick(0, bar.Time, instrum.InsID, v, bar.Close)); } } }); } else { List <DateTime> freeDays = null; var minInsStore = _insStoreBL.GetInsStore(instrum.InsID, Timeframes.Min); if (minInsStore != null) { freeDays = _insStoreBL.GetInsStoreCalendar(minInsStore.InsStoreID).FreeDays .Where(d => d >= StartDate && d <= EndDate).ToList(); } DateTime date = StartDate; while (date <= EndDate) { var ticks = await _tickHistoryBL.GetTicksAsync(instrum.InsID, date); if (ticks != null && ticks.Any()) { lock (_ticks) { _ticks.AddRange(ticks); } _realDays++; } else // тиковых данных нет, попробуем загрузить минутки и сделать из них тики { if (freeDays != null && !freeDays.Contains(date)) // дата не является выходным днем, значит должны быть минутки { BarRow barRow = new BarRow(Timeframes.Min, instrum.InsID); await _insStoreBL.LoadHistoryAsync(barRow, instrum.InsID, date, date, minInsStore.InsStoreID); if (barRow.Bars.Any()) { foreach (Bar bar in barRow.Bars) { var synTicks = SynTicks(bar, instrum); // синтезируем тики из минутного бара _synTicksCount += synTicks.Count(); _ticks.AddRange(synTicks); } _synDays++; } } } date = date.AddDays(1); } } if (_ticks.Any() && _ticks.Last().InsID == instrum.InsID) // тики внутри каждого инструмента отсортированы по времени, поэтому можно брать последний в списке и он будет последний по времени { if (!_insID_lastTick.ContainsKey(instrum.InsID)) { _insID_lastTick.Add(instrum.InsID, _ticks.Last()); } else // перестраховка { _insID_lastTick[instrum.InsID] = _ticks.Last(); } } } await Task.Run(() => { lock (_ticks) { _ticks = _ticks.OrderBy(t => t.Time).ToList(); int count = _ticks.Count; for (int i = 0; i < count; i++) { var tick = _ticks[i]; tick.TradeNo = i + 1; } } }); return(GetTicksCount()); }
/// <summary> /// Информация по потоку данных /// </summary> /// <param name="args">Ticker Tf [FreeDays]</param> public void GetInsStore(List <string> args) { if (args.Count < 2) { _console.WriteError("Неверное число аргументов"); return; } Timeframes tf; if (!Timeframes.TryParse <Timeframes>(args[0], out tf)) { _console.WriteError("Неверный агрумент: Timeframe"); return; } string ticker = args[1]; var insStore = _insStoreBL.GetInsStore(ticker, tf); if (insStore == null) { _console.WriteError("Не найден поток данных"); return; } _console.WriteLine("InsStoreID\tInsID\tTicker\tTf\tIsEnable"); _console.WriteSeparator(); _console.WriteLine(string.Format("{0}\t\t{1}\t{2}\t{3}\t{4}", insStore.InsStoreID.ToString(), insStore.InsID.ToString(), ticker, insStore.Tf.ToString(), insStore.IsEnable ? "*" : "-")); _console.WriteTitle("Periods"); var calendar = _insStoreBL.GetInsStoreCalendar(insStore.InsStoreID); var periods = calendar.Periods.OrderBy(p => p.StartDate).ToList(); var freeDays = calendar.FreeDays.OrderBy(d => d).ToList(); foreach (var period in periods) { _console.WriteLine(string.Format("{0} - {1}", period.StartDate.ToString("dd.MM.yyyy"), period.EndDate.ToString("dd.MM.yyyy") + (period.IsLastDirty ? "-dirty" : ""))); } if (args.Count >= 3 && args[2].Trim().ToLower() == "freedays") { _console.WriteTitle("Free Days"); foreach (var day in freeDays) { string dow = ""; switch (day.DayOfWeek) { case DayOfWeek.Monday: dow = "пн"; break; case DayOfWeek.Tuesday: dow = "вт"; break; case DayOfWeek.Wednesday: dow = "ср"; break; case DayOfWeek.Thursday: dow = "чт"; break; case DayOfWeek.Friday: dow = "пт"; break; case DayOfWeek.Saturday: dow = "сб"; break; case DayOfWeek.Sunday: dow = "вс"; break; } _console.Write(string.Format("{0}-{1}\t", day.ToString("dd.MM.yy"), dow)); } _console.WriteLine(""); } }