QuantLib: Analysing Cashflows – Introduction

In addition to the CashFlow class, QuanLib defines a number of helper functions that analyse cash flows. These function operate on sequences arrays of cash flows which, in QuantLib, are termed legs.

typedef std::vector< boost::shared_ptr<CashFlow> > Leg;

The functions for analysing cash flows are, somewhat confusingly, defined as static member functions of a class called CashFlows. Notice the plural s at the end and don’t confuse it with the CashFlow class that holds information about a single cash flow event. Many methods assume that the cash flows in a leg are sorted by their date as given by Event::date(). This will not be pointed out individually for the methods described below.

In this post I will be talking about some basic methods defined inside the CashFlows. These methods can be used to obtain dates or amounts of specific cash flows. In subsequent posts will focus on the methods that evaluate the cash flows and calculate data such as the NPV.

Basic Cash Flow Information

You can find the start date and end date of a Leg using the startDate and endDate methods. The method isExpired will return true when the leg is expired and false if it isn’t.

static Date startDate(const Leg& leg);
static Date maturityDate(const Leg& leg);
static bool isExpired(const Leg& leg,
                      bool includeSettlementDateFlows,
                      Date settlementDate = Date());

startDate will find and return the earliest date in leg. For most cash flows, the dates are taken from the date method of the Event class. For Coupon cash flows, on the other hand, the start date of the accrual period is obtained by calling the accrualStartDate method. Similarly maturityDate will return the latest cash flow in the leg. For Coupon cash flows the accrualEndDate is taken to be the relevant date, for all other cash flows the normal date returned by date is used.

The method isExpired will query all cash flows if they have occurred. If all cash flows return true then the leg is expired and isExpired returns true. If one of the cash flows returns false when queried via the hasOccured method then isExpired will return false. The settlementDate and includeSettlementDateFlows parameters are simply passed on to the hasOccured method in the Event class. If the settlement date is not specified then the Settings::evaluationDate will be used.  An empty leg is considered expired.

static Leg::const_reverse_iterator 
    previousCashFlow(const Leg& leg,
                     bool includeSettlementDateFlows,
                     Date settlementDate = Date());

static Leg::const_iterator
    nextCashFlow(const Leg& leg,
                 bool includeSettlementDateFlows,
                 Date settlementDate = Date());

static Date previousCashFlowDate(const Leg& leg,
                                 bool includeSettlementDateFlows,
                                 Date settlementDate = Date());

static Date nextCashFlowDate(const Leg& leg,
                             bool includeSettlementDateFlows,
                             Date settlementDate = Date());

static Real previousCashFlowAmount(const Leg& leg,
                                   bool includeSettlementDateFlows,
                                   Date settlementDate = Date());

static Real nextCashFlowAmount(const Leg& leg,
                               bool includeSettlementDateFlows,
                               Date settlementDate = Date());

The method previousCashFlow  will return the last cash flow on or before a given date while nextCashFlow will return the next cash flow after a given date. The methods use the hasOccured method of the Event class to decide if a cash flow has occurred. As with isExpired, the settlementDate and includeSettlementDateFlows parameters are passed on to hasOccured and an empty settlement date will mean that the global evaluation date is used.

previousCashFlow will return a reverse iterator pointing to the last cash flow that has occurred while nextCashFlow will return a forward iterator to the first cash flow that has not occurred. If no cash flow was found that matches the critetria then previousCashFlow will return leg.rend() while nextCashFlow will return leg.end(). The advantage of returning a reverse iterator from previousCashFlow is that you can easily iterate over all cash flows that have already occurred.

The other four methods are convenience methods that return the date or amount of the cash previous or next cash flow. previousCashFlowDate calls previousCashFlow and returns the date of the cash flow, and similarly nextCashFlowDate calls nextCashFlow and returns the date. In both cases a null Date is returned if no cash flow was found.

previousCashFlowAmount and nextCashFlowAmount will return the amount of the previous or next cash flow. Again the cash flows are found by calling previousCashFlow or nextCashFlow. If there are multiple cash flows that occur at the same date then all their amounts are added together. If no cash flow is found a value of zero is returned.

QuantLib defines many different types of cash flows and, using polymorphism, a Leg array can hold objects of different cash flow classes. However, in some cases one might be interested only in cash flows of a single type. Specifically, there are many cases in which only the Coupon cash flows should be taken into account. The CashFlows class defines a number of methods that only consider coupons within a cash flow and return Coupon related information. In this section I will discuss only the functions that return basic information about coupon dates and periods. The functions that perform calculations on coupons are dealt with in a future post.

static Date accrualStartDate(const Leg& leg,
                             bool includeSettlementDateFlows,
                             Date settlDate = Date());

static Date accrualEndDate(const Leg& leg,
                           bool includeSettlementDateFlows,
                           Date settlementDate = Date());

static Date referencePeriodStart(const Leg& leg,
                                 bool includeSettlementDateFlows,
                                 Date settlDate = Date());

static Date referencePeriodEnd(const Leg& leg,
                               bool includeSettlementDateFlows,
                               Date settlDate = Date());

static Time accrualPeriod(const Leg& leg,
                          bool includeSettlementDateFlows,
                          Date settlementDate = Date());

static BigInteger accrualDays(const Leg& leg,
                              bool includeSettlementDateFlows,
                              Date settlementDate = Date());

static Time accruedPeriod(const Leg& leg,
                          bool includeSettlementDateFlows,
                          Date settlementDate = Date());

static BigInteger accruedDays(const Leg& leg,
                              bool includeSettlementDateFlows,
                              Date settlementDate = Date());

static Real accruedAmount(const Leg& leg,
                          bool includeSettlementDateFlows,
                          Date settlementDate = Date());

If you look at the documentation of coupons, you will notice that these methods are direct mirror images of the methods defined by the Coupon class. All these methods will find the first Coupon cash flow in the leg that has not yet occurred. Then they call the respective method on that coupon.

For example the method accruedPeriod defined within CashFlows will first find the first Coupon object in leg that occurred after settlementDate. Once a coupon, let’s call it cp, is found the method will return cp.accruedPeriod. If no coupon is found a sensible default value will be returned, in this case a period of 0.0. In all methods that return a numerical value the default is zero, for methods that return a date the default is an empty Date object. As in nextCashFlow, if the  settlement date is not specified then the Settings::evaluationDate will be used. The hasOccurred method is called, with the settlement date and the includeSettlementDate parameter, to find the cash flow that has not yet occurred.

Two Coupon related function behave slightly differently to the functions above.

static Rate previousCouponRate(const Leg& leg,
                               bool includeSettlementDateFlows,
                               Date settlementDate = Date());

static Rate nextCouponRate(const Leg& leg,
                           bool includeSettlementDateFlows,
                           Date settlementDate = Date());

The function will return the coupon rate of the previous or the next coupon in the leg, with respect to the settlement date. In some cases the leg might contain multiple coupons for the same date. If this is the case then an aggregate rate will be calculated for all coupons that occur on the same date. This aggregate rate is simply the sum of all the rates of the coupons on that date. However, for the calculation to be successful all coupons on that date must have the same nominal value, accrual period and must be using the same day counter.

Leave a Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>