A Guide to ItosLemma

A Mathematica package that implements Ito's Lemma for stochastic calculus

by Mark Fisher

Revised April 2003

Financial Economist and Associate Policy Advisor
Research Department
Federal Reserve Bank of Atlanta
1000 Peachtree Street, N.E.
Atlanta, GA 30309-4470

mark@markfisher.net

http://www.markfisher.net/~mefisher/

What is Ito's lemma?

An Ito process can be thought of as a stochastic differential equation (SDE). Ito's lemma provides the rules for computing the Ito process of a function of Ito processes. In other words, it is the formula for computing stochastic derivatives. For example, given the stochastic differential equation \(TraditionalForm\`dx\  = \ μ\ dt\  + \ σ\ dB\) and the (suitably smooth) function f(x, t), the SDE for y(t)  = f(x(t), t) is dy  =  ((Subscript[f, t])(x, 
                  t)  +  (Subscript[f, x])(x, 
                    t) μ  + (Subscript[f, xx])(x, 
                    t) (1/2) (σ^2)) 
            dt  +  (Subscript[f, x])(x, 
              t) σ dB. 
This package will compute Ito's formula for arbitrary functions of an arbitrary number of Ito processes with an arbitrary number of Brownians. The Brownians may have an arbitrary correlation matrix.

For a reasonably accessible introduction to SDEs, see Bernt Øksendal, Stochastic Differential Equations: An Introduction with Applications, Springer-Verlag (currently in its 5th edition). The latest edition of Øksendal has a chapter of applications to finance. See also Darrell Duffie, Dynamic Asset Pricing Theory, Princeton University Press (currently in its 3rd edition) for many applications of Ito's lemma to finance.

A brief explanation of the code. (You don't need to read this.)

Ito's lemma itself (as a mathematical formula) is quite simple. The main programming challenge is to identify the Ito processes in the given expression and determine their drifts and diffusions. Below, I discuss two possible paradigms. The code in the package ItosLemma.m follows the second paradigm.

First paradigm

Ideally, the syntax for an Ito derivative would parallel that for an ordinary derivative. For example,

ItoD[expression,  arguments]

where the expression is to be "differentiated" with respect to the arguments. In principle, the arguments would be the Ito processes (including the time argument). However, the drifts and diffusions would still need to be specified. It would be possible to use the following syntax:

ItoD[f[x, t],  ItoProcess[x, (Subscript[μ, x]), (Subscript[σ, x])],  
      ItoProcess[t, 1, 0]]

where ItoProcess[x,μ,σ] specifies that x is an Ito process with drift μ and diffusion σ and ItoProcess[t,1,0] specifies that t is Ito process with drift 1 and diffusion 0  (i.e., t is time). ItoD could return an ''anonymous'' Ito process such as

ItoProcess[Derivative[0, 1][f][x, t]+(Subscript[μ, x]) Derivative[1, 0][f][x, t]+(1/2) (Subscript[σ, x]^2) Derivative[2, 0][f][x, t],(Subscript[σ, x]) Derivative[1, 0][f][x, t]]

The third argument in ItoProcess could be a vector. In addition, an option to ItoD could control how the correlations among the Brownian motions are treated.

Second paradigm

The code in ItosLemma.m takes a different route. Instead of passing an ItoProcess object as an argument to ItoD, one declares in advance that x is an Ito process with given drift and diffusion. In addition, global variables are used to identify time and other things. The three central global variables are TimeSymbol, TimeIncrement, and BrownianIncrement. Ordinarily, one would define convenient abbreviations using symbols that are not otherwise in use, such as t, dt, and dB.

To declare x to be an Ito process with drift μ and diffusion σ, use

ItoMake[x[t], μ, σ]

which stores the following rule:

x[t + dt]  =  x[t]  +  μ dt  +  σ (Subscript[dB, 1])

Note the rule will only match x[t + dt] and nothing else; there are no underscores on the left-hand side.

Programming note: ItoMake allows the user to redeclare x as an Ito process without clearing the previous definition by constructing and executing the following:

Set  @@  
      Hold[x[t + dt],  
        x[t]  +  μ dt  +  σ (Subscript[dB, 1])]

Having declared that x is an Ito process via this route, we are free to use ItoD on any expression containing x.

To see how ItoD works, consider the following expression:

expr  =  f[x[t], t]

To identify the Ito processes in the expression, substitute t+dt for t:

dtexpr  =  expr  /.  t -> t + dt

The rule matches for those symbols (and only those symbols) that have previously been declared Ito processes (including time, which has been declared implicitly).

Now we can compute the Ito-Taylor series for the expression. We need the first derivative with respect to the time increment and the first two derivatives with respect to the Brownian increment:

derivatives = (D[dtexpr,  #] & /@ {dt,  
              (Subscript[dB, 1]),  {(Subscript[dB, 1]), 2}})  /.  
        (Subscript[dB, 1]) | dt  ->  0

With these derivatives, we construct the series using the Ito "multiplication rule" (Subscript[dB, 1]^2) -> dt:

Collect[
      derivatives . {dt,  (Subscript[dB, 1]), (1/2) (Subscript[dB, 1]^2)}  /.  
        (Subscript[dB, 1]^2) -> dt,  dt]

Load the package

Off[General::spell]
Off[General::spell1]

You should put ItosLemma.m in a directory in the $Path (or add the directory where ItosLemma.m is located to the $Path).

<< ItosLemma`

?ItosLemma

Set the global symbols to convenient symbols:

{TimeSymbol, TimeIncrement, BrownianIncrement, CorrelationSymbol, 
        DriftSymbol, DiffusionSymbol} = {t, dt, 
        dB, ρ, μ, σ}

List of all of the symbols defined in the package:

Names["ItosLemma`*"]

Some usage statements

?ItoMake

?ItoD

?Drift

?Diffusion

Introductory examples

Getting started

The canonical example: Find dy where y  =  f(x, t) and \(TraditionalForm\`dx\  = \ μ\ dt\  + \ σ\ dW\).

Clear[x, y, f]
dx  =  ItoMake[x[t],  μ,  σ]

In this case, ItoMake stores a rule with x:

?x

The drift and diffusion can be extracted from dx:

Drift[dx]

Diffusion[dx]

Now let's compute the stochastic derivative:

y  =  f[x[t],  t]
ItoD[y]

By default, ItoD removes the dependence of x on t in the output. This behavior can be over-ridden with the option SuppressTime

Options[ItoD]

dy  =  ItoD[y,  SuppressTime -> False]

Here's what happens if x isn't an Ito process:

Clear[x]
ItoD[x[t],  SuppressTime  ->  False]

Other examples

Time itself:

ItoD[t]

Brownian motion. (Note: Do not make any assignments to dB, the BrownianIncrement symbol.)

Clear[b]

db  =  ItoMake[B[t], 0, 1]

\(ItoD[B[t]\^2\/2]\)

Declare x again:

ItoMake[x[t],  μ,  σ]

ItoD[(∫_t^T) x[s] \[DifferentialD]s, 
      SuppressTime -> False]

Make y[t] an Ito process with two Brownians

Clear[y, g]

ItoMake[
      y[t],   (Subscript[μ, y]),  {(Subscript[σ, (Subscript[y, 1])]),  (Subscript[σ, (Subscript[y, 2])])}]

ItoD[y[t]]

Here the Brownians are uncorrelated...

z = g[t, y[t]]

dz1 = ItoD[z]

While here they are correlated:

dz2 = ItoD[z, OrthogonalBrownians -> False]

Here is the extra term:

dz2 - dz1 // Simplify

We can mix x and y

ItoD[f[x[t], y[t]]]

To compute the instantaneous covariance between x and y, we can take the dot product of their diffusions

sigY  =  Diffusion[ItoD[y[t]]]

But the diffusion for x only has one Brownian

sigX  =  Diffusion[ItoD[x[t]]]

To fix that, use the option BrownianList

blist = 
      Cases[ItoD[y[t]],  
        Subscript[BrownianIncrement, _], ∞]

sigX  =  Diffusion[ItoD[x[t]], BrownianList  ->  blist]

sigX . sigY

Two variables, each with two shocks

Clear[Subscript, f]

ItoMake[
      (Subscript[x, 1])[t],  (Subscript[μ, 1]),  {(Subscript[σ, 11]),  (Subscript[σ, 12])}]

In this case, the rule is associated with Subscript (which is the Head of (Subscript[x, 1])).

?Subscript

ItoMake[
      (Subscript[x, 2])[t],  (Subscript[μ, 2]),  {(Subscript[σ, 21]),  (Subscript[σ, 22])}]

Alternatively one can use VectorItoMake, which applies ItoMake to a vector indexed with Subscripts:

VectorItoMake[x[t], 2]

ItoD[ f[(Subscript[x, 1])[t], (Subscript[x, 2])[t], t] ]

A vector of Brownians; three examples from Øksendal

Clear[B]
VectorItoMake[B[t],  0,  1,  3]
\(Bvec\  = \ Array[B\_#[t] &, \ 3]\)

First example

R = Sqrt[Bvec . Bvec]

Simplify  /@  ItoD[R]

Second example

vec2  =  {Plus  @@  Bvec,  
        (Subscript[B, 2])[t]^2 -  (Subscript[B, 1])[t] (Subscript[B, 3])[t]}

ItoD[vec2] // MatrixForm

Third example

Show that the following have zero drifts

vec3 = {(E^(t/2)) Cos[(Subscript[B, 1])[t]], 
        (E^(t/2)) Sin[(Subscript[B, 1])[t]],  ((Subscript[B, 1])[t]  +  t) 
          Exp[-(Subscript[B, 1])[t] - t/2]}

ItoD[vec3] // Drift // Simplify

Examples from finance

Forward rates and bond prices

Forward rates

Start with Ito process for forward rates, f[t, T], where T - t is the maturity of the forward rate and T is a fixed time in the future.

Clear[f]
ItoMake[f[t, T],  (Subscript[μ, f])[t, T],  (Subscript[σ, f])[t, T]]

The interest rate as f[t, t]

The instantaneous forward rate is the interest rate: r[t]  =  f[t, t]. In this case, however, the second argument is no longer fixed.

ItoD[f[t, t]]

The preceding result is formally correct if we interpret Derivative[0, 1][f][t, t] as follows:

Derivative[0, 1][f](t, t) = (f^((0, 1)))(0, t)  +  (∫_0^t)(∂/∂)t(Subscript[μ, f])(s, t)ds + (∫_0^t)(∂/∂)t 
              (Subscript[σ, f])(s, t) dW(s) .

From forward rates to bond prices and back again

Bond prices: \(TraditionalForm
      \`p[t, T]\  = \ 
        e\^\(-
            \(∫\_t\%T f[t, v] dv\)\)\).

dp  = 
      ItoD[(E^(-(∫_t^T) f[t, v] \[DifferentialD]v))]

Clear[p]

ItoMakeFromItoD[p[t, T], dp]

The Ito process for forward rates: \(TraditionalForm
      \`df[t, T]\  = \ 
        \(-\(∂\/∂T\)\) d
          \(log(p[t, T])\)\).

df  =  -D[ItoD[Log[p[t, T]]], T]

The preceding expression looks somewhat messy. We can simplify it a bit:

df /. 
        p -> Function[{t, 
              T},  (E^(-(∫_t^T) f[t, v] \[DifferentialD]v))] // Simplify

From bond prices to forward rates and back again

Start with the Ito process for bond prices

Clear[p]
RelativeItoMake[p[t, T], (Subscript[μ, p])[t, T], (Subscript[σ, p])[t, T]]

dp1  =  RelativeItoD[p[t, T]]

Again, the Ito process for forward rates: \(TraditionalForm
      \`df[t, T]\  = \ 
        \(-\(∂\/∂T\)\) d
          \(log(p[t, T])\)\).

Clear[f]

df  = 
      ItoMakeFromItoD[f[t, T], -D[ItoD[Log[p[t, T]]], T]]

An aside: The arbitrage-free drift of forward rates

Drift[df]  /.   (Subscript[μ, p]) -> 
          Function[{t, T},  r[t] + (Subscript[σ, p])[t, T] λ[t] ] // 
      Simplify

Use Ito's lemma to compute the Ito process for bond prices given the derived process for forward rates:

dp2  =  
      RelativeItoD[(E^(-(∫_t^T) f[t, v] \[DifferentialD]v))]

What is the difference between dp1 and dp2?

diff  =  {Diffusion[dp1] - Diffusion[dp2]  ==  0, 
        Drift[dp1] - Drift[dp2] == 0}

What conditions must be identically true?

SolveAlways[diff,  (Subscript[σ, p])[t, T]]

An annuity

Clear[p]
RelativeItoMake[p[t, T], (Subscript[μ, p])[t, T], (Subscript[σ, p])[t, T]]

Compute the process for an annuity (using the fact that a zero-coupon bond is worth one at maturity).

ItoD[(∫_t^T) p[t, s] \[DifferentialD]s] /.  
      p[T_, T_] -> 1

Exponential diffusions

ExponentialItoMake[v[t]]

ItoD[Log[v[t]]]

RelativeItoD[v[t]]

\(ExponentialItoMake[ψ[t], μ\&~, \ σ, 2]\)

Simplify /@ ItoD[Log[ψ[t]]]

State-price deflator and money-market account

Clear[m, β, ζ, n,  r,  λ,  
      R,  Λ]

State-price deflator

RelativeItoMake[m[t], -r, -λ]

RelativeItoD[m[t]]

Money-market account

RelativeItoMake[β[t], r, 0]

RelativeItoD[β[t]]

RelativeItoMake[ζ[t],  0,  -λ]

RelativeItoD[ζ[t]/β[t]]

Two state-price deflators

RelativeItoMake[n[t],  -R,  -Λ]

The Ito process for the log of the exchange rate

dX  =  ItoD[Log[m[t]/n[t]]] // Simplify

Expected exchange rate depreciation

Drift[dX] // Expand

Exponentially-weighted forecast

Exponentially-weighted forecast, where z[t, s]  :=  (Subscript[E, t])[z[s]].

Clear[z, V]

SetOptions[Integrate,  GenerateConditions -> False];

Conditional expectations are martingales:

ItoMake[z[t, s], 0, sigZ[t, s]]

Define the weighted forecast,

V[t_]  =  (∫_t^T) θ (E^(-θ (s - t))) 
          z[t, s] \[DifferentialD]s

where

(∫_t^T) θ (E^(-θ (s - t))) \[DifferentialD]s // 
      Simplify

dV   = ItoD[V[t]]

Note the drift of V is θ (V[t]  - z[t, t]).

Drift[dV]  ==  θ (V[t] - z[t, t]) // Simplify

Deriving the Black-Scholes PDE using a replicating, self-financing trading strategy

In this section, we use ItosLemma to derive the Black-Scholes PDE in two separate ways.

Setup

SetOptions[ItoD, SuppressTime -> False];

First Derivation

This derivation follows that given by Darrell Duffie in chapter 5 of Dynamic Asset Pricing Theory.

Clear[s, β, f, μ, σ]

The diffusions for the stock and the money-market account:

\(TraditionalForm\`\(d\(s(t)\)\)\/\(s(t)\) = \ \(μ\ dt + σ\ dB\_1\ \ \ \ and\ \ \ \(d\(β(t)\)\)\/\(β(t)\) = \ 
        r\ \(\(dt\)\(.\)\)\)\)

RelativeItoMake[s[t], μ,  σ]
RelativeItoMake[β[t], r,  0]

Consider the function of f(s(t), t). Its dynamics are given as follows:

df = ItoD[f[s[t], t]]

Suppose the function can be replicated by a self-financing trading strategy with portfolio weights a(t) and b(t):

self  =  a[t] s[t] + b[t] β[t]

By definition, the dynamics of a self-financing trading strategy are given by:

(†)          d(a(t) s(
                t) + b(t) β(t))  =  a(t) 
          ds(t) + b(t) 
          dβ(t)

dself = 
      Collect[
a[t] ItoD[s[t]] + 
          b[t] ItoD[β[t]], 
{dt,  
          (Subscript[dB, 1])}]

If the self-financing trading strategy replicates the function, then the drift and diffusion of the self-financing trading strategy will equal the drift and diffusion of the function:

\(equations = {
self == 
          f[s[t], t], 
Drift[dself] == Drift[df], \ 
        Diffusion[dself] == 
          Diffusion[df]
	}\)

We can obtain the PDE by eliminating the weights from the equations:

pde1  =  
      Eliminate[equations,  {a[t],  b[t]}] /. s[t] -> x

Is the trading strategy really self-financing?

We can solve for the portfolio weights using the equality of the function with the portfolio and the equality of the diffusions:

weights  =  
      First @ Solve[equations[[{1, 3}]], {a[t],  b[t]}]

Is the trading strategy really self-financing? We can check (†).

firstway  =  ItoD[self /. weights]

secondway = dself /. weights

The diffusions are equal:

Diffusion[firstway] == Diffusion[secondway] // 
      Simplify

The drifts are equal if and only if the PDE is satisfied. In other words, the trading strategy is self-financing if and only if it replicates.

pde2  =  
      Drift[firstway] == Drift[secondway] /. s[t] -> x

We can check that the two PDEs are the same by eliminating the parameter r from the two:

Eliminate[{pde1, pde2}, r]

Second derivation

The absence of arbitrage requires that any self-financing trading strategy deflated by the state-price deflator must be a martingale. In other words, the drift of the deflated trading strategy must be zero. The dynamics of the state-price deflator ℼ(t) can be expressed in terms of the risk-free rate and the price of risk λ:

RelativeItoMake[ℼ[t],  -r,  -λ]

The simplest trading strategy is to buy and hold an asset that pays no dividends. For the stock we have:

noarb1  = Drift @ ItoD[s[t] ℼ[t]] == 0

In this case, the martingale property implies the expected return equals the risk-free rate plus a risk premium that is the product of the relative volatility and the price of risk:

Solve[noarb1,  μ]

For the derivative security we have:

noarb2  =  
      Drift @ ItoD[f[s[t], t] ℼ[t]] == 0

We can obtain the PDE by eliminating the price of risk λ from the two absence-of-arbitrage conditions:

pde3 = 
      Eliminate[{noarb1,  noarb2},  λ] /. s[t] -> x

We can check that this PDE is the same as the one derived above:

Eliminate[{pde1, pde3},  r]

SetOptions[ItoD, SuppressTime -> True];

FYI: Black-Scholes solution to the PDE for price of a call option

European call option pays max(x - k, 0) on expiration date T > t.

Clear[V, Φ]
Φ[z_] = 
        CDF[NormalDistribution[0, 1], z];
V[x_, t_]  :=  
      With[{a = ((Log[x/k] + (r + (σ^2)/2) (T - t))/(σ Sqrt[T - t]))}, 
          x Φ[a] - 
            k Exp[-r (T - t)] Φ[
                a - σ Sqrt[T - t]]
] // 
        Evaluate

V[x, t] // TraditionalForm

pde1 /. f -> V // Simplify