public IAmortization Adjust(Schedule paymentSchedule, ICalendar calendar = null, BusinessDayConvention bda = BusinessDayConvention.None, Frequency frequency = Frequency.None) { Dictionary <Date, double> amortizationSchedule; if (AmortizationSchedule == null || !AmortizationSchedule.Any()) { amortizationSchedule = new[] { Tuple.Create(paymentSchedule.Last(), 1.0) }.ToDictionary(x => x.Item1, x => x.Item2); } else { var principalPay = AmortizationSchedule.Select( x => Tuple.Create( bda != BusinessDayConvention.None && calendar != null ? bda.Adjust(calendar, x.Key) : x.Key, x.Value)) .OrderBy(x => x.Item1).ToList(); if (paymentSchedule.Last() <= principalPay.First().Item1) { return(new Amortization(new[] { Tuple.Create(paymentSchedule.Last(), 1.0) }.ToDictionary(x => x.Item1, x => x.Item2))); } var preMaturity = principalPay.Where(x => x.Item1 <= paymentSchedule.Last()).OrderBy(x => x.Item1).ToList(); var remaingPrincipal = principalPay.Where(x => x.Item1 > paymentSchedule.Last()).ToList().Sum(x => x.Item2); amortizationSchedule = preMaturity.Select( (x, index) => Tuple.Create(x.Item1, index < preMaturity.Count - 1 ? x.Item2 : x.Item2 + remaingPrincipal)) .ToDictionary(x => x.Item1, x => x.Item2); } return(new Amortization(amortizationSchedule, RenormalizeAfterAmoritzation, AmortizationType)); }
public int SaveAmortizationToDB(Models.AmortizationSchedule _amortizationSchedule, int _consumerLoanSessionID) { int retval = 0; Models.AmortizationSchedule amortizationSchedule = _amortizationSchedule; ArnelAvesExamEntities db = new ArnelAvesExamEntities(); AmortizationSchedule asched = new AmortizationSchedule(); asched.SessionNumber = _consumerLoanSessionID; asched.ScheduleOrderNumber = amortizationSchedule.ScheduleOrderNumber; asched.DueDate = amortizationSchedule.DueDate; asched.PrincipalAmount = amortizationSchedule.PrincipalAmount; asched.InterestRate = amortizationSchedule.InterestRate; asched.InterestAmount = amortizationSchedule.InterestAmount; asched.DueAmount = amortizationSchedule.DueAmount; asched.RemainingBalance = amortizationSchedule.RemainingBalance; asched.DaysInterval = amortizationSchedule.DaysInterval; db.AmortizationSchedules.Add(asched); db.SaveChanges(); retval = asched.AmortizationID; return(retval); }
public static List<AmortizationScheduleModel> CreateScheduleItems(LoanApplication loanApplication, AmortizationSchedule schedule) { var today = DateTime.Now; LoanCalculatorOptions options = new LoanCalculatorOptions(); options.LoanReleaseDate = schedule.LoanReleaseDate; options.PaymentStartDate = schedule.PaymentStartDate; options.LoanAmount = loanApplication.LoanAmount; options.LoanTerm = loanApplication.LoanTermLength; options.LoanTermId = loanApplication.LoanTermUomId; var paymentMode = UnitOfMeasure.GetByID(loanApplication.PaymentModeUomId); options.PaymentMode = paymentMode.Name; options.PaymentModeId = paymentMode.Id; var aiInterestComputationMode = ApplicationItem.GetFirstActive(loanApplication.Application, ProductFeatureCategory.InterestComputationModeType); int interestComputation = 0; if (aiInterestComputationMode != null) interestComputation = aiInterestComputationMode.ProductFeatureApplicability.ProductFeatureId; var interestComputationMode = ProductFeature.GetById(interestComputation); var interestRate = ProductFeature.GetByName(loanApplication.InterestRateDescription); options.InterestComputationMode = interestComputationMode.Name; options.InterestRateDescription = interestRate.Name; options.InterestRate = loanApplication.InterestRate ?? 0; options.InterestRateDescriptionId = interestRate.Id; LoanCalculator calculator = new LoanCalculator(); var items = calculator.GenerateLoanAmortization(options); return items; }
public AmortizationSchedule LoadAmortizationSchedule(Project project, string asOfDate) { var filePath = GetAmortizationSchedulePath(project, asOfDate); AmortizationSchedule amortizationSchedule = new AmortizationSchedule(); amortizationSchedule.Load(filePath); return(amortizationSchedule); }
private List <AmortizationSchedule> BuildSchedule(BuyerInfo model) { try { // initial values var date = model.StartOfPayment; var noOfDays = (date - DateTime.Now).TotalDays; var rate = (decimal)(model.InterestRate / 100); var interest = model.LoanAmount * (decimal)noOfDays * rate / 365; var principal = model.LoanAmount / model.Term; var balance = model.LoanAmount - principal; var schedule = new List <AmortizationSchedule>(); schedule.Add(new AmortizationSchedule() { Id = Guid.NewGuid(), PersonUnitId = model.Id, Date = date, Principal = principal, Interest = interest, LoanAmount = model.LoanAmount, NoOfDays = noOfDays, Total = principal + interest, Balance = balance }); for (var i = 1; i < model.Term; i++) { // succeeding values date = schedule[i - 1].Date.AddMonths(1); noOfDays = (date - schedule[i - 1].Date).TotalDays; interest = schedule[i - 1].Balance * (decimal)noOfDays * rate / 365; balance = schedule[i - 1].Balance - principal; var item = new AmortizationSchedule() { Id = Guid.NewGuid(), PersonUnitId = model.Id, Date = date, Principal = principal, Interest = interest, LoanAmount = model.LoanAmount, NoOfDays = noOfDays, Total = principal + interest, Balance = balance }; schedule.Add(item); } return(schedule); } catch (DivideByZeroException) { return(null); } }
public IAmortization ResetAmortization(Date valueDate) { Dictionary <Date, double> amortizationSchedule = AmortizationSchedule.ToDictionary(x => x.Key, y => y.Value); if (RenormalizeAfterAmoritzation && AmortizationSchedule != null) { amortizationSchedule = AmortizationSchedule.Where(x => x.Key > valueDate).ToDictionary(x => x.Key, y => y.Value); var total = amortizationSchedule.Sum(y => y.Value); foreach (var scheduleKey in amortizationSchedule.ToDictionary(x => x.Key, y => y.Key).Keys) { amortizationSchedule[scheduleKey] = amortizationSchedule[scheduleKey] / total; } } return(new Amortization(amortizationSchedule, RenormalizeAfterAmoritzation, AmortizationType)); }
public void SaveAmortizationSchedule(Project project, string asOfDate, AmortizationSchedule amortizationSchedule) { var filePath = GetAmortizationSchedulePath(project, asOfDate); amortizationSchedule.Save(filePath); }
public static void Approve(LoanApplication loanApplication, DateTime today, List<AmortizationScheduleModel> model, DateTime loanReleaseDate) { RoleType borrowerRoleType = RoleType.BorrowerApplicationType; PartyRole borrowerPartyRole = PartyRole.GetPartyRoleFromLoanApplication(loanApplication, borrowerRoleType); PartyRole customerPartyRole = PartyRole.GetByPartyIdAndRole(borrowerPartyRole.PartyId, RoleType.CustomerType); LoanApplicationStatu loanStatus = LoanApplicationStatu.CreateOrUpdateCurrent(loanApplication, LoanApplicationStatusType.ApprovedType, today); var agreement = Agreement.Create(loanApplication, AgreementType.LoanAgreementType, today); //Create new Loan Agreement Record LoanAgreement loanAgreement = new LoanAgreement(); loanAgreement.Agreement = agreement; Context.LoanAgreements.AddObject(loanAgreement); var agreementItem = Create(loanApplication, agreement); Context.AgreementItems.AddObject(agreementItem); var borrower = RoleType.BorrowerAgreementType; var newBorrowerPartyRole = PartyRole.Create(borrower, customerPartyRole.Party, today); Context.PartyRoles.AddObject(newBorrowerPartyRole); var newBorrowerAgreementRole = CreateAgreementRole(agreement, newBorrowerPartyRole); Context.AgreementRoles.AddObject(newBorrowerAgreementRole); CreateAgreementForCoBorrowers(loanApplication, agreement, today); CreateAgreementForGuarantor(loanApplication, agreement, today); var pendingdvst = DisbursementVcrStatusEnum.PendingType; var disbursement = LoanDisbursementVcr.Create(loanApplication, agreement, today); DisbursementVcrStatu.CreateOrUpdateCurrent(disbursement, pendingdvst, today); AmortizationSchedule schedule = new AmortizationSchedule(); schedule.DateGenerated = today; schedule.EffectiveDate = today; schedule.LoanReleaseDate = today; schedule.PaymentStartDate = model.First().ScheduledPaymentDate; schedule.LoanAgreement = loanAgreement; Context.AmortizationSchedules.AddObject(schedule); foreach (var models in model) { AmortizationScheduleItem item = new AmortizationScheduleItem(); item.AmortizationSchedule = schedule; item.ScheduledPaymentDate = models.ScheduledPaymentDate; item.PrincipalPayment = models.PrincipalPayment; item.InterestPayment = models.InterestPayment; item.PrincipalBalance = models.PrincipalBalance; item.TotalLoanBalance = models.TotalLoanBalance; item.IsBilledIndicator = false; Context.AmortizationScheduleItems.AddObject(item); } Context.SaveChanges(); }
public static void Approve(LoanApplication loanApplication, DateTime today, DateTime loanReleaseDate, DateTime paymentStartDate) { RoleType borrowerRoleType = RoleType.BorrowerApplicationType; PartyRole borrowerPartyRole = PartyRole.GetPartyRoleFromLoanApplication(loanApplication, borrowerRoleType); PartyRole customerPartyRole = PartyRole.GetByPartyIdAndRole(borrowerPartyRole.PartyId, RoleType.CustomerType); LoanApplicationStatu loanStatus = LoanApplicationStatu.CreateOrUpdateCurrent(loanApplication, LoanApplicationStatusType.ApprovedType, today); var agreement = Agreement.Create(loanApplication, AgreementType.LoanAgreementType, today); //Create new Loan Agreement Record LoanAgreement loanAgreement = new LoanAgreement(); loanAgreement.Agreement = agreement; Context.LoanAgreements.AddObject(loanAgreement); var agreementItem = Create(loanApplication, agreement); Context.AgreementItems.AddObject(agreementItem); var borrower = RoleType.BorrowerAgreementType; var newBorrowerPartyRole = PartyRole.Create(borrower, customerPartyRole.Party, today); Context.PartyRoles.AddObject(newBorrowerPartyRole); var newBorrowerAgreementRole = CreateAgreementRole(agreement, newBorrowerPartyRole); Context.AgreementRoles.AddObject(newBorrowerAgreementRole); CreateAgreementForCoBorrowers(loanApplication, agreement, today); CreateAgreementForGuarantor(loanApplication, agreement, today); var pendingdvst = DisbursementVcrStatusEnum.PendingType; var disbursement = LoanDisbursementVcr.Create(loanApplication, agreement, today); DisbursementVcrStatu.CreateOrUpdateCurrent(disbursement, pendingdvst, today); //TODO :: Generate Amortization Schedule.... AmortizationSchedule schedule = new AmortizationSchedule(); schedule.DateGenerated = today; schedule.EffectiveDate = today; schedule.LoanReleaseDate = today; schedule.PaymentStartDate = paymentStartDate; schedule.LoanAgreement = loanAgreement; Context.AmortizationSchedules.AddObject(schedule); LoanCalculatorOptions options = new LoanCalculatorOptions(); var aiInterestComputationMode = ApplicationItem.GetFirstActive(loanApplication.Application, ProductFeatureCategory.InterestComputationModeType); options.InterestComputationMode = aiInterestComputationMode.ProductFeatureApplicability.ProductFeature.Name; options.LoanAmount = loanApplication.LoanAmount; options.LoanTerm = loanApplication.LoanTermLength; options.LoanTermId = loanApplication.LoanTermUomId; options.InterestRate = loanApplication.InterestRate ?? 0; options.InterestRateDescription = loanApplication.InterestRateDescription; options.InterestRateDescriptionId = Context.ProductFeatures.SingleOrDefault(entity => entity.Name == loanApplication.InterestRateDescription).Id; options.PaymentModeId = loanApplication.PaymentModeUomId; options.PaymentMode = UnitOfMeasure.GetByID(options.PaymentModeId).Name; options.PaymentStartDate = paymentStartDate; options.LoanReleaseDate = loanReleaseDate; LoanCalculator loanCalculator = new LoanCalculator(); var models = loanCalculator.GenerateLoanAmortization(options); foreach (var model in models) { AmortizationScheduleItem item = new AmortizationScheduleItem(); item.AmortizationSchedule = schedule; item.ScheduledPaymentDate = model.ScheduledPaymentDate; item.PrincipalPayment = model.PrincipalPayment; item.InterestPayment = model.InterestPayment; item.PrincipalBalance = model.PrincipalBalance; item.TotalLoanBalance = model.TotalLoanBalance; item.IsBilledIndicator = false; Context.AmortizationScheduleItems.AddObject(item); } Context.SaveChanges(); }
public double GetRemainingPrincipal(Date valueDate) { return(AmortizationSchedule.Where(x => x.Key > valueDate).Sum(x => x.Value)); }
private AmortizationSchedule CreateAmortizationScheduleWithParent(LoanAgreement loanAgreement, AmortizationItemsModel schedule, DateTime today, AmortizationSchedule parentSchedule) { AmortizationSchedule amortizationScheduleNew1 = new AmortizationSchedule(); amortizationScheduleNew1.LoanAgreement = loanAgreement; amortizationScheduleNew1.LoanReleaseDate = schedule.LoanReleaseDate; amortizationScheduleNew1.PaymentStartDate = schedule.PaymentStartDate; amortizationScheduleNew1.DateGenerated = today; amortizationScheduleNew1.EffectiveDate = today; amortizationScheduleNew1.ParentAmortizationScheduleId = parentSchedule.Id; return amortizationScheduleNew1; }
private AmortizationScheduleItem CreateAmortizationScheduleItem(AmortizationSchedule schedule, DateTime today, AmortizationScheduleModel item) { AmortizationScheduleItem amortizationItem = new AmortizationScheduleItem(); amortizationItem.AmortizationSchedule = schedule; amortizationItem.InterestPayment = item.InterestPayment; amortizationItem.IsBilledIndicator = item.IsBilledIndicator; amortizationItem.PrincipalBalance = item.PrincipalBalance; amortizationItem.PrincipalPayment = item.PrincipalPayment; amortizationItem.ScheduledPaymentDate = item.ScheduledPaymentDate; amortizationItem.TotalLoanBalance = item.TotalLoanBalance; return amortizationItem; }
public void PrepareForSave(LoanApplication app, AmortizationSchedule sched, AmortizationScheduleModel models) { if (this.IsNew) { if (app.LoanTermLength != 0) { AmortizationScheduleItem item = new AmortizationScheduleItem(); item.AmortizationSchedule = sched; item.ScheduledPaymentDate = models.ScheduledPaymentDate; item.PrincipalPayment = models.PrincipalPayment; item.InterestPayment = models.InterestPayment; item.PrincipalBalance = models.PrincipalBalance; item.TotalLoanBalance = models.TotalLoanBalance; item.IsBilledIndicator = false; Context.AmortizationScheduleItems.AddObject(item); } } else { if (app.LoanTermLength != 0) { var items = Context.AmortizationScheduleItems.Where(entity => entity.AmortizationScheduleId == sched.Id); foreach (var schedule in items) { Context.AmortizationScheduleItems.DeleteObject(schedule); } AmortizationScheduleItem item = new AmortizationScheduleItem(); item.AmortizationSchedule = sched; item.ScheduledPaymentDate = models.ScheduledPaymentDate; item.PrincipalPayment = models.PrincipalPayment; item.InterestPayment = models.InterestPayment; item.PrincipalBalance = models.PrincipalBalance; item.TotalLoanBalance = models.TotalLoanBalance; item.IsBilledIndicator = false; Context.AmortizationScheduleItems.AddObject(item); //int count = Convert.ToInt32(models.Counter.ElementAt(models.Counter.Length - 1)); //int i = 0; //foreach (var item in items) //{ // if (i != count) // i++; // else // { // DateTime date = models.ScheduledPaymentDate; // item.ScheduledPaymentDate = date; // item.PrincipalPayment = models.PrincipalPayment; // item.InterestPayment = models.InterestPayment; // item.PrincipalBalance = models.PrincipalBalance; // item.TotalLoanBalance = models.TotalLoanBalance; // item.IsBilledIndicator = false; // break; // } //} } } }
public AmortizationSchedule Calculate(decimal loanAmount, decimal interestRate, int termInMonths, DateTime startDate, decimal?monthlyPayment = null, ExtraPayment extraPayment = null) { if (termInMonths <= 0) { throw new Exception($"Loan term in months must be greater than zero. Term received was {termInMonths}."); } var monthlyInterestRate = interestRate / MonthsInYear; // calculate estimated monthly payment if calling code does not send an amount or valid amount if (monthlyPayment <= 0m || monthlyPayment == null) { monthlyPayment = loanAmount * (decimal)((double)monthlyInterestRate / (1 - Math.Pow(1 + (double)monthlyInterestRate, -termInMonths))); } var remainingBalance = loanAmount; var interestPaidToDate = 0m; DateTime maturityDate = startDate.AddMonths(termInMonths); var currentServicingDate = startDate; var amortizationPayments = new List <AmortizationPayment>(); var monthCount = 0; // month count will result in remaining balance > 0 by end of term if we account for missed payments while (monthCount < termInMonths || Math.Round(remainingBalance, 2) > MinimumBalanceLeft) { if (monthCount > 0) // added if to prevent adding of month if it is the first month { currentServicingDate = currentServicingDate.AddMonths(1); // assuming monthly intervals for payments } monthCount++; // while loop will always continue to end of term so that we can calculate relative total interest if actual balance is completed before end of term if (Math.Round(remainingBalance, 2) <= MinimumBalanceLeft) // can this remaining balance <= 0 be checked against 0.00 e.g. Math.Round(remainingBalance, 2) <= 0 currently there are scenarios where the remaining balance may be 0.00000001 { continue; } // set base interest and principal for month var interestForMonth = remainingBalance * monthlyInterestRate; var principalForMonth = monthlyPayment.Value - interestForMonth; // checks if current term will contain last payment if (remainingBalance < monthlyPayment.Value) { // updates principal for month since that will be the only value affected by the last payment principalForMonth = (monthlyInterestRate + 1) * remainingBalance - interestForMonth; // above is equal to principalForMonth = remainingBalance when you simplify. } // get any additional or historical payments var extraPaymentForMonth = GetExtraPayment(extraPayment, currentServicingDate); // calculate any left over extra payment. currently just stored in local variable if (remainingBalance < principalForMonth + extraPaymentForMonth) // moved remaining balance to the front for readibility { var leftoverExtraPayment = (principalForMonth + extraPaymentForMonth) - remainingBalance; // this equation works for both when principal < remaining balance and principal > remaining balance extraPaymentForMonth -= leftoverExtraPayment; } remainingBalance -= principalForMonth + extraPaymentForMonth; interestPaidToDate += interestForMonth; // apply payments saved and maturity date current iteration is last payment if (Math.Round(remainingBalance, 2) <= MinimumBalanceLeft) { // moved this setting of data out of previous if blocks because there are multiple ways to end a loan // remaining balance < monthly payment or remaining balance < principal for month + extra payment for month (if an extra payment is made on the last term) maturityDate = currentServicingDate; } // create amort payment and add to schedule (no rounding) amortizationPayments.Add(new AmortizationPayment() { PaymentDate = currentServicingDate, PaymentInterest = interestForMonth, PaymentPrincipal = principalForMonth, PaymentAmount = principalForMonth + interestForMonth, AdditionalPrincipal = extraPaymentForMonth, InterestPaidToDate = interestPaidToDate, BalanceToDate = remainingBalance }); } var amortizationSchedule = new AmortizationSchedule() { InterestPaid = interestPaidToDate, ExtraPrincipalPaid = amortizationPayments.Sum(x => x.AdditionalPrincipal), MonthlyPayment = monthlyPayment.Value, MaturityDate = maturityDate, Schedule = amortizationPayments }; return(amortizationSchedule); }
public List <Models.AmortizationSchedule> ComputeAmortizationScheduleAndSaveToDB(DateTime _startDate, double _loanAmount, double _interestRate, double _loanTenure) { List <Models.AmortizationSchedule> retval = new List <Models.AmortizationSchedule>(); DateTime startDate = _startDate; double loanAmount = _loanAmount; double interestRate = _interestRate; double loanTenure = _loanTenure; int sessionID = SaveSessionToDB(startDate, loanAmount, interestRate, loanTenure); DateTime previousDate = startDate; double principalAmount = loanAmount / loanTenure; double runningLoanAmount = _loanAmount; for (int i = 1; i <= loanTenure; i++) { Models.AmortizationSchedule amortizationSchedule = new Models.AmortizationSchedule(); amortizationSchedule.ScheduleOrderNumber = i; amortizationSchedule.PrincipalAmount = principalAmount; DateTime runningDate = GetNextDate(previousDate); amortizationSchedule.DueDate = runningDate; int runningDaysInterval = runningDate.Subtract(previousDate).Days; amortizationSchedule.DaysInterval = runningDaysInterval; double runningInterestAmount = runningLoanAmount * runningDaysInterval * interestRate / DaysInYear; amortizationSchedule.InterestAmount = runningInterestAmount; amortizationSchedule.DueAmount = principalAmount + runningInterestAmount; runningLoanAmount -= principalAmount; amortizationSchedule.RemainingBalance = runningLoanAmount; amortizationSchedule.InterestRate = interestRate; previousDate = runningDate; //retval.Add(amortizationSchedule); SaveAmortizationToDB(amortizationSchedule, sessionID); } // retrieve list from db ArnelAvesExamEntities db = new ArnelAvesExamEntities(); var empQuery = from emp in db.AmortizationSchedules where emp.SessionNumber == sessionID orderby emp.ScheduleOrderNumber select emp; List <AmortizationSchedule> dblist = empQuery.ToList(); foreach (var obj in dblist) { AmortizationSchedule asched = (AmortizationSchedule)obj; Models.AmortizationSchedule amortizationSchedule = new Models.AmortizationSchedule(); amortizationSchedule.ScheduleOrderNumber = (int)asched.ScheduleOrderNumber; amortizationSchedule.PrincipalAmount = (double)asched.PrincipalAmount; amortizationSchedule.DueDate = (DateTime)asched.DueDate; amortizationSchedule.DaysInterval = (int)asched.DaysInterval; amortizationSchedule.InterestAmount = (double)asched.InterestAmount; amortizationSchedule.DueAmount = (double)asched.DueAmount; amortizationSchedule.RemainingBalance = (double)asched.RemainingBalance; amortizationSchedule.InterestRate = (double)asched.InterestRate; retval.Add(amortizationSchedule); } return(retval); }