public static FinanceCalcResult <double> GetCumipmt(double rate, int nPer, double pv, int startPeriod, int endPeriod, PmtDue type) { if (startPeriod <= 0 || endPeriod < startPeriod || rate <= 0d || endPeriod > nPer || pv <= 0d) { return(new FinanceCalcResult <double>(eErrorType.Num)); } var result = InternalMethods.PMT_Internal(rate, nPer, pv, 0d, type); if (result.HasError) { return(new FinanceCalcResult <double>(result.ExcelErrorType)); } var pmtResult = result.Result; var retVal = 0d; if (startPeriod == 1) { if (type == PmtDue.EndOfPeriod) { retVal = -pv; } startPeriod++; } for (int i = startPeriod; i <= endPeriod; i++) { var res = FvImpl.Fv(rate, (i - 1 - (int)type), pmtResult, pv, type); if (res.HasError) { return(new FinanceCalcResult <double>(res.ExcelErrorType)); } retVal += type == PmtDue.BeginningOfPeriod ? res.Result - pmtResult : res.Result; } retVal *= rate; return(new FinanceCalcResult <double>(retVal)); }
public FinanceCalcResult <double> GetCumprinc(double rate, double nper, double pv, int startPeriod, int endPeriod, PmtDue type) { double fPmt, fPpmt; if (startPeriod < 1 || endPeriod < startPeriod || rate <= 0.0 || endPeriod > nper || pv <= 0.0) { return(new FinanceCalcResult <double>(eErrorType.Num)); } fPmt = _pmtProvider.GetPmt(rate, nper, pv, 0.0, type); fPpmt = 0.0; var nStart = startPeriod; var nEnd = endPeriod; if (nStart == 1) { if (type == PmtDue.EndOfPeriod) { fPpmt = fPmt + pv * rate; } else { fPpmt = fPmt; } nStart++; } for (var i = nStart; i <= nEnd; i++) { if (type == PmtDue.BeginningOfPeriod) { fPpmt += fPmt - (_fvProvider.GetFv(rate, i - 2, fPmt, pv, type) - fPmt) * rate; } else { fPpmt += fPmt - _fvProvider.GetFv(rate, i - 1, fPmt, pv, type) * rate; } } return(new FinanceCalcResult <double>(fPpmt)); }
public double GetFv(double Rate, double NPer, double Pmt, double PV = 0, PmtDue Due = PmtDue.EndOfPeriod) { return(InternalMethods.FV_Internal(Rate, NPer, Pmt, PV, Due)); }
public static double LEvalRate(double Rate, double NPer, double Pmt, double PV, double dFv, PmtDue Due) { double dTemp1; double dTemp2; double dTemp3; if (Rate == 0.0) { return(PV + Pmt * NPer + dFv); } else { dTemp3 = Rate + 1.0; // WARSI Using the exponent operator for pow(..) in C code of LEvalRate. Still got // to make sure that they (pow and ^) are same for all conditions dTemp1 = System.Math.Pow(dTemp3, NPer); if (Due != PmtDue.EndOfPeriod) { dTemp2 = 1 + Rate; } else { dTemp2 = 1.0; } return(PV * dTemp1 + Pmt * dTemp2 * (dTemp1 - 1) / Rate + dFv); } }
internal static FinanceCalcResult <double> Ppmt(double Rate, double Per, double NPer, double PV, double FV = 0, PmtDue Due = PmtDue.EndOfPeriod) { double Pmt; double dIPMT; // Checking for error conditions if ((Per <= 0.0) || (Per >= (NPer + 1))) { return(new FinanceCalcResult <double>(eErrorType.Num)); } var pmtResult = InternalMethods.PMT_Internal(Rate, NPer, PV, FV, Due); if (pmtResult.HasError) { return(new FinanceCalcResult <double>(pmtResult.ExcelErrorType)); } Pmt = pmtResult.Result; var iPmtResult = IPmtImpl.Ipmt(Rate, Per, NPer, PV, FV, Due); if (iPmtResult.HasError) { return(new FinanceCalcResult <double>(iPmtResult.ExcelErrorType)); } dIPMT = iPmtResult.Result; return(new FinanceCalcResult <double>(Pmt - dIPMT)); }
internal static FinanceCalcResult <double> Fv(double Rate, double NPer, double Pmt, double PV = 0, PmtDue Due = PmtDue.EndOfPeriod) { return(new FinanceCalcResult <double>(InternalMethods.FV_Internal(Rate, NPer, Pmt, PV, Due))); }
public static FinanceCalcResult <double> Rate(double NPer, double Pmt, double PV, double FV = 0, PmtDue Due = PmtDue.EndOfPeriod, double Guess = 0.1) { double dTemp; double dRate0; double dRate1; double dY0; double dY1; int I; // Check for error condition if (NPer <= 0.0) { throw new ArgumentException("NPer must by greater than zero"); } dRate0 = Guess; dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due); if (dY0 > 0) { dRate1 = (dRate0 / 2); } else { dRate1 = (dRate0 * 2); } dY1 = LEvalRate(dRate1, NPer, Pmt, PV, FV, Due); for (I = 0; I <= 39; I++) { if (dY1 == dY0) { if (dRate1 > dRate0) { dRate0 = dRate0 - cnL_IT_STEP; } else { dRate0 = dRate0 - cnL_IT_STEP * (-1); } dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due); if (dY1 == dY0) { return(new FinanceCalcResult <double>(eErrorType.Num)); } } dRate0 = dRate1 - (dRate1 - dRate0) * dY1 / (dY1 - dY0); // Secant method of generating next approximation dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due); if (System.Math.Abs(dY0) < cnL_IT_EPSILON) { return(new FinanceCalcResult <double>(dRate0)); } dTemp = dY0; dY0 = dY1; dY1 = dTemp; dTemp = dRate0; dRate0 = dRate1; dRate1 = dTemp; } return(new FinanceCalcResult <double>(eErrorType.Num)); }
/// <summary> /// The Excel FV function calculates the Future Value of an investment with periodic constant payments and a constant interest rate. /// </summary> /// <param name="rate">The interest rate, per period.</param> /// <param name="nper">The number of periods for the lifetime of the annuity.</param> /// <param name="pmt">An optional argument that specifies the payment per period.</param> /// <param name="pv">An optional argument that specifies the present value of the annuity - i.e. the amount that a series of future payments is worth now.</param> /// <param name="type">An optional argument that defines whether the payment is made at the start or the end of the period.</param> /// <returns></returns> public static double Fv(double rate, double nper, double pmt = 0d, double pv = 0d, PmtDue type = 0) { if ((type == PmtDue.EndOfPeriod && rate == -1d)) { return(-(pv * System.Math.Pow(1d + rate, nper))); } if (rate == -1d && type == PmtDue.EndOfPeriod) { return(-(pv * System.Math.Pow(1d + rate, nper) + pmt)); } return(FvCalc(rate, nper, pmt, pv, type));; }
/// <summary> /// Calculates the present value /// </summary> /// <param name="rate">The interest rate, per period.</param> /// <param name="nper">The number of periods for the lifetime of the annuity or investment.</param> /// <param name="pmt">An optional argument that specifies the payment per period.</param> /// <param name="fv">An optional argument that specifies the future value of the annuity, at the end of nper payments.If the[fv] argument is omitted, it takes on the default value 0.</param> /// <param name="type">An optional argument that defines whether the payment is made at the start or the end of the period. See <see cref="PmtDue"></see></param> /// <returns></returns> public static double Pv(double rate, double nper, double pmt = 0d, double fv = 0d, PmtDue type = 0) { return(-1 * (fv * (1d / System.Math.Pow(1.0 + rate, nper)) + pmt * GetAnnuityFactor(rate, nper, type))); }
private static double GetAnnuityFactor(double rate, double nper, PmtDue type) { return(rate == 0.0 ? nper : (1 + rate * (int)type) * (1 - 1d / System.Math.Pow(1.0 + rate, nper)) / rate); }
private static double FvCalc(double rate, double nper, double pmt, double pv, PmtDue type) { return(-1 * (pv * System.Math.Pow(1.0 + rate, nper) + pmt * (GetAnnuityFactor(rate, nper, type) * System.Math.Pow(1.0 + rate, nper)))); }
public static FinanceCalcResult <double> NPer(double Rate, double Pmt, double PV, double FV = 0, PmtDue Due = PmtDue.EndOfPeriod) { double dTemp3; double dTempFv; double dTempPv; double dTemp4; // Checking Error Conditions if (Rate <= -1.0) { return(new FinanceCalcResult <double>(eErrorType.Num)); } if (Rate == 0.0) { if (Pmt == 0.0) { return(new FinanceCalcResult <double>(eErrorType.Num)); } return(new FinanceCalcResult <double>(-(PV + FV) / Pmt)); } else { if (Due != 0) { dTemp3 = Pmt * (1.0 + Rate) / Rate; } else { dTemp3 = Pmt / Rate; } dTempFv = -FV + dTemp3; dTempPv = PV + dTemp3; // Make sure the values fit the domain of log() if (dTempFv < 0.0 && dTempPv < 0.0) { dTempFv = -1 * dTempFv; dTempPv = -1 * dTempPv; } else if (dTempFv <= 0.0 || dTempPv <= 0.0) { return(new FinanceCalcResult <double>(eErrorType.Num)); } dTemp4 = Rate + 1.0; var result = (System.Math.Log(dTempFv) - System.Math.Log(dTempPv)) / System.Math.Log(dTemp4); return(new FinanceCalcResult <double>(result)); } }
public double GetPmt(double Rate, double NPer, double PV, double FV = 0, PmtDue Due = PmtDue.EndOfPeriod) { return(InternalMethods.PMT_Internal(Rate, NPer, PV, FV, Due).Result); }
internal static double FV_Internal(double Rate, double NPer, double Pmt, double PV = 0, PmtDue Due = PmtDue.EndOfPeriod) { double dTemp; double dTemp2; double dTemp3; //Performing calculation if (Rate == 0) { return(-PV - Pmt * NPer); } if (Due != PmtDue.EndOfPeriod) { dTemp = 1.0 + Rate; } else { dTemp = 1.0; } dTemp3 = 1.0 + Rate; dTemp2 = System.Math.Pow(dTemp3, NPer); //Do divides before multiplies to avoid OverflowExceptions return(((-PV) * dTemp2) - ((Pmt / Rate) * dTemp * (dTemp2 - 1.0))); }
internal static FinanceCalcResult <double> PMT_Internal(double Rate, double NPer, double PV, double FV = 0, PmtDue Due = PmtDue.EndOfPeriod) { double dTemp; double dTemp2; double dTemp3; // Checking for error conditions if (NPer == 0.0) { return(new FinanceCalcResult <double>(eErrorType.Value)); } if (Rate == 0.0) { return(new FinanceCalcResult <double>((-FV - PV) / NPer)); } else { if (Due != 0) { dTemp = 1.0 + Rate; } else { dTemp = 1.0; } dTemp3 = Rate + 1.0; // WARSI Using the exponent operator for pow(..) in C code of PMT. Still got // to make sure that they (pow and ^) are same for all conditions dTemp2 = System.Math.Pow(dTemp3, NPer); var result = ((-FV - PV * dTemp2) / (dTemp * (dTemp2 - 1.0)) * Rate); return(new FinanceCalcResult <double>(result)); } }
internal static FinanceCalcResult <double> Ipmt(double Rate, double Per, double NPer, double PV, double FV = 0, PmtDue Due = PmtDue.EndOfPeriod) { double Pmt; double dTFv; double dTemp; if (Due != PmtDue.EndOfPeriod) { dTemp = 2d; } else { dTemp = 1; } // Type = 0 or non-zero only. Offset to calculate FV if ((Per <= 0) || (Per >= NPer + 1)) { return(new FinanceCalcResult <double>(eErrorType.Value)); } if (Due != PmtDue.EndOfPeriod && (Per == 1.0)) { return(new FinanceCalcResult <double>(0d));; } // Calculate PMT (i.e. annuity) for given parms. Rqrd for FV var result = InternalMethods.PMT_Internal(Rate, NPer, PV, FV, Due); if (result.HasError) { return(new FinanceCalcResult <double>(eErrorType.Num)); } Pmt = result.Result; if (Due != PmtDue.EndOfPeriod) { PV = PV + Pmt; } dTFv = InternalMethods.FV_Internal(Rate, (Per - dTemp), Pmt, PV, PmtDue.EndOfPeriod); return(new FinanceCalcResult <double>(dTFv * Rate)); }