示例#1
0
    def runLoans(self, economy):
        if self.wavgRemTerm <= 0.1:
            self.realizedLosses = 0
            self.principalPayments = self.loanUPB
            self.loanUPB = 0
            self.interestIncome = 0
            return

        self.realizedLosses = self.loanUPB * (self.wavgCDR + economy) / 400
        self.loanUPB = self.loanUPB - self.realizedLosses
        self.interestIncome = self.loanUPB * self.wavgCoupon / 400
        self.principalPayments = -np.ppmt(
            self.wavgCoupon / 1200,
            60 - self.wavgRemTerm, 60, self.loanUPB) - np.ppmt(
                self.wavgCoupon / 1200, 60 - self.wavgRemTerm - 1, 60,
                self.loanUPB) - np.ppmt(self.wavgCoupon / 1200, 60 -
                                        self.wavgRemTerm - 2, 60, self.loanUPB)
        self.principalPayments += self.loanUPB * self.wavgCPR / 400

        if self.loanUPB >= 0.1:
            if len(self.loanYield) <= 3:
                self.loanYield.append(
                    (self.interestIncome - self.realizedLosses) / self.loanUPB)
            else:
                self.loanYield.popleft()
                self.loanYield.append(
                    (self.interestIncome - self.realizedLosses) / self.loanUPB)

        self.wavgRemTerm -= 3
        self.loanUPB = self.loanUPB - self.principalPayments
    def test_broadcast(self):
        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.0, [0, 1]),
                            [21.5449442, 20.76156441], 4)

        assert_almost_equal(
            np.ipmt(0.1 / 12, list(range(5)), 24, 2000),
            [
                -17.29165168, -16.66666667, -16.03647345, -15.40102862,
                -14.76028842
            ],
            4,
        )

        assert_almost_equal(
            np.ppmt(0.1 / 12, list(range(5)), 24, 2000),
            [
                -74.998201, -75.62318601, -76.25337923, -76.88882405,
                -77.52956425
            ],
            4,
        )

        assert_almost_equal(
            np.ppmt(0.1 / 12, list(range(5)), 24, 2000, 0,
                    [0, 0, 1, "end", "begin"]),
            [
                -74.998201, -75.62318601, -75.62318601, -76.88882405,
                -76.88882405
            ],
            4,
        )
示例#3
0
def CPM_calc(startdate, duration, principal, interest, term):
    start = datetime.strptime(startdate, '%Y-%m-%d')
    if (term == "y"):
        amortization = pd.DataFrame(
            index=pd.date_range(start, periods=duration +
                                1, freq="Y").shift(n=start.day, freq="D"))
        amortization["payback"] = 0
        amortization["interest"] = 0
        amortization["principal"] = 0
        amortization.principal.iloc[1:amortization.shape[0]] = -np.ppmt(
            params["interest"],
            amortization.principal.iloc[1:amortization.shape[0]],
            params["duration"], params["principal"])
        amortization.interest.iloc[1:amortization.shape[0]] = -np.ipmt(
            params["interest"],
            amortization.interest.iloc[1:amortization.shape[0]],
            params["duration"], params["principal"])
        amortization.payback.iloc[1:amortization.shape[0]] = -np.pmt(
            interest, duration, principal)
        amortization.payback = amortization.apply(money_trim, axis=1)
    if (term == "q"):
        amortization = pd.DataFrame(
            index=pd.date_range(start, periods=duration * 4 +
                                1, freq="q").shift(n=start.day, freq="D"))
        amortization["payback"] = 0
        amortization["interest"] = 0
        amortization["principal"] = 0
        amortization.principal.iloc[1:amortization.shape[0]] = -np.ppmt(
            params["interest"] / 4,
            amortization.principal.iloc[1:amortization.shape[0]],
            params["duration"] * 4, params["principal"])
        amortization.interest.iloc[1:amortization.shape[0]] = -np.ipmt(
            params["interest"] / 4,
            amortization.interest.iloc[1:amortization.shape[0]],
            params["duration"] * 4, params["principal"])
        amortization.payback.iloc[1:amortization.shape[0]] = -np.pmt(
            interest / 4, duration * 4, principal)
        amortization.payback = amortization.apply(money_trim, axis=1)
    if (term == "m"):
        amortization = pd.DataFrame(
            index=pd.date_range(start, periods=duration * 12 +
                                1, freq="M").shift(n=start.day, freq="D"))
        amortization["payback"] = 0
        amortization["interest"] = 0
        amortization["principal"] = 0
        amortization.principal.iloc[1:amortization.shape[0]] = -np.ppmt(
            params["interest"] / 12,
            amortization.principal.iloc[1:amortization.shape[0]],
            params["duration"] * 12, params["principal"])
        amortization.interest.iloc[1:amortization.shape[0]] = -np.ipmt(
            params["interest"] / 12,
            amortization.interest.iloc[1:amortization.shape[0]],
            params["duration"] * 12, params["principal"])
        amortization.payback.iloc[1:amortization.shape[0]] = -np.pmt(
            interest / 12, duration * 12, principal)
        amortization.payback = amortization.apply(money_trim, axis=1)
    amortization = amortization.apply(money_trim, axis=0)
    return amortization
    def test_broadcast_decimal(self):
        # Use almost equal because precision is tested in the explicit tests, this test is to ensure
        # broadcast with Decimal is not broken.
        assert_almost_equal(
            np.ipmt(
                Decimal("0.1") / Decimal("12"),
                list(range(5)),
                Decimal("24"),
                Decimal("2000"),
            ),
            [
                Decimal("-17.29165168"),
                Decimal("-16.66666667"),
                Decimal("-16.03647345"),
                Decimal("-15.40102862"),
                Decimal("-14.76028842"),
            ],
            4,
        )

        assert_almost_equal(
            np.ppmt(
                Decimal("0.1") / Decimal("12"),
                list(range(5)),
                Decimal("24"),
                Decimal("2000"),
            ),
            [
                Decimal("-74.998201"),
                Decimal("-75.62318601"),
                Decimal("-76.25337923"),
                Decimal("-76.88882405"),
                Decimal("-77.52956425"),
            ],
            4,
        )

        assert_almost_equal(
            np.ppmt(
                Decimal("0.1") / Decimal("12"),
                list(range(5)),
                Decimal("24"),
                Decimal("2000"),
                Decimal("0"),
                [Decimal("0"),
                 Decimal("0"),
                 Decimal("1"), "end", "begin"],
            ),
            [
                Decimal("-74.998201"),
                Decimal("-75.62318601"),
                Decimal("-75.62318601"),
                Decimal("-76.88882405"),
                Decimal("-76.88882405"),
            ],
            4,
        )
示例#5
0
    def test_broadcast_decimal(self):
        # Use almost equal because precision is tested in the explicit tests, this test is to ensure
        # broadcast with Decimal is not broken.
        assert_almost_equal(np.ipmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')),
                            [Decimal('-17.29165168'), Decimal('-16.66666667'), Decimal('-16.03647345'),
                             Decimal('-15.40102862'), Decimal('-14.76028842')], 4)

        assert_almost_equal(np.ppmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')),
                            [Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-76.25337923'),
                             Decimal('-76.88882405'), Decimal('-77.52956425')], 4)

        assert_almost_equal(np.ppmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000'),
                                    Decimal('0'), [Decimal('0'), Decimal('0'), Decimal('1'), 'end', 'begin']),
                            [Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-75.62318601'),
                             Decimal('-76.88882405'), Decimal('-76.88882405')], 4)
示例#6
0
    def test_broadcast_decimal(self):
        # Use almost equal because precision is tested in the explicit tests, this test is to ensure
        # broadcast with Decimal is not broken.
        assert_almost_equal(np.ipmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')),
                            [Decimal('-17.29165168'), Decimal('-16.66666667'), Decimal('-16.03647345'),
                             Decimal('-15.40102862'), Decimal('-14.76028842')], 4)

        assert_almost_equal(np.ppmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')),
                            [Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-76.25337923'),
                             Decimal('-76.88882405'), Decimal('-77.52956425')], 4)

        assert_almost_equal(np.ppmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000'),
                                    Decimal('0'), [Decimal('0'), Decimal('0'), Decimal('1'), 'end', 'begin']),
                            [Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-75.62318601'),
                             Decimal('-76.88882405'), Decimal('-76.88882405')], 4)
示例#7
0
 def raise_error_because_not_equal():
     assert_equal(
         round(
             np.ppmt(
                 Decimal('0.23') / Decimal('12'), 1, 60,
                 Decimal('10000000000')), 8),
         Decimal('-90238044.232277036'))
示例#8
0
def approve_application(application_id):
    ''' approve application'''
    application = Application.query.get(application_id)
    application.status = 3
    db.session.add(application)
    loan = Loan(
        application=application,
        principal=application.amount,
        outstanding=application.amount,
        terms=application.terms,
        loan_date=datetime.utcnow(),
        borrower=application.borrower,
        guarantor=application.guarantor)
    db.session.add(loan)

    monthly_payment = -np.pmt(rate=loan.terms.rate/100,
                              nper=loan.terms.installments,
                              pv=loan.principal)

    for month in range(loan.terms.installments):
        ipmt = np.ipmt(rate=loan.terms.rate/100, per=month+1,
                       nper=loan.terms.installments, pv=loan.principal)
        ppmt = np.ppmt(rate=loan.terms.rate/100, per=month+1,
                       nper=loan.terms.installments, pv=loan.principal)
        payment = Payment(
            loan=loan,
            payment=Decimal(monthly_payment),
            principal_pmt=-ppmt,
            interest_pmt=-ipmt,
            scheduled_date=loan.loan_date + timedelta(days=30*(month+1)))
        db.session.add(payment)
    db.session.commit()
    flash('Application has been appproved.')
    return redirect(url_for('admin.pending_applications'))
def mortgage(price: int,
             downpayment: int,
             rate: float,
             term_years: int,
             interest_only=False) -> pd.DataFrame:

    principal = price - downpayment
    rate = rate / 12
    term = term_years * 12
    periods = np.arange(term) + 1

    if not interest_only:
        full_payments = np.pmt(rate, term, principal) * np.ones_like(periods)
        principal_payments = np.ppmt(rate, periods, term, principal)
        interest_payments = np.ipmt(rate, periods, term, principal)
    else:
        full_payments = (principal * rate) * -np.ones_like(periods)
        principal_payments = np.zeros_like(periods)
        interest_payments = full_payments

    debt_balance = (principal + principal_payments.cumsum()).round(2)

    return pd.DataFrame(
        data=np.array([
            debt_balance, full_payments, principal_payments, interest_payments
        ]).T,
        columns=
        'debt_balance, full_payments, principal_payments, interest_payments'.
        split(', '),
        index=pd.date_range(start=datetime.date.today(),
                            periods=term,
                            freq='M'))
示例#10
0
文件: main.py 项目: Jayie/db_final
def edit_periods(ProjectNumber, delete=False):
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    cur = conn.cursor()
    cur.execute("select StartDate, TypeNumber from LOAN_PROJECT where ProjectNumber = {}".format(ProjectNumber))
    project = dict(cur.fetchone())
    
    start_date = datetime.datetime.strptime(project['StartDate'], "%Y-%m-%d")
    cur.execute("select * from LOAN_PROJECT_TYPE where TypeNumber = {}".format(project['TypeNumber']))
    project_type = dict(cur.fetchone())

    temp = project_type['TotalPrinciple']
    rate = project_type['InterestRate']/12

    for period in range(project_type['NumberOfPeriod']):
        if delete:
            edit_data('LOAN_PERIOD', [ProjectNumber, period])
        else:
            due = start_date + relativedelta(months=period+1)
            principle = np.ceil(-np.ppmt(rate=rate, per=1, nper=20-period, pv=temp))
            interest = np.ceil(temp * rate)
            temp -= principle
            edit_data('LOAN_PERIOD', [ProjectNumber, period+1, due.strftime("%Y-%m-%d"), int(principle), int(interest)], from_project=True)
        
    
    conn.commit()
    conn.close()
    return
示例#11
0
def calc_PPMT(df, dts_r, first_due_period):
    first_due_month = pd.unique(df[first_due_period].ravel())
    df_ppmt = pd.DataFrame()

    for f_d_m in first_due_month:
        f_d_m_this_n_z = df[(df[first_due_period] == f_d_m)
                            & (df['Total_Fee_Rate'] > 0)]
        for ind_r, date_r in enumerate(dts_r):
            #f_d_m_this_n_z[date_r] = 0
            f_d_m_this_n_z[date_r] = f_d_m_this_n_z[date_r].where(
                (f_d_m_this_n_z[first_due_period] > ind_r) |
                (f_d_m_this_n_z['Term_Remain'] < (ind_r - f_d_m + 1)),
                np.ppmt(f_d_m_this_n_z['Total_Fee_Rate'] / 12,
                        (ind_r - f_d_m + 1), f_d_m_this_n_z['Term_Remain'],
                        ((-1) * f_d_m_this_n_z['OutstandingPrincipal'])))

        f_d_m_this_z = df[(df[first_due_period] == f_d_m)
                          & (df['Total_Fee_Rate'] == 0)]
        for ind_r, date_r in enumerate(dts_r):
            #f_d_m_this_z[date_r] = 0
            f_d_m_this_z[date_r] = f_d_m_this_z[date_r].where(
                (f_d_m_this_z[first_due_period] > ind_r) |
                (f_d_m_this_z['Term_Remain'] <
                 (ind_r - f_d_m + 1)), f_d_m_this_z['OutstandingPrincipal'] /
                f_d_m_this_z['Term_Remain'])
        df_ppmt = df_ppmt.append(f_d_m_this_n_z).append(f_d_m_this_z,
                                                        ignore_index=True)

    return df_ppmt
示例#12
0
    def calculate_return_specs(self):
        """
            Calculate the necessary attributes for the loan repayment process.
            Each element is represented by a list of floats and contains the relevant annual values.
        """

        sum_xreolisio = 0
        for year in range(1, self.loan_period + 1):
            self.interest_rate_instalment.append(
                -np.pmt(self.annual_interest, self.loan_period,
                        self.repayment_amount, 0))
            self.interest_rate.append(
                -np.ppmt(self.annual_interest, year, self.loan_period,
                         self.repayment_amount))
            self.interest.append(self.interest_rate_instalment[year] -
                                 self.interest_rate[year])
            if year == 1:
                self.interest_subsidy.append(self.repayment_amount *
                                             self.subsidized_interest)
            else:
                sum_xreolisio = sum_xreolisio + self.interest_rate[year - 1]
                endiameso = self.repayment_amount - sum_xreolisio
                self.interest_subsidy.append(endiameso *
                                             self.subsidized_interest)

            self.interest_paid.append(self.interest[year] -
                                      self.interest_subsidy[year])
            self.unpaid.append(self.unpaid[year - 1] -
                               self.interest_rate[year])
示例#13
0
def index():
    form = CalcForm()
    if form.validate_on_submit():
        print(form.data)
    interest = (0 if form.interestrate.data is None else
                (form.interestrate.data * .01))
    years = 30
    payments_year = 12
    mortgage = int(0 if form.homeprice.data is None else (form.homeprice.data))
    downpayment = form.downpayment.data or 0
    taxes = form.taxes.data or 0
    tax = (taxes / 12)
    pmt = -1 * np.pmt(interest / 12, years * payments_year,
                      mortgage - downpayment) + tax
    ipmt = -1 * np.ipmt(interest / payments_year, 1, years * payments_year,
                        mortgage - downpayment)
    ppmt = -1 * np.ppmt(interest / payments_year, 1, years * payments_year,
                        mortgage - downpayment)
    prin_int = ipmt + ppmt

    return render_template('index.html',
                           form=form,
                           prin_int=prin_int,
                           pmt=pmt,
                           tax=tax)
示例#14
0
def amortizing_loan(principal=None,
                    rate=None,
                    years=None,
                    amort_years=None,
                    payment_acct=None,
                    principal_acct=None,
                    interest_acct=None):
    periods = np.arange(amort_years) + 1
    amort_schedule = np.ppmt(rate, periods, amort_years, principal) * -1
    int_schedule = np.ipmt(rate, periods, amort_years, principal) * -1

    @assert_accounts(payment_acct, principal_acct)
    async def amortizing_loan_principal_cfs(clock, balances):
        yield principal, principal_acct, payment_acct, 'Initial loan'
        await clock.tick(years=1, days=-1)
        for period in range(years - 1):
            amortization_payment = amort_schedule[period]
            yield amortization_payment, payment_acct, principal_acct, 'Amortization payment'
            await clock.tick(years=1)
        amortization_payment = amort_schedule[period + 1]
        yield amortization_payment, payment_acct, principal_acct, 'Amortization payment'
        await clock.tick(days=1)
        yield balances[
            principal_acct] * -1, payment_acct, principal_acct, 'Paydown'

    @assert_accounts(payment_acct, interest_acct)
    async def amortizing_loan_interest_cfs(clock, balances):
        await clock.tick(years=1, days=-1)
        for period in range(years):
            interest_payment = int_schedule[period]
            yield interest_payment, payment_acct, interest_acct, 'Interest payment'
            await clock.tick(years=1)

    yield amortizing_loan_principal_cfs
    yield amortizing_loan_interest_cfs
    def test_broadcast(self):
        assert_almost_equal(np.nper(0.075,-2000,0,100000.,[0,1]),
                            [ 21.5449442 ,  20.76156441], 4)

        assert_almost_equal(np.ipmt(0.1/12,list(range(5)), 24, 2000),
                            [-17.29165168, -16.66666667, -16.03647345,
                                -15.40102862, -14.76028842], 4)

        assert_almost_equal(np.ppmt(0.1/12,list(range(5)), 24, 2000),
                            [-74.998201  , -75.62318601, -76.25337923,
                                -76.88882405, -77.52956425], 4)

        assert_almost_equal(np.ppmt(0.1/12,list(range(5)), 24, 2000, 0,
            [0,0,1,'end','begin']),
                            [-74.998201  , -75.62318601, -75.62318601,
                                -76.88882405, -76.88882405], 4)
示例#16
0
def populate_base_mortgage_table(
    monthly_breakdown_dict,
    mortgage_base_table,
):
    """
    Function populates the empy columns in a base mortgage equation in order with Monthly Paymenet,
    Interestes Paid at period x, principal paid at period x and the ending balance (or pending balance)
    at that particular perdiod.

    :param monthly_breakdown_dict: the dictionary with all the mortgage informaiton
    :param mortgage_base_table:
    :return:
    """
    # Populating table with Formulas
    mortgage_base_table["Monthly_Payment"] = monthly_breakdown_dict[
        "Monthly_Payment"]

    mortgage_base_table["Interests_Paid"] = -1 * np.ipmt(
        monthly_breakdown_dict["Interest_Rate"] /
        monthly_breakdown_dict["Payments_a_year"], mortgage_base_table.index,
        monthly_breakdown_dict["Mortgage_lifespan"] *
        monthly_breakdown_dict["Payments_a_year"],
        monthly_breakdown_dict["Mortgage_value"])
    mortgage_base_table["Principal_Paid"] = -1 * np.ppmt(
        monthly_breakdown_dict["Interest_Rate"] /
        monthly_breakdown_dict["Payments_a_year"], mortgage_base_table.index,
        monthly_breakdown_dict["Mortgage_lifespan"] *
        monthly_breakdown_dict["Payments_a_year"],
        monthly_breakdown_dict["Mortgage_value"])
    return mortgage_base_table
示例#17
0
    def __init__(self, logistic_cost, loan_rate, annual_interest, subsidized_interest, loan_period, grace_period):
        self.logistic_cost = logistic_cost #with taxes
        self.loan_rate = loan_rate
        self.annual_interest = annual_interest
        self.subsidized_interest = subsidized_interest
        self.loan_period = loan_period
        self.grace_period = grace_period

        self.own_funds_rate = 1 - self.loan_rate
        self.own_fund = self.logistic_cost*self.own_funds_rate
        self.loan_fund = self.loan_rate*self.logistic_cost

        if self.loan_period == 0:
            self.calculate_loan_period()

        self.grace_period_tokos = self.annual_interest*self.grace_period*self.loan_fund
        self.repayment_amount = self.loan_fund + self.grace_period_tokos

        #tok/ki dosi ana etos danismou
        self.interest_rate_instalment = []
        self.interest_rate_instalment.append(0)

        #xreolisio ana etos danismou
        self.interest_rate = []
        self.interest_rate.append(0)

        #tokos
        self.interest = []
        self.interest.append(0)

        #epidotisi tokou 
        self.interest_subsidy = []
        self.interest_subsidy.append(0)

        #tokos pliroteos 
        self.interest_paid = []
        self.interest_paid.append(0)

        #aneksoflito ipolipo
        self.unpaid = []
        self.unpaid.append(self.repayment_amount)
        
        sum_xreolisio = 0

        for year in range(1, self.loan_period+1):
            self.interest_rate_instalment.append(-np.pmt(self.annual_interest, self.loan_period, self.repayment_amount, 0))
            self.interest_rate.append(-np.ppmt(self.annual_interest, year, self.loan_period, self.repayment_amount))
            self.interest.append(self.interest_rate_instalment[year] - self.interest_rate[year])
            if year == 1:
                self.interest_subsidy.append(self.repayment_amount*self.subsidized_interest)
            else:
                sum_xreolisio = sum_xreolisio + self.interest_rate[year-1]
                endiameso = self.repayment_amount - sum_xreolisio
                self.interest_subsidy.append(endiameso*self.subsidized_interest)
            
            self.interest_paid.append(self.interest[year] - self.interest_subsidy[year])
            self.unpaid.append(self.unpaid[year-1] - self.interest_rate[year])
 def test_ppmt_decimal(self):
     assert_equal(
         np.ppmt(
             Decimal("0.1") / Decimal("12"),
             Decimal("1"),
             Decimal("60"),
             Decimal("55000"),
         ),
         Decimal("-710.2541257864217612489830917"),
     )
 def raise_error_because_not_equal():
     assert_equal(
         round(
             np.ppmt(
                 Decimal("0.23") / Decimal("12"), 1, 60,
                 Decimal("10000000000")),
             8,
         ),
         Decimal("-90238044.232277036"),
     )
示例#20
0
 def calc_int_n_pcp_payment(self, period, additional_payment=0):
     ipmt = np.ipmt(rate=self.rate/self.maturity,
                    per=period,
                    nper=self.payment_per_year*self.maturity,
                    pv=self.principal)
     ppmt = np.ppmt(rate=self.rate/self.maturity,
                    per=period,
                    nper=self.payment_per_year*self.maturity,
                    pv=self.principal)
     return round(ipmt, 2), round(ppmt, 2)
示例#21
0
def average_capital_plus_interest(PV,mouth_rate,nper,Sum_interest=0):
    for i in range(1, nper + 1):
        PPMT = np.ppmt(mouth_rate, i, nper, PV)
        IPMT = np.ipmt(mouth_rate, i, nper, PV)
        EIR=mouth_rate*12 #有效年化利率
        PMT = PPMT + IPMT
        Sum_interest+=IPMT
        yield i,round(-PPMT,1),round(-IPMT,1),round(-PMT,1)
        if i == nper:
            yield "总利息:"+str(round(-Sum_interest,1)),"实际利率:"+str("%.2f%%" % (EIR * 100))
示例#22
0
    def calculate(self):
        """Calculated annuitet values

        @percent_payments = dict with sum we need to pay at current period - for percent of loan
        @debt_payments = dict with sum we need to pay at current period - for body of loan
        @rest_payments = dict with sum, we still need to pay in next periods
        """

        from numpy import ppmt, ipmt, arange
        periods = arange(self.mperiods) + 1
        principal_repayments = ppmt(rate=self.rate,
                                    per=periods,
                                    nper=self.mperiods,
                                    pv=self.summa)
        interest_payments = ipmt(rate=self.rate,
                                 per=periods,
                                 nper=self.mperiods,
                                 pv=self.summa)

        date = self.start_date

        percent_payment = 0  # (self.summa * self.yrate / 12)
        debt_payment = 0
        rest_payment = self.summa + abs(interest_payments.sum())
        rest_payment_wo_percent = self.summa

        percent_payments = OrderedDict({date: percent_payment})
        debt_payments = OrderedDict({date: debt_payment})
        rest_payments = OrderedDict({date: rest_payment})
        rest_payments_wo_percents = OrderedDict(
            {date: rest_payment_wo_percent})

        for i in range(self.mperiods):
            date = lastDayNextMonth(date)

            percent_payment = interest_payments[i]
            debt_payment = principal_repayments[i]
            rest_payment -= abs(percent_payment) + abs(debt_payment)
            rest_payment_wo_percent -= abs(debt_payment)

            if rest_payment < 0.01:
                rest_payment = 0

            if rest_payment_wo_percent < 0.01:
                rest_payment_wo_percent = 0

            percent_payments[date] = percent_payment
            debt_payments[date] = debt_payment
            rest_payments[date] = rest_payment
            rest_payments_wo_percents[date] = rest_payment_wo_percent

        self.percent_payments = percent_payments
        self.debt_payments = debt_payments
        self.rest_payments = rest_payments
        self.rest_payments_wo_percents = rest_payments_wo_percents
示例#23
0
def get_equity(n):
    k = 0
    equity_accrued = []
    for per in range(nper):
        if per != 0 and per % 12 == 0:
            nv = pv * (1.07)**(per / 12)
            equity_accrued += [nv * k / pv]

        p = -np.ppmt(rate, per, nper, pv)
        k += p
    return equity_accrued[n]
示例#24
0
    def test_ppmt_special_rate_decimal(self):
        # When rounded out to 8 decimal places like the float based test, this should not equal the same value
        # as the float, substituted for the decimal
        def raise_error_because_not_equal():
            assert_equal(
                round(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')), 8),
                Decimal('-90238044.232277036'))

        assert_raises(AssertionError, raise_error_because_not_equal)
        assert_equal(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')),
                     Decimal('-90238044.2322778884413969909'))
示例#25
0
    def test_ppmt_special_rate_decimal(self):
        # When rounded out to 8 decimal places like the float based test, this should not equal the same value
        # as the float, substituted for the decimal
        def raise_error_because_not_equal():
            assert_equal(
                round(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')), 8),
                Decimal('-90238044.232277036'))

        assert_raises(AssertionError, raise_error_because_not_equal)
        assert_equal(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')),
                     Decimal('-90238044.2322778884413969909'))
示例#26
0
 def _calculate_principal_schedule(self):
     if self.tenor == 0:
         self.principal_schedule = []
     elif self.rate == 0:
         num_periods = len(self.loan_periods)
         self.principal_schedule = [self.principal / num_periods
                                    ] * num_periods
     else:
         self.principal_schedule = -np.ppmt(
             self.rate / 12, self.loan_periods, self.tenor * 12,
             self.principal)
示例#27
0
def average_capital_plus_interest_by_actualInterest(PV,mouth_rate,nper):
    year_actual_Interest=mouth_rate*PV*nper
    FV=PV+year_actual_Interest
    PMT=FV/nper
    EIR=np.rate(nper,-PMT,PV,0)*12
    actual_mouth_rate=EIR/12
    for i in range(1, nper + 1):
        PPMT = np.ppmt(actual_mouth_rate, i, nper, PV)
        IPMT = np.ipmt(actual_mouth_rate, i, nper, PV)
        yield i,-PPMT,-IPMT,PMT
        if i == nper:
            yield year_actual_Interest,round(EIR,4)
示例#28
0
def mort_pmt(df, purchase_date_eom):
    #Loops through each region ID
    purchase_date_eom = pd.to_datetime(purchase_date_eom)
    for i in region_list:
        df_region = df[df['RegionID'] == i].reset_index()
        df_region = df_region[df_region['date'] >= purchase_date_eom]
        #Skips region if data not available beginning on given purchase date
        if df_region['date'].iloc[0] != purchase_date_eom:
            continue
        else:
            #Calculate mortgage related components (period, principal, interest, remaining balance)
            #Dynamic scalar values
            purch_price = df_region[
                'Neighborhood_Zhvi_SingleFamilyResidence'].iloc[0]
            mort_rate = df_region['mort_rate'].iloc[
                0]  #Consider adding some refinancing feature
            mort_amt = (purch_price * (1 - DOWN_PMT))
            #Rolling columns for key mortgage components (period, interest, principal)
            df_region.loc[:, 'period'] = np.arange(1, len(df_region) + 1, 1)
            df_region.loc[:, 'prin_pmt'] = np.ppmt(mort_rate / 12,
                                                   df_region['period'],
                                                   YEARS * 12, mort_amt)
            df_region.loc[:, 'int_pmt'] = np.ipmt(mort_rate / 12,
                                                  df_region['period'],
                                                  YEARS * 12, mort_amt)
            df_region.loc[:, 'cum_prin'] = df_region['prin_pmt'].cumsum()
            #Ensures balance doesn't go above loan amt
            df_region.loc[:, 'cum_prin'] = df_region['cum_prin'].clip(
                lower=-mort_amt)
            df_region.loc[:, 'mort_balance'] = mort_amt + df_region['cum_prin']
            #Calculate depreciation and after-sale taxes
            df_region.loc[:, 'cum_deprec'] = (
                purch_price / (-27.5 * 12)
            ) * df_region['period']  #Depreciation limit set at 27.5 years
            #Ensures principal, interest payments go to zero when paid and depreciation doesn't exceed purchase price
            df_region.loc[:, 'cum_deprec'] = np.where(
                df_region['cum_deprec'] <= -purch_price, -purch_price,
                df_region['cum_deprec'])
            df_region.loc[:, 'prin_pmt'] = np.where(
                df_region['mort_balance'].shift(1) == 0, 0,
                df_region['prin_pmt'])
            df_region.loc[:, 'int_pmt'] = np.where(
                df_region['mort_balance'].shift(1) == 0, 0,
                df_region['int_pmt'])
            #Filters out relevant columns
            df_region.loc[:,
                          'book_value'] = purch_price + df_region['cum_deprec']
            df_region = df_region[[
                'date', 'RegionID', 'period', 'prin_pmt', 'int_pmt',
                'cum_prin', 'mort_balance', 'cum_deprec', 'book_value'
            ]]
            mort_df_list.append(df_region)
示例#29
0
    def add_oleary_amortization_info(self):
        """Calculate monthly principal and interest payment.
        Use those to calculate the accumulated principle at a given time"""

        self.oleary_df['oleary_principal_payment'] = np.ppmt(
            self.c.oleary_rate / 12, self.oleary_df.index,
            self.c.oleary_payment_years * 12, self.c.oleary_principal)
        self.oleary_df['oleary_interest_payment'] = np.ipmt(
            self.c.oleary_rate / 12, self.oleary_df.index,
            self.c.oleary_payment_years * 12, self.c.oleary_principal)

        self.oleary_df['oleary_cumulative_principal'] = self.oleary_df[
            'oleary_principal_payment'].abs().cumsum()
示例#30
0
    def add_castle_amortization_info(self):
        """Calculate monthly principal and interest payment for the new 'Castle' we are buying.
        Use those to calculate the accumulated principle at a given time"""

        self.main_df['castle_principal_payment'] = np.ppmt(
            self.c.castle_rate / 12, self.main_df.index,
            self.c.castle_payment_years * 12, self.c.castle_principal)
        self.main_df['castle_interest_payment'] = np.ipmt(
            self.c.castle_rate / 12, self.main_df.index,
            self.c.castle_payment_years * 12, self.c.castle_principal)

        self.main_df['castle_cumulative_principal'] = self.main_df[
            'castle_principal_payment'].abs().cumsum()
示例#31
0
def xPPMT(rate=0, per=0, nper=0, pv=0, fv=0, type1=0):
    # 一直用等额本金  默认0
    per = check_value(type(per))(per)
    if per == 0:
        return 0
    rate = check_value(type(rate))(rate)
    nper = check_value(type(nper))(nper)
    pv = check_value(type(pv))(pv)
    fv = check_value(type(fv))(fv)
    try:
        a = numpy.ppmt(rate, per, nper, pv, fv)
    except:
        a = 0
    return a
示例#32
0
def get_p(n):
    fv = 0
    running_pri_total = 0
    principal = []

    for per in range(nper):

        if per != 0 and per % 12 == 0:
            principal += [running_pri_total]
            running_pri_total = 0

        p = -np.ppmt(rate, per, nper, pv)
        running_pri_total += p
    return principal(n)
示例#33
0
def average_capital_plus_interest(PV,mouth_rate,nper,Sum_interest=0,returned_capital=0):
    for i in range(1, nper + 1):
        PPMT = -np.ppmt(mouth_rate, i, nper, PV)
        IPMT = -np.ipmt(mouth_rate, i, nper, PV)
        EIR=mouth_rate*12 #有效年化率
        PMT = PPMT + IPMT
        Sum_interest+=IPMT
        returned_capital+= PPMT  # 求出已还本金
        left_capital=PV-returned_capital #求出剩余本金
        actual_mouth_rate = IPMT / (left_capital+PPMT) #求出月利率
        Sum_money=PV+Sum_interest
        yield '第'+str(i)+'期',round(PPMT,1),round(IPMT,1),round(PMT,1),round(left_capital,1),"%.2f%%" % (actual_mouth_rate * 100)
        if i == nper:
            yield "还款总额:"+str(round(Sum_money,1)),"总利息:"+str(round(Sum_interest,1)),"年利率:"+str("%.2f%%" % (EIR * 100))
示例#34
0
    def test_when(self):
        # begin
        assert_almost_equal(np.rate(10, 20, -3500, 10000, 1), np.rate(10, 20, -3500, 10000, "begin"), 4)
        # end
        assert_almost_equal(np.rate(10, 20, -3500, 10000), np.rate(10, 20, -3500, 10000, "end"), 4)
        assert_almost_equal(np.rate(10, 20, -3500, 10000, 0), np.rate(10, 20, -3500, 10000, "end"), 4)

        # begin
        assert_almost_equal(np.pv(0.07, 20, 12000, 0, 1), np.pv(0.07, 20, 12000, 0, "begin"), 2)
        # end
        assert_almost_equal(np.pv(0.07, 20, 12000, 0), np.pv(0.07, 20, 12000, 0, "end"), 2)
        assert_almost_equal(np.pv(0.07, 20, 12000, 0, 0), np.pv(0.07, 20, 12000, 0, "end"), 2)

        # begin
        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 1), np.fv(0.075, 20, -2000, 0, "begin"), 4)
        # end
        assert_almost_equal(np.fv(0.075, 20, -2000, 0), np.fv(0.075, 20, -2000, 0, "end"), 4)
        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 0), np.fv(0.075, 20, -2000, 0, "end"), 4)

        # begin
        assert_almost_equal(np.pmt(0.08 / 12, 5 * 12, 15000.0, 0, 1), np.pmt(0.08 / 12, 5 * 12, 15000.0, 0, "begin"), 4)
        # end
        assert_almost_equal(np.pmt(0.08 / 12, 5 * 12, 15000.0, 0), np.pmt(0.08 / 12, 5 * 12, 15000.0, 0, "end"), 4)
        assert_almost_equal(np.pmt(0.08 / 12, 5 * 12, 15000.0, 0, 0), np.pmt(0.08 / 12, 5 * 12, 15000.0, 0, "end"), 4)

        # begin
        assert_almost_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0, 1), np.ppmt(0.1 / 12, 1, 60, 55000, 0, "begin"), 4)
        # end
        assert_almost_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0), np.ppmt(0.1 / 12, 1, 60, 55000, 0, "end"), 4)
        assert_almost_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0, 0), np.ppmt(0.1 / 12, 1, 60, 55000, 0, "end"), 4)

        # begin
        assert_almost_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0, 1), np.ipmt(0.1 / 12, 1, 24, 2000, 0, "begin"), 4)
        # end
        assert_almost_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0), np.ipmt(0.1 / 12, 1, 24, 2000, 0, "end"), 4)
        assert_almost_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0, 0), np.ipmt(0.1 / 12, 1, 24, 2000, 0, "end"), 4)

        # begin
        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.0, 1), np.nper(0.075, -2000, 0, 100000.0, "begin"), 4)
        # end
        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.0), np.nper(0.075, -2000, 0, 100000.0, "end"), 4)
        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.0, 0), np.nper(0.075, -2000, 0, 100000.0, "end"), 4)
示例#35
0
 def test_ppmt_special_rate(self):
     assert_equal(np.round(np.ppmt(0.23 / 12, 1, 60, 10000000000), 8), -90238044.232277036)
示例#36
0
 def test_ppmt_decimal(self):
     assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000')),
                  Decimal('-710.2541257864217612489830917'))
示例#37
0
 def test_ppmt(self):
     assert_equal(np.round(np.ppmt(0.1 / 12, 1, 60, 55000), 2), -710.25)
示例#38
0
    def test_decimal_with_when(self):
        """Test that decimals are still supported if the when argument is passed"""
        # begin
        assert_equal(np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), Decimal('1')),
                     np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), 'begin'))
        # end
        assert_equal(np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000')),
                     np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), 'end'))
        assert_equal(np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), Decimal('0')),
                     np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), 'end'))

        # begin
        assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), Decimal('1')),
                     np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), 'begin'))
        # end
        assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0')),
                     np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), 'end'))
        assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), Decimal('0')),
                     np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), 'end'))

        # begin
        assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), Decimal('1')),
                     np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), 'begin'))
        # end
        assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0')),
                     np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), 'end'))
        assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), Decimal('0')),
                     np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), 'end'))

        # begin
        assert_equal(np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
                            Decimal('0'), Decimal('1')),
                     np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
                            Decimal('0'), 'begin'))
        # end
        assert_equal(np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
                            Decimal('0')),
                     np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
                            Decimal('0'), 'end'))
        assert_equal(np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
                            Decimal('0'), Decimal('0')),
                     np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
                            Decimal('0'), 'end'))

        # begin
        assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
                             Decimal('0'), Decimal('1')),
                     np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
                             Decimal('0'), 'begin'))
        # end
        assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
                             Decimal('0')),
                     np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
                             Decimal('0'), 'end'))
        assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
                             Decimal('0'), Decimal('0')),
                     np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
                             Decimal('0'), 'end'))

        # begin
        assert_equal(np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
                             Decimal('0'), Decimal('1')).flat[0],
                     np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
                             Decimal('0'), 'begin').flat[0])
        # end
        assert_equal(np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
                             Decimal('0')).flat[0],
                     np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
                             Decimal('0'), 'end').flat[0])
        assert_equal(np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
                             Decimal('0'), Decimal('0')).flat[0],
                     np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
                             Decimal('0'), 'end').flat[0])
示例#39
0
    def test_when(self):
        # begin
        assert_equal(np.rate(10, 20, -3500, 10000, 1),
                     np.rate(10, 20, -3500, 10000, 'begin'))
        # end
        assert_equal(np.rate(10, 20, -3500, 10000),
                     np.rate(10, 20, -3500, 10000, 'end'))
        assert_equal(np.rate(10, 20, -3500, 10000, 0),
                     np.rate(10, 20, -3500, 10000, 'end'))

        # begin
        assert_equal(np.pv(0.07, 20, 12000, 0, 1),
                     np.pv(0.07, 20, 12000, 0, 'begin'))
        # end
        assert_equal(np.pv(0.07, 20, 12000, 0),
                     np.pv(0.07, 20, 12000, 0, 'end'))
        assert_equal(np.pv(0.07, 20, 12000, 0, 0),
                     np.pv(0.07, 20, 12000, 0, 'end'))

        # begin
        assert_equal(np.fv(0.075, 20, -2000, 0, 1),
                     np.fv(0.075, 20, -2000, 0, 'begin'))
        # end
        assert_equal(np.fv(0.075, 20, -2000, 0),
                     np.fv(0.075, 20, -2000, 0, 'end'))
        assert_equal(np.fv(0.075, 20, -2000, 0, 0),
                     np.fv(0.075, 20, -2000, 0, 'end'))

        # begin
        assert_equal(np.pmt(0.08 / 12, 5 * 12, 15000., 0, 1),
                     np.pmt(0.08 / 12, 5 * 12, 15000., 0, 'begin'))
        # end
        assert_equal(np.pmt(0.08 / 12, 5 * 12, 15000., 0),
                     np.pmt(0.08 / 12, 5 * 12, 15000., 0, 'end'))
        assert_equal(np.pmt(0.08 / 12, 5 * 12, 15000., 0, 0),
                     np.pmt(0.08 / 12, 5 * 12, 15000., 0, 'end'))

        # begin
        assert_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0, 1),
                     np.ppmt(0.1 / 12, 1, 60, 55000, 0, 'begin'))
        # end
        assert_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0),
                     np.ppmt(0.1 / 12, 1, 60, 55000, 0, 'end'))
        assert_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0, 0),
                     np.ppmt(0.1 / 12, 1, 60, 55000, 0, 'end'))

        # begin
        assert_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0, 1),
                     np.ipmt(0.1 / 12, 1, 24, 2000, 0, 'begin'))
        # end
        assert_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0),
                     np.ipmt(0.1 / 12, 1, 24, 2000, 0, 'end'))
        assert_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0, 0),
                     np.ipmt(0.1 / 12, 1, 24, 2000, 0, 'end'))

        # begin
        assert_equal(np.nper(0.075, -2000, 0, 100000., 1),
                     np.nper(0.075, -2000, 0, 100000., 'begin'))
        # end
        assert_equal(np.nper(0.075, -2000, 0, 100000.),
                     np.nper(0.075, -2000, 0, 100000., 'end'))
        assert_equal(np.nper(0.075, -2000, 0, 100000., 0),
                     np.nper(0.075, -2000, 0, 100000., 'end'))
示例#40
0
 def raise_error_because_not_equal():
     assert_equal(
         round(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')), 8),
         Decimal('-90238044.232277036'))
示例#41
0
               'default': 'ls_default'}

df = df.rename(columns=rename_dict)
df = df.rename(columns=purpose_dict)

# identify good loans and bad loans (might include the 31 to 120 day late category later)
df.loc[df['ls_default'] == 1, 'bad_loan'] = 1
df.loc[df['ls_chargeoff'] == 1, 'bad_loan'] = 1
df.loc[df['bad_loan'] != 1, 'bad_loan'] = 0
df.loc[df['bad_loan'] != 1, 'good_loan'] = 1
df.loc[df['good_loan'] != 1, 'good_loan'] = 0

# add columns related to debt service and debt service coverage

# calculate annual debt service payments for Lending Club loans
df['annual_prin'] = sum([np.ppmt(df['int_rate'] / 12, i, df['term'], -df['loan_amnt'], 0) for i in range(1, 13)])
df['annual_prin'] = df['annual_prin'].round(2)
df['annual_int'] = sum([np.ipmt(df['int_rate'] / 12, i, df['term'], -df['loan_amnt'], 0) for i in range(1, 13)])
df['annual_int'] = df['annual_int'].round(2)
df['annual_debt_svc'] = df['annual_prin'] + df['annual_int']
df['annual_debt_svc'] = df['annual_debt_svc'].round(2)

# total revolving debt NOT attributable to Lending Club loans
df['other_rev_debt'] = df['total_bal_ex_mort'] - df['out_prncp']
df.loc[df['other_rev_debt'] < 0, 'other_rev_debt'] = 0

# total mortgage/installment debt (also not Lending Club)
df['other_mort_debt'] = df['tot_cur_bal'] - df['other_rev_debt']
df.loc[df['other_mort_debt'] < 0, 'other_mort_debt'] = 0

# estimated annual debt service requirement on non-Lending-Club revolving debt (at Lending Club int_rate, 5yr amort)
 def test_ppmt(self):
     np.round(np.ppmt(0.1/12,1,60,55000),2) == 710.25
示例#43
0
    def cashflows(self):
        """
        Construct a dataframe with projections of balances and cashflows for a loan portfolio
        in an homogeneous loan pool, where the loans share the same origination period.
        :rtype: pandas dataframe
        """
        loss_rates = self._credit_model.get('loss')
        nonperforming_rates = self._credit_model.get('nonperforming')
        provision_rates = self._credit_model.get('provision')
        prepayment_rates = self._prepayment_vector
        rates = self._rates_vector
        index_to_apply = list(range(self.origination_month(), self.origination_month() + self._nper + 1))

        ans_df = pd.DataFrame(0.,
                              index = index_to_apply,
                              columns = ('saldo_inicial',
                                         'desembolsos',
                                         'amortizacion',
                                         'prepago',
                                         'castigo',
                                         'saldo_final',
                                         'interes',
                                         'improductiva',
                                         'saldo_provision'))

        ans_df.loc[self.origination_month()] = [0,
                                                self._origination,
                                                0,
                                                0,
                                                0,
                                                self._origination,
                                                0,
                                                0,
                                                self._origination * provision_rates[0]]

        rounding = 6
        min_balance = 0.01
        initial_balance = self._origination
        for payment in range(self._nper):
            index = payment + self.origination_month()
            loss = np.round(initial_balance * loss_rates[payment], rounding)
            prepayment = np.round(initial_balance * prepayment_rates[payment], rounding)
            nonperforming = np.round(initial_balance * nonperforming_rates[payment], rounding)
            provision = np.round((provision_rates[payment] * (initial_balance - nonperforming)) + nonperforming,
                                 rounding)
            ipmt = np.round((initial_balance - nonperforming) * rates[payment], rounding)

            contractual_ppmt = np.round(-(np.ppmt(rates[payment],
                                                  payment + 1, self._nper, self._origination)), rounding)
            if contractual_ppmt > (initial_balance - prepayment - loss):
                ppmt = np.round(initial_balance - prepayment - loss, rounding)
            else:
                ppmt = contractual_ppmt

            ending_balance = np.round(initial_balance - ppmt - prepayment - loss, rounding)
            if ending_balance < min_balance:
                ending_balance = 0.

            origination = np.round(0., rounding)

            ans_df.loc[index + 1] = [initial_balance,
                                     origination,
                                     ppmt,
                                     prepayment,
                                     loss,
                                     ending_balance,
                                     ipmt,
                                     nonperforming,
                                     provision]

            initial_balance = ending_balance
        return ans_df