Monte Carlo engine design

Home

Monte Carlo for Interest Rates derivatives

The valuation problem

Let us consider an instrument 1 , \Pi, that pays the following cash–flows \pi_0, \pi_1,\dots, \pi_N on dates t_0, t_1,\dots, t_N.

At this stage we do not really care what type of cash–flows \pi_i represent. Let us just consider them to be random.

The problem we face when pricing such a derivative is of calculating the following expected value 2 \label{eqn:pricing}
\mathbb E^\mathcal M\left[ \frac{\pi_0}{M_{t_0}} + \dots + \frac{\pi_N}{M_{t_N}}\right], where:

  1. \mathbb E is the expectation operator;

  2. \mathcal M represents the risk–neutral measure chosen;

  3. M_t is the value of the numeraire linked to the pricing measure \mathcal M with expiry t.

The pricing–measure / numeraire problem

We left unspecified the choice of pricing measure \mathcal M and numeraire M in Eq. [eqn:pricing] as that might change depending on applications.

Typically we can expect to be using on of the following pricing measures for calculating prices and risks of a derivative:

  1. risk–neutral measure. This is usually denoted by \mathbb Q and its numeraire by B, defined as dB(t) = r_t B(t) dt, \quad B_0 = 1.

  2. Tterminal measure. This is usually denoted by \mathbb Q^T. The numeraire associated to it is the zero–coupon bond with maturity T. Its price at time t is denoted by P_t(T).

  3. TODO add others

What all these choices have in common is that they all depend on interest rates. This means that in pricing IR derivatives (or, in fact, hybrid derivatives), our Monte Carlo engine must be able to consistently apply modelling rules both to cashflows and numeraires.

Main classes

In the following sections, we will describe what are the responsibilities of the main classes involved in the valuation/risk calculation problem:

  1. the concept of a Monte Carlo model is discussed in 1.2;

  2. the concept of a payoff is discussed in

  3. a Monte Carlo engine is discussed in.

Monte Carlo model

State variables representation

The first building block of a Monte Carlo model in our context is simulating the model state variables. Let us refer to them as X.

In particular, what we expect from such model is the definition of the state variables dynamics:

\begin{aligned}
d X^{(0)}_t &= \mu X^{(0)}_t + \sigma dX^{(0)}_t, \quad X^{(0)} = x^{(0)}\\
\dots & = \dots\\
d X^{(n)}_t &= \mu X^{(n)}_t + \sigma dX^{(n)}_t, \quad X^{(n)} = x^{(n)}\\
\end{aligned}

Meta programming techniques in C++

Polymorphism

Dynamic polymorphism

By dynamic dispatch we mean the usual virtual function based inheritance mechanism:


class base
{
public:
	virtual void do_something() const = 0;
	*@/*\marginpar{Dynamic polymorphism example}*/ @*
}

class derived : public base
{
public:
	virtual void do_something() const override
	{
	    //...;
	}
}

This approach has its advantages. The main one is that both base and derived classes are fully defined classes. This allows the compiler to know exactly what their size is at runtime. This makes possible to use pointers to base class

base* b;
b = new derived(/*...*/);

to achieve polymorphic behaviour from a function that expects a base type

void function_on_base(base* arg){ \* ...*\};

A function like that can be invoked with a derived type pointer as argument

vfunction_on_base(b);

Moreover, homogeneous containers can be used to store pointers to base class objects, even though each element of the vector can be of a different derived type:

std::vector<base*> v;
v.push_back(new derived(\*...*\));

Regrettably, this approach ha also disadvantages when it comes to performances. Given that the hierarchy structure can be as deep as a programmer want, the compiler doesn’t know when to stop looking for overrides. As a result, virtual functions cannot be inlined.

Inline

TODO explain

Static polymorphism

Static polymorphism, on the other hand, does not rely on virtual functions. TODO mention burtle and noble book


template<class derived>
class base
{
    const derived& true_this() const
    {
        return static_cast<const derived&>(*this); 
        *@/* \marginpar{static\_cast can be used
         to traverse the class hyerarchy}*/ @*
    }

public:
    void do_something() const
    {
        true_this().do_something();
*@/* \marginpar{and base can statically 
dispatch to derived implementation}*/ @*
    }
};


class derived : public base<derived>
{
public:
    void do_something() const
    {
         //...;
    }
};

image


  1. That can be both a security, like a bond or a structured product, or a derivative, like a future or a swaption.↩︎

  2. Let us consider we value it at time 0, and let us also consider t_i > 0, for i = 0,\dots,N.↩︎