Here are a few examples on pricing securities with a fixed maturity time. This code is mainly for illustrative purposes, and not optimized to run well.

Look simple? Well, there are a few traps we shouldn't fall for. For instance, we know range(S_n) has n+1 elements in it. Let's see how many elements are in our computed $\operatorname{range}(S_n)$ for $n=30$

Woops. I got 283 on my system. I should have gotten 31! What went wrong?

Turns out it's floating point errors. Mathematically $u(u^m d^n) = u^{m+1} d^n$ for any $u, d \in \mathbb R$. On computers this is false, due to round off errors. Let's check. (Note in Python $u^m$ is written as u**m.)

That gave false on my system, even though mathematically the identity is true...

How do you avoid this? There are a few ways. Here's a suggestion for one workaround: Instead of storing the floating point number $u^i d^j$ inside dom[n], why don't we just store the integers $(i, j)$. (Or even just $i$, since $j$ can be worked out from $i$ and $n$.) This will avoid all floating point errors. See if you can do this (or find a different approach that avoids these floating point errors).

If you can't find a way to do this, no worries: the floating error you make is super small (about $10^{-17}$). So the price of your security will likely be correct to a few decimal places. The real cost is the run time! Due to round off errors, dom[n] will grow much faster than it should. So if we wanted $N = 1000$, say, this algorithm may not finish as quickly as you would like. Try setting $N = 1000$ above for instance. (Good code will handle that instantly; bad code may not finish...)

We had an algorithm to price this in class. Choose the state process $Y = (S, M)$, where $M$ is the running maximum, and write the price in the form $V_n = f_n( S_n, M_n)$ and use the recurrence relation $$ f_{n}(s,m) = \frac{1}{1+r} \bigl( \tilde p f_{n+1}(us, m \vee (us) ) + \tilde q f_{n+1}(ds, m \vee (ds) \bigr) $$ To code this up, note that if $m \geq U$, the price is always $0$. So We only need to find the price when $m < U$. We also only need to keep track of the stock price when it is below $U$. Turns out, we won't even have to keep track of the range of $M$, and can simplify the above to $$ f_n(s) = \frac{1}{1+r} \bigl( \tilde p f_{n+1}(us) 1_{us < U} + \tilde q f_{n+1}(ds) 1_{ds < U} \bigr) $$