CLEAR oLoan = CREATEOBJECT("Loan") oLoan.nAnualNominalRate = .105 oLoan.nLoanAmount = 100000 oLoan.nPayment = ROUND(PAYMENT(oLoan.nLoanAmount,oLoan.nAnualNominalRate/12,24),2) oLoan.cFrequency = "M" oLoan.Calc oLoan.Dump("Option 1: Normal Monthly Payment ") oLoan.dDateOfFirstPAyment = oLoan.dDateOfLoan + 14 oLoan.cFrequency = "W" oLoan.nFrequency = 2 nOpt2Interest = oLoan.Calc() oLoan.Dump("Option 2: BiWeekly Payments ") oLoan.cFrequency = "M" nERate = oLoan.SeekinterestPaid(nOpt2Interest) ? ? "interest Rate for Option 1 that would roughly = " ? "Option 2 Iterest Paid: " + TRANSFORM(nERate*100,"999.99%") ? ? oLoan.nAnualNominalRate = nERate oLoan.Calc oLoan.Dump("Option 1: Normal Monthly Payment ") RETURN **************************************************************************** *** Calc interest Paid and Term alowing for Average Daily Balance *** calculation so that alterations to payment scheduling will *** be calculated. **************************************************************************** *** Note you would have to verify how the loan payments are being applied *** inorder to tell if this is the correct calculation method. **************************************************************************** DEFINE CLASS Loan AS Custom dDateOfLoan = DATE() dDateOfFirstPayment = GOMONTH((DATE()-DAY(DATE()))+1,1) nAnualNominalRate = 0 nLoanAmount = 0 nPayment = 0 cFrequency = "M" nFrequency = 1 && Ignored for monthly. nTotalinterestPaid = 0 nTotalPaid = 0 nTerm = 0 PROCEDURE Calc dLastEvent = THIS.dDateOfLoan nBalance = THIS.nLoanAmount CREATE CURSOR Ledger (TranType c(1), Date d, Credit n(10,2), Debit n(10,2), Balance n(10,2),Days n(2),ADB n(10,2)) INSERT INTO Ledger (TranType,Date ,Debit ,Balance) VALUES; ("B" ,dLastEvent,nBalance,nBalance) nMIRate = THIS.nAnualNominalRate/12 dNextinterestEvent = GOMONTH((dLastEvent - DAY(dLastEvent))+1,1) dNextPaymentEvent = THIS.dDateOfFirstPayment nAccumDays = dLastEvent - ((dLastEvent - DAY(dLastEvent))+1) nAccumBalance = 0 IF THIS.cFrequency = "W" nFrequency = THIS.nFrequency * 7 ENDIF nTotalinterestPaid = 0 nTotalPaid = 0 nTerm = 0 DO WHILE nBalance > 0 dNextEvent = MIN(dNextinterestEvent,dNextPaymentEvent) IF dNextEvent = dNextinterestEvent nDays = dNextEvent - dLastEvent nAccumBalance = nAccumBalance + (nDays * nBalance) nAccumDays = nAccumDays + nDays ninterestDue = ROUND((nAccumBalance/nAccumDays) * nMIRate,2) nTotalinterestPaid = nTotalinterestPaid + ninterestDue nBalance = nBalance + ninterestDue INSERT INTO Ledger (TranType,Date ,Debit ,Balance ,Days ,ADB) VALUES; ("I" ,dNextEvent,ninterestDue,nBalance,nAccumDays,nAccumBalance/nAccumDays) dNextinterestEvent = GOMONTH((dNextEvent - DAY(dNextEvent))+1,1) nAccumDays = 0 nAccumBalance = 0 dLastEvent = dNextEvent nTerm = nTerm + 1 ENDIF IF dNextEvent = dNextPaymentEvent nDays = dNextEvent - dLastEvent nAccumBalance = nAccumBalance + (nDays * nBalance) nAccumDays = nAccumDays + nDays nPayment = MIN(THIS.nPayment,nBalance) nTotalPaid = nTotalPaid + nPayment nBalance = nBalance - nPayment INSERT INTO Ledger (TranType,Date ,Credit ,Balance ,Days) VALUES; ("P" ,dNextEvent,nPayment,nBalance,nDays) DO CASE CASE THIS.cFrequency = "M" *** if dDateOfFirstPayment is later than the 28th *** it may get adjusted to the 28th This error has not *** been corrected. dNextPaymentEvent = GOMONTH(dNextEvent,1) CASE THIS.cFrequency = "W" dNextPaymentEvent = dNextEvent + nFrequency OTHERWISE ERROR "Unrecognized Frequency Type" RETURN ENDCASE ENDIF dLastEvent = dNextEvent ENDDO THIS.nTotalinterestPaid = nTotalinterestPaid THIS.nTotalPaid = nTotalPaid THIS.nTerm = nTerm RETURN nTotalinterestPaid ENDPROC PROCEDURE SeekinterestPaid(tnIntPaid) nSavedRate = THIS.nAnualNominalRate nIntPaid = oLoan.Calc() DO CASE CASE nIntPaid > tnIntPaid nMin = .001 nMax = nSavedRate CASE nIntPaid < tnIntPaid nMin = nSavedRate nMax = 1 OTHERWISE RETURN nSavedRate ENDCASE DO WHILE ROUND(nMin,4) != ROUND(nMax,4) nTest = nMin + ((nMax-nMin)/2) THIS.nAnualNominalRate = nTest nIntPaid = oLoan.Calc() DO CASE CASE nIntPaid > tnIntPaid nMax = nTest CASE nIntPaid < tnIntPaid nMin = nTest OTHERWISE RETURN nTest ENDCASE ENDDO RETURN ROUND(nMax,4) ENDPROC PROCEDURE DUMP(cTitle) ? PADR(cTitle,50,"*") ? ? "Loan: " + TRANSFORM(THIS.nLoanAmount ,"999,999,999.99") + " @ "+ TRANSFORM(THIS.nAnualNominalRate*100,"99.9%") ? "Payment Amount: " + TRANSFORM(THIS.nPayment ,"999,999,999.99") ? "Term: " + TRANSFORM(THIS.nTerm,"9999")+ " Months" ? "interest Paid: " + TRANSFORM(THIS.nTotalinterestPaid,"999,999,999.99") ? ? PADR("",50,"*") ? ? ENDPROC ENDDEFINE