public void SubscribeValueRow_fulltest() { IAccountDA accDA = new AccountDAMock(); SeriesData sd = new SeriesData(accDA); int accID = 10; // создали серию и подписали на нее поток int sid = sd.OpenSeries("key1"); BarRow bars = new BarRow(Timeframes.Day, 1); sd.SubscribeValueRow(sid, bars.Close, bars.Dates); // в поток добавляем 10 значений DateTime d = new DateTime(2019, 1, 1, 10, 0, 0); for (int i = 0; i < 10; i++) { bars.AddTick(d, 100, 1); d = d.AddDays(1); } bars.CloseLastBar(); sd.SetAccount(accID); sd.SaveData(); // после сохранения sid уже не актуален, надо использовать series[0].SeriesID var series = accDA.GetSeries(accID).ToList(); Assert.Single(series); // серия одна var vals = accDA.GetValues(series[0].SeriesID).ToList(); Assert.True(vals.Count == 10); // в серии 10 значений // теперь отпишемся от потока sd.SubscribeValueRow(series[0].SeriesID, null, null); // в поток добавляем еще 10 значений for (int i = 0; i < 10; i++) { bars.AddTick(d, 200, 1); d = d.AddDays(1); } bars.CloseLastBar(); // снова запишем данные sd.SaveData(); var vals1 = accDA.GetValues(series[0].SeriesID).ToList(); Assert.True(vals1.Count == 10); // в серии по прежнему 10 значений }
/// <summary> /// Load historical data into bars /// </summary> /// <param name="bars">Bars object</param> /// <param name="insStoreID">InsStote Id</param> /// <param name="date1">First date (without time)</param> /// <param name="date2">Last date (without time)</param> /// <returns>Async task</returns> public Task LoadHistoryAsync(BarRow bars, int insStoreID, DateTime date1, DateTime date2) { if (date2 == DateTime.MaxValue) { date2 = date2.AddDays(-1); } int d1 = StorageLib.ToDbTime(date1.Date); int d2 = StorageLib.ToDbTime(date2.Date.AddDays(1)); return(Task.Run(() => { var loadedBars = _da.DbContext.Table <BarHistory>() .Where(b => b.InsStoreID == insStoreID && b.Time >= d1 && b.Time < d2) .OrderBy(b => b.Time); bars.SuspendEvents(); foreach (var bar in loadedBars) { bars.AddTick(StorageLib.ToDateTime(bar.Time), bar.OpenPrice, 0); bars.AddTick(StorageLib.ToDateTime(bar.Time), bar.HighPrice, 0); bars.AddTick(StorageLib.ToDateTime(bar.Time), bar.LowPrice, 0); bars.AddTick(StorageLib.ToDateTime(bar.Time), bar.ClosePrice, bar.Volume); } bars.CloseLastBar(); bars.ResumeEvents(); })); }
/// <summary> /// Загрузка исторических данных в BarRow. /// Наиболее подходящий InsStore определяется автоматически. /// </summary> /// <param name="bars">BarRow</param> /// <param name="insID">Инструмент</param> /// <param name="date1">Нач дата</param> /// <param name="date2">Кон дата</param> /// <param name="insStoreID">Поток данных для загрузки (если null, то поток будет определен автоматически)</param> /// <returns>Асинхронная задача загрузки. Общее число баров после загрузки.</returns> public async Task <int> LoadHistoryAsync(BarRow bars, int insID, DateTime date1, DateTime date2, int?insStoreID = null) { Instrum instrum = _instrumBL.GetInstrumByID(insID); if (instrum == null) { return(0); } if (insStoreID == null) { var insStore = GetLoadHistoryInsStore(insID, bars.Timeframe); if (insStore != null) { insStoreID = insStore.InsStoreID; } } if (insStoreID == null) { return(0); } int k = (int)Math.Pow(10, instrum.Decimals); var list = await _insStoreDA.GetHistoryAsync(insStoreID.Value, date1, date2); return(await Task.Run(() => { bars.SuspendEvents(); foreach (var bar in list) { DateTime time = StorageLib.ToDateTime(bar.Time); decimal openPrice = (decimal)bar.OpenPrice / k; decimal lowPrice = (decimal)(bar.OpenPrice + bar.LowDelta) / k; decimal highPrice = (decimal)(bar.OpenPrice + bar.HighDelta) / k; decimal closePrice = (decimal)(bar.OpenPrice + bar.CloseDelta) / k; bars.AddTick(time, openPrice, 0); bars.AddTick(time, lowPrice, 0); bars.AddTick(time, highPrice, 0); bars.AddTick(time, closePrice, bar.Volume); } bars.CloseLastBar(); bars.ResumeEvents(); return bars.Count; })); }
/// <summary> /// Получить массив баров по другому массиву баров (более мелкому) /// </summary> /// <param name="insID">Инструмент</param> /// <param name="tf">ТФ нового массива</param> /// <param name="minBars">Старый массив</param> /// <param name="cancel">Токен отмены</param> /// <returns>Новый массив баров из старого</returns> public BarRow ConvertBars(int insID, Timeframes tf, IEnumerable <Bar> minBars, CancellationToken cancel) { BarRow barRow = new BarRow(tf, insID); foreach (var minBar in minBars) { if (cancel.IsCancellationRequested) { break; } barRow.AddTick(minBar.Time, minBar.Open, 0); barRow.AddTick(minBar.Time, minBar.High, 0); barRow.AddTick(minBar.Time, minBar.Low, 0); barRow.AddTick(minBar.Time, minBar.Close, minBar.Volume); } barRow.CloseLastBar(); return(barRow); }