CHAPTER 1

image

The Fixed Income Market

The fixed income market is a large part of the financial industry, and it presents unique challenges and opportunities for its practitioners. A large amount of the money managed by pension funds and other institutional funds is allocated to fixed income investments. Because fixed income has a predictable income stream, conservative money managers view it as a safer investment option when compared to stocks and more exotic derivatives. As a result, traditional institutions commit a lot of time and effort to the fixed income industry.

As software engineers, our main goal when working in the fixed income market is to define computational strategies and solve problems so that our clients can be successful. C++ is a language that is uniquely poised to the solution of problems in this industry. This is due to its flexibility and high performance on standard computational platforms. Moreover, C++ is a highly portable language that can be used in a variety of computer systems.

As a result of the advantages just mentioned, C++ programing has been widely used in this area of finance, and it is one of the preferred languages used in banks, hedge funds, pension funds, and other large institutions that have to deal with fixed income as one of their main investment vehicles. Programmers who work with C++ have over the years developed software that offers useful capabilities for fixed income analysis, such as computing prevailing interest rates and determining cash flow valuations. All of these features need to execute with incredible speed, with the help of some of the techniques explored in later sections of this book.

In this chapter, I provide a quick introduction to this area of finance and show you a few C++ coding examples that can be used in the solution of some of the most common programming problems occurring in fixed income markets. These coding examples include the solution to problems involving

  • Simple interest rate calculation.
  • Compound interest rate calculation.
  • Cash flow modeling.
  • Determination of the present value of cash flows.
  • Modeling and valuation of bonds.

In the remainder of this chapter, I will also show you why C++ may be the ideal language to deal with programming problems occurring in the financial investment industry, and in particular how to solve problems in fixed income investing. Then, I will provide a general introduction to the issues occurring in fixed income investments and an overview of how the fixed income market works. Then, I will start with a few programming examples that explore the concepts discussed in the previous sections.

Fixed Income Overview

We start our discussion with a general overview of fixed income instruments. While this is not a book on finance or economics, it is still important to have a few concepts in place. My general goal is to describe how to use these concepts in the solution of the practical computational problems that we discuss in the latter part of this chapter.

In a fixed income investment, a contractually defined exchange occurs between two parties. Both parties agree to exchange cash flows that are assigned based on interest rates and the time of cash exchanges. Fixed income investments are very diverse, but they include the following well-known types of investments vehicles:

  • Money market funds: These are short-term investments that offer a small rate of return but at the same time provide easy availability of funds at your own convenience. Money market funds have a very short-term horizon, and they only pay returns that are close to the spot rate practiced by banks. Since money market funds have a small return that is hard to predict over a long period, they are used mostly for their liquidity.
  • Bonds: This is a major category of fixed income applications. Bonds pay a predetermined interest rate for a well-defined period of time. They are issued by a variety of institutions, including companies and all levels of government. The American government, for example, issues treasury bonds, which are one of the main investment vehicles used throughout the world.
  • Certificates of deposit: These are fixed income investments issued by banks to their retail customers. They are simple investments that pay a fixed interest rate for a pre-defined period, usually between one and five years. They are used mainly for the convenience of small investors who lack access to more sophisticated fixed income markets and want to invest from their own checking or savings account.

The main reason for investors to enter the fixed income market is to take advantage of a relatively safe investment opportunity, where the returns are known and predictable. Compared to the stock market, fixed income investments have the advantage of being easier to analyze. This is true because, for equity investments, for example, it is practically impossible to determine how much money a company will make in a few years from now. With a fixed income investment such as a bond, however, you have a contract that guarantees the return on the investment for a specified period of time.

Clearly, there are also risks in such fixed income investments. A well-known risk is that of the default of the institution issuing the bond, for example. In that case, investors may lose a part of the, or the whole, investment. The second big risk, which is frequently overlooked by investors, is that the rate of return will not be able to cope with inflation during the period of the investment. For example, if the rate of return is 6% a year but inflation is around 4%, then your real rate of return is just 2% (and that is the return before taxes).

This all shows that analyzing fixed income investments is not as easy as it initially sounds. It is not just a matter of finding the institution paying the largest interest rate and putting all your money on its bonds. This is one of the reasons why money managers need reliable software that can be used to decide which the best among myriad fixed income investments are. Just as the stock market presents thousands of possibilities that need to be carefully analyzed, the fixed income industry has a huge number of available choices. One of the big tasks for software developers is to create systems that can easily track these investments and help in choosing the right options for long-term investors.

Image Note  Fixed income investments have risks that are hard to measure because they depend on the future economic environment. Sound fixed income investments need to take into consideration the several risks involved. High-quality C++ software for fixed income may help investors to take into consideration some of these external factors.

Here are some of the most important concepts about fixed income investments used through this chapter.

  • Interest rate: The return of investment in percentage points for a given period (usually one year). Fixed income investments will have a well-defined interest rate that is determined as a contractual obligation.
  • Principal: The amount of the original fixed income loan or investment. This is the value over which the interest rate is calculated in the case of a fixed income investment such as a bond.
  • Compound interest: Interest that is accrued over time and added to the principal as regular interest payments are made at each period. The amount of compound interest is regulated by the interval between interest payments.
  • Continuous compounding: As the number of periods increase, the effect of compound interest becomes more pronounced. For example, compound interest paid at the end of every month will produce more than at a yearly payment schedule. In theory, this compounding process could happen in a continuous schedule, and the resulting compound interest can be calculated using a simple formula, which I explain later in this chapter.
  • Present value: When a set of scheduled cash flows and an interest rate are defined, it is possible to calculate the present value of those cash flows. This is done using the contractual interest rate to determine the discounted value of each future cash flow and adding together all these values. The present value is a very powerful tool to compare two cash flow streams.

Using these simple concepts, it is possible to analyze very complex investments. You will learn how to use these concepts in some of the coding examples contained later in this chapter.

Why Using C++

C++ is a language that has been used with great success in all kinds of financial applications. It is the number-one language used by Wall Street firms to create fast, high-performance code that can be employed to implement efficient algorithms for financial engineering.

While C++ is already a mature language with more than 30 years of history, and other programming languages have appeared since then with high-level features that are easier to use, C++ still holds the place as the standard language for high-performance computation. Large financial institutions such as banks, hedge funds, and pension funds rely daily on C++ to solve their most complex computational problems for the following reasons:

  • Performance: The most obvious reason why C++ is used is its performance. Due to the fact that C++ has little runtime overhead compared to other high-level languages, it is possible to use it to write very fast software. Not only is C++ fast enough by default, but it also allows expert C++ programmers to explore many additional low-level techniques for code optimization, which are not available to programmers using languages such as Java and Python.
  • Standards compliance: C++ is a standard language, developed over the years by an international group of experts with the goal of providing high-level features such as object-oriented programming (OOP) without the overhead that is normally associated with them. As a result of the standardization effort, C++ is available on all kinds of platforms, ranging from microcontrollers to the largest servers. This means that you can run your algorithms unmodified between platforms. This is an obvious advantage for financial algorithms, since this kind of software can be easily ported to faster architectures over the years to take advantage of improvements in new hardware and software design.
  • Existing libraries: C++ offers an almost unparalleled set of libraries for numerical and financial programming. Each topic we discuss in this book has several libraries available that can save time and effort.
  • Multi-paradigm language: Developers designed the C++ language from the beginning to support multiple programming paradigms, so programmers don’t need to change the essence of an algorithm to fit into a particular paradigm. For example, although OOP is supported, the language does not mandate the use of OOP. In this way, programmers are free to use the most expressive technique for the desired application.
  • High-level features: Although C++ allows programmers to achieve high performance by targeting low-level features of their hardware, good programmers can still use several high-level features that make C++ a truly modern language. For example, C++ was one of the first languages to embrace the concept of OOP, which is without question the most common paradigm for modern software design. C++ has also pioneered other features such as exceptions and template-based containers. More recently, C++ incorporated even more high-level features by means of the new C++11 standard of the language. Type detection, lambda expressions, and user-defined constants are just a few of the new features that have become available to application developers since the new standard was approved.

For the reasons stated previously, programmers have trusted C++ as the main vehicle for implementing high-performance financial algorithms. In this book, we explore code examples that make use of these computational advantages.

Like any other tool, C++ also has its share of problems. One of the themes in learning C++ programming is to avoid dangerous practices that can lead to bugs and unsafe programs. Most of the techniques you will see in the next chapters embrace the use of modern libraries, which not only simplify the process of creating C++ programs but also allow you to create software that is well designed and fault-tolerant. Using the standard library, which includes the STL (standard templates library), is the best way to use C++ safely.

You will also learn how to use the high-quality libraries that have been made available through the boost project. The boost libraries have been designed from the ground up to use modern C++ concepts in a way that simplifies the creation of new software. The boost libraries are the result of the work of some of the greatest experts in C++ programming, including people involved in the C++ standard committee itself. In fact, many of the libraries shipped with boost have become part of the standard library. Therefore, using boost libraries you will be getting early access to some features that will be included in future versions of the language.

Calculating Simple Interest Rates

To start, I will show you how to solve a very simple problem in fixed income analysis, as a way to introduce some of the features of C++ class design that we use throughout this book.

Problem

Interest rates determine how much a financial institution is going to pay in exchange for holding a cash deposit over a period of time. Calculate the future value of a deposit given the interest rate and the initial value of the deposit, assuming a single period of deposit.

Solution

You just need to use the mathematic equation for simple interest rate calculation, which is given by the expression

V = P (1 + R)

In this formula, V is the future value after a single period, and P is the present value of the deposit. With this formula, you can calculate the interest rate for a single period.

How It Works

The IntRateCalculator class, defined in Listing 1-1, determines the calculation of single period interest rates:

Listing 1-1. The IntRateCalculator Class

class IntRateCalculator {
public:
    IntRateCalculator(double rate);
    IntRateCalculator(const IntRateCalculator &v);
    IntRateCalculator &operator =(const IntRateCalculator &v);
    ~IntRateCalculator();

    double singlePeriod(double value);
private:
    double m_rate;
};

First, we define a new class that becomes responsible for the calculation. A fundamental principle of object-oriented design is to have responsibilities unified under very well defined interfaces. You should embrace this principle when creating C++ classes, since it will simplify maintenance and avoid costly mistakes. Even if you need to write additional code using this strategy, the increased organization pays off in the long run.

In the definition of the IntRateCalculator class, we define a constructor, a destructor, a copy constructor, and the assignment operator. These are methods that, if you don’t define them yourself, will be added to the class by the compiler. It is useful to create your own versions of such member functions, however, because in this way you can be sure that you are getting the desired behavior, instead of what the compiler writers think is the right choice.

Image Note  You should create classes that specify the four basic member functions automatically defined by the C++ compiler. In this way, you can avoid costly mistakes by having the created objects use a well-defined life cycle. Failing to provide such member functions can result in classes that don’t respond correctly to such basic operations such as assignment (defined by the assignment operator) and copy construction. If your class is supposed to be the base for other classes, you should also make the destructor virtual, so that the derived classes can properly release the resources they use.

The compiler automatically adds the following member functions, unless you specify otherwise in the class declaration:

  • The default constructor: The default constructor is automatically added, allowing an object to be created using the new keyword, even if the class writer didn’t include it. A default constructor is one that has no arguments. It is not included automatically, however, if the class declaration contains another constructor that requires arguments. For example, in our IntRateCalculator class, the constructor receives one parameter, the interest rate. Therefore, the default constructor is not automatically included, which means that to create an object of the IntRateCalculator class the programmer needs to specify a valid interest rate argument.
  • The copy constructor: The copy constructor allows you to create copies of an existing object of the same class. It is included by default only if there are no other constructors in the class definition. In our case, we need to supply a copy constructor, to guarantee that it is possible to create copies of existing objects. Copy constructors become important when objects need to be added to containers, particularly the containers provided in the STL, such as vectors, maps, and multimaps.
  • The destructor: A destructor defines how the resources used by a particular object will to be freed once the object is destroyed. A proper constructor is required to avoid memory leaks and other undesirable resource leaks in an object. In the IntRateCalculator class, there are no internal or external resources that need to be freed, but it is still better to define this explicitly.
  • The assignment operator: This member function is used when an assignment operation occurs between two objects of the same class. Defining this type, you can specify how the contents of an object are transferred from one object to the next: that can be done either by value or by reference. Other details of the copy, such as reference counters, for example, can also be established in the assignment operator.

The singlePeriod member function encapsulates the operation that returns the future value of a deposit after a single period. Depending on the structure of the loan or the input parameters, this can refer to one month or one year of interest. The signature of the member function is

double singlePeriod(double value);

This simple version of the code uses the double type (instead of float) for extra precision. In the next chapters we will discuss how to deal with precision issues that are inherent to floating point numbers.

The IntRateCalculator class contains a single member variable, m_rate, which stores the current interest rate. In this way, it is not necessary to input the interest rate every time the singlePeriod member function is called. Therefore, to create a new instance of IntRateCalculator you need to provide the interest rate as a parameter to the constructor.

The header file, IntRateCalculator.h, defines the singlePeriod member function as inline (see Listing 1-2).

inline double IntRateCalculator::singlePeriod(double value)
{
    double f = value * ( 1 + this->m_rate );
    return f;
}

The keyword inline is used here to suggest that the member function be directly embedded in the code that calls it. What this means is that there is no penalty for calling this function, since the function call will be removed from the executed code, and the content of the method will be directly substituted. Think of this as a way of achieving the same performance of a macro, with all the compiler support of calling a function. In high-performance C++ code it is common to see member functions defined as inline, in order to achieve even higher performance than equivalent member function calls. This kind of flexibility is one of the features that separates C++ from other languages, where it would be much more difficult to achieve similar performance.

Complete Code

Listing 1-2. IntRateCalculator.h

//
//  IntRateCalculator.h

#ifndef __FinancialSamples__IntRateCalculator__
#define __FinancialSamples__IntRateCalculator__

#include <iostream>

class IntRateCalculator {
public:
    IntRateCalculator(double rate);
    IntRateCalculator(const IntRateCalculator &v);
    IntRateCalculator &operator =(const IntRateCalculator &v);
    ~IntRateCalculator();

    double singlePeriod(double value);
private:
    double m_rate;
};

inline double IntRateCalculator::singlePeriod(double value)
{
    double f = value * ( 1 + this->m_rate );
    return f;
}

#endif /* defined(__FinancialSamples__IntRateCalculator__) */

//
//  IntRateCalculator.cpp

#include "IntRateCalculator.h"

IntRateCalculator::IntRateCalculator(double rate)
: m_rate(rate)
{

}

IntRateCalculator::~IntRateCalculator()
{

}

IntRateCalculator::IntRateCalculator(const IntRateCalculator &v)
: m_rate(v.m_rate)
{

}

IntRateCalculator &IntRateCalculator::operator=(const IntRateCalculator &v)
{
    if (&v != this)
    {
        this->m_rate = v.m_rate;
    }
    return *this;
}

//
//  main.cpp

#include "IntRateCalculator.h"

#include <iostream>

// the main function receives parameters passed to the program
int main(int argc, const char * argv[])
{
    if (argc != 3)
    {
        std::cout << "usage: progName <interest rate> <value> " << std::endl;
        return 1;
    }

    double rate = atof(argv[1]);
    double value = atof(argv[2]);

    IntRateCalculator irCalculator(rate);
    double res = irCalculator.singlePeriod(value);
    std::cout << " result is " << res << std::endl;
    return 0;
}

Sample Use

First, you need to compile the code using your favorite C++ compiler. For example, using the makefile provided in a UNIX platform, you could just use the make command, with the following results:

$ make
gcc –c IntRateCalculator.cpp
gcc –c main.cpp
gcc –o intrate IntRateCalculator.o main.o

You can now run this program by passing a given interest rate and initial value. For example, you could type the following

./intrate 0.08 10000
 result is 10800

This shows that the future value of an investment of $10,000 at an 8% interest rate is $10,800 after a single period.

Compound Interest

You can use simple interest rates to analyze single period cash flows. However, most financial operations, such as loans, have multiple periods. For this purpose, you need to consider compound interest.

Problem

Calculate the compound interest accumulated by a given principal value after the passage of N time periods.

Solution

The solution uses a new C++ class that encapsulates the concept of compound interest. With this class, it is becomes easy to answer the proposed question using two member functions. The first function, multiplePeriod, returns the future value of a fixed income investment after a given number of periods, as passed in the function parameter.

As mentioned previously, interest can be calculated either as a discrete or a continuous compounding process. For discrete compounding, we assume that interest is paid only at regular intervals, as defined by the investment vehicle. The compounding happens as interest is added to the original principal.

The formula for discrete compounded interest rate is

eqn1.jpg

Where P is the present value, V is the future value, R is the interest rate, and N is the number of periods. The interest rate is the value passed as a parameter to the class constructor and stored as a member variable. The number of periods N is passed as the second parameter to the multiplePeriod method.

For continuous compounding calculation, you need to use a separate method, continuousCompounding. In this case, we assume that compounding doesn’t happen in discrete steps, but that the payments are made continuously over time. This is a possible way to determine the future value of a financial application (or at least an upper bound for the desired future value).

The formula for the calculation of continuous interest rate compounding is

eqn2.jpg

Here, V is the desired future value, P is the present value, R is the interest rate during the period, and N is the number of periods. For example, to find the future value of continuously compounded interest after two years at 8% interest per year, you should use the value of the previous equation with parameters R = 0.08 and N = 2.

How It Works

The two member functions, multiplePeriod and continuousCompounding, calculate the given formulas using the mathematical functions pow and exp from the standard C++ library. These two functions implement a fast way to calculate the power function and the exponential function, respectively.

To use any mathematical function from the standard library, you should first include the header file cmath. Table 1-1 provides a short list of mathematical functions made available from that header file.

Table 1-1. Some of the Mathematical Functions in the Standard Library

Function

Corresponding mathematical operations

exp

Exponential function (natural base)

pow

Power function

log

Natural logarithm function

log10

Logarithm function on decimal base

sqrt

Square root function

sin

Sine function

cos

Cosine function

tan

Tangent function

acos

Arc cosine function (inverse of cosine)

asin

Arc sine function (inverse of sine)

atan

Arc tangent function (inverse of tangent)

ceil

Ceiling function (smallest integer higher than parameter)

floor

Floor function (largest integer lower than parameter)

fabs

Absolute value for float numbers

The mathematical functions provided by the standard library should be used whenever possible, instead of custom versions, for the following reasons:

  • Compatibility: Using functions from the standard library guarantees that they will be available in any compiler that implements it.
  • Performance: Functions in the standard library are implemented as part of the package sold by compiler vendors. The code of these mathematical functions is generally optimized for the particular architecture, which usually results in much better performance.

Complete Code

The code in Listing 1-3 shows the implementation for class CompoundIntRateCalculator, divided into a header file and an implementation file. I also present a sample main function that shows how to use the class.

Listing 1-3. CompoundIntRateCalculator.h

//
//  CompoundIntRateCalculator.h

#ifndef __FinancialSamples__CompoundIntRateCalculator__
#define __FinancialSamples__CompoundIntRateCalculator__

class CompoundIntRateCalculator {
public:
    CompoundIntRateCalculator(double rate);
    CompoundIntRateCalculator(const CompoundIntRateCalculator &v);
    CompoundIntRateCalculator &operator =(const CompoundIntRateCalculator &v);
    ~CompoundIntRateCalculator();

    double multiplePeriod(double value, int numPeriods);
    double continuousCompounding(double value, int numPeriods);
 private:
    double m_rate;
};

#endif /* defined(__FinancialSamples__CompoundIntRateCalculator__) */

//
//  CompoundIntRateCalculator.cpp

#include "CompoundIntRateCalculator.h"

#include <cmath>

CompoundIntRateCalculator::CompoundIntRateCalculator(double rate)
: m_rate(rate)
{

}

CompoundIntRateCalculator::~CompoundIntRateCalculator()
{

}

CompoundIntRateCalculator::CompoundIntRateCalculator(const CompoundIntRateCalculator &v)
: m_rate(v.m_rate)
{

}

CompoundIntRateCalculator &CompoundIntRateCalculator::operator =(const CompoundIntRateCalculator &v)
{
    if (this != &v)
    {
        this->m_rate = v.m_rate;
    }
    return *this;
}

double CompoundIntRateCalculator::multiplePeriod(double value, int numPeriods)
{
    double f = value * pow(1 + m_rate, numPeriods);
    return f;
}

double CompoundIntRateCalculator::continuousCompounding(double value, int numPeriods)
{
    double f = value * exp(m_rate * numPeriods);
    return f;
}

//
//  main.cpp

#include "CompoundIntRateCalculator.h"

#include <iostream>

// the main function receives parameters passed to the program
int main(int argc, const char * argv[])
{
    if (argc != 4)
    {
        std::cout << "usage: progName <interest rate> <present value> <num periods>" << std::endl;
        return 1;
    }

    double rate = atof(argv[1]);
    double value = atof(argv[2]);
    int num_periods = atoi(argv[3]);

    CompoundIntRateCalculator cIRCalc(rate);
    double res = cIRCalc.multiplePeriod(value, num_periods);

    double contRes = cIRCalc.continuousCompounding(value, num_periods);
    std::cout << " future value for multiple period compounding is " << res << std::endl;
    std::cout << " future value for continuous compounding is " << contRes << std::endl;

    return 0;
}

Sample Use

The code in Listing 1-3 can be compiled into an executable and run from the command line. The program expects three arguments: the interest rate, the present value of the investment, and the number of periods of compounding.

Following is an example of its use:

$ ./compound 0.05 1000 4
 future value for multiple period compounding is 1215.51
 future value for continuous compounding is 1221.4

As expected, the value returned by continuous compounding is slightly higher than the value achieved by discrete compounding.

Modeling Cash Flows

A more general way of thinking about fixed income investments is to look at the flow of cash exchanged between the two involved parties. A cash flow is a sequence of payments, scheduled during a specified period of time. It is clear that the value of the cash flows between two entities should be equal in some way. In this section, you will learn how to determine if a set of cash flows is equivalent.

Problem

Calculate the present value of two cash flows and determine if they are equivalent.

Solution

Cash flows are the basic tool for comparing two or more fixed income investments. A cash flow establishes the sequence of cash transfers between two interested parties. The traditional way to denote these cash exchanges is by using positive and negative values.

For example, consider a common loan, where a customer requests a quantity at a given interest rate. The customer will make a sequence of cash payments during the lifetime of the loan. At the end of the transaction, the payments made by both parties should be equivalent.

The equivalence is established using the concept of present value. The present value of a payment in the future needs to be discounted by the interest rate that would be applied to that same value. In other words, discounting is the inverse concept to compounding.

Calculating Present Value

A general principle of investing is that money in your pocket today is more valuable than the same money received in the future. This general principle can be quantified using the knowledge of value compounding based on interest rates. The present value of a fixed income investment is the value that corresponds to the sum of cash flows taking place in the future, after their corresponding interest has been considered and discounted.

The formula for present value (PV) of a future payment is determined by

eqn3.jpg

In this equation, PV is the desired present value, FV is the future value that we want to discount, R is the interest rate, and N is the number of periods between the present value and the future value.

As you see, the formula for PV is the inverse of the calculation of compound interest rate. This clearly shows that we are just using a similar process to determine a present value when starting from a known future value.

Calculating Present Value in C++

Formulas for calculating PV can be found in any financial engineering book. For a C++ programmer, however, the main interest in this topic is centered on how to perform PV calculations with high performance. The standard procedure is to denote values paid by the two parties using positive and negative signs. For example, we can denote an initial loan as a negative number, and each payment of the loan as a positive number. Using this approach, for a cash flow from two parties to be equivalent, the present value of all cash transfers needs to add to zero.

This is the method used by the CashFlowCalculator class, which is presented next. Here is the class definition.

class CashFlowCalculator {
public:
    // constructors

    void addCashPayment(double value, int timePeriod);
    double presentValue();
private:
    std::vector<double> m_cashPayments;
    std::vector<int> m_timePeriods;
    double m_rate;
    double presentValue(double futureValue, int timePeriod);
};

The addCashPayment method is used to add new payments to the desired cash flow. The arguments are the value of the payment, and the second is the time period when this payment occurs. The value is positive or negative depending on the originator of the payment, as previously discussed. The data is stored on two vectors, m_cashPayments and m_timePeriods, using the STL vector template.

The presentValue method in this class is used to compute the PV or the whole cash flow stored in the current object. This is done with the determination of the PV for each cash exchange as stored in the m_cashPayments vector, and finally adding these values to the total variable.

double CashFlowCalculator::presentValue()
{
    double total = 0;
    for (int i=0; i<m_cashPayments.size(); ++i)
    {
        total += presentValue(m_cashPayments[i], m_timePeriods[i]);
    }
    return total;
}

The auxiliary member function presentValue(double, int) is used to calculate the PV for a single payment. It is defined using the foregoing formula.

double CashFlowCalculator::presentValue(double futureValue, int timePeriod)
{
    double pValue = futureValue / pow(1+m_rate, timePeriod);
    std::cout << " value " << pValue << std::endl;
    return pValue;
}

Using STL Containers

The code in the CashFlowCalculator class is made simpler by the use of vector containers. The std::vector<> template is used in modern C++ applications to store ordered sequences of elements that require random access. Unlike traditional C and C++ arrays, which decay to pointers when passed as arguments to a function, a vector is an object that maintains its properties, such as size, during the whole time the vector is used. A vector also knows how to clean up after itself, avoiding memory leaks that are so common in old-style C++ applications.

To use a vector in a C++ application you need to declare the object by passing the element type as a parameter to the vector template. Therefore, std::vector<int> will create a vector of int elements. The vector template class has member functions that can be used to manipulate and retrieve information about the elements.

  • size: Returns the number of elements stored in the vector object.
  • push_back: Copies the object passed as a parameter and stores it at the end of the vector. If necessary, additional memory is allocated for the new element.
  • pop_back: Removes the last element from the vector, and undoes the changes made by push_back.
  • operator[]: Provides access to the contents of the vector, using syntax similar to the access of traditional C++ arrays.

The vector template is just one among other STL containers that are available for C++ developers. The complete list changes as new templates are added to the standard library, but Table 1-2 lists the most used containers.

Table 1-2. Common Containers Provided by the STL

Container

Description

vector

Ordered collection of elements with constant random access time

queue

Container where elements are added at the end and removed from the front position.

map

Associative container that connects keys to their associated element

multimap

Associative container that connects keys to a set of associated elements

list

A linked list of elements, which provides constant time inclusion/exclusion at any position

stack

A specialized container that allows only addition and removal of the last element (the top of the stack)

Complete Code

Listing 1-4 presents the code for the class CashFlowCalculator. The code is divided into a header file and an implementation file. You can see how to use the code in the example shown in the section “Running the Code.”

Listing 1-4. CashFlowCalculator.h

//
//  CashFlowCalculator.h

#ifndef __FinancialSamples__CashFlowCalculator__
#define __FinancialSamples__CashFlowCalculator__

#include <vector>

class CashFlowCalculator {
public:
    CashFlowCalculator(double rate);
    CashFlowCalculator(const CashFlowCalculator &v);
    CashFlowCalculator &operator =(const CashFlowCalculator &v);
    ~CashFlowCalculator();

    void addCashPayment(double value, int timePeriod);
    double presentValue();
private:
    std::vector<double> m_cashPayments;
    std::vector<int> m_timePeriods;
    double m_rate;
    double presentValue(double futureValue, int timePeriod);
};

#endif /* defined(__FinancialSamples__CashFlowCalculator__) */

//
//  CashFlowCalculator.cpp

#include "CashFlowCalculator.h"

#include <cmath>
#include <iostream>

CashFlowCalculator::CashFlowCalculator(double rate)
: m_rate(rate)
{

}

CashFlowCalculator::CashFlowCalculator(const CashFlowCalculator &v)
: m_rate(v.m_rate)
{

}

CashFlowCalculator::~CashFlowCalculator()
{

}

CashFlowCalculator &CashFlowCalculator::operator =(const CashFlowCalculator &v)
{
    if (this != &v)
    {
        this->m_cashPayments = v.m_cashPayments;
        this->m_timePeriods = v.m_timePeriods;
        this->m_rate = v.m_rate;
    }
    return *this;
}

void CashFlowCalculator::addCashPayment(double value, int timePeriod)
{
    m_cashPayments.push_back(value);
    m_timePeriods.push_back(timePeriod);
}

double CashFlowCalculator::presentValue(double futureValue, int timePeriod)
{
    double pValue = futureValue / pow(1+m_rate, timePeriod);
    std::cout << " value " << pValue << std::endl;
    return pValue;
}

double CashFlowCalculator::presentValue()
{
    double total = 0;
    for (int i=0; i<m_cashPayments.size(); ++i)
    {
        total += presentValue(m_cashPayments[i], m_timePeriods[i]);
    }
    return total;
}

//
//  main.cpp

#include "CashFlowCalculator.h"

#include <iostream>

// the main function receives parameters passed to the program
int main(int argc, const char * argv[])
{
    if (argc != 2)
    {
        std::cout << "usage: progName <interest rate>" << std::endl;
        return 1;
    }

    double rate = atof(argv[1]);

    CashFlowCalculator cfc(rate);
    do {
        int period;
        std::cin >> period;
        if (period == -1) {
            break;
        }
        double value;
        std::cin >> value;
        cfc.addCashPayment(value, period);

    } while (1);

    double result = cfc.presentValue();
    std::cout << " The present value is " << result << std::endl;

    return 0;
}

Running the Code

The program can be compiled using a standards-compliant C++ compiler such as GCC on Linux or Mac OS X. The resulting program can be executed in the following way:

./presentValue 0.08
1 200
2 300
3 500
4 -1000
-1
 value 190.476
 value 272.109
 value 431.919
 value -822.702
 The present value is 71.8014

The first few lines display the input for the program. The command line argument (in this case 0.08) is the desired interest rate—it is used as the parameter to the class constructor. The following lines are a sequence of the time periods and payment values. The last line of the sequence is marked using the number -1. When that number is read, the program stops reading the input and starts to calculate the PV of the given cash transfers, in the order in which they were received.

The last few lines display the output of the program. The code prints the PV for each component of the cash flow. Finally, it prints the PV of the whole sequence of payments. To use this program to validate a common fixed income instrument, such as a loan, you should input each pair of time period–payment value. At the end of the calculation, the PV should add to zero (or close to zero, due to possible numerical inaccuracies).

Modeling Bonds

Bonds are a very common type of fixed income instrument. They are used by large corporations and governments all over the world to attract cash investments that will be repaid in the long term. In exchange they offer the guaranteed payment of a periodic coupon. Most bonds mature (are paid off) in a time period between 5 and 30 years.

Problem

Create a C++ class to model a bond instrument and determine its annual interest rate.

Solution

Bonds are structured in such a way that the investor deposits the principal value at the beginning of the term of the bond. Frequently, the principal is repaid in its entirety at maturity. Between the period between the initial investment and its maturity, investors are paid a constant value, also called the coupon value, which determines the interest rate paid by the bond.

For example, consider a 30-year, $100,000 bond investment in company XYZ, with an annual coupon of $5,000. This translates into a fixed income investment that pays a 5% interest on the principal. Company XYZ has the right to use the principal during the specified period of time, and the total value of the principal is returned to the investor in 30 years at maturity.

To model this kind of investment using C++, you can create a class that contains the needed information, such as principal value, coupon value and maturity period. The class has the following declaration:

class BondCalculator {
public:
    BondCalculator(const std::string institution, int numPeriods, double principal, double couponValue);
    BondCalculator(const BondCalculator &v);
    BondCalculator &operator =(const BondCalculator &v);
    ~BondCalculator();

    double interestRate();

private:
    std::string m_institution;
    double m_principal;
    double m_coupon;
    int m_numPeriods;
};

This class has member variables that store the name of the institution that originates the bond (known as the issuer), the principal invested, the coupon amount, and the number of periods (usually defined in years). The class can be used to record information about bond investments as part of an application that tracks such fixed-income investments. The interestRate method can be used to return the internal rate of returned implied by the coupon.

Complete Code

Listing 1-5 shows a complete listing for class BondCalculator. The code is split into a header file and an implementation file. You can also check a sample usage contained in the main function.

Listing 1-5. BondCalculator.h

//
//  BondCalculator.h

#ifndef __FinancialSamples__BondCalculator__
#define __FinancialSamples__BondCalculator__

class BondCalculator {
public:
    BondCalculator(const std::string institution, int numPeriods, double principal, double couponValue);
    BondCalculator(const BondCalculator &v);
    BondCalculator &operator =(const BondCalculator &v);
    ~BondCalculator();

    double interestRate();

private:
    std::string m_institution;
    double m_principal;
    double m_coupon;
    int m_numPeriods;
};

#endif /* defined(__FinancialSamples__BondCalculator__) */

//
//  BondCalculator.cpp

#include "BondCalculator.h"

BondCalculator::BondCalculator(const std::string institution,
                               int numPeriods, double principal, double couponValue)
: m_institution(institution),
  m_numPeriods(numPeriods),
  m_principal(principal),
  m_coupon(couponValue)
{

}

BondCalculator::BondCalculator(const BondCalculator &v)
: m_institution(institution),
  m_numPeriods(v.m_numPeriods),
  m_principal(v.m_principal),
  m_coupon(v.m_coupon)
{

}

BondCalculator::~BondCalculator()
{

}

BondCalculator &BondCalculator::operator =(const BondCalculator &v)
{
    if (this != &v)
    {
        this->m_institution = v.m_institution;
        this->m_principal = v.m_principal;
        this->m_numPeriods = v.m_numPeriods;
        this->m_coupon = v.m_coupon;
    }
    return *this;
}

double BondCalculator::interestRate()
{
    return m_coupon / m_principal;
}

// the main function receives parameters passed to the program
int main(int argc, const char * argv[])
{
    if (argc != 4)
    {
        std::cout << "usage: progName <institution> <principal> <coupon> <num periods>"
                  << std::endl;
        return 1;
    }

    std::string issuer = argv[1];
    double principal = atof(argv[2]);
    double coupon = atof(argv[3]);
    int num_periods = atoi(argv[4]);

    BondCalculator bc(issuer, principal, coupon, num_periods);
    std::cout << "reading information for bond issued by " << issuer << std::endl;
    std::cout << " the internal rate of return is " << bc.interestRate() << std::endl;
    return 0;
}

Running the Code

The code can be compiled using a standards-compliant C++ compiler. It has been tested on Linux and Mac OS X. You can run the program using the following command at your preferred shell:

$ ./bondCalculator XYZ 100000 5000 20
reading information for bond issued by XYZ
 the internal rate of return is 0.5

The first line in bold is the command that you need to execute. The parameters are the name of the issuer institution, the total principal invested in the bond, the value of the periodic coupon, and the number of time periods for this investment.

The output of the program displays the rate of return calculated from the coupon value. The class BondCalculator can now be used in a larger application to store information about this type of fixed income investment.

Further Reference

This chapter provides an introduction to the general topic of fixed income investments. While we are mostly concerned about the C++ programming issues involved in this area, there are several books that can help you getting a greater understanding of the financial engineering techniques the were introduced here.

The following books are just suggestions that you can explore to achieve a better understanding of the world of fixed income investments.

  • Investment Science by David Luenberger (Oxford University Press, 1998): This is an undergraduate-level book that describes the basic theory of investment. Most of the book explains the fundamentals of fixed income investments, including algorithms for the most common problems.
  • Investments by Zvi Bodie, Alex Kane, and Alan Marcus (McGraw-Hill/Irwin, 2004): This is a standard textbook on investment theory that explains, among other topics, the ideas behind fixed income investments.
  • Mathematics for Finance by Marek Carpinski and Tomasz Zastawniak (Springer, 2011): This book is more for the mathematically inclined. It not only explains the basics of fixed income investments but also gives a lot of mathematical methods that are useful in their analysis.

Conclusion

In this chapter I introduced the topic of fixed income investments and how they can be modeled and analyzed using C++ code. The first part of the chapter explains the general concepts behind fixed income investments. These investments are used as a relatively safe way to maintain and generate wealth, as compared to the equity and derivatives market.

I have also explained why C++ is the ideal programming language to create computational solutions for the problems in this area of finance. Due to its performance characteristics and high-level programming support, C++ provides the best balance between expressiveness and raw speed. As a result, C++ is the de facto standard for development of core applications in the finance field, especially in applications that deal with fixed income data.

The first example introduced a basic class that can be used to calculate simple interest rates. It introduces not only the concept of interest rate calculation methods but also the typical way such solutions are designed and coded in modern C++.

The second example introduced the concept of interest rate compounding, both in discrete and continuous intervals. You learned there how to create a C++ class to calculate this type of interest rate using standard C++ library functions. I presented a summary of such mathematical functions and how they are used in C++ programs.

The third example in this chapter explored the important concept of cash flows and their corresponding PV. The calculation of PV is central to the comparison of two or more fixed income investments. Using the inverse of the formulas for interest rate, you can determine the real value of a given set of cash flows in the present. You learned how to solve this type of problem using a new C++ class.

Finally, this chapter explains how bonds are used in financial applications and presented a class to model these investments. In future chapters, you will learn more about the computational challenges of using these financial vehicles as part of an investment portfolio.

In the next chapter, I will introduce another large part of the financial investment landscape: the equities market. You will see a few programming techniques that can be useful in these markets, along with an introduction to other important concepts that we explore in the later part of this book.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.19.174