public GeneralInvestingInfo(IEnumerable <BalancesRow> data, IEnumerable <FlowRow> flows, IEnumerable <Rate> ratesUSD = null) { Data = data; Flows = flows; if ((flows == null) || (Flows.Where(o => o.DateTimeStamp <= data.First().DateTimeStamp) .Sum(o => o.Payment) != data.First().Balance)) { throw new InvalidOperationException("Error in database! Flows sum is not equal to initial balance."); } Profits = StatsCalculator.GetProfits(data, flows); updateProfitsPerMonth(); updateSavingsPerMonth(); updateDollarBHs(ratesUSD); }
public AccountData(User user, IEnumerable <BalancesRow> balances, IEnumerable <FlowRow> flows) { UserName = user.Name; Flows = flows.Where(o => o.User.Id == user.Id).ToArray(); var startDate = Flows.Min(o => o.DateTimeStamp); var ratios = new Dictionary <DateTime, double>(); var dbs = balances.OrderBy(o => o.DateTimeStamp).ToDictionary(o => o.DateTimeStamp, o => o.Balance); Balances = new Dictionary <DateTime, double>(); double ownMoney = 0; double othersMoney = 0; DateTime date = DateTime.MinValue; foreach (var d in dbs.Keys) { var currFlows = flows.Where(o => o.DateTimeStamp <= d && o.DateTimeStamp > date); var currBal = dbs[d] - currFlows.Sum(o => o.Payment); var profit = d == dbs.Min(o => o.Key) ? 0 : currBal - (othersMoney + ownMoney); var currRatio = d == dbs.Min(o => o.Key) ? 0 : ownMoney / (othersMoney + ownMoney); ownMoney += profit * currRatio; othersMoney += profit * (1 - currRatio); foreach (var f in currFlows) { if (f.User.Id == user.Id) { ownMoney += f.Payment; } else { othersMoney += f.Payment; } } ratios.Add(d, ownMoney / (othersMoney + ownMoney)); if (startDate <= d) { Balances.Add(d, ownMoney); } date = d; } var ownFlowsSum = Flows.Where(o => o.Payment > 0).Sum(o => o.Payment); SharedRatio = Math.Round(ratios[balances.Last().DateTimeStamp] * 100, 2); Money = Math.Round(ownMoney, 2); OthersMoney = Math.Round(othersMoney, 2); var lastMonthBalance = dbs.LastOrDefault(o => o.Key < date && o.Key.Month != date.Month); var lastMonthInOut = Flows.Where(o => o.DateTimeStamp > lastMonthBalance.Key).Sum(o => o.Payment); TotalProfit = Math.Round(Money - ownFlowsSum, 2); if (TotalProfit > 0) { Money -= Math.Round(TotalProfit * (Benefit / 100), 2); } TotalProfitPercent = Math.Round(100 * TotalProfit / ownFlowsSum, 2); ProfitsPerMonth = StatsCalculator.GetProfitsByMonths(StatsCalculator.GetProfits(Balances, Flows), Balances); var lastMonthProfit = ProfitsPerMonth.Last(); LastMonthProfit = Math.Round(lastMonthProfit.Value * (1 - Benefit / 100), 2); LastMonthPercent = Math.Round(lastMonthProfit.Percent * (1 - Benefit / 100), 2); }