options cmplib=work.ORBA;
proc fcmp outlib=work.ORBA.pv; * Present value;
subroutine pvLoan( /* input */
loanAmount,
maturityMonth,
interestRateAnnual,
inflationAnnual,
/* output */
amortizationSumAnnuity,
interestSumAnnuity,
invoiceSumAnnuity,
amortizationSumFlat,
interestSumFlat,
invoiceSumFlat,
pvAmortizationSumAnnuity,
pvInterestSumAnnuity,
pvInvoiceSumAnnuity,
pvAmortizationSumFlat,
pvInterestSumFlat,
pvInvoiceSumFlat);
outargs amortizationSumAnnuity, interestSumAnnuity, invoiceSumAnnuity,
amortizationSumFlat, interestSumFlat, invoiceSumFlat,
pvAmortizationSumAnnuity, pvInterestSumAnnuity, pvInvoiceSumAnnuity,
pvAmortizationSumFlat, pvInterestSumFlat, pvInvoiceSumFlat;
if missing(loanAmount) or missing(maturityMonth) or missing(interestRateAnnual) then
do;
pvAmortizationSumAnnuity = .;
pvInterestSumAnnuity = .;
pvInvoiceSumAnnuity = .;
pvAmortizationSumFlat = .;
pvInterestSumFlat = .;
pvInvoiceSumFlat = .;
end;
else
do;
inflationMonth = sum(exp((log(sum(1,inflationAnnual)))/12),-1);
do maturityPeriod = 1 to maturityMonth;
* ------------------------------------------------------------------------------------------;
* ANNUITY;
* ------------------------------------------------------------------------------------------;
fv = 0; * Specifies the future value after the last payment is made;
paymentDueDate = 0; * Specifies whether the payments occur at the beginning or end of a period. 0 represents the end-of-period payments;
* NOMINAL VALUE;
* If the interest rate is zero you only amortize. Equal to flat amortization;
if interestRateAnnual = 0 then
do;
amortizationAnnuity = loanAmount / maturityMonth;
interestPaymentAnnuity = 0;
invoiceAnnuity = sum(amortizationAnnuity, interestPaymentAnnuity);
end;
else
do;
amortizationAnnuity = abs(finance('ppmt', interestRateAnnual/12, maturityPeriod, maturityMonth, loanAmount, paymentDueDate));
invoiceAnnuity = abs(finance('pmt', interestRateAnnual/12, maturityMonth, loanAmount, fv, paymentDueDate));
interestPaymentAnnuity = abs(sum(invoiceAnnuity, - amortizationAnnuity));
end;
* Cumulative nominal flat amortization;
amortizationSumAnnuity = sum(amortizationSumAnnuity, amortizationAnnuity);
interestSumAnnuity = sum(interestSumAnnuity, interestPaymentAnnuity);
invoiceSumAnnuity = sum(amortizationSumAnnuity, interestSumAnnuity);
* PRESENT VALUE;
* Present value of the interest and amortization for a annuity;
pvAmortizationAnnuity = amortizationAnnuity / ((1+inflationMonth)**maturityPeriod);
pvInterestAnnuity = interestPaymentAnnuity / ((1+inflationMonth)**maturityPeriod);
pvInvoiceAnnuity = sum(pvAmortizationAnnuity, pvInterestAnnuity);
* Cumulative present value annuity;
pvAmortizationSumAnnuity = sum(pvAmortizationSumAnnuity, pvAmortizationAnnuity);
pvInterestSumAnnuity = sum(pvInterestSumAnnuity, pvInterestAnnuity);
pvInvoiceSumAnnuity = sum(pvAmortizationSumAnnuity, pvInterestSumAnnuity);
* ------------------------------------------------------------------------------------------;
* FLAT AMORTIZATION;
* ------------------------------------------------------------------------------------------;
* NOMINAL VALUE;
* Payment in period n;
amortizationFlat = loanAmount / maturityMonth;
interestPaymentFlat = (sum(loanAmount, -amortizationFlat*(maturityPeriod-1)) * interestRateAnnual/12);
invoiceFlat = sum(amortizationFlat, interestPaymentFlat);
* Cumulative nominal flat amortization;
amortizationSumFlat = sum(amortizationSumFlat, amortizationFlat);
interestSumFlat = sum(interestSumFlat, interestPaymentFlat);
invoiceSumFlat = sum(amortizationSumFlat, interestSumFlat);
* PRESENT VALUE;
* Present value of the interest and amortization for flat amortization;
pvAmortizationFlat = amortizationFlat / ((1+inflationMonth)**maturityPeriod);
pvInterestFlat = interestPaymentFlat / ((1+inflationMonth)**maturityPeriod);
pvInvoiceFlat = sum(pvAmortizationFlat, pvInterestFlat);
* Cumulative present value flat amortization;
pvAmortizationSumFlat = sum(pvAmortizationSumFlat, pvAmortizationFlat);
pvInterestSumFlat = sum(pvInterestSumFlat, pvInterestFlat);
pvInvoiceSumFlat = sum(pvAmortizationSumFlat, pvInterestSumFlat);
end;
end;
endsub;
run;
data have;
call streaminit(12345);
do i = 1 to 5;
loanAmount = abs(floor(rand("normal", 300E3, 200E3)));
maturityMonth = abs(floor(rand("normal", 120, 24)));
interestRateAnnual = abs(rand('normal',0.05,0.05));
output;
end;
format loanAmount maturityMonth comma10. interestRateAnnual percent10.2;
drop i;
run;
data want;
set have;
* Call the subroutine and performe the calculations;
call pvLoan( /* input */
loanAmount,
maturityMonth,
interestRateAnnual,
0.02,
/* output */
amortizationSumAnnuity,
interestSumAnnuity,
invoiceSumAnnuity,
amortizationSumFlat,
interestSumFlat,
invoiceSumFlat,
pvAmortizationSumAnnuity,
pvInterestSumAnnuity,
pvInvoiceSumAnnuity,
pvAmortizationSumFlat,
pvInterestSumFlat,
pvInvoiceSumFlat);
format _numeric_ comma20. interestRateAnnual percent5.2;
run;