-
Notifications
You must be signed in to change notification settings - Fork 0
/
Javascript recursion convergence
199 lines (192 loc) · 6.47 KB
/
Javascript recursion convergence
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<head>
<title>Convergence Example</title>
</head>
<BODY>
<SCRIPT language=JAVASCRIPT>
/*
convergence and recursion example / irr calcualtion
Eddy Vasile
*/
function ClearForm(form){
form.investment.value ="";
form.cf1.value ="";
form.cf2.value ="";
form.cf3.value ="";
form.cf4.value ="";
form.cf5.value ="";
form.cf6.value ="";
form.cf7.value ="";
form.cf8.value ="";
form.cf9.value ="";
form.cf10.value ="";
form.cf11.value ="";
form.cf12.value ="";
form.cf13.value ="";
form.cf14.value ="";
}
function calcIRR(form){
var cashFlows = new Array(15);
var i = new Number();
var numPeriods = new Number();
var guessRate = new Number();
var irr = new Number();
guessRate = 10;
cashFlows[0]=Math.abs(parseFloat(form.investment.value));
cashFlows[1]=parseFloat(form.cf1.value);
cashFlows[2]=parseFloat(form.cf2.value);
cashFlows[3]=parseFloat(form.cf3.value);
cashFlows[4]=parseFloat(form.cf4.value);
cashFlows[5]=parseFloat(form.cf5.value);
cashFlows[6]=parseFloat(form.cf6.value);
cashFlows[7]=parseFloat(form.cf7.value);
cashFlows[8]=parseFloat(form.cf8.value);
cashFlows[9]=parseFloat(form.cf9.value);
cashFlows[10]=parseFloat(form.cf10.value);
cashFlows[11]=parseFloat(form.cf11.value);
cashFlows[12]=parseFloat(form.cf12.value);
cashFlows[13]=parseFloat(form.cf13.value);
cashFlows[14]=parseFloat(form.cf14.value);
i=0;
//get the last cash flow entered
while (i<15 || i==15) {
if (isNaN(cashFlows[i])) {
numPeriods=i-1;
break;
}
else i++;
}
document.open();
document.write("<html><title>IRR Convergence Sample</title><body>");
document.write("i=", numPeriods);
irr=internalRR(cashFlows,cashFlows[0],0 - guessRate,guessRate,numPeriods);
// now do the funky javascript rounding to 2 places
irr = Math.round(irr*100)/100
if (irr!=-1)
document.write("<b>A solution of ", irr,"% was found.</b><br>");
else
document.write("No solution was found between 0% and 200%.<br>");
document.write("Hit your browser back button to return to parent page.</body></html>");
document.close();
}
//calc present value
function pv(a,intrate,numflows)
{
var i = new Number();
var temp = new Number();
temp=0;
for (i=1;i<=numflows;i++) {
temp +=(a[i]/Math.pow(1+intrate/100,i));
}
return(temp);
}
//calc irr
function internalRR(a,invest,intrate,inc,numflows)
{
var tol = new Number();
var d1 = new Number();
var d2 = new Number();
tol=invest/10000;
d1=invest-pv(a,intrate + inc,numflows);
document.write("Intrest Rate of ",(intrate + inc),"% generates delta= ",d1,"<br>\n");
if (((intrate+inc)<0) || ((intrate+inc)>200)) {
document.write("\nNo solution\n");
return(-1);
}
else {
if (Math.abs(d1)<=tol) return(intrate+inc);
else {
d2=invest-pv(a,intrate,numflows);
if (d2*d1<0) {
inc /= 10;
document.write("backing up and decreasing size of increments to ", inc, "<br>");
}
else intrate +=inc;
return(internalRR(a,invest,intrate,inc,numflows));
}
}
}
</SCRIPT>
<CENTER>
<H1>Convergence Example / IRR calculation</H1>
<HR SIZE=10>
</CENTER>
<P>
<H2>Convergence and Recursion Example for Internal Rate of Return </H2>You buy a
mountain cabin for $25,000. During the first four years you are able to rent it
out and you collect $3,500, $100, $4000 and $100 respectively. The fifth year
you have a negative cash flow of $300 due to repairs. The cash flows for years 6
through 11 are : 4000, 2300, -150, 5600, 321, and -100. In the twelfth year you
sell the cabin for $24,900. You ask yourself, would you have been better off
depositing your $25,000 at 6% or is the series of cash flows generated by your
investment greater in value? In our example, the interest rate that would
generate a $25,000 NPV to match the initial investment is 6.847%. This interest
rate is called the Internal Rate of Return (IRR) and it cannot be computed
analytically. There are instances when several solutions are possible and
sometimes there are no solutions.
<P>The program should look only for solutions that are financially acceptable
(e.g. between 0% and 200%) and it should return the lowest if more than one are
available. The irr function should look for a solution by moving on the graph
from 0% to the right in assigned increments while trying to match the initial
investment with the NPV generated by the current interest rate. If the
difference between Investment and NPV changes signs, then the function has moved
too far and it should step back to the prior tick and continue with smaller
increments. This process should invoke itself recursively until the difference
is smaller then a ten thousandth of the NPV.
<P>
<H2>The values in the form are from the sample above. Feel free to change
them</H2>
<FORM method=post name=eddyirrcalc>
<TABLE border=1 cellPadding=1 cellSpacing=1 style="HEIGHT: 400px; WIDTH: 300px"
width="75%">
<TBODY>
<TR>
<TD>Initial Investment:</TD>
<TD><INPUT name=investment value=-25000></TD></TR>
<TR>
<TD>
<P>Cash Flow #1:</P></TD>
<TD><INPUT name=cf1 value=3500></TD></TR>
<TR>
<TD>Cash Flow #2:</TD>
<TD><INPUT name=cf2 value=100></TD></TR>
<TR>
<TD>Cash Flow #3</TD>
<TD><INPUT name=cf3 value=4000></TD></TR>
<TR>
<TD>Cash Flow #4</TD>
<TD><INPUT name=cf4 value=100></TD></TR>
<TR>
<TD>Cash Flow #5</TD>
<TD><INPUT name=cf5 value=-300></TD></TR>
<TR>
<TD>Cash Flow #6</TD>
<TD><INPUT name=cf6 value=4000></TD></TR>
<TR>
<TD>Cash Flow #7</TD>
<TD><INPUT name=cf7 value=2300></TD></TR>
<TR>
<TD>Cash Flow #8</TD>
<TD><INPUT name=cf8 value=-150></TD></TR>
<TR>
<TD>Cash Flow #9</TD>
<TD><INPUT name=cf9 value=5600></TD></TR>
<TR>
<TD>Cash Flow #10</TD>
<TD><INPUT name=cf10 value=321></TD></TR>
<TR>
<TD>Cash Flow #11</TD>
<TD><INPUT name=cf11 value=-100></TD></TR>
<TR>
<TD>Cash Flow #12</TD>
<TD><INPUT name=cf12 value=24900></TD></TR>
<TR>
<TD>Cash Flow #13</TD>
<TD><INPUT name=cf13></TD></TR>
<TR>
<TD>Cash Flow #14</TD>
<TD><INPUT name=cf14></TD></TR></TBODY></TABLE>
<P><INPUT onclick=calcIRR(this.form) type=button value=Calc> <INPUT onclick=ClearForm(this.form) type=reset value=Reset> </FORM>
<CENTER></CENTER>
<P>
<HR SIZE=10>
</BODY></HTML>