numpy / numpy-financial

Standalone package of the NumPy financial functions
BSD 3-Clause "New" or "Revised" License
340 stars 80 forks source link

Add CUMPRINC and CUMIPMT functions #38

Open eduardosl opened 3 years ago

eduardosl commented 3 years ago

The Open Document Format for Office Applications (OpenDocument)v1.2 on which numpy-financial is based specifies two functions which are currently not implemented: CUMPRINC and CUMIPMT. These functions calculate the cumulative principal and interest paid down in an installment loan after a number of payment periods.

To implement these, one could simply call npf.ppmt/npf.ipmt with a 1-D array for the per argument and then sum over rows.

I'd be happy to contribute code and submit a pull request.

PythonNerd0911 commented 2 years ago

I would also appreciate CUMPRINC and CUMIPMT.

My code: def CUMPRINC(rate, nper, pv, start_period, end_period, fv, when): cumprinc = 0 for per in range(start_period, end_period + 1): cumprinc += npf.ppmt(rate, per, nper, pv, fv, when) return cumprinc

And likewise with CUMIPMT.

patrickxli commented 1 year ago

CUMPRINC shows also in SAS, with a bit different masking:

def SAS_CUMPRINC(rate, nper, pv, start_period, end_period, fv=0, when='end'): return -CUMPRINC(rate=rate, nper=nper, pv=pv, start_period=start_period, end_period=end_period, fv=fv, when=when)

""" test based on: https://documentation.sas.com/doc/en/edmcdc/v_031/ds2ref/p1ae3ccwcl1y4dn0zld1p5rj88yx.htm

    proc ds2;
    data test/overwrite=yes;
       dcl double PrincipalYear2 having format dollar10.2;
       method run();
          PrincipalYear2=CUMPRINC(0.09/12, 360, 125000, 12, 24, 0);
          put 'Principal Year 2 EOP=' PrincipalYear2;
       end;
    enddata;
    run;
    quit;
    This computation returns a value of $1008.23.

    proc ds2;
    data test/overwrite=yes;
       dcl double PrincipalYear2b having format dollar10.2;
       method run();
          PrincipalYear2b = CUMPRINC(0.09/12, 360, 125000, 12, 24, 1);
          put 'Principal Year 2 BOP=' PrincipalYear2b;
       end;
    enddata;
    run;
    quit;
    This computation returns a value of $1000.73.

    """
    rate = 0.09 / 12
    nper = 30 * 12
    pv = 125000
    end_period = 24

    start_period = 12
    sas_cumprinc = SAS_CUMPRINC(rate, nper, pv, start_period, end_period)
    np.testing.assert_almost_equal(sas_cumprinc, 1008.23, decimal=2)

    when = 1
    sas_cumprinc = SAS_CUMPRINC(rate, nper, pv, start_period, end_period,
                                when=when)
    np.testing.assert_almost_equal(sas_cumprinc, 1000.73, decimal=2)