Notes
1A few gentle users happened to refer to our library as “the QuantLib.” As much as I like the expression, modesty and habit have so far prevented me from using it.↩
2In this case, of course, it would be “How we did it.”↩
3A more thorough exposition of this point can be found in Kerievsky, 2004.↩
4Even fancy new C++11 stuff like variadic templates won’t help.↩
5This does not excuse you from reading the Gang of Four book.↩
6Most likely, such objects ultimately depend on Quote
instances, e.g., a yield term structure might depend on the quoted
deposit and swap rates used for bootstrapping.↩
7The Instrument class also defines an errorEstimate_
member, which is omitted here for clarity of exposition. The
discussion of NPV_ applies to both.↩
8The implementation shown in this section is somewhat outdated. However, I’m still using it here since it provides a simpler example.↩
9If you happen to feel slightly cheated, consider that the point of this example is to show how to package calculations into a class—not to show how to implement the calculations. Your curiosity will be satisfied in a later chapter devoted to cash flows and related functions.↩
10NaN might be a better choice, but the means of
detecting it are not portable. Another possibility still to be
investigated would be to use boost::optional.↩
11Beside being conceptually clearer, this would prove useful to external functions implementing serialization and deserialization of the instrument—for instance, to and from the FpML format.↩
12The Instrument::results class also contains a
std::map where pricing engines can store additional results. The
relevant code is here omitted for clarity.↩
13dynamic_pointer_cast is
the equivalent of dynamic_cast for shared pointers.↩
14You can find the full code of the engine in the QuantLib sources.↩
15No, it’s not a mistake. It is an inaccurately-named trilogy of five books. It’s a long story.↩
16Nor automatic, nor hydromatic. That would be the Grease Lightning.↩
17For instance, a simple expression like Time t = 2.0;
wouldn’t compile. You’d also have to write f(Time(1.5)) instead
of just f(1.5), even if f wasn’t overloaded.↩
18I won’t explain it here, but go read it. It’s almost insanely cool.↩
19The same technique is used in a number of other classes,
such as DayCounter in the next section or Parameter from
chapter 5.↩
20Well, we could use heuristics, but it could get ugly fast.↩
21The choice to return the latest increment is kind of unusual; the idiomatic choice in C and C++ would be to return the old value.↩
22There are different views on safety among the core developers, ranging from “babysit the user and don’t let him hurt himself” to “give him his part of the inheritance, pat him on his back, and send him to find his place in the world.”↩
23Both support pattern matching on an object, which is like a
neater switch on steroids. Go have a look when you have some
time.↩
24Note that by “instances of the same index” I mean here
instances of the same specific index, not of the same class (which
might group different indexes); for instance, USDLibor(3*Months)
and USDLibor(6*Months) are not instances of the same index;
two different USDLibor(3*Months) are.↩
25If you’re not familiar with the darker corners of C++: when the constructor of a base class is executed, any data members defined in derived classes are not yet built. Since any behavior specific to the derived class is likely to depend on such yet-not-existing data, C++ bails out and uses the base-class implementation of any virtual method called in the base-class constructor body.↩
26Lovers of encapsulation will probably prefer the version taking an index to the one returning a vector, since the latter reveals more than necessary about the internal storage of the class.↩
27This also constrains how we model payoffs based on multiple fixings of an underlying; for instance, Asian options are passed the payoff for a plain option and the average of the fixings is done externally, before passing it to the payoff. One might want the whole process to be described as “the payoff”.↩
28The presence of the primitive and derivative methods
is a bit of implementation leak. They were required by
interpolated interest-rate curves in order to pass from zero rates
to forwards and back.↩
29This also goes for a few multi-dimensional optimizers. In that case, apart from the obvious copyright issues, we also rewrote them in order to use idiomatic C++ and start indexing arrays from 0.↩
30Although you might be a bit surprised that it
doesn’t declare operator() instead.↩
31Some of them declare those data members as
mutable, suggesting the methods might have been
const in the past. As I write this, I haven’t investigated
this further.↩
32It always bothered me that a*b returns the element-wise
product and not the dot product, but I seem to be alone among
programmers.↩
33This is not as far-fetched as it might seem; we’ve been bitten by it.↩
34Well, it doesn’t actually force us, but writing
return Disposable<Array>(Array(n, 10)) is even uglier than the
alternative.↩
35Notice that I didn’t say was.↩
36Another alternative would be to do nothing, but we preferred not to fail silently.↩
37In fact, you’re not even required to define an accept
method; you could just inherit it. However, this would prevent
visitors to target this specific class.↩
38However, the QuantLib developers are human. As such, they sometimes fail to follow the rules I am describing.↩