Friday 8 June 2012

Using QuantLib on the iPad: Part III - Interface QuantLib


You need to consider what is important to you when interfacing Objective-C and C++. Generally, when interfacing to QuantLib, you will be connecting GUI components to callbacks that calculate something based on input parameters and then sending the output back to the GUI. When looking at what I wanted to do I thought about:
  • Ease of keeping up to date with QuantLib. If I want to use a newer verstion of QuantLib, how easy would it be to change the application code to keep it in line with any updates?
  • Debugging and memory management. Interfacing between two languages introduces ownership of objects (memory) issues within the interface. Which side owns an chunk of memory and who can delete it when it's finished with? Most problems I have seen with mixing languages is memory being deallocated at the wrong point, making it hard to debug issues.
  • Performance. A more granular interface provides greater control over the QuantLib libraries from the calling application, but introduces a performance penalty as there is overhead in each call. A less granular (fatter) interface is more bespoke, but has less of a performance penalty.
The easiest way to interface is to let someone else do the work for you. SWIG is a Simplified Wrapper and Interface Generator that generates wrapper (conversion) code from interface definition files. The QuantLib developers have provided the interface definition files in the QuantLib-SWIG package that can be downloaded here. Unfortunately, SWIG does not support Objective-C out of the box, the code was removed after 2009. However, the branch is still available and can be checked out using the command:

svn co https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-ashishs99 swig-objc

It compiles using configure and make.

I could not get it to work. Running the compiler over the QuantLib interface files generated the wrapper code, but it would not compile correctly for me giving errors that structures had been multiply defined. I think it could be a namespace/scoping issue with the generated code.

On reflection, this was a good thing. Using QuantLib through the SWIG interface would probably prove cumbersome and because I will be making multiple calls through it to access the QuantLib routines, slower than wrapping the code in my own methods that could roll up the calls to QuantLib which would be faster. It comes down to granularity. Having a generic Objective-C interface that would allow me to call QuantLib functions directly or a handcrafted interface that was not generic and hid all the QuantLib calls from the rest of the application.

Looking at how QuantLib works, a basic example to price a fixed rate bond entails creating:
  • A calendar
  • Settlements date
  • Fixing days
  • Settlement days
  • Face Amount
  • Redemption
  • Issue date
  • Maturity
  • Coupon Rate
  • Yield
  • Settlement Date
  • Todays Date
  • Day Counter

Which would then be used to create:
  • A discount term structure
  • Flat Term Structure
  • Fixed Bond Schedule

And a Bond Engine that would be used to setup the Fixed Rate Bond.

Using a SWIG interface, there would be multiple calls between Objective-C and the C++ library just to create the configuration. Several of the structures are boost shared pointers that would also need to be wrapped.

Instead, I decided to bundle the bond creation code in an Objective-C++ class that would be exposed to the rest of the Objective-C application using the PIMPL idiom. A very good description of how this works between C++ and Objective-C has been written by Phil Jordan. Basically, you call the QuantLib C++ interface in an Objective-C++ module and just expose the Objective-C interface through header files. The trick is to keep the header files clean of C++ code. I've not tried the ivars in class extensions, but will do soon.

The interface to the class is exposed through a structure:

// example bond interface using PIMPL

struct MyBondImpl;
@interface MyBond : NSObject {
    @private
    struct MyBondImpl * impl;
}

// get the dirty price of the bond
- (double) dirtyPrice;

@end

This is then called from the application code like a normal Objective-C class

MyBond * myBond = [[MyBond alloc] init];
double dirty = [myBond dirtyPrice];

An example implementation is shown below. It does not do much other than show how the QuantLib is used by the Objective-C++ class and exposed through the PIMPL idiom.

MyBond.mm:

@implementation MyBond

- (id) init
{
    self = [super init];
    if(self)
    {
        impl = new MyBondImpl;
        
        Calendar calendar = UnitedStates(UnitedStates::GovernmentBond);
        Date settlementDate(28, January, 2011);
        Integer fixingDays = 1;
        Natural settlementDays = 1;
        Real faceAmount = 100.0;
        Real redemption = 100.0;
        Date issueDate(31, August, 2010);
        Date maturity(31, August, 2020);
        Real couponRate = 0.03625;
        Real yield = 0.034921;
        
        settlementDate = calendar.adjust(settlementDate);
        Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);
        Settings::instance().evaluationDate() = todaysDate;
        //DayCounter dayCounter = ActualActual(ActualActual::Bond);
        DayCounter dayCounter = ActualActual();
        
        RelinkableHandle<YieldTermStructure> discountingTermStructure;
        boost::shared_ptr<YieldTermStructure>
            flatTermStructure(
                new FlatForward(
                    settlementDate,                                                         Handle<Quote>(boost::shared_ptr<Quote>(new SimpleQuote(yield))), 
                    dayCounter,
                    Compounded,
                    Semiannual));
             discountingTermStructure.linkTo(flatTermStructure);
        
        boost::shared_ptr<PricingEngine>
bondEngine(new DiscountingBondEngine(discountingTermStructure));
        
        Schedule fixedBondSchedule(
                                   issueDate,
                                   maturity, 
                                   Period(Semiannual),
                                   calendar,
                                   Unadjusted
                                   Unadjusted
                                   DateGeneration::Backward
                                   false);
        
        FixedRateBond * fixedRateBond = new FixedRateBond(
                                    settlementDays,
                                    faceAmount,
                                    fixedBondSchedule,
                                    std::vector<Rate>    
                                        (1,couponRate),
                                    dayCounter,
                                    ModifiedFollowing,
                                    redemption, 
                                    issueDate);
        
        impl->mBond = fixedRateBond;
        impl->mBond->setPricingEngine(bondEngine);
    }
    return self;
}

- (void) dealloc
{
    // need to think about memory management in the structure
    // as this is Objective-C++ code
    delete impl->mBond;
    delete impl;
}

- (double) dirtyPrice
{
    QuantLib::Real dirty = 0;
    dirty = impl->mBond->dirtyPrice(); 
    return dirty;
}

@end

This class would then be expanded out with mutator methods (getters and setters) to make it more useful - i.e. to allow interface elements to setup the bond and display the price results.

1 comment:

  1. This comment has been removed by the author.

    ReplyDelete