Business::US_Amort
Business::US_Amort - class encapsulating US-style amortization
use Business::US_Amort;
my $loan = Business::US_Amort->new;
$loan->principal(123654);
$loan->interest_rate(9.25);
$loan->term(20);
my $add_before_50_amt = 700;
sub add_before_50 {
my $this = $_[0];
if($this->{'_month_count'} == 50) {
$this->{'_monthly_payment'} += $add_before_50_amt;
}
}
$loan->callback_before_monthly_calc(\&add_before_50);
$loan->start_date_be_now;
$loan->run;
$loan->dump_table;
print "Total paid toward interest: ", $loan->total_paid_interest, "\n";
This class encapsulates amortization calculations figured according to what I've been led to believe is the usual algorithm for loans in the USA.
I used to think amortization was simple, just the output of an algorithm that'd take just principle, term, and interest rate, and return the monthly payment and maybe something like total paid toward interest. However, I discovered that there's a need for loan calculations where, say, between the 49th and 50th month, your interest rate drops, or where you decide to add $100 to your monthly payment in the 32nd month.
So I wrote this class, so that I could amortize simply in simple cases while still allowing any kind of strangeness in complex cases.
This module provides one function, which is a simple amortizer. This is just to save you the bother of method calls when you really don't need any frills.
Amortizes based on these parameters. In a scalar context, returns the initial monthly payment.
In an array context, returns a three-item list consisting of: the initial monthly payment, the total paid toward interest, and the loan object, in case you want to do things with it.
Example usages:
$monthly_payment = Business::US_Amort::simple(123654, 9.25, 20);
($monthly_payment, $total_toward_interest, $o)
= Business::US_Amort::simple(123654, 9.25, 20);
Of course, if you find yourself doing much of anything with the loan object, you probably should be using the OOP interface instead of the functional one.
All attributes for this class are scalar attributes. They can be read via:
$thing = $loan->principal OR $thing = $loan->{'principal'}
or set via:
$loan->principal(VALUE) OR $loan->{'principal'} = VALUE
These attributes are used as parameters to the run method.
The annual rate, expressed like 8.3, not like .083.
Note that if you're defining callbacks, you can change this attribute at any time in your callbacks, to change the rate of interest from then on.
run from adding to table. (This
is false by default.) If you're not going to access table, set this
to true before calling run -- it'll speed things up and use less
memory.
_date will be defined
appropriately for each month. You can set start_date to the current
month by just saying $loan->start_date_be_now.
These attributes are set by the run method:
_monthly_payment.
This will be a reference to a list of copies made of the object ("snapshots") each month. You can then use this if you want to generate a dump of particular values of the object's state in each month.
Note that snapshots have their am_snapshot attribute set to true,
and have their table attribute set to undef. (Otherwise this'd be
a circular data structure, which would be a hassle for you and me.)
A string explaining any error that might have occurred, which would/should
accompany run returning 0. Use like:
$loan->run or die("Run failed: " . $loan->error);
Other attributes:
table.
run method sets this to twelve plus twice the number
of months that it's expected this loan will take.
Increase as necessary.
These are attributes of little or no interest once run is done, but
may be of interest to callbacks while run is running, or may
be of interest in examining snapshots in table.
_abort to true. You may also choose
to set error to something helpful.
initial_monthly_payment is
figured to be, but you can manipulate _monthly_payment with
callbacks to change how much actually gets paid when.
start_date to something, this will be undef.
Creates a new loan object.
Copies a loan object or snapshot object. Also performs a somewhat deep copy of its table, if applicable.
Destroys a loan object. Probably never necessary, given Perl's garbage collection techniques.
This sets start_date to the current date, based on $^T.
This performs the actual amortization calculations.
Returns 1 on success; otherwise returns 0, in which case you should
check the error attribute.
This method dumps a few fields selected from snapshots in the table
of the given object. It's here more as example code than as anything
particularly useful. See the source. You should be able to use this
as a basis for making code of your own that dumps relevant fields from
the contents of snapshots of loan objects.
When in panic or in doubt, run in circles, scream and shout.
Or read the source. I really suggest the latter, actually.
* There's little or no sanity checking in this class. If you want to amortize a loan for $2 at 1% interest over ten million years, this class won't stop you.
* Perl is liable to produce tiny math errors, like just about any other language that does its math in binary but has to convert to and from decimal for purposes of human interaction. I've seen this surface as tiny discrepancies in loan calculations -- "tiny" as in less than $1 for even multi-million-dollar loans amortized over decades.
* Moreover, oddities may creep in because of round-off errors. This seems to result from the fact that the formula that takes term, interest rate, and principal, and returns the monthly payment, doesn't know that a real-world monthly payment of "$1020.309" is impossible -- and so that ninth of a cent difference can add up across the months. At worst, this may cause a 30-year-loan loan coming to term in 30 years and 1 month, with the last payment being needed to pay off a balance of two dollars, or the like.
These errors have never been a problem for any purpose I've put this class to, but be on the look out.
This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.
But let me know if it gives you any problems, OK?
Copyright 1999-2002, Sean M. Burke sburke@cpan.org, all rights
reserved. This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
Sean M. Burke sburke@cpan.org