There are so many types of volatility structures that finding common behavior between them is a bit of a stretch. In fact, I'm not sure that the base class we defined for them (the

VolatilityTermStructure class, shown in listing 3.16) is a useful abstraction.

Listing 3.16: Interface of the VolatilityTermStructure class.

```
class VolatilityTermStructure : public TermStructure {
public:
VolatilityTermStructure(BusinessDayConvention bdc,
const DayCounter& dc = DayCounter());
VolatilityTermStructure(const Date& referenceDate,
const Calendar& cal,
BusinessDayConvention bdc,
const DayCounter& dc = DayCounter());
VolatilityTermStructure(Natural settlementDays,
const Calendar& cal,
BusinessDayConvention bdc,
const DayCounter& dc = DayCounter());
virtual BusinessDayConvention businessDayConvention() const {
return bdc_;
}
Date optionDateFromTenor(const Period&) const {
return calendar().advance(referenceDate(),
p,
businessDayConvention());
}
virtual Rate minStrike() const = 0;
virtual Rate maxStrike() const = 0;
protected:
void checkStrike(Rate strike, bool extrapolate) const;
private:
BusinessDayConvention bdc_;
};
```

The class adds two things to

TermStructure, from which it inherits. The first is a method,

optionDateFromTenor, that calculates the exercise date of an option from its tenor; to do this, it used the calendar provided by the base-class interface as well as a business-day convention stored in this class (which is passed to the constructors, and from which the usual inspector is provided). Instead, this functionality could be encapsulated in some kind of utility class and used elsewhere. (The idea of such date calculator was suggested years ago on the mailing list by someone who will forgive me if I can no longer recall nor find out his name.)

The second addition involves two pure virtual methods that return the minimum and maximum strike over which the term structure is defined and a protected method that checks a given strike against the defined range. Unfortunately, these don't make sense for a local volatility structure; but leaving them out would require yet another level of hierarchy to hold them (namely, an implied-vol structure class) so I'm not shocked to see them here instead.

#### Equity volatility structures

Equity and FX-rate Black volatilities are modeled by the

BlackVolTermStructure class, shown in listing 3.17. Apart from its several constructors (which, as usual, forward their arguments to the base class and would be made unnecessary by constructor inheritance, introduced in C++11 [1]) the class defines the overloaded

blackVol method to retrieve the volatility for a given exercise date or time; the

blackVariance method for the corresponding variance (the product of the square of the volatility by the time); and the

blackForwardVol and

blackForwardVariance methods for the forward volatility and variance between two future dates.

Listing 3.17: Partial interface of the BlackVolTermStructure class.

```
class BlackVolTermStructure : public VolatilityTermStructure {
public:
Volatility blackVol(const Date& maturity,
Real strike,
bool extrapolate = false) const;
Volatility blackVol(Time maturity,
Real strike,
bool extrapolate = false) const;
Real blackVariance(const Date& maturity,
Real strike,
bool extrapolate = false) const;
Real blackVariance(Time maturity,
Real strike,
bool extrapolate = false) const;
Volatility blackForwardVol(const Date& date1,
const Date& date2,
Real strike,
bool extrapolate = false) const;
Real blackForwardVariance(const Date& date1,
const Date& date2,
Real strike,
bool extrapolate = false) const;
// same two methods as above, taking two times
protected:
virtual Real blackVarianceImpl(Time t,
Real strike) const = 0;
virtual Volatility blackVolImpl(Time t,
Real strike) const = 0;
};
```

Following the Template Method pattern (no surprise there) all these methods are implemented by calling the protected and pure virtual

blackVolImpl and

blackVarianceImpl methods. The public interface adds range checking and, in the case of forward volatility or variance, the bit of logic required to calculate the forward values from the spot values at the two passed dates.

At the time of this writing, the

BlackVolTermStructure class also defines a private

static const data member

dT that is no longer used—much like we still carry around an appendix, or a vestigial tailbone. By the time you read this, I hope to have it removed. The data member, I mean. Not my appendix.

As usual, adapters are provided to write only one of the

blackVolImpl or the

blackVarianceImpl method; they are shown in listing 3.18. (For simple examples of either kind, you can look at the

ConstantBlackVol and the misleadingly-named

ImpliedVolTermStructure classes in the library.) It is unfortunate that the name of one of the adapters, the

BlackVolatilityTermStructure class, is so confusingly similar to the name of the base class. I'm open to suggestions for changing either one in a future version of the library.

Listing 3.18: Adapters for the BlackVolTermStructure class.

```
class BlackVolatilityTermStructure
: public BlackVolTermStructure {
... // constructors, not shown
protected:
Real blackVarianceImpl(Time maturity, Real strike) const {
Volatility vol = blackVolImpl(t, strike);
return vol*vol*t;
}
};
class BlackVarianceTermStructure
: public BlackVolTermStructure {
... // constructors, not shown
protected:
Volatility blackVolImpl(Time t, Real strike) const {
Time nonZeroMaturity = (t==0.0 ? 0.00001 : t);
Real var = blackVarianceImpl(nonZeroMaturity, strike);
return std::sqrt(var/nonZeroMaturity);
}
};
```

#### Aside: Interpolations and extrapolations.

One of the available volatility classes is the

BlackVarianceSurface class, which interpolates a matrix of quoted Black volatilities. I won't describe it here, since you're probably sick of term-structure examples by now; but it has a couple of interesting features.

The first is that the interpolation can be changed once the structure is built; the relevant method is

```
template <class Interpolator>
void setInterpolation(const Interpolator& i = Interpolator()) {
varianceSurface_ =
i.interpolate(times_.begin(), times_.end(),
strikes_.begin(), strikes_.end(),
variances_);
notifyObservers();
}
```

This is not possible in other interpolated curves, in which the type of the interpolation is a template argument and is fixed at instantiation; see, for instance, the

PiecewiseYieldCurve class template in

this post. The difference is that

BlackVarianceSurface doesn't need to store the interpolator, and thus doesn't need to know its type outside the

setInterpolation method.

The second feature of

BlackVarianceSurface is the possibility to customize the kind of extrapolation to use when the passed strike is outside the range of the interpolation. It is possible either to extend the underlying interpolation or to extrapolate flatly the value at the end of the range; the behavior at either end can be specified independently.

Now, it would be nice if this behavior could be extracted in some base class and reused. The choice of extrapolation can be implemented in a generic way; given any interpolation

*f* defined up to

*xmax* (or down to

*xmin*), and given an

*x > xmax*, the two choices can be realized by returning

*f(x)* for extension of

*f(xmax)* for flat extrapolation.

The

Extrapolator class would seem the obvious choice for defining such behavior; but, unfortunately, this wouldn't work if we still want to make different choices on different boundaries. As a base class,

Extrapolator would have no knowledge of the fact that, for instance, an interest-rate structure is defined over a time range whose lower bound is 0, while a volatility surface also has a range of strikes. Since it can't distinguish between boundaries,

Extrapolator can't define an interface that specifies behavior on any of them; we'd be forced to make a single choice and apply it everywhere.

Therefore, the only possibility I see for code reuse at this time would be to define a polymorphic

Extrapolation class, code the different behaviors into derived classes, and store the required number of instances into any given term structure.

#### Bibliography

[1] International Standards Organization,

*Programming Languages – C++,* International Standard ISO/IEC 14882:2011. Available as a

working draft.