void Calc(int index) { if (_mo[index - 1] == null) { decimal?sum = 0; for (int i = index - _n + 1; i <= index; i++) { if (_source[i] != null) { sum += _source[i].Value; } else { sum = null; break; } } _mo.Add(sum / _n); } else { if (_source[index - _n] != null && _source[index] != null) { decimal next = _mo[index - 1].Value + _source[index].Value / _n - _source[index - _n].Value / _n; _mo.Add(next); } } decimal?s = null; if (_mo[index] != null) { s = 0; for (int i = index - _n + 1; i <= index; i++) { if (_source[i] == null) { s = null; break; } s += (_source[i] - _mo[index]) * (_source[i] - _mo[index]); } } double?res = null; if (s != null) { res = Math.Sqrt(Convert.ToDouble(s.Value / _n)); } if (res != null) { this.Add(Convert.ToDecimal(res)); } else { this.Add(null); } }
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); } })); }