Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Monthly payment calculator (amortization)
#1
This code will calculate a monthly loan payment (based on monthly compounding, not bi-annual as in Canada) if principal, interest rate, and term are supplied.
There is a combo box to pick a term of years or months, and another to pick from several currency formats. Validation is not robust, but can stop most user errors. The dialog still needs work, but it is functional.
 
Code:
Copy      Help
//.
using System.Windows.Controls;

script.setup(trayIcon: true, sleepExit: true);
//..
var b = new wpfBuilder("Amortization Helper").WinSize(300);

b.R.Add("Principal", out TextBox principal).Focus(); //Label and TextBox
b.R.Add("Interest Rate", out TextBox interest).Focus(); //Label and TextBox
b.R.Add("Loan term", out TextBox loanTerm).Focus(); //Label and TextBox
b.R.Add("Years/months", out ComboBox yearsOrMonths).Items("Years|Months"); //Label and ComboBox with two items
b.R.Add("Currency region", out ComboBox currencyRegion)
    .Items("en-US|en-GB|de-DE|fr-FR|es-ES|lt-LT|ru-RU|zh-CN|ar-EG"); //Currency regions (a few)
b.R.Add("Monthly payment", out TextBox monthlyPayment).Readonly();
b.Row((0, 30..30 )).AddButton("Calculate", _ => monthlyPayment.Text = CalcFunc(principal.Text, interest.Text,
    yearsOrMonths.SelectionBoxItem.ToString(),
    loanTerm.Text,
    currencyRegion.SelectionBoxItem.Text,
    monthlyPayment.Text)).Width(70).Align("L")
    .AddButton("Exit", 0).Width(70).Align("R"); // This overload will exit and return 0
b.End();
if (!b.ShowDialog()) return;


string CalcFunc(string principal, string rate, string comboitem, string term, string currencyitem, string monthlyPayment) {
    /*
    Monthly payment = amount times {rate times the quantity (1 plus rate) to the power of rate)} > func_top
                                   {___________________________________________________________}
                                   { ((1 plus rate) to the power of rate) - 1                  } > func_bottom
    */
    double localRate = rate.ToNumber();
    double localPrincipal = principal.ToNumber();
    double localTerm = term.ToNumber();
    if ( comboitem == "Years")
        {localTerm = localTerm * 12;}

    double thisRate = localRate/100/12;
    // In the comments below, p=Principal, r=Interest Rate, t=Loan term
    double funcTop = thisRate * Math.Pow(1 + thisRate, localTerm); // r * ( 1+r)^t
    double funcBottom = Math.Pow(1 + thisRate, localTerm) - 1; // ((1+r)^t) -1
    double monthly = localPrincipal * (funcTop / funcBottom); // monthly = p * ((r * (1+r)^t))/((1+r)^t-1)
    CultureInfo myCulture = new CultureInfo(currencyitem);
    print.it(monthly.ToString("C", myCulture));
    // minimal validation: If the calculation is not a number or principal.ToNumber()
    // evaluates to zero (i.e. non-digit, string, or empty),
    // or loanTerm evaluates to positive infinity or is <0, return an admonition.
    if (monthly.ToString() == "NaN" | double.IsPositiveInfinity(monthly) | localTerm <0 | localPrincipal == 0) {
        return("Positive numbers in all fields!");
    } else {
        return monthlyPayment = monthly.ToString("C", myCulture);
    }
};

// http://www.blackwasp.co.uk/csharpinfinity.aspx
// https://www.hughcalc.org/formula.html

Regards,
burque505

EDIT 2023-07-18: Change "currencyRegion.SelectionBoxItem.ToString()," to "currencyRegion.SelectionBoxItem.Text,". Original failed after latest Windows update.


Attached Files Image(s)
   


Forum Jump:


Users browsing this thread: 1 Guest(s)