Sunday 24 June 2012

QuantLib on iPad - a working example


I've posted a working copy of an xcode project on github that demonstrates using QuantLib in an Objective-C iPad application without exposing the C++ interface to the GUI. It uses the previously described PIMPL idiom built using the boost and QuantLib frameworks.
It's not pretty, but the objective of the project is to show how to interface an Objective-C GUI with QuantLib.

However, it's dull work. Writing an interface from scratch that converts between QuantLib types and Objective-C objects and types is time consuming. Fortunately, QuantLib defines a lot of types ultimately as native C++ types, so conversion is straightforward. There is just potentially a lot of it. Dates proved to be the most involved in the example, but I've always found date handling using NSDate and NSDateFormatters to be long-winded anyway. I expect anyone using QuantLib from another language without using SWIG will end up writing a lot of glue conversion code and putting it in a library.

The interface does not bear any resemblance to what is going on under the covers as it is very high level. I don't think that this is a bad thing, the interface provides mutators and a price method to price the FX Vanilla Swap that matches the GUI. Anything more complicated in would expose more of the QuantLib internals. This was just enough.

@interface FXVanillaSwapPricer : NSObject {
}


- (double) price;


// mutators - note that we don't create properties or mutators for the
// QuantLib data members else we will expose them to the rest of the
// Objective-C application that defeats the object of PIMPL.
//
// Instead we create use a facade-style interface and convert the
// Objective-C types to QuantLib types.
//
// For this example we do it in the maturity mutator only. See the .mm
// file for more information.


@property (nonatomic) double quote;
@property (nonatomic) double strikePrice;
@property (nonatomic) double foreignRate;
@property (nonatomic) double domesticRate;
@property (nonatomic) double volatility;
@property (strong, nonatomic) NSDate *today;
@property (strong, nonatomic) NSDate *settlement;


- (NSDate *) maturity;
- (void) setMaturity:(NSDate *) newMaturity;

All the work to create the yield term structures and pricing engine is hidden. In the interface above I have hand coded the maturity mutators. This is to demonstrate the type of work that you would need to do if you wanted to convert from Objective-C to QuantLib types when passing around values.

// example mutator methods to show how what is involved in
// interfacing between objective-c and C++ - the price method
// pulls in the maturity, but these show the sort of conversions
// that would need to be done if you wanted to fully expand the
// mutators in the Objective-C++ class.


- (NSDate *) maturity
{
    NSLog(@"Maturity get mutator called");
    
    // convert the QuantLib::Date to NSDate using a Date
    // Formatter it helps that the QuantLib day/month/year are
    // defined as ints so the compiler does the implicit
    // conversions for us
    
    QuantLib::Day day = _maturity.dayOfMonth();
    QuantLib::Month month = _maturity.month();
    QuantLib::Year year = _maturity.year();
    
    NSString * dateString = [[NSString alloc]
        initWithFormat:@"%d-%02d-%02d", year, month, day];
    NSDateFormatter * dateFormatter =
        [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    
    NSLog(@"maturity day %@", dateString);
    
    NSDate * date = [dateFormatter dateFromString:dateString];
    
    return date;
}
- (void) setMaturity:(NSDate *) newMaturity
{
    NSLog(@"Maturity set mutator called");
    
    // convert the maturity date from an NSDate to a
    // QuantLib::Date
    
    NSDateFormatter *dateFormatter =
        [[NSDateFormatter alloc]init];
    dateFormatter.dateFormat = @"dd";
    NSString *dayString =
        [dateFormatter stringFromDate: newMaturity];
    dateFormatter.dateFormat = @"MM";
    NSString *monthString =
        [dateFormatter stringFromDate: newMaturity];
    dateFormatter.dateFormat = @"YYYY";
    NSString *yearString =
        [dateFormatter stringFromDate: newMaturity];
    
    NSLog(@"maturity day %@ month %@ year %@",
        dayString, monthString, yearString);
    
    QuantLib::Day day = [dayString intValue];
    QuantLib::Month month = intToQLMonth([monthString intValue]);
    QuantLib::Year year = [yearString intValue];
    
    _maturity = Date(day, month, year);
      
    // no need to set the maturity here
    // maturity = newMaturity;
}

These are then called using standard Objective-C callbacks from the GUI.

- (IBAction)maturityChanged:(UIDatePicker *)sender
{
    NSDate *date = [sender date];
    
    NSLog(@"maturityChanged %@", date);
    
    [fxvanillaswappricer setMaturity:date];
}

The pricing object is defined in the view as:

fxvanillaswappricer = [[FXVanillaSwapPricer alloc] init];

Again, this makes sense as the GUI that the user interacts with does not display yields, etc. I expect that if the user wanted to do this, then the interface would change to accomodate the requirement and the price method would grow or be split up to accomodate this.

The rest of the example application lets xcode do the work in creating the mutators. I define the QuantLib attributes in the interface:

@interface FXVanillaSwapPricer ()
{  
    QuantLib::Real _S;         // simple quote value
    QuantLib::Real _K;         // strike price
    QuantLib::Spread _f;       // Foreign rate
    QuantLib::Rate _r;         // Domestic rate
    QuantLib::Volatility _vol; // volatility
    QuantLib::Date _maturity;
    QuantLib::Date _todaysDate;
    QuantLib::Date _settlementDate;
    
    NSDate * maturity;
}
@end

And then copy the data at the start of the price method. A little lazy, but the point was to demonstrate techniques.

- (double) price
{
    using namespace QuantLib;
    
    QuantLib::DayCounter _dayCounter = Actual365Fixed();
    
    // get the parameters used to generate the price
    // if we hand crafted the mutators like the maturity example
    // we would not need to do this
    
    _S = quote;
    _K = strikePrice;
    _f = foreignRate;
    _r = domesticRate;
    _vol = volatility;


... etc

return npv;
}

If I was writing a more complicated application, I would need to make a decision on how to do this. Either to convert the Objective-C types into QuantLib types in the mutators and store them in the object (as above), or store them as Objective-C types and convert them before I wanted to use them. The application shows a hybrid approach for both techniques.

The swap price is displayed using a text field that is updated when the "calculate" button is pressed.

- (IBAction)calculate:(UIButton *)sender
{
    NSLog(@"calculate");
    double npv;
    npv = [fxvanillaswappricer price];
    [price setText:[NSString stringWithFormat:@"%2.6f", npv]];
}

It's a very basic application that hopefully provides pointers for how to call QuantLib on iOS.

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.