Financial Modeling With C
------------------------------------------------------

The code of the following programs will introduce
several financial modeling concepts ranged from very simple to
complex (recursion) and their solutions. 

Future Value
-------------
If one makes a series of regular deposits for a certain interest
rate for a certain number of periods, the amount of money
accrued at the end of the periods is the future value. 

The FV formula is: FV = PMT * ((1+i)^N-1)/i where PMT is the periodic
deposit, i is the interest rate and N is the number of periods.


The program should prompt for the monthly deposit, the annual
interest rate (e.g. 8 for 8%) and then divide that number by 12
and by 100 for the true monthly interest rate. The number of
periods is the number of years multiplied by 12.


Since the power function takes doubles as arguments (along with
exp, log and most of the other math functions), all variables
are doubles (although type casting is possible). Since the scanf
input routine takes only floats as arguments, a temp
variable of type float is introduced. Also note that when
reading with the scanf routine, one must pass the address of the
variable to the routine (i.e. scanf("%f",&temp)) and not the
variable itself. Some compilers such as Turbo C will alert you
if you forget to pass by reference but most of them will simply
let you suffer. Also you must remember to include math.h or else
pow will return garbage cleverly disguised as a valid number.


This is the code for the future value program:

----------------------------------------------
#include <stdio.h>
#include <math.h>
main()
{
   double interest, pmt, periods, fv;
   float temp;
   printf("Monthly deposit                 : ");
   scanf("%f",&temp); pmt=temp;
   printf("Annual Interest (e.g. 8 for 8%) : ");
   scanf("%f",&temp); interest=temp/100/12;
   printf("Number of years                 : ");
   scanf("%f",&temp); periods=temp*12;
   fv=pmt*((pow(1+interest,periods)-1)/interest);
   printf("Future value of investment      : %1.2f\n",fv);
}



Present Value
------------------
The present value is the amount of the loan that can be obtained
for the i interest rate, PMT monthly payment and N number of
periods. The formula is PV=PMT * (1-(1+i)^-N)/i.



#include <stdio.h>
#include <math.h>
main()
{
   double interest, pmt, periods, pv;
   float temp;
   printf("Monthly payment                 : ");
   scanf("%f",&temp); pmt=temp;
   printf("Annual Interest (e.g. 8 for 8%) : ");
   scanf("%f",&temp); interest=temp/100/12;
   printf("Number of years                 : ");
   scanf("%f",&temp); periods=temp*12;
   pv=pmt*((1-pow(1+interest,-periods))/interest);
   printf("Amount to be borrowed           : %1.2f\n",pv);
}


Most spread sheets provide PV and FV functions. There are
situations where the FV and PV are known but either i or N need
to be calculated. FV and PV are linked by the formula:
FV = PV * (1+i)^N or (1+i)^N=FV/PV. Applying natural logarithm
to both sides the equation becomes N*ln(1+i)=ln(FV/PV).
N is therefore (ln(FV)-ln(PV))/ln(1+i).


Interest rate
--------------------------
The interest rate calculation is given by:

ln(1+i)=(ln(FV)-ln(PV))/N. After applying exp to both sides the
equation becomes 1+i=exp((ln(FV)-ln(PV))/N) or
i=exp((ln(FV)-ln(PV))/N)-1.
The program that calculates i through the FV PV link is:
--------------------------


#include <stdio.h>
#include <math.h>
main()
{
   double interest, periods, fv, pv;
   float temp;
   printf("Future Value    : ");
   scanf("%f",&temp); fv=temp;
   printf("Present Value   : ");
   scanf("%f",&temp); pv=temp;
   printf("Number of years : ");
   scanf("%f",&temp); periods=temp*12;
   interest=(exp((log(fv)-log(pv))/periods)-1)*1200;
   printf("Interest Rate   : %1.2f\n",interest);
}

 
 
Net Present Value
------------------
It's difficult to imagine a bank account with nothing but
regular and equal deposits (i.e positive cash flows) and no
withdrawals (i.e. negative cash flows). 
<br>Net present value addresses the worth of a series of unequal and different sign
cash flows. The NPV formula is:

CF[1]/(1+i)^1+CF[2]/(1+i)^2+..CF[N]/(1+i)^N where CF are the
cash flows in the respective periods, N is the number of periods
and i is the considered interest rate.


The NPV function would look like this:
--------------------------------------

double pv(a,intrate,numflows)
double a[],intrate; int numflows;
{
   int i;
   double temp=0;
   for (i=1;i<=numflows;i++) {
      if (intrate==0) temp +=a[i-1];
      else temp +=(a[i-1]/pow(1+intrate/100,i));
   }
   return(temp);
}

 

If the interest rate is 0 then the denominator is 1. Therefore,
if i=0 the net present value is the sum of cash flows. As i
becomes larger NPV gets smaller. Consider the following example:


Here's an example: 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 -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? Solving the NPV equation for 6% gives a net present value
of $26,675.49 or $1,675.49 more than your initial investment.
Plotting the Net Present Value as a function of i between -5%
and 100% will illustrate the inverse proportionality between
the two values.



|
|. NPV(0)=$44,271
|-.              Net Present Value
|  .             as a function of interest
|-  .
|      . NPV(5)=$28,858.16
|-        .  NPV(6)=$26,675.49
|             .
|-                . . . . NPV(20)=$11,091.59
|
-=-=-=-=-=-=-=-=-=-=-=-=-
|     |     |     |     |


 
Internal Rate of Return
----------------------------

When dealing with multiple cash flows, often times the required
value is the interest rate that would generate the NPV equal to
the initial investment. 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.


The program should look only for solutions that are
financially acceptable (i.e. 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 until the
difference is smaller then a ten thousandth of the NPV.


This time the program will accept input from a file. Note
that the program expects the name of the input file as its
argument. However, if no arguments are passed the user is
prompted for the file name. Note that the getvals function uses
pointers to the variables in order to be able to modify their
values globally. The irr function keeps track of the increment
and the current interest rate in the same manner:


irr(a,invest,&intrate,&inc,numflows)



However note that when the function is invoking itself recursively the "&" address symbol
is not used because you are already dealing with a pointer. The
program reads the annual interest rate, the initial investment
and the cash flows. If the interest rate is not 0 the NPV is
calculated. Else, the programs assumes that the user is
searching for IRR. 

To run the program with the example above
create a file containing the values on separate lines or on the
same line. E.g. file "data.dat" contains the line:
-------------------------------------------------------------------

0 -25000 3500 100 4000 100 -300 4000 2300 -150 5600 321 -100 24900
-------------------------------------------------------------------

IRR and NPV program listing:

------------------
#include <stdio.h>
#include <math.h>
#define MAX 500
main (argc,argv)
int argc;
char *argv[];
{
    FILE *fopen(), *f;
    char fn[80];
    double a[MAX],invest,intrate,inc,pv(),irr();
    int numflows;
    if (argc==2) strcpy(fn,argv[1]);
    else {
       printf("File > ");
       gets(fn);
    }
    if ((f = fopen(fn,"r"))==NULL) {
       printf("Can not open %s\n",fn);
       exit(1);
    }
    getvals(f,a,&intrate,&invest,&numflows);
    fclose(f);
    if (intrate!=0) printf("pv=%1.3f\n",pv(a,intrate,numflows));
    else
       {
         inc=10;
         printf("irr=%1.3f\n",irr(a,invest,&intrate,&inc,numflows));
       }
}

getvals(f,a,intrate,invest,numflows)
FILE *f; double a[],*intrate,*invest; int *numflows;
{
   float temp;
   int i;
   fscanf(f,"%f",&temp); *intrate=temp;    /*fscanf reads only floats*/
   fscanf(f,"%f",&temp); *invest=fabs((double) temp);
   for (i=0;i < MAX;i++) a[i]=0;
   i=0;
   while (fscanf(f,"%f",&temp)!=EOF) a[i++]=temp;
   *numflows=i;
}

double pv(a,intrate,numflows)
double a[],intrate; int numflows;
{
   int i;
   double temp=0;
   for (i=1;i<=numflows;i++) {
      if (intrate==0) temp +=a[i-1];
      else temp +=(a[i-1]/pow(1+intrate/100,i));
   }
   return(temp);
}

double irr(a,invest,intrate,inc,numflows)
double a[],invest,*intrate,*inc; int numflows;
{
   double tol,d1,d2;
   tol=invest/10000;  /*this will grant precision past 3rd decimal*/
   d1=invest-pv(a,*intrate + *inc,numflows);
   printf("Int Rate %1.3f generates delta=%1.3f\n",(*intrate + *inc),d1);
   if (((*intrate+*inc)<0) || ((*intrate+*inc)>200)) {
      printf("\nNo solution\n");
      return(EOF);
   }
   else {
      if (fabs(d1)<=tol) return(*intrate+*inc);
      else {
         d2=invest-pv(a,*intrate,numflows);
         if (d2*d1<0) *inc /= 10;
         else *intrate +=*inc;
         return(irr(a,invest,intrate,inc,numflows));
      }
    }
}



Amortization
------------
Amortization comes from French and liberally translated means
taking something to death in tiny amounts. When you consider that
one must pay for a mortgage monthly for thirty years, the
description is fitting. When you borrow money from a bank you
must pay back both the principal and the interest. Each payment
you make contains a portion of the principal and a portion of the
interest. During the beginning periods one pays a very small
amount for the principal and a large amount for the interest.
Eventually, after building some equity, things change and a large
portion of the payment goes to the principal. 

The following
program calculates the payment for a certain loan, the principal
balance, the principal and the interest portion of each payment.
A table of these values is printed for each period. To make
things interesting, I'll request the program to bring in the
variables from the command line. Thus, the program must be
invoked like this from the command line: 


amort 100000 10.5 30


in order to amortize a
$100,000 loan for a 10.50% annual interest rate lasting for 30
years. Modify the program to prompt you for the values of the
three variables. 

The payment formula is:
paymemt=loan amount*(monthly int/(1-1/(1+monint^periods)))


Amortization program source:
----------------------------

#include <stdio.h>
#include <math.h>
main (argc,argv)
int argc;
char *argv[];
{
    double amount,annint,years,periods,monint,pmt,intrate,
           principal,priorprinc,princpaid;
    int curperiod;
    if (argc!=4) {
        printf("Format is <amort amount interest years>\n");
        exit(EOF);
     }
    else {
       amount=atof(argv[1]);
       annint=atof(argv[2]);
       years=atof(argv[3]);
    }
    periods = years*12;
    monint=annint/100/12;
    pmt=amount*(monint/(1-1/(pow(1+monint,periods))));
    curperiod=0;
    principal=amount;
    intrate=monint*principal;
    princpaid=pmt-intrate;
    printf("Monthly Payment                  :%1.2f\n",pmt);
    printf("Mon Balance Interest Principal\n\n");
    while (curperiod <=periods) {
      printf("%3d %9.2f %7.2f %7.2f\n",curperiod++,principal,
             intrate,princpaid);
      priorprinc=principal;
      principal=priorprinc-(pmt-(monint*priorprinc));
      intrate=monint*principal;
      princpaid=pmt-intrate;
  }
}