Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #3
0
 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));
 }
Example #4
0
        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);
            }
        }
Example #5
0
        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));
        }
Example #6
0
 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)));
 }
Example #7
0
        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));
        }
Example #8
0
 /// <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));;
 }
Example #9
0
 /// <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)));
 }
Example #10
0
 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);
 }
Example #11
0
 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))));
 }
Example #12
0
        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));
            }
        }
Example #13
0
 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);
 }
Example #14
0
        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)));
        }
Example #15
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));
            }
        }
Example #16
0
        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));
        }