/// <summary> /// User has clicked the PMT compute Button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mBtnPMTCompute_Click(object sender, EventArgs e) { TvmObject O = new TvmObject(); double Pmt; bool Valid = true; #region Verify Format if ((double.TryParse(mN.Text, out double w)) == false) { mN.Text = ""; mN.Hint = "Invalid Input"; Valid = false; } if ((double.TryParse(mIY.Text, out double x)) == false) { mIY.Text = ""; mIY.Hint = "Invalid Input"; Valid = false; } if ((double.TryParse(mPV.Text, out double y)) == false) { mPV.Text = ""; mPV.Hint = "Invalid Input"; Valid = false; } if ((double.TryParse(mFV.Text, out double z)) == false) { mFV.Text = ""; mFV.Hint = "Invalid Input"; Valid = false; } #endregion if (Valid == true) { O.N = double.Parse(mN.Text); O.I = double.Parse(mIY.Text); O.Pv = double.Parse(mPV.Text); O.Fv = double.Parse(mFV.Text); if (this.IsBegMode == true) { Pmt = PmtAdCompute(O); } else { Pmt = PmtCompute(O); } mOnPmtComptComplete.Invoke(this, new OnPmtComputeEventArgs(Pmt)); this.Dismiss(); } }
/// <summary> /// Computes the interest rate in a TVM equation, note that this method utilizes Newton's Method /// to iterate through possible options to find the best fit as interest rate cannot be directly computed. /// Regular Annuity or payment at end of the period. /// </summary> public static double ICompute(TvmObject obj) { var n = obj.N; var pv = obj.Pv; var pmt = obj.Pmt; var fv = obj.Fv; var type = 0; var guess = 0.1; try { int itrMax = 20; double espMax = 1e-10; double y, y1, rate = 0, f = 0, count = 0; double i = guess; f = Math.Pow(1 + i, n); y = pv * f + pmt * ((f - 1) / i) * (1 + i * type) + fv; //first derivative: y1 = (f * ((pmt * n * type + n * pv) * Math.Pow(i, 2) + (pmt * n - pmt) * i - pmt) + pmt * i + pmt) / (Math.Pow(i, 3) + Math.Pow(i, 2)); rate = i - y / y1; while ((Math.Abs(i - rate) > espMax) && (count < itrMax)) { i = rate; f = Math.Pow(1 + i, n); y = pv * f + pmt * ((f - 1) / i) * (1 + i * type) + fv; //first derivative: y1 = (f * ((pmt * n * type + n * pv) * Math.Pow(i, 2) + (pmt * n - pmt) * i - pmt) + pmt * i + pmt) / (Math.Pow(i, 3) + Math.Pow(i, 2)); rate = i - y / y1; ++count; } i = rate; return(i * 100); } catch { throw new System.ArgumentException(); } }
public void PVAd2_Compute() { //Arrange, var obj = new TvmObject { N = 5, I = 10, Pv = 0, Pmt = 10, Fv = -350 }; //Act, var result = Math.Round(PvAdCompute(obj), 4); //Assert Assert.AreEqual(175.6238, result); }
public void PVAd_Compute() { //Arrange, var obj = new TvmObject { N = 5, I = 10, Pv = 0, Pmt = -10, Fv = 200, }; //Act, var result = Math.Round(PvAdCompute(obj), 4); //Assert Assert.AreEqual(-82.4856, result); }
public void IAd2_Compute() { //Arrange, var obj = new TvmObject { N = 15, I = 0, Pv = 100, Pmt = 50, Fv = -925, }; //Act, var result = Math.Round(IAdCompute(obj), 4); //Assert Assert.AreEqual(0.9519, result); }
public void IAd_Compute() { //Arrange, var obj = new TvmObject { N = 10, I = 0, Pv = -100, Pmt = -10, Fv = 1000, }; //Act, var result = Math.Round(IAdCompute(obj), 4); //Assert Assert.AreEqual(20.9629, result); }
public void NAd2_Compute() { //Arrange, var obj = new TvmObject { N = 0.00, I = 12, Pv = 200, Pmt = 5, Fv = -400, }; //Act, var result = Math.Round(NAdCompute(obj), 4); //Assert Assert.AreEqual(5.2394, result); }
public void FVAd_Compute() { //Arrange, var obj = new TvmObject { N = 5, I = 10, Pv = -5, Pmt = -10, Fv = 0, }; //Act, var result = Math.Round(FvAdCompute(obj), 4); //Assert Assert.AreEqual(75.2087, result); }
public void PMT2_Compute() { //Arrange, var obj = new TvmObject { N = 15, I = 5, Pv = -30, Pmt = 0, Fv = 250, }; //Act, var result = Math.Round(PmtCompute(obj), 4); //Assert Assert.AreEqual(-8.6953, result); }
public void PV2_Compute() { //Arrange, var obj = new TvmObject { N = 8, I = 12, Pv = 0, Pmt = 10, Fv = -500, }; //Act, var result = Math.Round(PvCompute(obj), 4); //Assert Assert.AreEqual(152.2652, result); }
public void I6_Compute() { //Arrange, var obj = new TvmObject { N = 5, I = 0, Pv = -10, Pmt = 5, Fv = 0, }; //Act, var result = Math.Round(ICompute(obj), 4); //Assert Assert.AreEqual(41.0415, result); }
public void I4_Compute() { //Arrange, var obj = new TvmObject { N = 2, I = 0, Pv = -10, Pmt = 10, Fv = 0, }; //Act, var result = Math.Round(ICompute(obj), 4); //Assert Assert.AreEqual(61.8034, result); }
public void I2_Compute() { //Arrange, var obj = new TvmObject { N = 12, I = 0, Pv = 140, Pmt = 50, Fv = -1000, }; //Act, var result = Math.Round(ICompute(obj), 4); //Assert Assert.AreEqual(4.3512, result); }
public void N2_Compute() { //Arrange, var obj = new TvmObject { N = 0.00, I = 15, Pv = 200, Pmt = 15, Fv = -750, }; //Act, var result = Math.Round(NCompute(obj), 4); //Assert Assert.AreEqual(7.4516, result); }
public void N_Compute() { //Arrange, var obj = new TvmObject { N = 0.00, I = 15, Pv = -250, Pmt = -15, Fv = 750, }; //Act, var result = Math.Round(NCompute(obj), 4); //Assert Assert.AreEqual(6.3487, result); }
public void PMTAd2_Compute() { //Arrange, var obj = new TvmObject { N = 10, I = 15, Pv = 20, Pmt = 0, Fv = -346, }; //Act, var result = Math.Round(PmtAdCompute(obj), 4); //Assert Assert.AreEqual(11.3532, result); }
public void FV2_Compute() { //Arrange, var obj = new TvmObject { N = 10, I = 6, Pv = -25, Pmt = -50, Fv = 0, }; //Act, var result = Math.Round(FvCompute(obj), 4); //Assert Assert.AreEqual(703.8109, result); }
public void FVAd2_Compute() { //Arrange, var obj = new TvmObject { N = 65, I = 8, Pv = 1000, Pmt = 100, Fv = 0, }; //Act, var result = Math.Round(FvAdCompute(obj), 4); //Assert Assert.AreEqual(-348282.6396, result); }
public void NAd_Compute() { //Arrange, var obj = new TvmObject { N = 0.00, I = 10, Pv = -100, Pmt = -10, Fv = 500, }; //Act, var result = Math.Round(NAdCompute(obj), 4); //Assert Assert.AreEqual(11.1882, result); }
public void PMTAd_Compute() { //Arrange, var obj = new TvmObject { N = 10, I = 10, Pv = -15, Pmt = 0, Fv = 100, }; //Act, var result = Math.Round(PmtAdCompute(obj), 4); //Assert Assert.AreEqual(-3.4849, result); }
/// <summary> /// Computes the present value in a TVM equation. Regular Annuity or payment at end of the period. /// </summary> public static double PvCompute(TvmObject obj) { var n = obj.N; var i = obj.I; double pv = 0; var pmt = obj.Pmt; var fv = obj.Fv; try { i = i / 100; pv = (1 / i) * (Math.Pow((1 + i), (n * -1))) * (((-1 * fv) * i) - ((pmt * (Math.Pow((1 + i), n)))) + pmt); return(pv); } catch { throw new System.ArgumentException(); } }
/// <summary> /// Computes the future value in a TVM equation. Annuity Due or payment at the beginning of the period. /// </summary> public static double FvAdCompute(TvmObject obj) { var n = obj.N; var i = obj.I; var pv = obj.Pv; var pmt = obj.Pmt; double fv = 0; try { i = i / 100; fv = (1 / i) * ((i * -1) * (pmt * Math.Pow((i + 1), n) - pmt + pv * Math.Pow((i + 1), n)) - pmt * Math.Pow((i + 1), n) + pmt); return(fv); } catch { throw new System.ArgumentException(); } }
/// <summary> /// Computes the payment in a TVM equation. Annuity Due or payment at the beginning of the period. /// </summary> public static double PmtAdCompute(TvmObject obj) { var n = obj.N; var i = obj.I; var pv = obj.Pv; double pmt = 0; var fv = obj.Fv; try { i = i / 100; pmt = -1 * ((i * (fv + pv * Math.Pow((i + 1), n))) / (i * Math.Pow((i + 1), n) - i + Math.Pow((i + 1), n) - 1)); return(pmt); } catch { throw new System.ArgumentException(); } }
/// <summary> /// Computes the present value in a TVM equation. Annuity Due or payment at the beginning of the period. /// </summary> public static double PvAdCompute(TvmObject obj) { var n = obj.N; var i = obj.I; double pv = 0; var pmt = obj.Pmt; var fv = obj.Fv; try { i = i / 100; pv = (-1 * fv) * Math.Pow((i + 1), (n * -1)) - pmt + pmt * Math.Pow((i + 1), (n * -1)) - (pmt / i) + (pmt / i) * Math.Pow((i + 1), (n * -1)); return(pv); } catch { throw new System.ArgumentException(); } }
//TVM *annuity due* calculations *BEG MODE* /// <summary> /// Computes the number of periods in a TVM equation. Annuity Due or payment at the beginning of the period. /// </summary> public static double NAdCompute(TvmObject obj) { double n = 0; var i = obj.I; var pv = obj.Pv; var pmt = obj.Pmt; var fv = obj.Fv; try { i = i / 100; n = Math.Log((((fv * -1) * (i)) + (i * pmt) + pmt) / ((i * pv) + (i * pmt) + pmt)) / (Math.Log(1 + i)); return(n); } catch { throw new System.ArgumentException(); } }
/// <summary> /// User has clicked the PMT compute Button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mBtnPMTCompute_Click(object sender, EventArgs e) { TvmObject O = new TvmObject(); double Pmt; bool Valid = true; #region Verify Format if ((double.TryParse(mN.Text, out double w)) == false) { mN.Hint = "Invalid Input"; Valid = false; } if ((double.TryParse(mIY.Text, out double x)) == false) { mIY.Hint = "Invalid Input"; Valid = false; } if ((double.TryParse(mPV.Text, out double y)) == false) { mPV.Hint = "Invalid Input"; Valid = false; } if ((double.TryParse(mFV.Text, out double z)) == false) { mFV.Hint = "Invalid Input"; Valid = false; } #endregion if (Valid == true) { O.N = double.Parse(mN.Text); O.I = double.Parse(mIY.Text); O.Pv = double.Parse(mPV.Text); O.Fv = double.Parse(mFV.Text); Pmt = PmtCompute(O); mPMT.Text = Pmt.ToString(); } }
/// <summary> /// This Method preforms an Amortization Calculation (giving the user the balance, interest paid, and principle paid /// between time p1 and p2. Note that p1 & p2 and be period 1 (start of loan) and period 10 (potential end of loan) or /// P1 & P2 could both be for period five which would provide the balance at P5, as well as principle and interest paid for that period. /// </summary> /// <param name="tObj"></param> /// <param name="aObj"></param> /// <returns></returns> public static AmortObject AmortCompute(TvmObject tObj, AmortObject aObj) { var r = tObj.I / 100; aObj.C_Bal = tObj.Pv; for (int i = 1; i <= aObj.P2; i++) { aObj.I_Paid = aObj.C_Bal * r; aObj.P_Paid = tObj.Pmt + aObj.I_Paid; aObj.C_Bal = aObj.C_Bal + aObj.P_Paid; if (i >= aObj.P1) { aObj.IntPaid = aObj.IntPaid + aObj.I_Paid; aObj.PrnPaid = aObj.PrnPaid + aObj.P_Paid; } } aObj.EndBal = aObj.C_Bal; aObj.IntPaid = aObj.IntPaid * -1; return(aObj); }
public void Amort3() { //Arrange, var tObj = new TvmObject(); tObj.N = 10; tObj.I = 10; tObj.Pv = 250; tObj.Pmt = -40.6863; tObj.Fv = 0; var obj = new AmortObject(); obj.P1 = 3; obj.P2 = 3; //Act, var result = AmortCompute(tObj, obj); //Assert Assert.AreEqual(198.0783, Math.Round(result.EndBal, 4)); //calc returned 198.0784 which is strange. Because a double is used it is likely more accurate than the BA II Plus. Assert.AreEqual(-18.9804, Math.Round(result.PrnPaid, 4)); Assert.AreEqual(-21.7059, Math.Round(result.IntPaid, 4)); }
public void Amort6() // With + payment and -FV { //Arrange, var tObj = new TvmObject(); tObj.N = 10; tObj.I = 10; tObj.Pv = 250; tObj.Pmt = 10; tObj.Fv = -907.8099; var obj = new AmortObject(); obj.P1 = 1; obj.P2 = 1; //Act, var result = AmortCompute(tObj, obj); //Assert Assert.AreEqual(285.0000, Math.Round(result.EndBal, 4)); Assert.AreEqual(35.0000, Math.Round(result.PrnPaid, 4)); Assert.AreEqual(-25.0000, Math.Round(result.IntPaid, 4)); }
public void Amort4() //With Balloon Payment { //Arrange, var tObj = new TvmObject(); tObj.N = 10; tObj.I = 10; tObj.Pv = 250; tObj.Pmt = -40.0589; tObj.Fv = -10; var obj = new AmortObject(); obj.P1 = 3; obj.P2 = 9; //Act, var result = AmortCompute(tObj, obj); //Assert Assert.AreEqual(45.5080, Math.Round(result.EndBal, 4)); Assert.AreEqual(-172.8683, Math.Round(result.PrnPaid, 4)); Assert.AreEqual(-107.5440, Math.Round(result.IntPaid, 4)); }