007 - Pure, Functional, Financial Python Katas

Perhaps the main way programming diverges from mathematics is state mutability.

In maths you can set and forget x's.

When programming algorithms we have to carefully shepherd our x's from the beginning to the end of our program.

Flexibility can be good, but it can also be bloody annoying, when I set and believe an x to be one thing, only to have it change somewhere - somewhere - in my code.

Setting and forgetting, i.e. only using immutable data, is one advantage of only using lambdas in Python. Once we set a lambda, we cannot mutate it.


In [1]: a = lambda: [0,1,2,3,4,5]

and let's try 'popping' off the last element in the array,

In [2]: a().pop()  
Out[2]: 5  

and we can pop over and over, and still get the same result - '5'.

In [3]: a().pop()  
Out[3]: 5  

Why? Because the lambda is our rock, it always equals the same array.

Now, you could of course set a equal to something else, overwriting our lambda completely, and unfortunately Python allows this, but at least we have some measure of safety.

There is also a second reason why constants are important.

In anything but the simplest code we will have two pieces of logic sharing state. If they share fungible state serious accidents will occur. Immutable state ensures that we can only at best copy immutable shared state and then work upon it, there is no chance that we have two processes meddling with each other's data.


Paul Wilmott claims in his book, that we really only need 3 (or 4) ideas in maths to understand all of financial mathematics. Let's practice our immutable lambdas with two of these salient ideas.


Firstly, compound interest.

principle * e^rt

A sum of cash in a bank account, say $100, will be equal to $100exp^(0.012) at a interest rate of 1% over 2 years.

We can represent a fixed cash account which accrues 1% per annum over 10 years by the following dictionary.

In [1]: c = lambda: {'principle':100,'rate':0.01,'maturity':10}

First task is to show how the principle increases as the years march on. Of course we cannot change the lambda as it is immutable, so we will need to produce a list of 10 lambdas. The principle will increase as maturity decreases.


Secondly. Logarithms are the inverse of e, in a sense.


In [1]: math.log(math.exp(1))  
Out[1]: 1.0  

While math.exp or 'e' can generate future returns, 'ln' or logarithms, deconstruct past returns (in fact it's the only safe way to do so!).

The second task is the take the daily prices we found in kata 004 and generate logarithmic returns from them.


The third piece of maths that is indispensable is the Taylor Series.

Unfortunately, the Taylor series belongs to the realm of ideas which are infinite in nature, or at least sometimes don't have well defined stopping points. In the jargon, they are not total functions as they are not guaranteed to stop in finite time.

Non-total functions are very common, but unfortunately not possible when confining ourselves to using Python's lambdas.

Soon we will have to leave lambdas behind.


(The fourth piece of maths is taking expectations - more to come on that soon also!)