307 lines
12 KiB
Java
307 lines
12 KiB
Java
import java.awt.*;
|
|
|
|
public class Proto extends java.applet.Applet
|
|
{
|
|
SpreadSheetInterface mSpreadSheet;
|
|
PurePassThru mPurePassThru=new PurePassThru();
|
|
PureCashflow mPureCashflows[];
|
|
TextField mCtlPrincipal;
|
|
TextField mCtlInterest;
|
|
TextField mCtlTerm;
|
|
|
|
TextField mCtlPrepayment;
|
|
TextField mCtlIncrement;
|
|
TextField mCtlFrequency;
|
|
Label mCtlCost;
|
|
|
|
Button mCtlButton;
|
|
|
|
public void init()
|
|
{
|
|
performLayout();
|
|
mSpreadSheet=new SpreadSheetInterface(this,361,10,new Dimension(630,200));
|
|
mSpreadSheet.setDocumentTitle("Paydown Calculator v1.00");
|
|
mSpreadSheet.gridLock(true);
|
|
repaint();
|
|
}
|
|
public void update(Graphics graphics)
|
|
{
|
|
if(null!=mSpreadSheet)mSpreadSheet.update(graphics);
|
|
}
|
|
public void paint(Graphics graphics)
|
|
{
|
|
if(null!=mSpreadSheet)mSpreadSheet.paint(graphics);
|
|
}
|
|
public boolean mouseDown(Event event,int x,int y)
|
|
{
|
|
if(null!=mCtlPrincipal&&mCtlPrincipal==event.target)return false;
|
|
else if(null!=mCtlInterest&&mCtlInterest==event.target)return false;
|
|
else if(null!=mCtlTerm&&mCtlTerm==event.target)return false;
|
|
else if(null!=mCtlButton&&mCtlButton==event.target)return false;
|
|
else if(null!=mCtlPrepayment&&mCtlPrepayment==event.target)return false;
|
|
else if(null!=mCtlIncrement&&mCtlIncrement==event.target)return false;
|
|
else if(null!=mCtlFrequency&&mCtlFrequency==event.target)return false;
|
|
else if(null!=mSpreadSheet)return mSpreadSheet.mouseDown(event,x,y);
|
|
return true;
|
|
}
|
|
public boolean keyDown(Event event,int key)
|
|
{
|
|
if(null!=mCtlPrincipal&&mCtlPrincipal==event.target)return false;
|
|
else if(null!=mCtlInterest&&mCtlInterest==event.target)return false;
|
|
else if(null!=mCtlTerm&&mCtlTerm==event.target)return false;
|
|
else if(null!=mCtlButton&&mCtlButton==event.target)return false;
|
|
else if(null!=mCtlPrepayment&&mCtlPrepayment==event.target)return false;
|
|
else if(null!=mCtlIncrement&&mCtlIncrement==event.target)return false;
|
|
else if(null!=mCtlFrequency&&mCtlFrequency==event.target)return false;
|
|
else if(null!=mSpreadSheet)return mSpreadSheet.keyDown(event,key);
|
|
return true;
|
|
}
|
|
public void performLayout()
|
|
{
|
|
GridBagLayout layout=new GridBagLayout();
|
|
GridBagConstraints constraints=new GridBagConstraints();
|
|
setFont(new Font("Fixed",Font.BOLD,12));
|
|
setLayout(layout);
|
|
|
|
constraints.fill=GridBagConstraints.BOTH;
|
|
constraints.weightx=0.25;
|
|
Label prnLabel=new Label("Principal",Label.LEFT);
|
|
layout.setConstraints(prnLabel,constraints);
|
|
add(prnLabel);
|
|
mCtlPrincipal=new TextField("$100000.00");
|
|
layout.setConstraints(mCtlPrincipal,constraints);
|
|
add(mCtlPrincipal);
|
|
|
|
Label intLabel=new Label("Interest",Label.LEFT);
|
|
layout.setConstraints(intLabel,constraints);
|
|
add(intLabel);
|
|
mCtlInterest=new TextField("8.00%");
|
|
layout.setConstraints(mCtlInterest,constraints);
|
|
add(mCtlInterest);
|
|
|
|
Label trmLabel=new Label("Term",Label.LEFT);
|
|
layout.setConstraints(trmLabel,constraints);
|
|
add(trmLabel);
|
|
mCtlTerm=new TextField("360");
|
|
layout.setConstraints(mCtlTerm,constraints);
|
|
add(mCtlTerm);
|
|
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
|
mCtlButton=new Button("Calculate");
|
|
layout.setConstraints(mCtlButton,constraints);
|
|
add(mCtlButton);
|
|
|
|
constraints.fill=GridBagConstraints.BOTH;
|
|
constraints.gridwidth=1;
|
|
Label ppyLabel=new Label("Prepayment",Label.LEFT);
|
|
layout.setConstraints(ppyLabel,constraints);
|
|
add(ppyLabel);
|
|
mCtlPrepayment=new TextField("$0.00");
|
|
layout.setConstraints(mCtlPrepayment,constraints);
|
|
add(mCtlPrepayment);
|
|
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
|
Label ppyHlpLabel=new Label("Enter the amount of your prepayment(s).");
|
|
layout.setConstraints(ppyHlpLabel,constraints);
|
|
add(ppyHlpLabel);
|
|
|
|
|
|
|
|
constraints.fill=GridBagConstraints.BOTH;
|
|
constraints.gridwidth=1;
|
|
Label incLabel=new Label("Increment",Label.LEFT);
|
|
layout.setConstraints(incLabel,constraints);
|
|
add(incLabel);
|
|
mCtlIncrement=new TextField("$0.00");
|
|
layout.setConstraints(mCtlIncrement,constraints);
|
|
add(mCtlIncrement);
|
|
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
|
Label incHlpLabel=new Label("Increment the prepayment(s) by this amount.");
|
|
layout.setConstraints(incHlpLabel,constraints);
|
|
add(incHlpLabel);
|
|
|
|
|
|
constraints.fill=GridBagConstraints.BOTH;
|
|
constraints.gridwidth=1;
|
|
Label frqLabel=new Label("Frequency",Label.LEFT);
|
|
layout.setConstraints(frqLabel,constraints);
|
|
add(frqLabel);
|
|
mCtlFrequency=new TextField("0.00");
|
|
layout.setConstraints(mCtlFrequency,constraints);
|
|
add(mCtlFrequency);
|
|
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
|
Label frqHlpLabel=new Label("Frequency at which to increment the prepayments (ie) number of months.");
|
|
layout.setConstraints(frqHlpLabel,constraints);
|
|
add(frqHlpLabel);
|
|
|
|
constraints.fill=GridBagConstraints.BOTH;
|
|
constraints.gridwidth=1;
|
|
Label costLabel=new Label("Cost Of Capital:",Label.LEFT);
|
|
layout.setConstraints(costLabel,constraints);
|
|
add(costLabel);
|
|
mCtlCost=new Label("$0.00",Label.LEFT);
|
|
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
|
layout.setConstraints(mCtlCost,constraints);
|
|
add(mCtlCost);
|
|
}
|
|
public boolean action(Event event,Object object)
|
|
{
|
|
if(null!=mCtlButton&&mCtlButton==event.target)performCalc();
|
|
return true;
|
|
}
|
|
public void performCalc()
|
|
{
|
|
Prepayment prepayment=new Prepayment();
|
|
String strPrincipal=mCtlPrincipal.getText();
|
|
String strInterest=mCtlInterest.getText();
|
|
String strTerm=mCtlTerm.getText();
|
|
String strPrepayment=mCtlPrepayment.getText();
|
|
String strIncrement=mCtlIncrement.getText();
|
|
String strFrequency=mCtlFrequency.getText();
|
|
Double workDouble;
|
|
double principal;
|
|
double interest;
|
|
int term;
|
|
int itemIndex;
|
|
|
|
workDouble=new Double(0);
|
|
strPrincipal=strPrincipal.replace('$',' ');
|
|
workDouble=workDouble.valueOf(strPrincipal);
|
|
principal=workDouble.doubleValue();
|
|
strInterest=strInterest.replace('%',' ');
|
|
workDouble=workDouble.valueOf(strInterest);
|
|
interest=workDouble.doubleValue();
|
|
term=Integer.parseInt(strTerm);
|
|
strPrepayment=strPrepayment.replace('$',' ');
|
|
workDouble=workDouble.valueOf(strPrepayment);
|
|
prepayment.amount(workDouble.doubleValue());
|
|
strIncrement=strIncrement.replace('$',' ');
|
|
workDouble=workDouble.valueOf(strIncrement);
|
|
prepayment.increment(workDouble.doubleValue());
|
|
workDouble=workDouble.valueOf(strFrequency);
|
|
prepayment.frequency(workDouble.doubleValue());
|
|
|
|
mPurePassThru.issBal(principal);
|
|
mPurePassThru.wac(interest);
|
|
mPurePassThru.coupon(interest);
|
|
mPurePassThru.wam((short)term);
|
|
mPurePassThru.origTerm((short)term);
|
|
mPurePassThru.psa(0.00);
|
|
if(0.00!=prepayment.amount()||0.00!=prepayment.increment())generateFlows(prepayment);
|
|
else generateFlows();
|
|
Money money=new Money(0);
|
|
mSpreadSheet.clear();
|
|
repaint();
|
|
mSpreadSheet.setCellData(0,0,"BeginBal");
|
|
mSpreadSheet.setCellData(0,1,"SMM");
|
|
mSpreadSheet.setCellData(0,2,"MtgPay");
|
|
mSpreadSheet.setCellData(0,3,"NetIntPay");
|
|
mSpreadSheet.setCellData(0,4,"GrossIntPay");
|
|
mSpreadSheet.setCellData(0,5,"SchedPrinPay");
|
|
mSpreadSheet.setCellData(0,6,"Prepayment");
|
|
mSpreadSheet.setCellData(0,7,"TotPrin");
|
|
mSpreadSheet.setCellData(0,8,"Cashflow");
|
|
mSpreadSheet.setCellData(0,9,"Factor");
|
|
|
|
for(itemIndex=0;itemIndex<mPurePassThru.wam();itemIndex++)
|
|
{
|
|
if(mPureCashflows[itemIndex]==null)break;
|
|
money.setValue(mPureCashflows[itemIndex].beginBal());
|
|
mSpreadSheet.setCellData(itemIndex+1,0,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].smm());
|
|
mSpreadSheet.setCellData(itemIndex+1,1,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].mtgPay());
|
|
mSpreadSheet.setCellData(itemIndex+1,2,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].netIntPay());
|
|
mSpreadSheet.setCellData(itemIndex+1,3,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].grossIntPay());
|
|
mSpreadSheet.setCellData(itemIndex+1,4,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].schedPrinPay());
|
|
mSpreadSheet.setCellData(itemIndex+1,5,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].prepayment());
|
|
mSpreadSheet.setCellData(itemIndex+1,6,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].totPrin());
|
|
mSpreadSheet.setCellData(itemIndex+1,7,money.toString());
|
|
money.setValue(mPureCashflows[itemIndex].cashflow());
|
|
mSpreadSheet.setCellData(itemIndex+1,8,money.toString());
|
|
mSpreadSheet.setCellData(itemIndex+1,9,String.valueOf(mPureCashflows[itemIndex].factor()));
|
|
}
|
|
money.setValue(mPureCashflows[itemIndex-1].grossIntPay());
|
|
mCtlCost.setText(money.toString());
|
|
repaint();
|
|
}
|
|
public void generateFlows()
|
|
{
|
|
double issBal;
|
|
double tmpCPR;
|
|
int actualMonth;
|
|
int indexFlows;
|
|
|
|
indexFlows=0;
|
|
mPureCashflows=new PureCashflow[mPurePassThru.wam()];
|
|
issBal=mPurePassThru.issBal();
|
|
for(int wam=mPurePassThru.wam();wam>0&&issBal>0.00;wam--)
|
|
{
|
|
mPureCashflows[indexFlows]=new PureCashflow();
|
|
actualMonth=(mPurePassThru.origTerm()-wam)+1;
|
|
if(actualMonth<=30)tmpCPR=.002*(double)actualMonth;
|
|
else tmpCPR=.06;
|
|
mPureCashflows[indexFlows].beginBal(issBal);
|
|
mPureCashflows[indexFlows].smm(1.00-Math.pow(1.00-(tmpCPR*mPurePassThru.psa()/100.00),1.00/12.00));
|
|
if(0==indexFlows)mPureCashflows[indexFlows].mtgPay((issBal*(mPurePassThru.wac()/1200.00))/
|
|
(1.00-Math.pow(1.00/(1.00+(mPurePassThru.wac()/1200.00)),(double)wam)));
|
|
else mPureCashflows[indexFlows].mtgPay(mPureCashflows[indexFlows-1].mtgPay());
|
|
if(issBal<=mPureCashflows[indexFlows].mtgPay())mPureCashflows[indexFlows].mtgPay(issBal);
|
|
mPureCashflows[indexFlows].netIntPay(issBal*(mPurePassThru.coupon()/1200.00));
|
|
if(0==indexFlows)mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows].netIntPay());
|
|
else mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows-1].grossIntPay()+mPureCashflows[indexFlows].netIntPay());
|
|
mPureCashflows[indexFlows].schedPrinPay(mPureCashflows[indexFlows].mtgPay()-mPureCashflows[indexFlows].netIntPay());
|
|
mPureCashflows[indexFlows].prepayment(0.00);
|
|
mPureCashflows[indexFlows].totPrin(mPureCashflows[indexFlows].schedPrinPay()+mPureCashflows[indexFlows].prepayment());
|
|
mPureCashflows[indexFlows].cashflow(mPureCashflows[indexFlows].netIntPay()+mPureCashflows[indexFlows].totPrin());
|
|
mPureCashflows[indexFlows].factor(issBal/mPurePassThru.issBal());
|
|
issBal-=mPureCashflows[indexFlows].totPrin();
|
|
indexFlows++;
|
|
}
|
|
}
|
|
public void generateFlows(Prepayment prepayment)
|
|
{
|
|
double issBal;
|
|
double tmpCPR;
|
|
int actualMonth;
|
|
int indexFlows;
|
|
|
|
indexFlows=0;
|
|
mPureCashflows=new PureCashflow[mPurePassThru.wam()];
|
|
issBal=mPurePassThru.issBal();
|
|
for(int wam=mPurePassThru.wam();wam>0&&issBal>0.00;wam--)
|
|
{
|
|
mPureCashflows[indexFlows]=new PureCashflow();
|
|
actualMonth=(mPurePassThru.origTerm()-wam)+1;
|
|
if(actualMonth<=30)tmpCPR=.002*(double)actualMonth;
|
|
else tmpCPR=.06;
|
|
mPureCashflows[indexFlows].beginBal(issBal);
|
|
mPureCashflows[indexFlows].smm(1.00-Math.pow(1.00-(tmpCPR*mPurePassThru.psa()/100.00),1.00/12.00));
|
|
if(0==indexFlows)mPureCashflows[indexFlows].mtgPay((issBal*(mPurePassThru.wac()/1200.00))/
|
|
(1.00-Math.pow(1.00/(1.00+(mPurePassThru.wac()/1200.00)),(double)wam)));
|
|
else mPureCashflows[indexFlows].mtgPay(mPureCashflows[indexFlows-1].mtgPay());
|
|
if(issBal<=mPureCashflows[indexFlows].mtgPay())mPureCashflows[indexFlows].mtgPay(issBal);
|
|
mPureCashflows[indexFlows].netIntPay(issBal*(mPurePassThru.coupon()/1200.00));
|
|
if(0==indexFlows)mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows].netIntPay());
|
|
else mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows-1].grossIntPay()+mPureCashflows[indexFlows].netIntPay());
|
|
mPureCashflows[indexFlows].schedPrinPay(mPureCashflows[indexFlows].mtgPay()-mPureCashflows[indexFlows].netIntPay());
|
|
mPureCashflows[indexFlows].prepayment(prepayment.amount());
|
|
prepayment.period(prepayment.period()+1);
|
|
if(prepayment.period()>prepayment.frequency())
|
|
{
|
|
prepayment.amount(prepayment.amount()+prepayment.increment());
|
|
prepayment.period(1);
|
|
}
|
|
mPureCashflows[indexFlows].totPrin(mPureCashflows[indexFlows].schedPrinPay()+mPureCashflows[indexFlows].prepayment());
|
|
mPureCashflows[indexFlows].cashflow(mPureCashflows[indexFlows].netIntPay()+mPureCashflows[indexFlows].totPrin());
|
|
mPureCashflows[indexFlows].factor(issBal/mPurePassThru.issBal());
|
|
issBal-=mPureCashflows[indexFlows].totPrin();
|
|
indexFlows++;
|
|
}
|
|
}
|
|
}
|
|
|