public void SaveData() { DateTime firstDate; DateTime lastDate; var lastHistData = _reposBL.GetIntParam(LAST_HISTORY_DATA); if (lastHistData == null) { firstDate = DateTime.Today.AddHours(_config.CorrectHours).Date; } else { firstDate = StorageLib.ToDateTime(lastHistData.Value).AddDays(1); } lastDate = firstDate; _logger.AddInfo("InsStoreData", "Bars saving ..."); bool isNewTran = _storage.BeginTransaction(); try { foreach (var insStore in _insStore_barRow.Keys) { var bars = _insStore_barRow[insStore].Bars; if (!bars.Any()) { continue; } var lastBarDate = bars.Last().Time.Date; if (lastBarDate > lastDate) { lastDate = lastBarDate; } _insStoreBL.InsertData(insStore.InsStoreID, bars, firstDate, lastBarDate, false, new CancellationToken()); } _reposBL.SetIntParam(LAST_HISTORY_DATA, StorageLib.ToDbTime(lastDate)); _storage.Commit(isNewTran); } catch (Exception ex) { _storage.Rollback(isNewTran); _logger.AddException("InsStoreBL:SaveData", ex); } _logger.AddInfo("InsStoreData", string.Format("Bars saved: {0} - {1}", firstDate.ToString("dd.MM.yyyy"), lastDate.ToString("dd.MM.yyyy"))); }
/// <summary> /// Синхронизация данных симулятора для списка инструментов. /// Для каждого инструмента синхронизируется минимальный поток (кроме тиков). /// Синхронизация выполняется на размер форварда по умолчанию, свой для каждого таймфрейма. /// </summary> /// <param name="insIDs">Инструменты</param> /// <param name="startDate">Начало периода данных</param> /// <param name="cancel">Токен отмены</param> /// <returns>Асинхронная задача синхронизации</returns> public async Task SyncForward(IEnumerable <int> insIDs, DateTime startDate, CancellationToken cancel) { foreach (int insID in insIDs) { if (cancel.IsCancellationRequested) { break; } var ins = _instrumBL.GetInstrumByID(insID); if (ins == null) { continue; } var insStore = _insStoreBL.GetInsStore(insID, Timeframes.Min); // минимальный ТФ if (insStore == null || insStore.Tf == Timeframes.Tick) { continue; } var insStores = _insStoreBL.GetInsStores(insID).ToList(); // список потоков всех кроме минимального, их мы будем синхронизировать особо var f_ss = insStores.FirstOrDefault(s => s.Tf == Timeframes.Min); if (f_ss != null) { insStores.Remove(f_ss); } DateTime endDate = _insStoreBL.GetDefaultEndForwardDate(startDate, insStore.Tf); var parts = GetDownloadParts(insStore.Tf, startDate, endDate, true); // forward foreach (var part in parts) { if (cancel.IsCancellationRequested) { break; } bool hasData = _insStoreBL.HasData(part.Date1, part.Date2, insStore.InsStoreID); if (hasData) { continue; } var bars = await SyncDataBlock(insStore, part.Date1, part.Date2, part.Date2 >= DateTime.Today, cancel); // синхронизируем поток с минимальным ТФ, данные за сегодня грязные foreach (var ss in insStores) // остальные потоки формируем из минимального { if (cancel.IsCancellationRequested) { break; } var newBarRow = _insStoreBL.ConvertBars(ss.InsID, ss.Tf, bars, cancel); bool isLastDirty = part.Date2 >= DateTime.Today; // данные за сегодня помечаем как грязные, поскольку не уверены что они полные _insStoreBL.InsertData(ss.InsStoreID, ins.Decimals, newBarRow.Bars, part.Date1, part.Date2, isLastDirty, cancel); } } } }