Assignment 2, CSC458, Spring 2010
1 Assignment
This week, we’re going to model the elements of financial analysis by representing them as values in F#.
2 Events
First, we’re going to model a single coin flip using a boolean; we’ll call it an event1:
type event1 = bool |
Next, we’re going to model events (that is, whole events) as mappings from timesteps to event1s:
type event = int -> event1 |
With these definitions, define the events eAllHeads that corresponds to always flipping heads and eAllTails that corresponds to always flipping tails. Next, define the eAlternating event that corresponds to a head on even-numbered timesteps, and a tail otherwise.
Next, we’d like the ability to define a random event. However, a particular event is fixed, so it must be the case that if a given event signals a Head at time 57, that it always signals a Head at time 57. Define the makeERandom function that produces a random event, defined as follows: the mapping from timesteps to flips is random, chosen with the Next method of a Random object, but each flip must be remembered by that event, so that every subsequent query to the event at that timestep produces the same flip that was chosen first for that timestep. You probably want to use a hash table for this.
Operationally, suppose that I define two random events, like this:
let eRandom1 = makeERandom() |
let eRandom2 = makeERandom() |
Suppose further that I sample these two events at step 57, twice each.
let t1 = eRandom1 57 |
let t2 = eRandom1 57 |
let t3 = eRandom2 57 |
let t4 = eRandom2 57 |
The requirement is that t1 = t2 and that t3 = t4, but not that t1 = t3
Next, we’d like to be able to define events with different probability measures.
Develop the makeERandP function, that accepts the likelihood of a head and produces a random event otherwise similar to that produced by makeERandom that has a ’p’ chance of containing a head at each position (naturally, p must be in the range [0,1]).
Next, we’d like one exotic ’trending’ probability measure, where each flip has a 75% chance of being the same as the prior one, and the probability of a head on the initial flip is 50%. Call this event generator makeERandT.
Finally (this will help with test cases), we’d like to be able to force certain parts of an event to match some given set of outcomes. Define forceEParts that consumes a timestep t and an array of booleans ba and an event and produces a new event that is like the old one but has the sequence of values specified by the array "pasted in" at the given timestep. More specifically, for a timestep n such that t <= n < t + (Array.length ba), the event should contain the flip ba.[n-t] . Note that the original event must be unchanged.
3 Random Variables
A random variable is a map from an event to a real number (remember: this is the one thing that you’re learning in this class).
type rv = event -> double |
The simplest random variables are those whose values are constant. Define the doubleToRV function that consumes a floating point number and produces the random variable whose value is always the given number.
Next, there’s the random variable that counts the number of heads at time n. Define rvNCountHeads, the random variable that consumes a number n of timesteps and produces the random variable that evaluates to the number of heads that have occurred in the event in time steps 0 through n-1.
For symmetry, define its dual, rvNCountTails.
4 Modeling Finance entities
First, we want to be able to talk about families of random variables, indexed by time. We can do this with an rvseq type:
type rvseq = int -> rv |
An rvseq represents a sequence of random variables.
Next, let’s define our classic stock model: develop rvNStock, that consumes a value for the parameter u that multiplies the stock on the flip of a head, a value for the parameter d that multiplies the stock on the flip of a tail, an initial value for the stock, and a number of timesteps, and produces a random variable representing the price of the stock on a given event.
But wait! By currying, notice that since the last argument is the integer, we have in fact just defined a function that maps u, d, and the initial price to an rvseq. Neat!
Also, we’d like to define a path-dependent random variable rvPathD that represents a random variable whose value is 10 times the number of heads that occurred a multiple of 3 flips ago. So, at time step 102, if the 99th flip was a head and the 93rd flip was a head and all the others were tails, the value of this random variable would be 20. Since (like the prior function) this one depends on a timestep, it’s an rvseq, rather than a random variable.
Finally, we want to be able to manipulate random variables by plugging them into larger equations. Generally, these larger equations can be represented as functions from one or more doubles to another double. Develop the function unaryLiftRV that consumes a unary function on doubles and a random variable and "plugs in" the random variable, producing another random variable. For instance, plugging a CountHeads random variable into the function x^2 + 4 should produce a random variable that takes on the value of the square of the number of heads, plus four. After this, define binaryLiftRV, that performs the same service for binary functions.
5 Options and Delta Hedging
First, define putOptionPayoff, that consumes a double strike representing the strike price and a double stock representing the price of a stock at the option’s expiry and returns a double representing the value of a put option with the given strike at expiry.
For symmetry, define callOptionPayoff, with the same type, representing a call option.
Next, develop the optionValue function that computes an rvseq representing the value of an option. This function should accept a stockmodel (see type below) containing the parameters that make up the binomial stock model, a number of time periods until expiry, and an option and produces an rvseq representing the value of the option at each point in time.
To go along with this, develop the delta function that accepts an rvseq representing the stock prices and an rvseq representing the option values and returns an rvseq indicating how many shares of the underlying stock you need to buy in order to hedge (not replicate, but hedge) the given option using a risk-neutral strategy. N.B.: The difference between hedging and replicating is just one of sign. If you need to buy 3 shares of the stock to replicate the option, then you would *sell* 3 shares of the stock to hedge it.
To see whether this makes any sense, develop the illustration function. It accepts a stockmodel and a number of timesteps and an option and an event, and produces printed output (printf) )showing how starting with the initial value of the option, an investor would buy and sell shares along the given event’s path in order to produce the same result as buying the option.
6 Types and Contracts
Here are the types we defined:
type event1 = bool |
type event = int -> event1 |
type rv = event -> double |
type rvseq = int -> rv |
type option = double -> double |
type stockmodel = (double * double * double * double) // u, d, 1+r, and S_0 |
Here are the types of the required definitions. Add this to the end of your file to make sure that your definitions have the required types:
(eAllHeads : event) |
(eAllTails : event) |
(eAlternating : event) |
(makeERandom : unit -> event) |
(makeERandP : double -> event) |
(makeERandT : unit -> event) |
(forceEParts : int -> bool array -> event -> event) |
|
(doubleToRV : double -> rv) |
(rvNCountHeads : int -> rv) |
(rvNCountTails : int -> rv) |
|
(rvNStock : double -> double -> double -> rvseq) |
(rvPathD : rvseq) |
(unaryLiftRV : (double -> double) -> rv -> rv) |
(binaryLiftRV : (double -> double -> double) -> rv -> rv -> rv) |
|
(putOptionPayoff : double -> option) |
(callOptionPayoff : double -> option) |
(optionValue : stockmodel -> int -> option -> rvseq) |
(delta : rvseq -> rvseq -> rvseq) |
(illustration : stockmodel -> int -> option -> event -> ()) |
|
|
7 Testing
You must test your code thoroughly. You will lose credit for functions that are not tested.
8 Parters
I would encourage you to tackle this assignment with a partner.
9 Handin
DeltaHedging |
10 Disclaimer
There may well be bugs in this assignment. Let me know right away if you find some!