File indexing completed on 2024-05-12 05:06:39

0001 /*
0002     SPDX-FileCopyrightText: 2003-2012 Thomas Baumgart <tbaumgart@kde.org>
0003     SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef MYMONEYFINANCIALCALCULATOR_H
0008 #define MYMONEYFINANCIALCALCULATOR_H
0009 
0010 // ----------------------------------------------------------------------------
0011 // QT Includes
0012 
0013 #include <qglobal.h>
0014 
0015 #include <cmath>
0016 
0017 // ----------------------------------------------------------------------------
0018 // KDE Includes
0019 
0020 // ----------------------------------------------------------------------------
0021 // Project Includes
0022 
0023 #include "kmm_mymoney_export.h"
0024 #include "mymoneyunittestable.h"
0025 
0026 /**
0027   * @author Thomas Baumgart
0028   */
0029 
0030 /**
0031   * This class implements the financial calculator as found in GNUCash.
0032   * For a detailed description of the algorithms see
0033   * gnucash-1.8.5/src/doc/finutil.html.
0034   */
0035 class MyMoneyFinancialCalculatorPrivate;
0036 class KMM_MYMONEY_EXPORT MyMoneyFinancialCalculator
0037 {
0038     Q_DISABLE_COPY(MyMoneyFinancialCalculator)
0039     Q_DECLARE_PRIVATE(MyMoneyFinancialCalculator)
0040     MyMoneyFinancialCalculatorPrivate * d_ptr;
0041 
0042     KMM_MYMONEY_UNIT_TESTABLE
0043 
0044 public:
0045     MyMoneyFinancialCalculator();
0046     ~MyMoneyFinancialCalculator();
0047 
0048     /**
0049       * This method calculates the number of payments required to amortize
0050       * the loan. ir, pv, fv and pmt must be set. It sets the member variable
0051       * m_npp with the calculated value.
0052       *
0053       * @return number of periodic payments
0054       *
0055       * @exception If one of the required values is not set, a MyMoneyException
0056       *             will be thrown
0057       */
0058     double numPayments();
0059 
0060     /**
0061       * This method calculates the amount of the payment (amortization and interest)
0062       * for the loan. ir, pv, fv and npp must be set. It sets the member variable
0063       * m_pmt with the calculated value.
0064       *
0065       * @return amount of payment
0066       *
0067       * @exception If one of the required values is not set, a MyMoneyException
0068       *             will be thrown
0069       */
0070     double payment();
0071 
0072     /**
0073       * This method calculates the present value
0074       * for the loan. ir, pmt, fv and npp must be set. It sets the member variable
0075       * m_pv with the calculated value.
0076       *
0077       * @return present value of loan
0078       *
0079       * @exception If one of the required values is not set, a MyMoneyException
0080       *             will be thrown
0081       */
0082     double presentValue();
0083 
0084     /**
0085       * This method calculates the future value
0086       * for the loan. ir, pmt, pv and npp must be set. It sets the member variable
0087       * m_fv with the calculated value.
0088       *
0089       * @return future value of loan
0090       *
0091       * @exception If one of the required values is not set, a MyMoneyException
0092       *             will be thrown
0093       */
0094     double futureValue();
0095 
0096     /**
0097       * This method calculates the nominal interest rate
0098       * for the loan. fv, pmt, pv and npp must be set. It sets the member variable
0099       * m_ir with the calculated value.
0100       *
0101       * @return interest rate of the loan
0102       *
0103       * @exception If one of the required values is not set, a MyMoneyException
0104       *             will be thrown
0105       */
0106     double interestRate();
0107 
0108     /**
0109       * This method calculates the interest due for the next payment according
0110       * to the equation
0111       *
0112       *   id[n] = (pv[n-1] + (X * pmt)) * i
0113       *
0114       *   with
0115       *
0116       *   - pv[n-1]\n
0117       *     the present value at the end of the last period
0118       *   - X\n
0119       *     0 for end of period payments, 1 for beginning of period payments
0120       *   - pmt\n
0121       *     the periodic payment amount and
0122       *   - i\n
0123       *     the effective interest rate
0124       *
0125       * pv[n-1] will be the value as set with setPv(), i will be calculated
0126       * from the nominal interest rate as set with setIr(), pmt will be the
0127       * value as set with setPmt() and X is determined by the argument to
0128       * setBep().
0129       *
0130       * @return the interest amount
0131       */
0132     double interestDue() const;
0133 
0134     /**
0135       * This method sets the rounding precision to @p prec fractional
0136       * digits. The default of @p is 2. Rounding is applied to pv, pmt
0137       * and fv.
0138       *
0139       * @param prec Number of fractional digits after rounding.
0140       */
0141     void setPrec(const unsigned short prec = 2);
0142 
0143     /**
0144       * This method sets the number of payment periods to the value
0145       * passed in parameter @p npp. The length of a period is controlled
0146       * via setPF().
0147       *
0148       * @param npp number of payment periods
0149       */
0150     void setNpp(const double npp);
0151 
0152     double npp() const;
0153 
0154     /**
0155       * This method sets the payment frequency. The parameter @p PF
0156       * specifies the payments per year.
0157       *
0158       *  - 1 == annual
0159       *  - 2 == semi-annual
0160       *  - 3 == tri-annual
0161       *  - 4 == quaterly
0162       *  - 6 == bi-monthly
0163       *  - 12 == monthly
0164       *  - 24 == semi-monthly
0165       *  - 26 == bi-weekly
0166       *  - 52 == weekly
0167       *  - 360 == daily
0168       *  - 365 == daily
0169       *
0170       * @param PF length of payment period (default is 12 - monthly)
0171       */
0172     void setPF(const unsigned short PF = 12);
0173 
0174     /**
0175       * This method sets the compounding frequency. The parameter @p CF
0176       * specifies the compounding period per year.
0177       *
0178       *  - 1 == annual
0179       *  - 2 == semi-annual
0180       *  - 3 == tri-annual
0181       *  - 4 == quaterly
0182       *  - 6 == bi-monthly
0183       *  - 12 == monthly
0184       *  - 24 == semi-monthly
0185       *  - 26 == bi-weekly
0186       *  - 52 == weekly
0187       *  - 360 == daily
0188       *  - 365 == daily
0189       *
0190       * @param CF length of compounding period (default is 12 - monthly)
0191       */
0192     void setCF(const unsigned short CF = 12);
0193 
0194     /**
0195       * This method controls whether the interest will be calculated
0196       * at the end of the payment period of at it's beginning.
0197       *
0198       * @param bep if @p false (default) then the interest is due at the
0199       *            end of the payment period, if @p true at it's beginning.
0200       */
0201     void setBep(const bool bep = false);
0202 
0203     /**
0204       * This method controls whether the interest is compounded in periods
0205       * or continuously.
0206       *
0207       * @param disc if @p true (default) then the interest is compounded in
0208       *             periods, if @p false continuously.
0209       */
0210     void setDisc(const bool disc = true);
0211 
0212     /**
0213       * This method sets the nominal interest rate to the value passed
0214       * in the argument @p ir.
0215       *
0216       * @param ir nominal interest rate
0217       */
0218     void setIr(const double ir);
0219 
0220     double ir() const;
0221 
0222     /**
0223       * This method sets the present value to the value passed
0224       * in the argument @p pv.
0225       *
0226       * @param pv present value
0227       */
0228     void setPv(const double pv);
0229 
0230     double pv() const;
0231 
0232     /**
0233       * This method sets the payment amount to the value passed
0234       * in the argument @p pmt.
0235       *
0236       * @param pmt payment amount
0237       */
0238     void setPmt(const double pmt);
0239 
0240     double pmt() const;
0241 
0242     /**
0243       * This method sets the future value to the value passed
0244       * in the argument @p fv.
0245       *
0246       * @param fv future value
0247       */
0248     void setFv(const double fv);
0249 
0250     double fv() const;
0251 
0252 private:
0253 #define PV_SET        0x0001
0254 #define IR_SET        0x0002
0255 #define PMT_SET       0x0004
0256 #define NPP_SET       0x0008
0257 #define FV_SET        0x0010
0258 };
0259 
0260 #endif