From: rjm@lookoutit.uswc.uswest.com (Rod J. Murillo)
Subject:  REPOST: Software for calculating "accelerated"  mortgage payments
Organization: US WEST Information Technologies
Date: Tue, 15 Sep 1992 20:06:17 GMT

Sorry, my last posting had a few bugs included at no extra charge.  Some of
may prefer this version.

 /* amort.c
 * @(#) amort.c amoritization program
 * 
 * acronym:     loan amortization program
 *
 * purpose:     calculates monthly payment, future value
 *              and creates an amortization schedule
 *
 * arguments:   -s suppresses the month-by-month schedule
 *
 * compile on Unix: 'cc -O -o amort amort.c -lm'
 * 
 * 06/27/84  Bill Gregg, Informatics General Corp.
 * 07/12/84  Revisions
 * 01/31/89  Robert Drabek, Univ of Ariz
 *             added -s
 *             added months and years
 *             changed everything to doubles instead of floats
 *             cleaned up code
 * 09/27/91  Amarjit Dhingra, Cap Gemini America / AT&T Bell Labs
 * 	   	Added additional principal payments code - NOT TESTED 
 *							   THOROUGHLY
 *
 */

#include <stdio.h>
#include <string.h>

#include <math.h>
#include <time.h>

extern char *ctime();
static double years();

static char buf[BUFSIZ];
static char *MONTHS[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 
main(argc,argv)
int argc;
char *argv[];
{
  double initial_principal, total_years, yearly_rate;
  int    beginning_month = 1;

  long   Tloc, time();
  char   temp_time[26];

  double interest_charge;	/* expected interest payment if there is
				   no extra payments
				 */
  double total_interest_charge = 0.0;  	/* ACTUAL interest paid	*/
  double balance;
  double monthly_rate;
  double monthly_payment;
  double future_value;
  double monthly_interest_payment;
  double outstanding_principal;
  double equity = 0;
  double ti = 0;
  double interest_year_to_date = 0.0;
  double extra_payment = 0.0; /* ad */
  int    total_months, month, first_year, this_year, this_month;
  int    extra =0;
  int	epm = 0;	/* extra payment month */

  /*  prompt for input from terminal  */

  fprintf(stderr, "Enter principal amount: ");
  gets(buf);
  sscanf(buf, "%lf", &initial_principal);

  fprintf(stderr, "Enter interest rate in percent: ");
  gets(buf);
  sscanf(buf, "%lf", &yearly_rate);
  monthly_rate = yearly_rate / (12.0 * 100.0);

  fprintf(stderr, "Enter term in years (or RETURN then the desired monthly payment): ");
  gets(buf);
  if (strlen(buf) == 0) {
    fprintf(stderr, "Enter desired monthly payment: ");
    gets(buf);
    sscanf(buf, "%lf", &monthly_payment);
    total_years = years(monthly_payment, initial_principal, monthly_rate);
    }
  else {
    sscanf(buf, "%lf", &total_years);
    monthly_payment = (initial_principal * monthly_rate)
              / (1.0 - 1.0 / pow(1.0 + monthly_rate, total_years * 12.0));
  }

  if (argc <= 1 || strcmp(argv[1], "-s") != 0) {
    fprintf(stderr, "Enter month payments begin (ex: 8 = August): ");
    scanf("%d", &beginning_month);
  }

  fprintf(stderr, "Want any extra yearly payments");
  fprintf(stderr, 
	" 0 - NO\n 1 - YES, anually\n 2 - YES, Monthly\n 3 - YES, One time\n");
  scanf("%d", &extra );
  if ( extra )
  {
    fprintf(stderr, "Enter amount:");
    scanf("%lf", &extra_payment);
  }
  if ( extra == 3 )
  {
  	fprintf(stderr, "Enter the month in which extra payment to be made: ");
  	scanf("%d", &epm );
  }

  total_months = (int) ceil(total_years * 12);
  future_value = monthly_payment * total_months;
  interest_charge = future_value - initial_principal;

  /*  print header  */
  
  fprintf(stdout, "\n\t *** Amortization Schedule ***\n\n");
  fprintf(stdout, "Principal              %4.2f\n", initial_principal);
  fprintf(stdout, "Total interest charge  %4.2f", interest_charge);
  if (extra)
  {
	fprintf(stdout,"**If No extra payments**\n");
  }
  else
  {
	fprintf(stdout, "\n");
  }
  fprintf(stdout, "Future value           %4.2f", future_value);
  if (extra)
  {
	fprintf(stdout,"**If No extra payments**\n");
  }
  else
  {
	fprintf(stdout, "\n");
  }
  fprintf(stdout, "Interest Rate          %3.3f\n", yearly_rate);
  fprintf(stdout, "Term of loan in years  %.2g\n",   total_years);
  fprintf(stdout, "Payment                %4.2f\n", monthly_payment);
  switch ( extra )
  {
	case 0 :
		break;
	case 1 : 
		fprintf( stdout, "Annual ");
		break;
	case 2 :
		fprintf( stdout, "Monthly ");
		break;
	case 3 :
		fprintf( stdout, "One-Time ");
		break;
	default:
		fprintf( stdout, "jiowejhfodijckxzfsdlkfjsdkfjsdf ");
		break;
  }
  fprintf(stdout, "extra Payment   %4.2f\n", extra_payment);
  
  
  if (argc <= 1 || strcmp(argv[1], "-s") != 0) {

    /* Get the current year. */
    Tloc = time((long *)0);
    strcpy(temp_time, ctime(&Tloc));
    this_year = first_year = atoi(temp_time + 20);

    /* loop to print amortization schedule */
    fprintf(stdout, "\n      MONTH    PRINCIPAL     INTEREST      BALANCE\n");
    fprintf(stdout,   "--------------------------------------------------\n\n");
    this_month = beginning_month;
    balance = initial_principal;
    interest_year_to_date = 0.0;
    for (month = 1; month <= total_months; month++) {

    switch (extra)
    {
	case 1:
		/* Annual recurring payment starting end of first year */
		if ( (this_month ==  beginning_month) && (month != 1) )
    		{
         		balance -= extra_payment;
    		}
		break;
	case 2:
		/* Monthly recurring payment 	*/
         	balance -= extra_payment;
		break;
	case 3:
		/* One time payment */
		/* epm is extra payment month */
		if ( month == epm )
    		{
         		balance -= extra_payment;
    		}
		break;
	default:
		break;
    } /* switch ends */

if (balance <= 0) { printf("LOOK\n"); break; }

      monthly_interest_payment = balance * monthly_rate;
      interest_year_to_date += monthly_interest_payment;
      outstanding_principal = monthly_payment - monthly_interest_payment;
      balance -= outstanding_principal;
      if (balance < 0) {
        outstanding_principal += balance;
        balance = 0.0;
      }
     /* rod */
     equity = equity + outstanding_principal;
     

    if (((extra == 1) &&  (this_month == beginning_month) && 
	(month != 1)) || (( extra == 3) && ( month == epm)))
      {
      
      fprintf(stdout, "\n");
      fprintf(stdout, "(%3d)   %3s %12.2f %12.2f %12.2f %12.2f  *Extra Payment month*\n",
                      month, MONTHS[this_month], 
			outstanding_principal+extra_payment,
                      monthly_interest_payment, balance,equity);
      fprintf(stdout, "\n");
      }
      else if ( extra == 2 )
      {
	/* The only difference between this and the previous case is that
 	 * the string "extra payment month" is NOT printed in this case
	 */
      fprintf(stdout, "(%3d)   %3s %12.2f %12.2f %12.2f %12.2f\n",
                      month, MONTHS[this_month], 
			outstanding_principal+extra_payment,
                      monthly_interest_payment, balance, equity);
      }
      else
      {
      fprintf(stdout, "(%3d)   %3s %12.2f %12.2f %12.2f %12.2f\n",
                      month, MONTHS[this_month], 
			outstanding_principal,
                      monthly_interest_payment, balance, equity);
      }

      this_month++;
      if (this_month > 12 ) {
        ti = ti + interest_year_to_date;
        fprintf(stdout, "* * * Interest paid for %d (year %d) is %.2f\n\n",
                        this_year, this_year - first_year + 1,
                        interest_year_to_date);
        fprintf(stdout, "      Interest Total to date: %.2f\n",ti);
        this_year++;
	total_interest_charge = total_interest_charge + interest_year_to_date;
        interest_year_to_date = 0;
        this_month = 1;
      }
    }

    if (this_month > 1)
    {
	total_interest_charge = total_interest_charge + interest_year_to_date;
        fprintf(stdout, "* * * Interest paid for %d is %.2f\n\n",
                      this_year, interest_year_to_date);
    }

    /* Calculate the interest saved due to extra payments */
    if (extra)
    {
	fprintf(stdout, "\n\n Interest SAVED = %.2f\n\n",interest_charge - total_interest_charge );
    }
  }

}  /* main */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

static double years(monthly_payment,principal, rate)
double monthly_payment;
double principal;
double rate;
{

  return log(monthly_payment / (monthly_payment - principal * rate))
         / (12.0 * log(1 + rate));

}  /* years */




-- 
Rod Murillo 303-592-6449  rjm@lookout.uswest.com
------------------------------------------------