Integer Sequence Explorer

My integer sequence database explorer is finally up and running over at my website.  Essentially, this application allows the user to choose two integer sequences from many common sequences, then runs a query which selects common members from each sequence.

One of the interesting tasks has been to write many small applications which produce the sequences to be loaded into the database relations.  I started out a little too optimistic, and wrote code which calculated the first million primes, squares, sum of divisors, and others.  I quickly found that when I ran queries on these tables, they took way to long, and my server was timing out.  I incrementally scaled things back until I was left with the first 10,000 members of most sequences.  Now my task is to re-design the database to allow for larger searches.

I will be loading up more sequences over the next few weeks, and posting explanations and links for the sequences.

Object Oriented Factorization Program in PHP

I love actuarial stuff.  But, when I am learning any kind of new programming or mathematics, I always think number theory.

On my deathbed, I will probably not be thinking about loss ratios.  But I will be thinking about divisibility.  Number theory is the thing that originally drew me, and many others, to mathematics.

So, in the interest of learning PHP, I wanted to put a factorization application up on my website. But I wanted to be able to factorize more than one number at a time, so that one can observe the relationship between properties of different integers. So, I thought, what I want is several instances of the factorizer. That means writing an object oriented application.
You will observe below that the constructor does all of the work. That is because number theory stuff is very calculation intensive. Many of the variables, like phi, can be calculated as by-products of other calculations.

class DestructNumber
{ var $N;
private $sumofdivisors = 0;
private $divisorlist=array();
private $primedivisorlist=array();
private $primedivisorstring;
private $phi = 1;
// this constructor does all of the work
// that allows the utility to use a more efficient
// algorithm than a strictly obect oriented approach
// would allow

public function __construct($N) { $this->number = $N;
// find half of divisors
$counter = 1;
$end = floor(sqrt($this->number));
for ($m=1; $m <= $end;$m++ ) { if ($this->number%$m == 0)
$this->sumofdivisors=$this->sumofdivisors + $m;
//find other half of divisors
for( $m = $counter-1;$m > 0;$m--)
$quotient = $this->number/$this->divisorlist[$m];
if ($this->divisorlist[$m] != $quotient)
{$this->divisorlist[$counter] = $quotient;
$this->sumofdivisors=$this->sumofdivisors + $quotient;

// extract primes
for($m = 2; $m <= $counter-1; $m++) { if (DestructNumber::primep($this->divisorlist[$m]))
//find powers of primes
for ($m=1; $m <= $bar-1; $m++) { $power=1; $x = round(pow($this->primedivisorlist[$m][1], $power));

while ($this->number % $x == 0
&& $x <= $this->number)
$x = round(pow($this->primedivisorlist[$m][1], $power));
$this->primedivisorlist[$m][2] = $power-1;
// create prime divisor string
$this->primedivisorstring =””;
for ($m = 1; $m <= $bar-1;$m++) { $this->primedivisorstring .= $this->primedivisorlist[$m][1];
if ($this->primedivisorlist[$m][2]>1 )
{ $this->primedivisorstring .= ““.$this->primedivisorlist[$m][2].”“;
if ($m < $bar-1) {$this->primedivisorstring .= “*”;}
$this->phi = $this->phi * round(pow($this->primedivisorlist[$m][1], ($this->primedivisorlist[$m][2]-1)))*($this->primedivisorlist[$m][1]-1);

All of the work has been done by my constructor. Now, I just need some methods to return the values.

// define methods
private function primep ($N){
$stop = floor(sqrt ($N));
for ( $m=2; $m <= $stop; $m++) { if ($N%$m ==0) return 0; } return 1; } public function get_N(){ return $this->number;
public function get_sigma(){
return $this->sumofdivisors-$this->number;
public function get_numberdivisors(){
return count($this->divisorlist);
public function get_divisorstring(){
return $this->primedivisorstring;
public function get_phi(){
return $this->phi;
public function get_prime(){
return (count($this->divisorlist) == 2 ) ? "Yes" : "No";
public function get_perfect(){
return ($this->sumofdivisors == $this->number) ? "Yes" : "No";
public function get_square(){
return ( count($this->divisorlist)%2 == 1) ? "Yes" : "No";


There are some fun things here. A number is prime if it has two divisors. A number is square if it has an odd number of divisors.
Here is the link for my web factorizer.

Next, I will be posting a database mining application to explore number properties.

A Simple Windows Application for Factorizing Integers

So, I spend so much time working and doing mathematics and walking the dogs that I don’t always spend much time on programming. But, over the last year, I have realized that everything that I need to make windows applications is already on my computer. I don’t need any fancy software: just a text editing program, and an open source compiler to compile from the command line.
So my first code that I am posting here is a C++ application for factorizing integers. It just runs in a window with no fancy GUI. But it factorizes numbers very nicely.

The link for the downloadable exe file is below the code.

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstdint>
#include <string>
//  #include <NTL/ZZ.h>  get this number theory stuff eventually

bool primep (int64_t N);

int main()
using namespace std;
std::string another ="N";
int64_t N;
int64_t divisorlist[1000];
int64_t primedivisorlist[100][3];
int64_t sumofdivisors =0;
int64_t phi=1;
int counter (1);
bool squarep (false);
cout<< "This application factors integers of up to seventeen digits."<<endl;
cout << "Enter an integer to be factored: " <<endl;
cin.ignore(32767, '\n');

for (int m=1; m<= floor(sqrt(N));m++ )
if (N%m == 0)

for(int m=counter-1;m> 0;m--)
int64_t quotient = N/divisorlist[m];
if (divisorlist[m] != quotient)
// now extract primes
int bar=1;
for(int m =2; m<=counter-1;m++)
if (primep(divisorlist[m]))
// now find powers of primes

for (int m=1; m<=bar-1; m++)
int power=1;
int64_t x = round(pow(primedivisorlist[m][1], power));

while (N % x ==0
&& x<=N)
x = round(pow(primedivisorlist[m][1], power));
cout<<N<<" = ";
for(int m =1; m<=bar-1;m++)

if (primedivisorlist[m][2]>1 )
cout<< "^"<< primedivisorlist[m][2];
if (m<bar-1) cout<<"*";
phi=phi*round(pow(primedivisorlist[m][1], (primedivisorlist[m][2]-1)))*(primedivisorlist[m][1]-1);

cout<< "Number of divisors: "<<counter-1<<endl;
cout<<"The divisors are: "<<endl;
for(int m =1; m<=counter-1;m++)
cout<<divisorlist[m]<<" ";
sumofdivisors = sumofdivisors+divisorlist[m];
cout<<"The sum of the aliquot divisors of "<<N<<" is "<<sumofdivisors-N<<". Hence, this number is ";
if (sumofdivisors >(2*N)) {cout<<"abundant. "<<endl;}
else if (sumofdivisors<(2*N)){cout<<"deficient. "<<endl;}
else {cout<<"perfect. "<<endl;}

cout<<"Phi, the number of integers less than and relatively prime to "<<N<<" is "<<phi<<endl;
cout<<N<<" is ";
if (primep (N))
cout<<" ";
else cout<<"not ";
squarep = (counter-1)%2;
cout<<N<<" is ";
if (squarep)
cout<<" ";
else cout<<"not ";
cout<<"a perfect square."<<endl;
cout<<"Another number? ";

std::getline(std::cin, another);
while ((another == "yes") || (another == "y"));

return 0;

bool primep (int64_t N)

//returns t if N is prime
for (int m=2; m<= floor(sqrt (N)); m++)
if (N%m ==0) return false;
return 1;

The code is very simple and self-explanatory.  It is not the most efficient and beautiful way to factorize a number, but it works well enough within the realm of integers that can be easily handled by the base C++ variable types.

Here is the link for the exe file:


Multi-Period Binomial Options

Here is my latest program for calculating the prices of options using a multi-period binomial tree. It works, but represents a bunch of strange methods to solve unexpected problems.
First, I decided to calculate the price at each node by finding the price at the terminal nodes, then use a formula, rather than calculate the prices recursively. This technique, as you will see, led to the problem of calculating binomial coefficients.

The thing that I am most satisfied with is that I was able to get the program to output to a text file, which can be opened in Excel to visualize the data.  The only thing that the program does not do is to do the same calculation with the Black-Scholes formula, and visualize how the binomial calculation approaches the Black-Scholes result.

First, take a look at my output:

Binomial Pricing

We can see how the results approach a limit with each iteration.  The pricing for periods 34 and 35 is starting to get weird because of limits of integer sizes and floating point number sizes.

Here is a chart of the above data:

Binomial Option Tree

Finally, here is the code:

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <fstream>

//Calculates price of European call or put option, and portfolio required to duplicate option, using binomial tree

int nchoosek(int n,int k);
//choice holds the binomial tree so that it doesn’t need to be recalculated
unsigned long long choice [50][50]={};

int main() {
using namespace std;
float S0, r,div, K, h,t,sigma, u, d,pStar, uS,dS,Cu,Cd,delta, bondValue;
double optionPrice;
double prices [50];
int n;
string callPut;
int putTrue;
//fill in nchoosek tree
for (int m=1; m<50;m++)
{ choice [m][0]=1;
choice [m][m]=1;}
for (int m=2;m<(50);m++)
{ for (int l=1;l<m;l++){
//get data from user
cout<<“Calculate the price of a European call or put, using a one period binary tree, then find rate with n period tree.”<<endl;
cout<<“Current Stock Price?”;
cout<<“Continuously Compounded Risk Free Rate?”;
cout<<“Continuous Dividend Rate?”;
cout<<“Strike Price?”;
cout<<“Time to Expiration?”;
cout<<“Number of Periods? (less than 50 please)”;
cout<<“Call or Put?”;
if ((callPut == “put”)||(callPut==”p”))
else putTrue=1;
//calculate likely upward and downward motions
cout<<“Upward Move “<<uS<<endl;
cout<<“Downward Move “<<dS<<endl;
//calculate payoff of call, given motions above
//the variable putTrue turns Us-K into K-Us.  Cool.
Cu=fmax(0, putTrue*(uS-K));
Cd=fmax(0, putTrue*(dS-K));
//calculate Delta, Beta, and call option price
delta=exp(-div * t)*(Cu-Cd)/(S0*(u-d));
bondValue=exp(-r * t)*((u*Cd)-(d*Cu))/(u-d);
cout<<“To duplicate the option, buy “<<delta<<” shares=”” of=”” the=”” stock=”” for=”” “<<delta*s0<<“=”” dollars=”” and=”” borrow=”” “<<-1=”” *=”” bondvalue<<“=”” at=”” rate=”” “<<r<<“=”” a=”” total=”” price=”” “<<optionprice<<<span=”” class=”hiddenSpellError” pre=”” data-mce-bogus=”1″>endl;
cout<<“Price of Option “<<optionPrice<<endl;
cout<<“Prices above 30 levels deep may accumulate errors wildly”<<endl;

//Multi Period tree
int j=1;

for (int m=0; m<(j+1); m++) {
//This is the big doozy.
//Instead of computing the price at each interior node, only the terminal nodes are calculated
//and the price is found using the binomial theorem
optionPrice=optionPrice+nchoosek(j,m)*pow(pStar,j-m)*pow((1-pStar),m)*fmax(0,(putTrue* ((S0*pow(u, j-m)*pow(d,m))-K)));
prices [j]=optionPrice;
cout<<“Periods: “<<j<<”  “;
cout<<“Option Price:  “<<optionPrice<<endl;
++j;  }

//output prices to text file
//open the text file in excel
//data is delimited by commas
ofstream outf(“Results.txt”);
if (!outf)
{  cerr << “File Error”<<endl;
exit(1); }
outf<<“Depth of Tree”<<“,”<<“Price”<<endl;
outf << j <<“,”<< prices[j]<< endl;
++j;  }
return 0;}

int nchoosek(int n, int k)
{ if (n>49 ||k>49)return 0;
else { return choice[n][k]; }}

The heart of everything is this ugly beast:

optionPrice=optionPrice+nchoosek(j,m)*pow(pStar,j-m)*pow((1-pStar),m)*fmax(0,(putTrue* ((S0*pow(u, j-m)*pow(d,m))-K)));

This is better put as C=C+\binom j m p^{*^{j-m}}(1-p*)^m*max(0,put(S_ou^{j-m}d^m-K)

You can figure out why this works fairly easily.  I like the bit where I multiply (F_{0,T}-K) by -1 to get (K-F_{0,T}.

More than anything, this exercise shows how errors creep into these long calculations.  Looking at the graph, you can see how our numbers are already wandering away from the correct numbers after the 20th iteration.

A Simple C++ Program for Computing Binomial Option Prices

I have been advised that C++ and VBA are commonly requested languages for actuaries. So, while I am studying for exam MFE, I have been writing simple programs.  My native language is LISP.  I like its beauty, and its adaptability.  I am sure that C++ has its promoters, but I think that it is a shame that such an ugly programming language has become one of the most used.

Of course, I am still a novice to the language, so my code is still extra ugly.

Computes call price using binomial model:

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <iomanip>

//Calculates price of call option, and portfolio required to duplicate option, using binomial tree

int main() {
using namespace std;
    float S0, r,div, K, h, sigma, u, d, uS,dS,Cu,Cd,delta, bondValue, callPrice;
//get data
    cout<<“Calculate the price of a call, using a one period binary tree”<<endl;
    cout<<“Current Stock Price?”;
    cout<<“Continuously Compounded Risk Free Rate?”;
    cout<<“Continuous Dividend Rate?”;
    cout<<“Strike Price?”;
    cout<<“Time to Expiration?”;
//calculate likely upward and downward motions
    cout<<“Upward Move “<<uS<<endl;
    cout<<“Downward Move “<<dS<<endl;
//calculate payoff of call, given motions above
    if (uS > K)
    Cu = uS-K;
    else Cu = 0;
    if (dS > K)
    Cd = dS-K;
    else Cd = 0;
//calculate Delta, Beta, and call option price
    delta=exp(-div * h)*(Cu-Cd)/(S0*(u-d));
    bondValue=exp(-r * h)*((u*Cd)-(d*Cu))/(u-d);
    cout<<“To duplicate the call, buy “<<delta<<” shares=”” of=”” the=”” stock=”” for=”” “<<delta*s0<<“=”” dollars=”” and=”” borrow=”” “<<-1=”” *=”” bondvalue<<“=”” at=”” rate=”” “<<r<<“=”” a=”” total=”” price=”” “<<callprice<<<span=”” class=”hiddenSpellError” pre=”” data-mce-bogus=”1″>endl;
    cout<<“Price of Call “<<callPrice<<endl;

//find the price of some other related calls
    cout<<“Some other Call prices: “<<endl;
    float step;
    step = 0.05*K;
    K= K-5*step;
       for (int z=0;z<11;z++){
       if (uS > K)
    Cu = uS-K;
    else Cu = 0;
    if (dS > K)
    Cd = dS-K;
    else Cd = 0;

    delta=exp(-div * h)*(Cu-Cd)/(S0*(u-d));
    bondValue=exp(-r * h)*((u*Cd)-(d*Cu))/(u-d);

    cout<<setw(8)<<k<<” “<<callprice<<<span=”” class=”hiddenSpellError” pre=”” data-mce-bogus=”1″>endl;
    return 0;
//Wow what an ugly program

Here is a sample run:

Binomial option pricing

Problems in the Queue

A week left until the financial mathematics exam. The best thing that I can say is that I can honestly not have worked any harder at studying. In the last three months, I have studied at least three hours a day, and frequently I have done eight to ten hours a day. Much of that time has been absolutely focused. The question is: have I studied as smartly as possible? I won’t know the answer to that until after the examination.

I have done about two hours of problems today. I see that there are 19 problems remaining in the queue. These are problems that I have seen before, and that I still wish to spend some time with. I spend enough time with each problem that I feel I am confident that I understand several ways to get to a solution, or until I get sick of looking at it. If I get sick of looking at it, it comes up on the queue again later today or tomorrow. If I am fluent with it, I don’t look at it for a few days. Eventually, it disappears from the queue.

Earlier today, I already did some easy numerical exercises. Later today, I will probably do an exam, which is a whole other kind of problem solving, because of time pressure (5 minutes per problem.)

What I am going to do here is type in problems as they come up on my screen, then write up solutions. If I don’t understand the problem, you will get to watch me struggle.

Person X enters into a long forward contract. If the spot price at expiration were S, the payoff would be -20. If the spot price at expiration were 1.2S, the payoff would be X.

Person Y enters into a short forward contract. If the spot price at expiration were 0.8S, the payoff would be 40. If the spot price at expiration were 1.1S, the payoff would be Y.

The forward price on each contract is the same.

What is X+Y?

We aren’t going to do a diagram for this one. I tried, on paper, and since we don’t know the values of 0.8S, 1.1S, or 1.2S, it is hard to know where to place them in relation to the forward price. So, let’s go with straight algebra, and see if that leads us to a reasonable solution.

Payoff on Long Forward = S – F

Payoff on Short Forward = F – S

From Givens:

S-F = -20 \\    1.2S=S=X \\    F-0.8S=40 \\    F-1.1S = Y

Add equations 1 and 3 to get S=100. Then solve for F and get F=120.

Using equations 2 and 4:

X+Y = 1.2(100)-120+120-1.1(100) = 10

That wasn’t too bad. These derivative problems can be a little intimidating at first.

A 15 year bond with semiannual coupons has a redemption value of $100. It is purchased at a discount to yield 10% compounded semiannually. If the amount for accumulation of discount in the 27th payment is $2.25, which of the following is closest to the total amount of discount in the original purchase price?

We have all sorts of information here, so it should be easy to get to an answer. First, since the coupons are semiannual, we can just think entirely in 6 month terms. Since the bond is sold at a discount, we know that the coupon rate is less than the interest rate. We know that we can solve this problem by finding the original purchase price, and subtracting it from the redemption price. First, we need the coupon, which we can find using the premium discount formula.

Let’s start with that. Assuming that F=C, the amount of discount in the kth payment is:


Here are our givens:

n=30 \\    F=C=100 \\    i=0.1 \\    F(i-r)v^{n-1+k} = 2.25 \\    100 (0.05-r)1.05^{-(31-27)} = 2.25 \\    r=0.02265 \\

Now solve for the original sale price. We might as well continue with the premium discount formula:

P = C+(Fr-Ci) a_{\overline{n}\lvert } \\    P=100-0.2735\frac{1-1.05^{-30}}{0.05} \\    P=57.96

Discount in original price = 42.04.

Let’s just do one more.

To accumulate 8000 at the end of 3n years, deposits are made at the end of the each of the first n years and 196 at the end of each of the next 2n years.  (1+i)^n = 2.

What is n?

These problems are much simplified by visualizing them in the right way. The easiest way to think of it is payments of 98 from 1 to 3n years, plus payments of 98 in years 2n+1 through 3n.

In math:

98s_{\overline{3n}\lvert }+98_{\overline{2n}\lvert }=8000 \\    \frac{(1+i)^{3n}}{i} + \frac{(1+i)^{2n}}{i}=81.633 \\    \frac{2^3-1}{i} + \frac{2^2-1}{i} = 81.633 \\    i= 12.25%

I am going to post one more, because it is a real bear. To solve it, you trust that the math will lead you to the answer.

Given a k year bond with semiannual coupons, and a yield rate of 10% convertible semi-annually, sold at a price p.

If the coupon rate had been r-0.04, the price would be P-200.

Calculate the present value of a 3k year annuity immediate paying 100 at the end of each 6 month period, at a rate of 10% semiannually.

Start at the end. We need to find:

100 \frac{1-1.05^{-6k}}{0.005}

Which means that what we really need is k (although v^k will do).

Dive in:

P=1000\frac r 2 \frac{1-1.05^{-2k}}{0.05}+1000(1.05)^{-2k} \\    P-200 = 1000\frac{r-0.04}{2}\times \frac{1-1.05^{-2k}}{0.05}+1000(1.05)^{-2k} \\    \text{We can see that the redemption values will not be significant}\\    1000 \frac r 2 a_{\overline{2k}\lvert }=1000 \frac{r-0.04}{2}a_{\overline{2k}\lvert }+200 \\    1000 \frac r 2 a_{\overline{2k}\lvert }-1000 \frac{r-0.04}{2}a_{\overline{2k}\lvert }=200 \\    500a_{\overline{2k}\lvert }(r-r+0.04)=200 \\    a_{\overline{2k}\lvert } = 10 \\    k = 7.1 \\    100 \frac{1-1.05^{-6\times7.1}}{0.05} =1749.75

Forward Contracts

The thing about math at a certain level is that there are no more easy exercises.  I have learned to make a habit of creating simple exercises.  These are for the forward price, which is the contracted price to buy an asset at time T in the future; and the prepaid forward price, which is the price paid now for an asset that will be delivered at time T.  In these problems, r is the continuous interest rate, and delta is the continuous dividend rate.
F^P_{0, T} = S_o = S_o -PV(divs) = S_0 e^{-\delta} T
F_{0, T} = S_0 e^{rT} = S_oE^{rT} - AV(divs) = S_0e^{(r-\delta)}T

  1. S_0 =1000, r=0.04, \delta = 0.01\quad F^P_{0, 6m}?
  2. S_0 =800, r=0.02, \delta = 0\quad F_{0, 2m}?
  3. S_0 =800, r=0.02, \delta = 0\quad F^P_{0, 2yr}?
  4. S_0 =500, r=0.04, \delta = 0\quad F_{0, 2yr}?
  5. S_0 =500, r=0.04, \delta = 0\quad F_{0, 6m}?
  6. S_0 =500, r=0.04, \delta = 0\quad F^P_{0, 1yr}?
  7. S_0 =100, r=0.03, \delta = 0.01\quad F^P_{0, 2yr}?
  8. S_0 =100, r=0.03, \delta = 0.01\quad F^P_{0, 3m}?
  9. S_0 =1000, r=0.04, \delta = 0.01\quad F_{0, 1yr}?
  10. S_0 =1000, r=0.04, \delta = 0.01\quad F_{0, 6m}?
  11. S_0 =800, r=0.02, \delta = 0\quad F^P_{0, 5m}?
  12. S_0 =100, r=0.03, \delta = 0.01\quad F_{0, 1yr}?
  13. S_0 =100, r=0.03, \delta = 0.01\quad F_{0, 9m}?
  14. S_0 =500, r=0.04, \delta = 0\quad F^P_{0, 9m}?
  15. S_0 =1000, r=0.04, \delta = 0.01\quad F^P_{0, 1yr}?
  16. S_0 =800, r=0.02, \delta = 0\quad F_{0, 1yr}?


  1. 1000e^{-0.01*0.5}=995.01
  2. 800e^{0.02*(\frac 1 6)}=802.67
  3. 800
  4. 500e^{.04*2}=541.64
  5. 500e^{0.04*.5}=510.10
  6. 500
  7. 100e^{-0.01 *2}=98.02
  8. 100e^{-0.01*0.25}=99.75
  9. 1000e^{0.04-0.01}=1030.45
  10. 1000e^{(0.04-0.01)*0.5} =1015.11
  11. 800
  12. 100e^{0.03-0.01}=102.02
  13. 100e^{(0.03-0.01)*0.75}=101.51
  14. 500
  15. 1000e^{-0.01}=990.05
  16. 800e^{0.02}=816.16

Later today, I will post some tougher ones that require a little thinking.

Don’t Let Yourself be Thrown By Easy Calculations

You have to calculate quickly on this exam. I didn’t really realize that until took my first practice examination.  I was cruising along on problem number 25, with forty minutes left to go.  No problem!

Then I looked at the upper corner of my screen and found that I still had ten problems to do!  There are 35 problems on this exam!  That is only a smidgen more than five minutes per problem!  Aaaahhhhhhhhh!!!!!!!!!!

Practice your calculations.  You need your time for problem solving: you don’t have time to recalculate when you get to a solution that is not one of the choices.  Practice your calculations.

  1. (Ia) _{\overline{15}\lvert 0.05}
  2. (Ia)_{\overline{5}\lvert 0.01}
  3. (Ia)_{\overline{12}\lvert 0.08}
  4. (Ia)_{\overline{20}\lvert 0.005}
  5. (Ia)_{\overline{10}\lvert 0.0425}
  6. (Ia)_{\overline{40}\lvert 0.1225}
  1. 73.67
  2. 14.46
  3. 42.17
  4. 196.22
  5. 41.32
  6. 70.86

The Tribulations of Calculations

81 days until exam FM.  I am spending most of my time plowing head-first into derivatives  markets, but I am also working random interest theory problems each day, as well as finishing up a thorough study of duration, volatility, and convexity.  Most of these problems present a calculation challenge.  For instance, as soon as a solution requires calculating an increasing annuity, trouble is near:

\displaystyle (Ia)_{\overline{n}\lvert }=\frac{\ddot a_{\overline{n}\lvert }-nv^n}{i}=\frac{\frac{1-v^n}{i}(1+i)-nv^n}{i}

This looks even prettier once you put some numbers into it (suppose that n=20 and i=0.09):

\displaystyle (Ia)_{\overline{20}\lvert }=\frac{\frac{1-(1.09)^{-20}}{0.09}(1.09)-20(1.09)^{-20}}{0.09}

For the duration of a bond, this calculation is just a small piece of the whole numerical birds-nest.  You might know just what needs to be calculated for a solution, but it is trouble to coax the right number out of the other end of a calculator.  It seems silly to get wrong answers for this reason, so I have been putting a little thought into the best ways to arrive at numerically correct answers.  My initial guess was that the best technique is to store a bunch of intermediate values in the calculator.

Let’s look the duration of a bond.  This quantity is

\displaystyle \frac{\sum tv^tCF_t}{\sum v^tCF_t}=\frac{Fr(Ia)_{\overline{n}\lvert }+Cnv^n}{Fra_{\overline{n}\lvert }+Cv^n}

The way I figure it, you are better off using the definition on the left for a bond with only a few coupon periods. Lets take a 4 year par value 1000 bond with 8% coupons and a 7% yield rate.  The left hand formula produces:

t vt CF
1 1.07-1 80
2 1.07-2 80
3 1.07-3 80
4 1.07-4 1080

Which yields: (technique #1)

\displaystyle \frac{1(1.07)^{-1}(80)+2(1.07)^{-2}(80)+3(1.07)^{-3}(80)+2(1.07)^{-4}(1080)}{(1.07)^{-1}(80)+(1.07)^{-2}(80)+(1.07)^{-3}(80)+(1.07)^{-4}(1080)}

That looks a little hairy.  But our alternative is this:  (technique #2)

\displaystyle \frac {80 (\frac{\frac{1-1.07^{-4}}{0.07}(1.07)-4(1.07)^{-4}}{0.07})+1000(4)(1.07)^{-4}} {80 (\frac{1-1.07^{-4}}{0.07})+1000(1.07)^{-4}}

That is much worse.

The moral of the story is: just because your TI-30XS multiview calculator allows you to create nice looking nesting fractions on the screen, doesn’t mean that you should always actually make those fractions.  To find durations, or convexities, using technique #1, we simply make a chart on paper, then multiply across the rows.  Using technique #2, we create a monstrous mess that is nearly impossible to trouble-shoot.  If we absolutely need to compute using technique #2, we need to store some intermediate values in calculator memories.  I usually store 1+i, a angle n, and v^n.  It is still treacherous.  I think I will post some practice exercises tomorrow.

Update: the Annuity Symbol on WordPress

A few months back, I was trying to get the annuity symbol to come out right in Latex. I got it working pretty good, but the hack that I used did not work on these blog posts.

At the time, I did not really put enough work into trying to get the annuity symbol to appear correctly just using standard ams symbols. But here it is:

a_{\overline{n}\lvert }
a_{\overline{n}\lvert }

\ddot{a}_{\overline{n}\lvert }
\ddot{a}_{\overline{n}\lvert }

There you have it.