Economics Problem.

Programming, for all ages and all languages.
Post Reply
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Economics Problem.

Post by B.E »

The problem I'm having is I need to be able to calculate the future value of a fixed payment on a loan with a odd first period. for example Say I wanted a loan in 11 payments (compounded weekly), and I wanted to start in 8 days. Using TVM (TIme Value Money), you would need to pay $48.06. Now say if you wanted to pay 48 a week, what would the Future Value be?

I have the following (calc) script (please note this script is for development purposes and will not be use for production).

Code: Select all

#!/usr/bin/calc -f
debug_setting2=5;
a=config("fullzero",1);
a=config("display", 2);
a=config("tilde", 0);
a=config("lib_debug", 0);


define assert(cond, ans){
	if (cond != ans)
		printf("Assertion Failed. %d != %d\n", cond, ans);
}

define debug(str, level=5){
	global debug_setting;
	if (debug_setting2 >= level){
		print(str);
	}
}
define apr(IPP, P, PV, BN, N, N_PART,FV){
	local i, Ni, TOTAL_tCAL, TOTAL_PV, BAL,tCAL, iBAL,TOTAL_INT;
	BAL=P;
	Ni=(N+N_PART)/N;
	debug(strprintf("Balance......................= $%.2d", BAL),5);
	
	debug(strprintf("+-------+--------------------------+-----------+-----------+----------+----------+"));
	debug(strprintf("| Time  | (pv/(1+ipp)^i+n_part)    | Principal | Interest  | BALANCE  | Paid     |"));
	debug(strprintf("+-------+--------------------------+-----------+-----------+----------+----------|"));
		iBAL=(BAL*power(1+IPP, N_PART))-P;
		TOTAL_PV+=PV-iBAL;

		tCAL=PV/power(1+IPP, i+N_PART);
		TOTAL_tCAL+=tCAL;
		TOTAL_INT+=iBAL;

		BAL-=PV-iBAL;
		debug(strprintf("|%6.2d | $%23.2d | $%8.2d | $%8.2d | $%7.2d | $%7.2d |", i+N_PART, tCAL, PV-iBAL, iBAL, BAL, TOTAL_tCAL));

	for(i=BN;i<=N-1;i++){
		iBAL=(BAL*power(IPP, 1));
		TOTAL_PV+=PV-iBAL;

		tCAL=PV/power(1+IPP, (i+N_PART));
		TOTAL_tCAL+=tCAL;
		TOTAL_INT+=iBAL;

		BAL-=PV-iBAL;
		debug(strprintf("|%6.2d | $%23.2d | $%8.2d | $%8.2d | $%7.2d | $%7.2d |", i+N_PART, tCAL, PV-iBAL, iBAL, BAL, TOTAL_tCAL));

	}
	PV=FV;
	iBAL=(BAL*power(IPP, 1));
	TOTAL_PV+=PV-iBAL;

	tCAL=PV/power(1+IPP, (i+N_PART));
	TOTAL_tCAL+=tCAL;
	TOTAL_INT+=iBAL;

	BAL-=PV-iBAL;
	debug(strprintf("|%6.2d | $%23.2d | $%8.2d | $%8.2d | $%7.2d | $%7.2d |", i+N_PART, tCAL, PV-iBAL, iBAL, BAL, TOTAL_tCAL));


	/*****************************************************/
	debug(strprintf("+-------+--------------------------+-----------+-----------+----------+----------+"));
	debug(strprintf("| TOTAL | $%23.2d | $%8.2d | $%8.2d |", round(TOTAL_tCAL,2), TOTAL_PV, TOTAL_INT));
	debug(strprintf("+-------+--------------------------+-----------+-----------+"));
	return BAL;
}

define efr(PYR, PV, PMT, BN, N, N_PART){
	local tmp, r, i, dec;
	dec = 1/10;
	r = 0;
	do {
		for (i=9;i >= 0; i--){
			tmp = apr(r+(dec*i), PMT, BN, N, N_PART);
			if (round(tmp, 2) >= PV){
				r += (dec*(i));
				break;
			}
		}

		dec /= 10;

	}while(round(tmp, 2) != PV);
	return r*PYR*100;
}



define pmt(PV, FV, BE, IPP, N,N_PART){
	local A, A_T, B, PMT, PMT_EXP;

	A=power((1+IPP), N)-1;
	A_T=power((1+IPP), N+N_PART)-1;
	B=(1+IPP*BE)/(IPP);
	debug(strprintf("A = %d, B = %d", A,B),2);

	PMT = (FV+PV*(A_T+1))/(A*B);

	PMT_EXP = (FV+PV*((power((1+IPP),(N+N_PART))-1)+1))/(((power((1+IPP),N))-1)*((1+IPP*BE)/(IPP)));;
	return PMT;
	

}
define FV(PV, PMT, BE, IPP, N , N_PART ){
	local FV;
	FV=((IPP*(power((IPP+1),(N+N_PART)))*PV+((power((IPP+1),N))*(-BE*IPP-1)+BE*IPP+1)*PMT)/IPP);
	return FV;
}

define interest(PV, IPP, N){
	return PV*power(1+IPP, N);
}

define Const_tvm(PV, PYR, PMT, BE, I, N_PART, N)
{
	debug(strprintf("=================TVM on Fixed Payments ==============="),1);
	debug(strprintf("Days = %.d, N = %.d", ((N-1)+N_PART)*(365/PYR), N),2);
	local FV, IPP, TIP, WEEKLY_PAYMENT V, N_REAL, APR;
	N_REAL=N+N_PART;
	IPP=I/PYR;
	FV= FV(PV, PMT, BE, IPP, N, N_PART);
	TIP=PMT*N+(FV+PMT);
	WEEKLY_PAYMENT=TIP/N;
	V=PMT;	
	debug(strprintf("Principal Final..............= $%d", interest(PV, IPP, N_PART)),2);
	debug(strprintf("Principal....................= $%d", PV),2);
	debug(strprintf("Payments Per Year............=  %d", PYR),2);
	debug(strprintf("Future Value.................= $%d\n", FV),1);
	debug(strprintf("Begin/End....................=  %s", BE==1 ? "Beginning" : "End"),2);
	debug(strprintf("Interest Rate................=  %d %%", I*100),2);

	debug(strprintf("Weekly payment...............= $%d\n", V),1);
	debug(strprintf("TOTAL being Repaid...........= $%d\n", round(TIP,2)),2);
	APR=apr(IPP, PV, V, 1, N, N_PART, FV);
	assert(round(APR,2),0);
		debug(strprintf("APR Balence..................= $%d", APR),1);
	

	return FV;
}

define tvm(PV, PYR, FV, BE, I, N_PART, N)
{
	debug(strprintf("===================TVM on worked out payments ============================\n"),1);
	debug(strprintf("Days = %.d, N = %.d, N_PART = %d", ((N-1)+N_PART)*(365/PYR), N, N_PART),2);
	local PMT, IPP, TIP, WEEKLY_PAYMENT V, N_REAL, APR;
	N_REAL=N+N_PART;
	IPP=I/PYR;
	PMT= pmt(PV, -FV, BE, IPP, N, N_PART);
	TIP=PMT*(N)+(FV+PMT);
	WEEKLY_PAYMENT=TIP/N;
	V=PMT;
	debug(strprintf("Principal Final..............= $%d", interest(PV, IPP, N_PART)),2);
	debug(strprintf("Principal....................= $%d", PV),2);
	debug(strprintf("Payments Per Year............=  %d", PYR),2);
	debug(strprintf("Future Value.................= $%d", FV),1);
	debug(strprintf("Begin/End....................=  %s", BE==1 ? "Beginning" : "End"),2);
	debug(strprintf("Interest Rate................=  %d %%", I * 100), 2);

	debug(strprintf("Weekly payment...............= $%d", V),1);
	debug(strprintf("TOTAL being Repaid...........= $%d", round(TIP, 2)),1);
	APR=apr(IPP, PV, V, 1, N, N_PART, FV);
	assert(round(APR,2),0);
		debug(strprintf("APR Balence..................= $%d", APR),1);	return PMT;
}
define getFV(PV, PYR, PMT, BE, I, N_PART, N){
	local FV, newPMT;
	FV=Const_tvm(PV, PYR, PMT, BE, I, N_PART, N);
	newPMT=tvm(PV, PYR, FV, BE, I, N_PART, N);
	assert(newPMT, PMT);
}
DAY=7;
FORTNIGHT=14;
MONTH=30;
YEAR=365;

CalcFV=0;
PV=2;
PYR=52.18;
FV=0;
BE=1;
I=0.48;
PMT=40;
FSTPMT=8/7;
N=11;
define Main(){
	while(1){
		printf("Enter present value: ");
		scanf("%e", PV);
		printf("Enter payments per year (Weekly=52.18, etc): ");
		scanf("%e", PYR);

		printf("Enter interest rate as a percentage (i.e enter 0.48 for 48%%): ");
		scanf("%e", I);

		printf("Enter number of Payments: ");
		scanf("%e", N);
		
		printf("Enter time between first payment: ");
		scanf("%e", FSTPMT);
		
		printf("Enter future value: ");

		scanf("%e", FV);
		if (FV == 0){
			printf("Do you want me to calculate it for you?(Y/N): ");
			scanf("%s", CalcFV);
			if (CalcFV == "Y"){
				printf("Enter Payment Per period: ");
				scanf("%e", PMT);
				getFV(PV, PYR, PMT, BE, I, FSTPMT, N);
				continue;
			}
		}
		a=tvm(PV, PYR, FV, BE, I, FSTPMT, N);
	}
}
Main();
Last edited by B.E on Tue Oct 21, 2008 6:31 pm, edited 2 times in total.
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Re: Economics Problem.

Post by B.E »

I've solved the problem (finally) and will explain to you the result tomorrow (it's 11:40PM here).
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Re: Economics Problem.

Post by B.E »

Here's a few definitions

IPP is the interest rate per period.
N is the number of payments.
BE is when to make the payment in relation to the period (i.e 0 is the beginning, 1 is the end).
FV is the future value.
PV=Present value

Solution:

PMT (or the required amount per payment you are required to payback to payback the loan):

A=power((1+IPP), N)-1;
B=(1+IPP*BE)/(IPP);

PMT = (FV+PV*(A+1))/(A*B);

But PMT does not take into account a odd first period (for example if you wanted make the first weekly payment in 4 days).

So to solve this the revised formula is:

A=power((1+IPP), N)-1;
B=(1+IPP*BE)/(IPP);
C=power((1+IPP), N+N_PART)-1; // this adds the interest payable for the first payment

PMT = (FV+PV*(C+1))/(A*B);

Where:
N_PART is the total number of periods between the first day of the loan and the first payment.
NOTE: BE must be 1.

So with a bit of refactoring, we can then solve FV. So the formula becomes:

FV = ((IPP*(power((IPP+1),(N+N_PART)))*PV+((power((IPP+1),N))*(-BE*IPP-1)+BE*IPP+1)*PMT)/IPP);

NOTE: BE must be 1.

I've updated the above program to reflect the new formula
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
Post Reply