Well, this is a new one. While I was writing a new post about the new finite-difference framework, I tried to refer to a past post only to find out it wasn’t there. So here it is: a lost post on time-dependent finite-difference operators. It should have been posted after this one, but that can’t be helped now.
The next week, on December 7th and 8th, I’ll be in Düsseldorf for the next QuantLib User Meeting. I haven’t been hearing from the organizers lately, but there might be places left, so download the flyer and reach out to them if you’re interested.
Follow me on Twitter if you want to be notified of new posts, or add me to your Google+ circles, or subscribe via RSS: the buttons for that are in the footer. Also, make sure to check my Training page.
So far, I ignored the possibility that the parameters of the model depend on time. However, the basic classes in the framework need little modification to cover that case; the additional code is shown in the listing below.
TridiagonalOperator class gains an inner class,
TimeSetter, and a data member holding an instance (possibly
null) of the same. The interface of the inner class is simple enough;
apart from the destructor, it consists of the single method
setTime that takes a reference to the operator and modifies its
elements accordingly to the current time (also passed). Of course, the
method is declared as pure virtual; the actual logic will be
implemented in derived classes. In what can be seen as an
implementation of the Strategy pattern, the
setTime method of
TridiagonalOperator works by delegating the job to the stored
setter, if any.
BoundaryCondition class doesn’t follow the same pattern;
instead, it simply declares a virtual
setTime method that is
supposed to perform any required setup. In the simple Dirichlet and
Neumann conditions available from the library, the method does
Finally, the code of the evolution schemes needs to be modified to
take into account the possibility of time dependence. As an example,
the listing shows the modified
step method from the
class template; you can compare it with the version in this post.
First, it calls the
setTime method on all boundary conditions; then,
if the operator is time dependent, it calls its
setTime method and
recomputes the explicit and implicit operators \( I - (1-\theta) \cdot
\Delta t \cdot L \) and \( I + \theta \cdot \Delta t \cdot L \) as required.
The remaining calculations are performed as before.
Unfortunately, the available implementations of actual time-dependent operators are not as simple as the modifications required in the basic classes. The next listing shows part of the code used to implement a Black-Scholes-Merton operator with time-dependent coefficients.
Like for the engine I’ve shown in the previous example, several bits of
behavior were put in different classes in order to reuse them. For
PdeSecondOrderParabolic class can be used for
partial differential equations (PDE) of the form
and defines a
generateOperator method that calculates the
coefficients of the corresponding tridiagonal operator, given a grid
and a time; the \( \nu \), \( \sigma \) and \( r \) coefficients
above are provided by inheriting from the class and overriding the
discount methods, respectively. As you
might have noticed,
discount is a misnomer; the coefficient actually
corresponds to the instantaneous risk-free rate. (Come to think of it,
generateOperator is not the correct name, either. The method
doesn’t create an operator; it fills, or updates, the coefficients of
an existing one.) In our case, the derived class
PdeBSM specifies the
coefficients for the Black-Scholes-Merton process; the methods above,
not shown for brevity, are implemented by fetching the corresponding
information from the passed process.
PdeOperator class template, shown in the same listing,
TridiagonalOperator. It takes as template
argument a class like
PdeBSM; that is, one that provides a
generateOperator method with the correct semantics. The
constructor uses an instance of such class, together with a given
grid, to build a time setter. Once the setter is stored, the
PdeOperator instance can be safely sliced and passed around as
TridiagonalOperator instance. The setter is an instance of
GenericTimeSetter class template, not shown here, that
simply implements its required
setTime method by passing the
given time, the stored grid and the operator to the
generateOperator method of the stored PDE class.
Finally, by instantiating
PdeOperator with the
class we get a time-dependent Black-Scholes-Merton operator; we can
give it a name by means of a simple
Again, I’m not sure that this is the right balance between readability
and reusability (and to be fair, I’m not sure it isn’t, either). Like
in the previous example, you could simplify the hierarchy by putting
the whole thing in a single
BSMTimeSetter class. Its constructor
would store the grid and a process, and its
setTime method would
contain the code which is currently split between the several classes
in the previous listing. All in all, I think we’re short of actual
evidence about which version is best.
There are lots of other things in the framework that I could
describe. There’s the
OperatorFactory I mentioned earlier,
whose methods take a process, dispatch on its type, and return the
corresponding operator; and which, this being C++ and not Java,
could have been implemented as a set of overloaded functions instead.
PdeShortRate class, which works as
for one-factor short-rate models. There’s an
class used to define a few types used around the framework. There are
others I don’t even remember.
However, I’ll leave them for you to explore. Next time, we’ll be back to the new finite-differences framework.