QuantLib: Discounting Bond Engine

In the previous post about QuantLib Pricing engines I talked about the basic functionality of pricing engines. These are implemented by the PricingEngine and the GenericPricingEngine class. These engines provide an interface and some basic functions but the actual calculations have not been implemented. One of the simplest pricing engines that actually performs some calculations is the DiscountingBondEngine. This engine uses a discount curve to discount all the cash flows. In fact, the implementation of simply calls the CashFlows::NPV method to evaluate the NPV and the settlement value.

The public interface of the DiscountingBondEngine looks as follows.

class DiscountingBondEngine : public Bond::engine {
  public:
    DiscountingBondEngine(
          const Handle<YieldTermStructure>& discountCurve =
                                            Handle<YieldTermStructure>(),
          boost::optional<bool> includeSettlementDateFlows = boost::none);
    void calculate() const;
    Handle<YieldTermStructure> discountCurve();
};

The constructor takes a handle to a YieldTermStructure which contains the discount curve. An optional boolean can be specified to indicate whether cash flows on the settlement date should be included in the calculations. If the flag is not specified, the global value of the flag from the Settings singleton will be used. One more thing to be noted is that the DiscountingBondEngine inherits from Bond::engine and not directly from PricingEngine. The reason is that the Bond class checks the type of the pricing engine that is passed to it. If the eninge cannot be cast to a Bond::engine an exception is thrown. The definition of the Bond::engine class is simple.

class Bond::engine : public GenericEngine<Bond::arguments,
                                          Bond::results> {};

This engine does not add any functionality but simply defines the arguments and results that the pricing engine should use. As explained above, any pricing engine that is to be used with the Bond instrument class MUST inherit from Bond::engine. The reason for this is that the Bond class expects the type of arguments to be of type Bond::arguments and the results to be of type Bond::results. More about arguments and result types below.

Setting Arguments

Remember in the discussion of the Instrument class that arguments should be set inside the virtual setupArguments method. The parameter to the method is a pointer to PricingEngine::arguments. The pricing engine should supply the actual arguments object via the getArguments method. By virtue of the GenericEngine template class we can ensure that the arguments will, in fact, always be of type Bond::arguments.

class Bond::arguments : public PricingEngine::arguments {
  public:
    Date settlementDate;
    Leg cashflows;
    Calendar calendar;
    void validate() const;
};

The arguments include a settlement date, a leg of cash flows and a calendar that is used to adjust the cash flow dates. The validate method ensures that a settlement date is specified and that there is at least one cash flow in the leg. When an object of this type is passed to the setupArguments method of the Bond class, it is filled with the values taken from the bond.

Obtaining Results

The Instrument class defines, and already implements the fetchResults method. As I stated __here__ the Instrument class fetches the NPV, the error estimate and any additional results from the pricing engine. It also sets the valuationDate of the instrument. In order to do this, the results type returned by the PricingEngine has to be of the nested type Instrument::results which extends PricingEngine::results.

class Instrument::results : public virtual PricingEngine::results {
  public:
    void reset();
    Real value;
    Real errorEstimate;
    Date valuationDate;
    std::map<std::string,boost::any> additionalResults;
};

This class is filled by the pricing engine and delivers the results to the Instrument class which then reads from it in the fetchResults method. In addition to the fields defined in the Instrument::results class, the Bond class requires one additional value to be calculated by the pricing engine, namely the settlement value. For this reason Bond defines its own results type. Because Bond extends the Instrument class the result type defined by Bond also has to extend Instrument::results.

class Bond::results : public Instrument::results {
  public:
    void reset();
    Real settlementValue;
};

As stated above, the Bond::engine ensures that it can only take argument types and return result types that extend from Bond::arguments and Bond::results by extending GenericEngine<Bond::arguments, Bond::results>.

Summary

All of what I described in the last two sections happens behind the scenes and is only interesting if you intend to write your own pricing engines. If you want to simply use the existing pricing engines that QuantLib provides you simply need to pass a pricing engine to the setPricingEngine method of the instrument. The only thing that you need to ensure is that you are using a pricing engine class that is compatible with your instrument. Note again that this compatibility is not checked during compile time. Instead an exception is thrown during runtime if a non-compatible pricing engine is used.

If you are interested in the internals of QuantLib and you are thinking about implementing your own pricing engines or even you own instruments here is a little diagram that might help you. I have extracted the UML diagram of some of the classes that are related to the DiscountingBondEngine. In this hierarchy the PricingEngine and its nested classes arguments and resuls stand at the top. In this diagram I have omitted the properties and methods of the classes involved for clarity.UML Diagram of DiscountingBondEngine and related classes

4 Comments

  1. JohnPaul

    Hello!
    Thanks for this very wonderful blog. I use it a lot.
    I am trying to price a floating rate bond. I get some results, but very different from the one provided by Bloomberg for the same bond. By looking at its cash flows in Bloomberg, I understood that my problem comes from that Bloomberg sets the future rates (unknown) to the present rate: every future floating coupon is fixed and equal. On the Internet, I found that it is a very popular way of pricing future cash flows of a floating rate bond.
    With Quantlib however, we use the forward rate on each coupon. Is there a way (such as a different pricing engine, or something else) to get the future floating coupon set to a fixed rate, like Bloomberg does?

    Reply
  2. Mikail (Post author)

    Hi Paul,
    The only Pricing Engine for the Bond class that QuantLib provides is the DiscountingBondEngine. This engine takes the actual cash flows of every coupon in the bond and discounts it back to the evaluation date. For a floating rate bond, the coupon rates are calculated using an Index. If I understand your question correctly then you want to ignore the index completely and simply assume that all coupon rates are fixed to a constant value. As far as I can see you have two options. The first is to duplicate your bond by creating a fixed rate bond with all the same settings as your floating rate bond, except for that you specify the rate explicitly. The second option is to write your own pricing engine. But even in this case, you will either have to convert every single floating rate coupon into a fixed rate coupon or you would have to create a fixed rate bond from the values stored in the floating rate bond.

    Reply
  3. Baruch Youssin

    Thanks for the clear exposition!
    There is one piece of the puzzle that I cannot find: building yield curves and credit spreads from fixed income instrument quotes (bonds and others).
    Is there an engine for this in Quantlib?

    Reply
    1. Baruch Youssin

      I guess I have found a part of the answer: this seems to be done by the constructors of YieldTermStructure class as one can see here: QuantLib: Yield Curves.

      This page does not mention which instruments can be bootstrapped. I guess I need to see the source code for this.

      Reply

Leave a Reply to Baruch Youssin Cancel reply

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>