/// <summary> /// Adds the payment dates to a given Amortization Table. This function takes /// into consideration the holidays of the given country as well as weekend days. /// </summary> /// <param name="amortizationTable">Amortization table to which dates will be added</param> /// <param name="startDate">Date from where the loan is valid. All payments will be /// calculated taking this date as the base /// </param> /// <param name="frequency">Payment frequency</param> /// <param name="country">Country from which holidays need to be accounted for</param> /// <remarks>The First payment will be calculated after the StartDate from the Amortization. /// The Amortization object will be modified inside this function.</remarks> public void AddAmortizationPaymentDates(AmortizationTable amortizationTable, DateTime startDate, AmortizationPaymentFrequencyType frequency, Country country) { /* Calculate the amortizations first without * taking into account the holidays or weekends */ foreach (AmortizationEntry entry in amortizationTable) { entry.Date = GetPaymentDate (startDate, frequency, entry.Number); } /* Now verify all dates are working days */ VerifyWorkingDates (amortizationTable, country); }
public void UT_Calculate_Amortization_table(double totalLoan, double rate, int periodsNumber, double fixCoute) { try { var result = FinantialFunctions.CalculateFixCuote(totalLoan, rate, periodsNumber); var rounded = Math.Round(result, 2); Assert.Equal(fixCoute, rounded); AmortizationTable table = new AmortizationTable(); table = FinantialFunctions.CalculateAmortizationTable(totalLoan, rate, 1, rounded); Trace.TraceInformation(table.PrintString()); } catch (Exception ex) { Assert.True(false, ex.Message); } }
//public int Period { get; set; } //public double Cuote { get; set; } //public double Interests { get; set; } //public double NewBalance { get; set; } //public double Amortization { get; set; } /// <summary> /// Calcula la cuota fija en base al total del préstamo la tasa y el numero de periodos /// R = P[(i(1 + i)n) / ((1 + i)n – 1)] /// P = principal(préstamo adquirido) /// i = tasa de interés /// n = número de periodos /// </summary> /// <param name="balance">Total outstanding balance </param /// <param name="rate">Loan Rate 1 relative E.G. .04 = 4%</param> /// <param name="actualPeriodNumber">Actual number of payment</param> /// <param name="fixCoute">Fix Cuote to pay</param> public static AmortizationTable CalculateAmortizationTable(double balance, double rate, int actualPeriodNumber, double fixCoute) { AmortizationTable table = new AmortizationTable(); table.Rows = new List <AmortizationRow>(); AmortizationRow amortizationActualRow; double intereses = 0; double amortization = 0; double newBalance = balance; while (newBalance > 0) { intereses = newBalance * rate; amortization = fixCoute - intereses; newBalance = newBalance - amortization; amortizationActualRow = new AmortizationRow(actualPeriodNumber++, fixCoute, intereses, newBalance, amortization); table.Rows.Add(amortizationActualRow); } return(table); }
/// <summary> /// Calculates an Amortization Table using a Flat Interest approach /// </summary> /// <returns>Flat Interest Amortization Table</returns> protected override AmortizationTable CalculateSpecificAmortizationTable() { //Stores all the table entries in a list form. //Each item in this list will contain all the columns that the amortization //table has. IList<AmortizationEntry> amortizationEntries = new List<AmortizationEntry> (); //Local variables used to store each payments //calculated values decimal interestPayment = 0.0000m; decimal principalPayment = 0.0000m; decimal principalBalance = 0.0000m; decimal taxPayment = 0.0000m; for (int i = 0; i < base.NumberOfPayments; i++) { //First Payment is of the total amount of the loan if (i == 0) { //Calculates the amounts if (base.GracePeriod - 1 >= i) //While there is a grace period, { //only interests are paid principalPayment = 0; interestPayment = base.CalculationInterest * base.Amount; taxPayment = interestPayment * base.Tax; } else { principalPayment = base.Amount / (base.NumberOfPayments - base.GracePeriod); interestPayment = base.CalculationInterest * base.Amount; taxPayment = interestPayment * base.Tax; } principalBalance = base.Amount - principalPayment; AmortizationEntry newAmortizationTableEntry = new AmortizationEntry (); newAmortizationTableEntry.Number = i + 1; newAmortizationTableEntry.Principal = principalPayment; newAmortizationTableEntry.Interest = interestPayment; newAmortizationTableEntry.Tax = taxPayment; newAmortizationTableEntry.RemainingPrincipalBalance = principalBalance; //Add the new entry to the table. amortizationEntries.Add (newAmortizationTableEntry); } else //All other payments { //Retrieve the previous entry in the table. AmortizationEntry previousTableEntry = amortizationEntries[i - 1]; //Calculates the amounts if (base.GracePeriod - 1 >= i) //While there is a grace period, { //only interests are paid principalPayment = 0; interestPayment = base.CalculationInterest * base.Amount; taxPayment = interestPayment * base.Tax; } else { principalPayment = base.Amount / (base.NumberOfPayments - base.GracePeriod); interestPayment = base.CalculationInterest * base.Amount; taxPayment = interestPayment * base.Tax; } principalBalance = previousTableEntry.RemainingPrincipalBalance - principalPayment; AmortizationEntry newAmortizationTableEntry = new AmortizationEntry (); newAmortizationTableEntry.Number = i + 1; newAmortizationTableEntry.Principal = principalPayment; newAmortizationTableEntry.Interest = interestPayment; newAmortizationTableEntry.Tax = taxPayment; newAmortizationTableEntry.RemainingPrincipalBalance = principalBalance; //Add the new entry to the table. amortizationEntries.Add (newAmortizationTableEntry); } } //Create table and return it based on the calculated entries. AmortizationTable amortizationTable = new AmortizationTable (amortizationEntries); return amortizationTable; }
/// <summary> /// Calculates the chosen amortization table. /// </summary> /// <returns>Calculated amortization table.</returns> /// <exception cref="ArgumentOutOfRangeException" /> public void CalculateAmortizationTable() { // Verify that the provided values are correct if (Amount <= 0) { throw new ZiblerFinanceArgumentOutOfRangeException ( Resources.AmortAmountInvalidMessage); } if (NumberOfPayments <= 0) { throw new ZiblerFinanceArgumentOutOfRangeException ( Resources.AmortNmbrPaymentsInvalidMessage); } if (AnualInterest < 0) { throw new ZiblerFinanceArgumentOutOfRangeException ( Resources.AmortAnualInterestInvalidMessage); } if (GracePeriod < 0) { throw new ZiblerFinanceArgumentOutOfRangeException ( Resources.AmortGracePeriodInvalidMessage); } if (GracePeriod >= NumberOfPayments) { throw new ZiblerFinanceArgumentOutOfRangeException ( Resources.AmortNmbrPaymentsInvalidMessage); } if (Tax < 0) { throw new ZiblerFinanceArgumentOutOfRangeException ( Resources.AmortTaxInvalidMessage); } //Convert the interest to be used in calculation _calculationInterest = ConvertAnualInterestToCalculationInterest (AnualInterest, PaymentFrequency); // Call the childs class AmortizationTable method // to calculate the actual table. _amortizationTable = CalculateSpecificAmortizationTable (); }
/// <summary> /// Gets the payment number date. /// </summary> /// <param name="startDate">The start date.</param> /// <param name="paymentNumber">The payment number.</param> /// <param name="frequency">The frequency.</param> /// <param name="country">The country.</param> public DateTime GetPaymentNumberDate(DateTime startDate, int paymentNumber, AmortizationPaymentFrequencyType frequency, Country country) { /* Date to return */ DateTime? paymentDate = null; IList<AmortizationEntry> entries = new List<AmortizationEntry> (); /* Perform calculations for all payments before the * requested payment in case there was days shifted * before the paymentNumber required */ for (int i = 1; i <= paymentNumber; i++) { paymentDate = GetPaymentDate (startDate, frequency, i); AmortizationEntry entry = new AmortizationEntry (); entry.Number = i; entry.Date = Convert.ToDateTime (paymentDate); entries.Add (entry); } AmortizationTable amortTable = new AmortizationTable (entries); /* Now verify all dates are working days */ VerifyWorkingDates (amortTable, country); /* Now get the the actual date */ foreach (AmortizationEntry entry in amortTable) { if (entry.Number == paymentNumber) { paymentDate = entry.Date; break; } } return Convert.ToDateTime (paymentDate); }
/// <summary> /// Verifies the dates in the amortization table are working days /// </summary> /// <param name="amortizationTable">Amortization table</param> /// <param name="country">Country used for holidays</param> private void VerifyWorkingDates(AmortizationTable amortizationTable, Country country) { /* Now, loop through the amortizations and make sure non of the days * are either holidays or weekend days */ foreach (AmortizationEntry entry in amortizationTable) { /* If the payment date is a holiday then find the closest working day forward */ while (DateUtilities.IsHoliday (country, entry.Date)) { /* Add on the days */ entry.Date = entry.Date.AddDays (1); } /* Make sure the payment date is not a weekend. If it is, then find the * closest (ahead) working day forward */ while (entry.Date.DayOfWeek == DayOfWeek.Saturday || entry.Date.DayOfWeek == DayOfWeek.Sunday) { //Add one day at the time until it is //a business day. entry.Date = entry.Date.AddDays (1); } } }