001         package com.croftsoft.core.math;
002    
003    import java.io.*;
004    
005         /*********************************************************************
006         * Financial calculations.
007         *
008         * @version
009         *   2001-10-10
010         * @since
011         *   1999-08-15
012         * @author
013         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
014         *********************************************************************/
015    
016         public final class  FinanceLib
017         //////////////////////////////////////////////////////////////////////
018         //////////////////////////////////////////////////////////////////////
019         {
020    
021         public static final void  testRetire (
022           double  desiredSavingsInterestIncome,
023           double  savingsInterestRate,
024           double  inflationRate,
025           double  taxRate,
026           double  investmentInterestRate,
027           double  yearsOfSaving )
028         //////////////////////////////////////////////////////////////////////
029         {
030         
031    //     desiredSavingsInterestIncome
032    //       = savings
033    //       * ( savingsInterestRate * ( 1.0 - taxRate ) - inflationRate )
034    //       / ( 1.0 + inflationRate );
035         
036           double  savings
037             = desiredSavingsInterestIncome * ( 1.0 + inflationRate )
038             / ( savingsInterestRate * ( 1.0 - taxRate ) - inflationRate );
039    
040           double  futureValueSavings
041             = savings * Math.pow ( 1.0 + inflationRate, yearsOfSaving );
042    
043           double  annualSavings = annualSavingsNeeded (
044             futureValueSavings, investmentInterestRate, yearsOfSaving );
045    
046           System.out.println ( savings );
047           System.out.println ( futureValueSavings );
048           System.out.println ( annualSavings );
049           System.out.println ( futureValueAnnuity (
050             annualSavings, investmentInterestRate, yearsOfSaving ) );
051           System.out.println ( presentValueAnnuity (
052             annualSavings, investmentInterestRate, yearsOfSaving ) );
053         }
054    
055         /*********************************************************************
056         * Test method.  Prints the future value of an annuity followed by
057         * the present value calculated three different ways.
058         *
059         * @param c Annual cash income starting one year from today.
060         * @param r Annual interest earned on income.
061         * @param t Number of years of cash income.
062         *********************************************************************/
063         public static final void  testAnnuity (
064           double  C,
065           double  r,
066           double  T )
067         //////////////////////////////////////////////////////////////////////
068         {
069           double  FV = futureValueAnnuity ( C, r, T );
070           System.out.println ( FV );
071           System.out.println ( presentValue ( FV, r, T ) );
072           System.out.println ( presentValueAnnuity ( C, r, T ) );
073           double [ ]  c = new double [ ( int ) T ];
074           for ( int  i = 0; i < T; i++ ) c [ i ] = C;
075           System.out.println ( presentValue ( c, r ) );
076         }
077    
078         //////////////////////////////////////////////////////////////////////
079         //////////////////////////////////////////////////////////////////////
080    
081         /*********************************************************************
082         * The future value of a cash flow received today.
083         *
084         * @param c Cash flow today.
085         * @param r Inflation rate.
086         * @param t Number of years from today when the value is evaluated.
087         *********************************************************************/
088         public static final double  futureValue (
089           double  c,
090           double  r,
091           double  t )
092         //////////////////////////////////////////////////////////////////////
093         {
094           return c * Math.pow ( 1.0 + r, t );
095         }
096    
097         /*********************************************************************
098         * Calculates the future value of an annuity.
099         *
100         * @param c Annual cash income starting one year from today.
101         * @param r Annual interest earned on income.
102         * @param t Number of years of cash income.
103         *********************************************************************/
104         public static final double  futureValueAnnuity (
105           double  c,
106           double  r,
107           double  t )
108         //////////////////////////////////////////////////////////////////////
109         {
110           return c * ( ( Math.pow ( 1.0 + r, t ) - 1.0 ) / r );
111         }
112    
113         /*********************************************************************
114         * The calculated discount rate where the net present value is 0.
115         *
116         * @param  irrEstimate
117         *
118         *   The initial estimated value for the IRR (e.g., 0.10 for 10%).
119         *
120         * @param  cashFlows
121         *
122         *   Array of cash flows received in the future, indexed from time = 0.
123         *********************************************************************/
124         public static final double  internalRateOfReturn (
125           double      irrEstimate,
126           double [ ]  cashFlows )
127         //////////////////////////////////////////////////////////////////////
128         {
129           double  irr = irrEstimate;
130    
131           double  delta = -irr * 0.1;
132    
133           double  oldNpv = 0.0;
134    
135           while ( true )
136           {
137             double  npv = netPresentValue ( irr, cashFlows );
138    
139             if ( npv == 0.0 )
140             {
141               return irr;
142             }
143    
144             if ( oldNpv < 0.0 )
145             {
146               if ( npv > 0.0 )
147               {
148                 delta *= -0.9;
149               }
150               else if ( npv > oldNpv )
151               {
152                 delta *= 1.1;
153               }
154               else if ( npv < oldNpv )
155               {
156                 delta = -delta;
157               }
158               else
159               {
160                 delta = 0.0;
161               }
162             }
163             else if ( oldNpv > 0.0 )
164             {
165               if ( npv < 0.0 )
166               {
167                 delta *= -0.9;
168               }
169               else if ( npv < oldNpv )
170               {
171                 delta *= 1.1;
172               }
173               else if ( npv > oldNpv )
174               {
175                 delta = -delta;
176               }
177               else
178               {
179                 delta = 0.0;
180               }
181             }
182    
183    /*
184    System.out.println (  "irr = " + irr + ", oldNpv = " + oldNpv + ", npv = " + npv + ", delta = " + delta );
185    
186    try{
187    new BufferedReader ( new InputStreamReader ( System.in ) ).readLine ( );
188    }catch (Exception x ) { }
189    */
190    
191             if ( delta == 0.0 )
192             {
193               return irr;
194             }
195    
196             irr += delta;
197    
198             oldNpv = npv;
199           }
200         }
201    
202         /*********************************************************************
203         * The discounted value of multiple cash flows received in the future.
204         *
205         * @param  discountRate
206         *
207         *   The discount rate or cost of capital (e.g., 0.10 for 10%).
208         *
209         * @param  cashFlows
210         *
211         *   Array of cash flows received in the future, indexed from time = 0.
212         *********************************************************************/
213         public static final double  netPresentValue (
214           double      discountRate,
215           double [ ]  cashFlows )
216         //////////////////////////////////////////////////////////////////////
217         {
218           double  npv = 0.0;
219    
220           for ( int  i = 0; i < cashFlows.length; i++ )
221           {
222             npv += cashFlows [ i ] / Math.pow ( 1.0 + discountRate, i );
223           }
224    
225           return npv;
226         }
227    
228         /*********************************************************************
229         * The discounted value of a single cash flow received in the future.
230         *
231         * @param c Cash flow received in the future
232         * @param r Inflation or annual interest.
233         * @param t Number of years from today when the cash flow is received.
234         *********************************************************************/
235         public static final double  presentValue (
236           double  c,
237           double  r,
238           double  t )
239         //////////////////////////////////////////////////////////////////////
240         {
241           return c / Math.pow ( 1.0 + r, t );
242         }
243    
244         /*********************************************************************
245         * The discounted value of varying annual cash flows.
246         *
247         * @param c Array of annual cash income starting one year from today.
248         * @param r Annual interest earned on income.
249         *********************************************************************/
250         public static final double  presentValue (
251           double [ ]  c,
252           double      r )
253         //////////////////////////////////////////////////////////////////////
254         {
255           double  sum = 0.0;
256           for ( int  i = 0; i < c.length; i++ )
257           {
258             sum += presentValue ( c [ i ], r, i + 1 );
259           }
260           return sum;
261         }
262    
263         /*********************************************************************
264         * Calculates the present value of an annuity.
265         *
266         * @param c Annual cash income starting one year from today.
267         * @param r Inflation or annual interest.
268         * @param t Number of years of cash income.
269         *********************************************************************/
270         public static final double  presentValueAnnuity (
271           double  c,
272           double  r,
273           double  t )
274         //////////////////////////////////////////////////////////////////////
275         {
276           return c * ( 1.0 - 1.0 / Math.pow ( 1.0 + r, t ) ) / r;
277         }
278    
279         /*********************************************************************
280         * Calculates the annual savings necessary to accumulate a specified
281         * value in the future.
282         *
283         * @param f Future value desired.
284         * @param r Annual interest.
285         * @param t Number of years of savings.
286         *********************************************************************/
287         public static final double  annualSavingsNeeded (
288           double  f,
289           double  r,
290           double  t )
291         //////////////////////////////////////////////////////////////////////
292         {
293           return f * r / ( Math.pow ( 1.0 + r, t ) - 1.0 );
294         }
295    
296         //////////////////////////////////////////////////////////////////////
297         //////////////////////////////////////////////////////////////////////
298    
299         private  FinanceLib ( ) { }
300    
301         //////////////////////////////////////////////////////////////////////
302         //////////////////////////////////////////////////////////////////////
303         }
304