//Updates AmountOwn for master and investors due to Profit, Reinvestment, ManagementFee, SuccessFee private void ProfitCalculation(MasterWithInvestors master, decimal profit) { decimal totalProfitInvestors = master.Investors.Sum(investor => MathHelper.UnfairRound(profit * investor.percent / 100)); master.AmountOwn += MathHelper.UnfairRound(profit - totalProfitInvestors); foreach (var investor in master.Investors) { if (investor.status == (short)AccountStatus.PendingIn) { continue; } var investorFullProfit = MathHelper.UnfairRound(profit * investor.percent / 100); TrustService.Logger.Info("Profit fot investor {0} is {1}", investor.id, investorFullProfit); var managementFee = MathHelper.UnfairRound(master.FeeManagement / (365m / master.Period) * investor.amount / 100); if (profit > 0) { var totalProfit = repository.GetTotalInvestorProfit(investor.id, master.TradingAccountId); TrustService.Logger.Info("Total profit for investor {0} for all previous periods is {1}", investor.id, totalProfit); if (investorFullProfit + totalProfit > 0) { var successFee = totalProfit > 0 ? MathHelper.UnfairRound(investorFullProfit * master.FeeSuccess / 100) : MathHelper.UnfairRound((investorFullProfit + totalProfit) * master.FeeSuccess / 100); master.AmountOwn += successFee; var netProfit = investorFullProfit - successFee - managementFee; var reinvest = MathHelper.UnfairRound(netProfit * (decimal)investor.reinvest_percent / 100); investor.amount += reinvest; TrustService.Logger.Info("Values for investor {0} : Net Profit - {1}, Success Fee - {2}, Reinvest Amount - {3}", investor.id, netProfit, successFee, reinvest); } } else { investor.amount += (investorFullProfit - managementFee); } master.AmountOwn += managementFee; repository.WriteStatistics(investor.id, master.TradingAccountId, investorFullProfit, profit, master.DateNextProcessing.AddDays(-master.Period), master.DateNextProcessing); } }
//Process PendingOut masters private void ProcessMasterLeaving(MasterWithInvestors master) { var info = accountService.GetAccountInfo(master.TradingAccountId); if (!info.IsSuccess) { throw new Exception(info.Error); } TrustService.Logger.Info("Current balance of master {0} is {1}", master.TradingAccountId, info.Result.Balance); var totalAmountAtStart = master.Investors.Where(investor => investor != null).Sum(investor => investor.amount) + master.AmountOwn; TrustService.Logger.Info("Total amount at the beginning of period for master {0} is {1}", master.TradingAccountId, totalAmountAtStart); var profit = (decimal)info.Result.Balance - totalAmountAtStart; TrustService.Logger.Info("Total profit for account {0} is {1}", master.TradingAccountId, profit); ProfitCalculation(master, profit); var masterInvestments = InvestmentsCalculation(master.TradingAccountId, master.AmountOwn, true); if (masterInvestments > 0) { master.AmountOwn += masterInvestments; } TrustService.Logger.Info("Incoming amount to wallet for master {0} is {1}", master.TradingAccountId, master.AmountOwn); var accountResult = accountService.ChangeAccountBalance(master.TradingAccountId, (decimal) - info.Result.Balance, " closure"); if (!accountResult.IsSuccess) { throw new Exception(accountResult.Error); } foreach (var investor in master.Investors) { var invesments = InvestmentsCalculation(investor.id, investor.amount, false); if (invesments > 0) { investor.amount += invesments; } TrustService.Logger.Info("Incoming amount to wallet for investor {0} is {1}", investor.id, investor.amount); } repository.CloseMasterWithInvestors(master.TradingAccountId, master.Investors.Select(x => (long)x.id).ToArray()); accountService.DeleteAccount(master.TradingAccountId); }
//Process In or PendingIn masters private void ProcessMasterStaying(MasterWithInvestors master) { var info = accountService.GetAccountInfo(master.TradingAccountId); if (!info.IsSuccess) { throw new Exception(info.Error); } TrustService.Logger.Info("Current balance of master {0} is {1}", master.TradingAccountId, info.Result.Balance); if (master.AccountStatus == AccountStatus.PendingIn) { master.AmountOwn = (decimal)info.Result.Balance; } else { var totalAmountAtStart = master.Investors.Where(investor => investor != null).Sum(investor => investor.amount) + master.AmountOwn; TrustService.Logger.Info("Total amount at the beginning of period for master {0} is {1}", master.TradingAccountId, totalAmountAtStart); var profit = (decimal)info.Result.Balance - totalAmountAtStart; TrustService.Logger.Info("Total profit for account {0} is {1}", master.TradingAccountId, profit); ProfitCalculation(master, profit); } var masterChangeModel = NextPeriodParametersCalculation(master.TradingAccountId, master.AccountStatus, master.WalletId, master.AmountOwn, InvestmentsCalculation(master.TradingAccountId, master.AmountOwn, true), true); var investorsChangeModel = master.Investors.Select(investor => NextPeriodParametersCalculation(investor.id, (AccountStatus)investor.status, investor.wallet_id, investor.amount, InvestmentsCalculation(investor.id, investor.amount, false), false)).ToList(); var amountTotal = investorsChangeModel.Sum(x => x.AmountOwn) + masterChangeModel.AmountOwn; TrustService.Logger.Info("Master {0} balance for next period is {1}", master.TradingAccountId, amountTotal); masterChangeModel.Percent = amountTotal != 0 ? masterChangeModel.AmountOwn / amountTotal * 100 : 0; foreach (var investorChangeModel in investorsChangeModel) { investorChangeModel.Percent = amountTotal != 0 ? investorChangeModel.AmountOwn / amountTotal * 100 : 0; } accountService.ChangeAccountBalance(master.TradingAccountId, amountTotal - (decimal)info.Result.Balance, " processing"); repository.ChangeParameters(masterChangeModel, investorsChangeModel, master.DateNextProcessing, master.DateNextProcessing.AddDays(master.Period)); }
private void Process(MasterWithInvestors master) { try { switch (master.AccountStatus) { case AccountStatus.PendingIn: case AccountStatus.In: ProcessMasterStaying(master); break; case AccountStatus.PendingOut: ProcessMasterLeaving(master); break; } } catch (Exception e) { TrustService.Logger.Error(" processing error: {0}", e.Message); } }