A common problem in financial engineering is to determine the value of a financial option, that is, the right to collect an uncertain future payoff. In this example, we value a path-dependent option known as the Asian (or average value) call option.
A stock's price
S(ti)
is observed at a finite number
m
of increasing times ti. The average price of
this stock is:
avgPrice = [S(t1) + S(t2) + … + S(tm)]/m.
tm
(the option's maturity), the option holder (buyer)
receives a final payoff that equals the amount by which the
observed average price exceeds a given exercise price
E
. In Hava, this is expressed as:
payoff = max(avgPrice - E, 0).
E = 9.50.
If the observed stock prices are 10.00, 10.80, 11.25,
10.28, 9.59, 8.92, then the final payoff is
max(10.14-9.50, 0) = 0.64.
We use a
binomial lattice
to describe the evolution of stock prices: Next period's
stock price either goes up by a factor
U
with probability
q
or goes down by a factor
1/U
with probability
1-q
.
The values for
U
and
q
are derived from basic parameters in the conventional way:
S0 = 10; // initial price
sigma = 0.5; // annual volatility
dt = 1/52; // period length in years
K = 26; // number of periods in lattice
r = 0.02; // annual interest rate
The option's market value today is simply the discounted expected value of the final payoff, where the discount factor is determined from these same parameters:
beta = exp(-r*K*dt); // discount for option duration
Since the evaluation of the option's value requires a computation of an expectation (or average) of a function of a price path, Monte Carlo simulation is a convenient approach. The steps in a Monte Carlo simulation are:
The random event at each period is either "Stock price goes up" or "Stock price goes down". We represent each of these outcomes as a Hava structure that contains both the probability that the outcome will occur, and the price multiplier with which it is associated. Then we place the two outcomes in a list:
struct Event(prob, multiplier);
EventList = (Event(q, U), Event(1-q, 1/U));
EventList
serves as a probability mass function.
A single random event may be expressed as
random(EventList)
. A single random
multiplier is therefore:
function rm = random(EventList).multiplier;
rm
must be a function, not a variable,
since it will be computed more than once.
(A variable retains its value the first time it is computed,
and retrieves the earlier value each time it is subsequently requested.)
To generate a single sample price path, we proceed in two steps.
rlm
of (random) multipliers, one for each period:
function rlm = collect(k=1 to K) {rm};
rpp
from the list of multipliers rlm
:
function rpp = buildPP(rlm, 1, collect(S0));
function buildPP(lm, k, pp) =
if (k > K) {pp}
else {buildPP(lm, k+1, join(pp, lm[k]*pp[k]))};
Click here to view the Hava program so far. This sample code contains a additional line (at the bottom) to generate three sample paths.
The value of an Asian option for a single random price
path
rpp
is calculated as:
F_Asian(rpp) = max((1/(K+1))*sum(i=1 to K+1) {rpp[i]} - E, 0);
N
such paths is given by:
stats = sum(i=1 to N) {F_Asian(rpp)};
sampleMeanPayoff = stats/N;
Finally, the discounted (present) value is obtained by multiplying the expected value by the discount rate for the duration of the option:
optionValue = beta*sampleMeanPayoff;
Click here to view the complete Hava program.
It is possible to gather sample statistics associated with multiple functions of the sample path. For example, a holder of this option might well want to know the probability that an Asian option payoff exceeds a given "tail" value. It is also straightforward to add more events to the multiplier probability mass function, or to add moments to the statistics. Finally, the methods described here can be applied to other options problems, such as Asian put option, Max or Min price option, or European call/put options.