Welcome back.

This post marks a break in the series on chapter 3 which started in this post and ran for the past few weeks. It covers interest rates, which are relevant to its subject but are not technically part of the chapter.

The idea is that a number of basic classes are glossed over in the main part of the book and are described in an appendix instead, so they don’t interrupt the flow of the chapters. As pointed out by Douglas Adams in the fourth book of his Hitchhiker trilogy, (no, that’s right: it’s an inaccurately-named trilogy of five books. It’s a long story.)

“[An excessive amount of detail] is guff. It doesn’t advance the action. It makes for nice fat books such as the American market thrives on, but it doesn’t actually get you anywhere.”

I’m not sure that this is still the case with the blog form. I’m already cutting up every chapter in several posts, so the additional content might follow one of those. We’ll see: I’m still new at this blogging thing, so I’m likely to experiment in the future.

Follow me on Twitter if you want to be notified of new posts, or add me to your circles, or subscribe via RSS: the buttons for that are in the footer. Also, make sure to check my Training page.

Odds and ends: interest rates

The InterestRate class (shown in listing A.6) encapsulates general interest-rate calculations. Instances of this class are built from a rate, a day-count convention, a compounding convention, and a compounding frequency (note, though, that the value of the rate is always annualized, whatever the frequency). This allows one to specify rates such as “5%, actual/365, continuously compounded” or “2.5%, actual/360, semiannually compounded.” As can be seen, the frequency is not always needed. I’ll return to this later.

Listing A.6: Outline of the InterestRate class.

    enum Compounding { Simple,              // 1+rT
                       Compounded,          // (1+r)^T
                       Continuous,          // e^{rT}
                       SimpleThenCompounded
    };

    class InterestRate {
      public:
        InterestRate(Rate r,
                     const DayCounter&,
                     Compounding,
                     Frequency);
        // inspectors
        Rate rate() const;
        const DayCounter& dayCounter();
        Compounding compounding() const;
        Frequency frequency() const;
        // automatic conversion
        operator Rate() const;
        // implied discount factor and compounding after a given time
        // (or between two given dates)
        DiscountFactor discountFactor(Time t) const;
        DiscountFactor discountFactor(const Date& d1,
                                      const Date& d2) const;
        Real compoundFactor(Time t) const;
        Real compoundFactor(const Date& d1,
                            const Date& d2) const;
        // other calculations
        static InterestRate impliedRate(Real compound,
                                        const DayCounter&,
                                        Compounding,
                                        Frequency,
                                        Time t);
        ... // same with dates
        InterestRate equivalentRate(Compounding,
                                    Frequency,
                                    Time t) const;
        ... // same with dates
    };

Besides the obvious inspectors, the class provides a number of methods. One is the conversion operator to Rate, i.e., to double. On afterthought, this is kind of risky, as the converted value loses any day-count and compounding information; this might allow, say, a simply-compounded rate to slip undetected where a continuously-compounded one was expected. The conversion was added for backward compatibility when the InterestRate class was first introduced; it might be removed in a future revision of the library, dependent on the level of safety we want to force on users. (There 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.”)

Other methods complete a basic set of calculations. The compoundFactor returns the unit amount compounded for a time t (or equivalently, between two dates d1 and d2) according to the given interest rate; the discountFactor method returns the discount factor between two dates or for a time, i.e., the reciprocal of the compound factor; the impliedRate method returns a rate that, given a set of conventions, yields a given compound factor over a given time; and the equivalentRate method converts a rate to an equivalent one with different conventions (that is, one that results in the same compounded amount).

Like the InterestRate constructor, some of these methods take a compounding frequency. As I mentioned, this doesn’t always make sense; and in fact, the Frequency enumeration has a NoFrequency item just to cover this case.

Obviously, this is a bit of a smell. Ideally, the frequency should be associated only with those compounding conventions that need it, and left out entirely for those (such as Simple and Continuous) that don’t. If C++ supported it, we would write something like

    enum Compounding { Simple,
                       Compounded(Frequency),
                       Continuous,
                       SimpleThenCompounded(Frequency)
    };

which would be similar to algebraic data types in functional languages, or case classes in Scala (both support pattern matching on an object, which is like a neater switch on steroids; go have a look when you have some time) but unfortunately that’s not an option. To have something of this kind, we’d have to go for a full-featured Strategy pattern and turn Compounding into a class hierarchy. That would probably be overkill for the needs of this class, so we’re keeping both the enumeration and the smell.