/// <summary> /// Загрузка истории для пустых Bars. /// Если Bars не пустой, то история не загружается. /// </summary> /// <returns></returns> public async Task LoadHistoryAsync() { DateTime start, end; if (_tickDispatcher != null) { end = _tickDispatcher.CurrentDate.AddDays(-1); } else { end = _endDate; } foreach (var psrc in _guid_source.Values) { if (psrc.Bars.Count > 0) { continue; // история уже загружена } if (_tickDispatcher != null) { start = _insStoreBL.GetDefaultStartHistoryDate(end, psrc.Bars.Timeframe); } else { start = _startDate; } await _insStoreBL.LoadHistoryAsync(psrc.Bars, psrc.Instrum.InsID, start, end); if (_tickDispatcher != null) { psrc.Bars.TickDispatcher = _tickDispatcher; } } }
public async Task <IBarRow> CreateBarRow(int insId, Timeframes tf, int historyDays) { BarRow bars = new BarRow(tf, _tickDisp, insId); DateTime curDate = DateTime.Today; var endHistoryDate = curDate.AddDays(-1); var startHistoryDate = endHistoryDate.AddDays(-historyDays); await _insStoreBL.LoadHistoryAsync(bars, insId, startHistoryDate, endHistoryDate); _barRows.Add(bars); return(bars); }
public async Task<IBarRow> CreateBarRow(int insID, Timeframes tf, int historyDays) { BarRow bars = new BarRow(tf, _tickSource, insID); var insStore = _insStoreBL.GetLoadHistoryInsStore(insID, tf); // наиболее подходящий insStore if (insStore == null) return null; DateTime? curDate = _tickSource.CurrentTime; if (curDate == null) return null; var endHistoryDate = curDate.Value.AddDays(-1); var startHistoryDate = _insStoreBL.GetStartHistoryDate(insStore.InsStoreID, endHistoryDate, historyDays); if (startHistoryDate != null) { await _insStoreBL.LoadHistoryAsync(bars, insID, startHistoryDate.Value, endHistoryDate, insStore.InsStoreID); } _barRows.Add(bars); return bars; }
public Task Generate(int accountID, Timeline timeline) { return(Task.Run(() => { _cashRow.Clear(); _portfolioRow.Clear(); _equityRow.Clear(); _prices.Clear(); var trades = _accountDA.GetTrades(accountID).OrderBy(r => r.Time).ToList(); var account = _accountDA.GetAccountByID(accountID); var cash = _accountDA.GetCash(accountID); List <EqHold> eqHoldList = new List <EqHold>(); decimal cashSumma = cash.Initial; decimal pfSumma = 0; var bd1 = timeline.GetBarDate(0); var bd2 = timeline.GetBarDate(timeline.Count - 1); if (bd1 == null || bd2 == null) { return; } DateTime date1 = bd1.Value.Start.Date; DateTime date2 = bd2.Value.NextStart.Date; // для таймфреймов day и week загрузим историю на один лишний день int tradeIdx = 0; for (int i = 0; i < timeline.Count; i++) { var barDates = timeline.GetBarDate(i); if (barDates == null) { continue; } while (tradeIdx < trades.Count && trades[tradeIdx].Time < barDates.Value.NextStart) { var trade = trades[tradeIdx]; var instrum = _instrumBL.GetInstrumByID(trade.InsID); // из кеша var tradeSumma = trade.Price * trade.LotCount * instrum.LotSize; var hold = eqHoldList.FirstOrDefault(r => r.InsID == instrum.InsID); if (trade.BuySell == BuySell.Buy) { cashSumma -= tradeSumma; if (hold != null) { hold.LotCount += trade.LotCount; } else { eqHoldList.Add(new EqHold() { InsID = instrum.InsID, LotSize = instrum.LotSize, LotCount = trade.LotCount }); } } else { cashSumma += tradeSumma; if (hold != null) { hold.LotCount -= trade.LotCount; if (hold.LotCount == 0) { eqHoldList.Remove(hold); } } else { eqHoldList.Add(new EqHold() { InsID = instrum.InsID, LotSize = instrum.LotSize, LotCount = -trade.LotCount }); } } tradeIdx++; } // вычисляем сумму портфеля на конец бара pfSumma = 0; foreach (var hold in eqHoldList) { if (!_prices.ContainsKey(hold.InsID)) { BarRow barRow = new BarRow(timeline.Timeframe, hold.InsID); _insStoreBL.LoadHistoryAsync(barRow, hold.InsID, date1, date2).Wait(); _prices.Add(hold.InsID, barRow); } var bars = _prices[hold.InsID]; var bar = bars.Bars.FirstOrDefault(r => r.Time == barDates.Value.Start); if (bar != null) { pfSumma += bar.Close * hold.LotCount * hold.LotSize; } } _cashRow.Add(cashSumma); _portfolioRow.Add(pfSumma); _equityRow.Add(cashSumma + pfSumma); } })); }
/// <summary> /// Вывод исторических данных /// </summary> /// <param name="args">Tf, Ticker, Date1, Date2</param> public void GetBars(List <string> args) { if (args.Count < 4) { _console.WriteError("Неверное число аргументов"); return; } Timeframes tf; if (!Timeframes.TryParse <Timeframes>(args[0], out tf)) { _console.WriteError("Неверный агрумент: Timeframe"); return; } string ticker = args[1]; var instrum = _instrumBL.GetInstrum(ticker); if (instrum == null) { _console.WriteError("Тикер не найден"); return; } DateTime date1, date2; DateTime d; if (DateTime.TryParse(args[2].Trim(), out d)) { date1 = d; } else { _console.WriteError("Неверно указана дата начала"); return; } if (DateTime.TryParse(args[3].Trim(), out d)) { date2 = d; } else { _console.WriteError("Неверно указана дата окончания"); return; } BarRow bars = new BarRow(tf, instrum.InsID); _insStoreBL.LoadHistoryAsync(bars, instrum.InsID, date1, date2).Wait(); _console.WriteLine("Time\t\t\tOpen\tHigh\tLow\tClose\tVolume"); _console.WriteSeparator(); string format = "0." + (new string('0', instrum.Decimals)); foreach (var bar in bars.Bars) { _console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", bar.Time.ToString("dd.MM.yyyy HH:mm:ss"), bar.Open.ToString(format), bar.High.ToString(format), bar.Low.ToString(format), bar.Close.ToString(format), bar.Volume)); } _console.WriteSeparator(); _console.WriteLine("Count: " + bars.Count.ToString()); }
/// <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()); }