Course banner

Introduction to QuantLib Development with Luigi Ballabio, London, UK. September 22nd-24th, 2014.
Group discounts available. Register now!

Monday, January 20, 2014

Chapter 4, part 1 of 5: Cash flows and coupons

Welcome back.

This week, I'm starting a new series of posts on chapter 4. Into the limelight: the various kinds of cash flows and coupons, and what we can do with them.

Did I mention that I'll teach another Introduction to QuantLib Development course in March? In the tasteful banner above there's a link for more details and for registering. Click on it. Also, what with the holidays and all, you might have missed the new Bibliography page on this blog. Go check it now if you still didn't.

On the QuantLib front, not much to say—yet. I'm currently knee-deep in version-control logs, looking at the changes since the 1.3 release and deciding if I should do a bug-fix 1.3.1 release or a 1.4 release with the new features people have contributed. It will depend on how much new stuff there is. I'll let you know as soon as I pick one.

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

Cash flows and coupons

"Cash is king," says a sign in the office of StatPro's CFO. (I trust I'm not revealing any secret business practice.) In order to deal with the comings and goings of its Majesty (yes, I'm ironic), QuantLib must provide the means not only to price, but also to analyze coupon-bearing instruments such as bonds and interest-rate swaps. This chapter describes the classes that model different kinds of cash flows and coupons.

The CashFlow class

As usual, we start at the top of the class hierarchy. The CashFlow class provides the basic interface for all cash flows. As this level of abstraction, the information is of course rather poor; namely, the only provided inspectors return the date and amount of the cash flow. To save one from comparing dates explicitly (and for consistency, as explained in the aside below) another convenience method tells whether the cash flow has already occurred at a given date. Finally, yet another method allows cash-flow classes to take part in the Acyclic Visitor pattern [1]; an example of its use will be provided in a later post.

In earlier versions of the library, all these methods were declared in the CashFlow class. Later on, the date-related methods were moved into a separate class, Event, from which CashFlow inherits (ok, so we didn't start from the very top of the hierarchy. It's still the top of the cash-flow related classes, though. I'm not here to con you, you know) and which is reused in other parts of the code. The interfaces of the two classes are shown in listing  4.1.

Listing 4.1: Interfaces of the Event and CashFlow classes.
    class Event : public Observable {
      public:
        virtual Date date() const = 0;
        bool hasOccurred(const Date &d) const;
        virtual void accept(AcyclicVisitor&);
    };

    class CashFlow : public Event {
      public:
        virtual Real amount() const = 0;
        virtual void accept(AcyclicVisitor&);
    };
The library provides a simple implementation of the interface in the aptly named SimpleCashFlow class. It's boring enough that I won't show it here; it takes a date and an amount to be paid, and returns them from the date and amount methods, respectively. To find more interesting classes, we have to turn to interest-rate coupons—the subject of next section.

Aside: late payments.

The implementation of the Event::hasOccurred method is simple enough: a date comparison. However, what should it return when the cash-flow date and the evaluation date are the same—or in other words, should today's payments be included in the present value of an instrument? The answer is likely to depend on the conventions of any given desk. QuantLib lets the user make his choice by means of a few global settings; the choice can be overridden at any given time by passing the appropriate boolean flag to hasOccurred.

Interest-rate coupons

The Coupon class (shown in listing 4.2) can be used as a parent class for any cash-flow that accrues an interest rate over a given period and with a given day-count convention. Of course, it is an abstract base class; it defines additional interface methods for any such cash flow, and implements a few concrete methods dealing with date calculations.

Listing 4.2: Interface of the Coupon class.
    class Coupon : public CashFlow {
      public:
        Coupon(Real nominal,
               const Date& paymentDate,
               const Date& accrualStartDate,
               const Date& accrualEndDate,
               const Date& refPeriodStart = Date(),
               const Date& refPeriodEnd = Date());

        Date date() const {
            return paymentDate_;
        }

        Real nominal() const {
            return nominal_;
        }
        const Date& accrualStartDate() const;  // similar to the above
        const Date& accrualEndDate() const;
        const Date& referencePeriodStart() const;
        const Date& referencePeriodEnd() const;
        Time accrualPeriod() const {
            return dayCounter().yearFraction(accrualStartDate_,
                                             accrualEndDate_,
                                             refPeriodStart_,
                                             refPeriodEnd_);
        }
        Integer accrualDays() const;  // similar to the above

        virtual Rate rate() const = 0;
        virtual DayCounter dayCounter() const = 0;
        virtual Real accruedAmount(const Date&) const = 0;

        virtual void accept(AcyclicVisitor&);

      protected:
        Real nominal_;
        Date paymentDate_, accrualStartDate_, accrualEndDate_,
             refPeriodStart_, refPeriodEnd_;
    };

The abstract interface includes a rate method, which in derived classes will return the interest rate accrued by the coupon; and the dayCounter and accruedAmount methods, which return, respectively, the day-count convention used for accrual and the cash amount accrued until the given date.

The choice to declare the rate method as purely abstract seems obvious enough. However, the same doesn't hold for the other two methods. As for dayCounter, one could make a case for storing the day counter as a data member of the Coupon class; as discussed in this post, this is what we did for the TermStructure class. Furthermore, the nominal method (which is conceptually similar) is not abstract and is based on a corresponding data member. As I'm all for abstract interfaces, I don't complain—well, apart from playing the devil's advocate here for illustration's purposes. But I admit that the asymmetry is somewhat disturbing.

The accruedAmount method is another matter; it is abstract for the wrong reason. It could have a default implementation in terms of the rate method, whose result would be multiplied by the notional and the accrual time up to the given date. To make it abstract was a choice a posteriori, due to the fact that a few derived classes define the rate method in terms of the amount method instead of the other way around. In such classes, accruedAmount is defined in terms of amount, on the dubious grounds that this might be more efficient. However, the correct choice would be to add the default implementation to the Coupon class and override it when (and if) required. We might do this in a future release. (The same could be said for the amount method; it could, too, have a default implementation.)

The rest of the interface is made of concrete methods. The constructor takes a set of data and stores them in data members; the data include the nominal of the coupon, the payment date, and the dates required for calculating the accrual time. Usually, such dates are just the start and end date of the accrual period. Depending on the chosen day-count convention, two more dates (i.e., the start and end date of a reference period) might be needed.

For each of the stored data, the Coupon class defines a corresponding inspector; in particular, the one which returns the payment date implements the date method required by the CashFlow interface. Furthermore, the accrualPeriod and accrualDays methods are provided; as shown in the listing, they use the given day-count convention and dates to implement the corresponding calculations.

Two notes before proceeding. The first is that, as for the dayCounter method, we had an alternative here between storing the relevant dates and declaring the corresponding methods as abstract. As I said, I'm all for abstract interfaces; but in this case, a bit of pragmatism suggested that it probably wasn't a good idea to force almost every derived class to store the dates as data members and implement the same inspectors. (The only derived classes that wouldn't need to store the coupon dates as data members would probably be those decorating an existing coupon.) If you like, that's yet another hint that we should make dayCounter a concrete method.

The second note: exposing the dates through the corresponding inspectors is obviously the right thing to do, as the information might be needed for reporting or all kind of purposes. However, it might also give one the idea of using them for calculations, instead of relying on the provided higher-level methods such as accrualPeriod. Of course, it's not possible to restrict access, so all we can do is warn against it.

And finally—no, I haven't forgot to describe the accept method. I'll get back to it in a future post, as we tackle the Visitor pattern.

Fixed-rate coupons


Let's now turn to concrete classes implementing the Coupon interface. The simplest is of course the one modeling a fixed-rate coupon; it is called FixedRateCoupon and its implementation is sketched in listing 4.3. Actually, the current implementation is not the very simplest: although it started as a simply-compounding coupon, it was later generalized (by a user who needed it; as you know, premature generalization is evil) to support different compounding rules.

Listing 4.3: Sketch of the FixedRateCoupon class.
    class FixedRateCoupon : public Coupon {
      public:
        FixedRateCoupon(Real nominal,
                        const Date& paymentDate,
                        Rate rate,
                        const DayCounter& dayCounter,
                        const Date& accrualStartDate,
                        const Date& accrualEndDate,
                        const Date& refPeriodStart = Date(),
                        const Date& refPeriodEnd = Date())
        : Coupon(nominal, paymentDate,
                 accrualStartDate, accrualEndDate,
                 refPeriodStart, refPeriodEnd),
          rate_(InterestRate(rate,dayCounter,Simple)),
          dayCounter_(dayCounter) {}
        Real amount() const {
            return nominal() *
                   (rate_.compoundFactor(accrualStartDate_,
                                         accrualEndDate_,
                                         refPeriodStart_,
                                         refPeriodEnd_) - 1.0);
        }
        Rate rate() const { return rate_; }
        DayCounter dayCounter() const { return dayCounter_; }
        Real accruedAmount(const Date&) const; // similar to amount
      private:
        InterestRate rate_;
        DayCounter dayCounter_;
    };

The constructor takes the arguments required by the Coupon constructor, as well as the rate to be paid and the day-count convention to be used for accrual. The constructor in the listing takes a simple rate; another constructor, not shown here for brevity, takes an InterestRate instance instead. The nominal and dates are forwarded to the Coupon constructor. while the other arguments are stored in two corresponding data members; in particular, the rate (passed as a simple floating-point number) is used to instantiate the required InterestRate.

Part of the required Coupon interface (namely, the rate and dayCounter methods) is easily implemented by returning the stored values. The remaining methods—amount and accruedAmount—are implemented in terms of the available information. The amount is obtained by multiplying the nominal by the rate, compounded over the coupon life, and subtracting the nominal in order to yield only the accrued interest. The accrued amount is obtained in a similar way, but with a different accrual period.

One final note to end this section. I mentioned earlier on that we might include in the base Coupon class a default implementation for the amount method; as you have already guessed, it would multiply the nominal by the rate and the accrual time. Well, that seemingly obvious implementation already breaks in this simple case—which seems to cast a reasonable doubt about its usefulness. Software design is never easy, is it?

Next time: floating-rate coupons.

Bibliography

[1] R.C. Martin, Acyclic Visitor. In Pattern Languages of Program Design 3. Addison-Wesley, 1997.

Liked this post? Share it:

1 comment:

  1. I would love you to address one issue which is a huge bottleneck in many real-time contexts: the virtuality of Event::hasOccurred()

    Nested deep inside calculation engines there is often (always?) a for loop over a cashflow sequence summing those (discounted) cashflows if they are not in the past. This if condition uses hasOccurred() and has a severe performance penalty because it is a virtual method.

    Of course one could sort the cashflows, then detect "once and for all" the first cashflow still in the future, and update this detection if needed. Anyway this is a lot of housekeeping, so a more effective alternative would be welcome.

    ReplyDelete