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.
Coupon Related Functions
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.