I have been trying to get my amortization calculator to work however the ending payment balance does not end on 0 and my code does not output the correct values and I am stuck after doing some googling for a couple hours. I believe my issue is underneath the comment "Listbox Loop." Any help would be appreciated.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
// Allows for the hotkeys to be used even when out of focus from main form
this.KeyPreview = true;
}
private void MainForm_KeyPress(object sender, KeyPressEventArgs e)
{
// Adds hotkeys; Enter = Calculate, Escape = Exit
if (e.KeyChar == (char)Keys.Enter)
{
calculateButton.PerformClick();
}
else if (e.KeyChar == (char)Keys.Escape)
{
exitButton.PerformClick();
}
}
private void rebateCheck_CheckedChanged(object sender, EventArgs e)
{
// Enables & Disables rebate textbox based on rebate checkbox
if (rebateCheck.Checked == true)
{
rebateBox.Enabled = true;
}
else
{
rebateBox.Clear();
rebateBox.Enabled = false;
}
}
/* Selects data inside of the textbox when tabbing or clicking into it */
private void loanAmountBox_Enter(object sender, EventArgs e)
{
loanAmountBox.SelectAll();
}
private void loanAmountBox_Click(object sender, EventArgs e)
{
loanAmountBox.SelectAll();
}
private void annualAPRBox_Enter(object sender, EventArgs e)
{
annualAPRBox.SelectAll();
}
private void annualAPRBox_Click(object sender, EventArgs e)
{
annualAPRBox.SelectAll();
}
private void rebateBox_Enter(object sender, EventArgs e)
{
rebateBox.SelectAll();
}
private void rebateBox_Click(object sender, EventArgs e)
{
rebateBox.SelectAll();
}
/* Clears the list box when text is changed on any of the input boxes */
private void loanAmountBox_TextChanged(object sender, EventArgs e)
{
loanListBox.Items.Clear();
}
private void annualAPRBox_TextChanged(object sender, EventArgs e)
{
loanListBox.Items.Clear();
}
private void rebateBox_TextChanged(object sender, EventArgs e)
{
loanListBox.Items.Clear();
}
/* Only allows digits, periods, and control keys to be entered into textboxes */
private void loanAmountBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !Char.IsDigit(e.KeyChar) && e.KeyChar != '.')
{
e.Handled = true;
return;
}
}
private void annualAPRBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !Char.IsDigit(e.KeyChar) && e.KeyChar != '.')
{
e.Handled = true;
return;
}
}
private void rebateBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !Char.IsDigit(e.KeyChar) && e.KeyChar != '.')
{
e.Handled = true;
return;
}
}
private void exitButton_Click(object sender, EventArgs e)
{
// Asks the user if they are sure they want to exit
DialogResult dialog = MessageBox.Show("Are you sure you want to exit?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); ;
if (dialog == DialogResult.Yes)
this.Close();
}
private void calculateButton_Click(object sender, EventArgs e)
{
// Declaring all variables
int monthsCounter;
double loan;
double rate;
double rebate;
double principal;
double balance;
int months = 0;
double principalPayment = 0;
double pmt = 0;
double interest = 0;
double totalInterest = 0;
double totalPrincipal = 0;
double totalPayment = 0;
double monthlyRate;
try
{
// Parse data from textboxes
double.TryParse(loanAmountBox.Text, out loan);
double.TryParse(annualAPRBox.Text, out rate);
double.TryParse(rebateBox.Text, out rebate);
// Check which loan month radio button is selected
if (loan6Months.Checked)
{
months = 6;
}
else if (loan12Months.Checked)
{
months = 12;
}
else if (loan18Months.Checked)
{
months = 18;
}
else if (loans24Months.Checked)
months = 24;
// Validates if the Loan Amount textbox is blank and if so, throws an error message pop up
if (loan == 0)
{
MessageBox.Show("Please enter a loan value.", "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
loanAmountBox.Focus();
loanAmountBox.SelectAll();
}
else if (rate == 0)
{
MessageBox.Show("Please enter/select an APR value.", "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
annualAPRBox.Focus();
annualAPRBox.SelectAll();
}
rate = (rate / 100) / 12;
loan = loan - rebate;
// Listbox loop
for (monthsCounter = 1; monthsCounter <= months; monthsCounter = monthsCounter + 1)
{
// Add to total variables
totalInterest += interest;
totalPrincipal += principalPayment;
totalPayment += pmt;
// Calculate the principal payment
interest = loan * rate;
principalPayment = (loan * rate * Math.Pow(1 + rate, months)) / (Math.Pow(1 + rate, months) - 1);
pmt = principalPayment + interest;
loan = loan - principalPayment;
// Output data to listbox
loanListBox.Items.Add(String.Format("{0,5}{1,12}{2,12}{3,12}{4,12}", monthsCounter, interest.ToString("N2"), principalPayment.ToString("N2"), pmt.ToString("N2"), loan.ToString("N2")));
}
loanListBox.Items.Add("");
loanListBox.Items.Add(String.Format("{0,5}{1,12}{2,12}{3,12}", "Total", totalInterest.ToString("N2"), totalPrincipal.ToString("N2"), totalPayment.ToString("N2")));
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
}
This is what my output looks like when running the program:
However, the output is supposed to be this:
The formula you're using for amortization is correct, it's what you do after this that is giving you the wrong result.
principalPayment
is the total payment which includes interest. You should probably rename this tototalPayment
because the name is misleading. If you know the total payment amount, and you know the interest. How are you going to get the principal amount?Update: Keep in mind that the loan value used in the amortization formula is not changed--the original loan amount is used for all calculations.
Any time you see "???", it means that you need to fill in the code.
You may consider adding a variable:
Then put the loan amount into
originalLoanAmount
.Set initial values before the "for" loop:
How do you calculate the interest?
Calculate total payment: (original loan amount doesn't change)
What's the principalPayment?
What's the new balance?