Striding Edge Technologies
Friday, 12 October 2012
Using QuantLib on the iPad: Part IV - Submitting the Application to the App Store
My objective is to submit an application to the App Store using the QuantLib framework. The first part to build and test the framework using a simple application I completed a few months ago. Due to work and other commitments, I had still to submit a test application to the App Store. By submitting a test application, I would know if the QuantLib (and boost) frameworks were suitable as a platform for further development.
The process to do this is well documented. From the documentation "Before you can submit the archive to the App Store, it must pass validation tests." These include checks that the binary is signed, that the binary does not contain unsupported system calls and has the correct binary architecture for the target platform (iPhone 3GS/4/5/iPad/etc) amongst other checks. It's a great shakedown of the framework build and passing the test means that the application is architecturally "sound" for the App Store.
Since last writing about QuantLib on the iPad, Apple have released a new version of Xcode 4.5.1 and dropped support for armv6 binaries.
I found this the hard way when first using Xcode 4.5.1. My build gave the following error:
ld: file is universal (2 slices) but does not contain a(n) armv7s slice: /Volumes/Home/Users/philipbarnes/frameworks/ql.framework/ql for architecture armv7s clang: error: linker command failed with exit code 1 (use -v to see invocation)
So I updated my scripts to add armv7 support and immediately found the same problem with my boost framework build.
To make life easy, I visited github and found a version of boostoniphone that supported the armv7s library. I have started using the huuskpe fork of boostoniphone which builds boost 1.51.0, the latest stable version.
Once setup, I built a new version of the QuantLib framework using the latest 1.2.1 release. Rebuilding the FX Vanilla Swap Example application proved the framework.
The next step was to submit this to the App Store for verification. To do this, I created a New App submission on itunesconnect with generic icons and data.
This is needed because Xcode submits the binary to the Apple servers for validation and needs an application record for some of the tests and to check code signing.
Once setup, the application was built with the iOS device as the target and an Archive as the Product. This is pretty standard for iPad development.
As you can see, this succeeded with no errors. The final thing to do was to submit the binary archive to the Apple servers for validation.
Which was successful. Based on this, I know that the QuantLib and boost frameworks do not have any technical issues with the App Store, so I can develop and publish iPad applications using them.
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(
flatTermStructure(
new FlatForward(
settlementDate, Handle<Quote>(boost::shared_ptr<Quote>(new SimpleQuote(yield))),
dayCounter,
Compounded,
Compounded,
Semiannual));
discountingTermStructure.linkTo(flatTermStructure);
boost::shared_ptr<PricingEngine>
bondEngine(new DiscountingBondEngine(discountingTermStructure));
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),
(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
// 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.
Wednesday, 18 April 2012
Using QuantLib on the iPad: Part II - Build QuantLib
I have found most discussions about building QuantLib for the iPhone or iPad recommending to include the source code directly in an Xcode project and building it as part of the application.
Whilst this enables development to start quickly, it is restrictive in that you need to do this for every project that uses QuantLib and it makes it more difficult to upgrade versions. Building the QuantLib library as a framework enables better reuse and different versions can be built and swapped in and out of projects more quickly. Also, using the build system supplied with QuantLib (configure and autogen) guarantees that the libraries will be built correctly and include all the relevant dependancies.
The steps to build the framework to build the static libraries for each architecture, merge them and build the framework.
To build the static libraries:
- "configure" the system to build the Armv6 libraries
- "make" the Armv6 library using the Xcode arm-apple-darwin10-llvm-g++-4.2 compiler
- "configure" the system to build the Armv7 libraries
- "make" the Armv7 library using the Xcode arm-apple-darwin10-llvm-g++-4.2 compiler
- "configure" the system to build the i386 libraries
- "make" the i386 library using the default Xcode compiler
Between each build a "make clean" is performed to clear down the previously built objects (this ensures that we don't have any problem with dependancies in the next build).
Once the libraries are built, they are merged together into a fat (multi-architecture) library containing the Arm and i386 libraries in using lipo.
The framework directory structure and manifest is then created and the fat library and header files are copied.
To simplify this, I created a script that is available on github under the quantlib-on-iOS project.
To use it:
- Download the QuantLib source code and unpack it
- Copy the script buildql.sh into the QuantLib source code root directory
- Configure the boost directory variable in the script
- Configure the number of concurrent jobs to run in the script (usually 1+number of cores)
- Run ./buildql.sh
At this point it may take between 30 minutes to over 1 hour to build, depending on the performance of your machine as QuantLib is built 3 times to create each architecture.
The QuantLib framework is created in the "framework" subdirectory which can then be included in iOS applications link libraries.
The previously built Boost framework also needs to be included as it is a QuantLib dependancy.
I have tested the framework on both the simulator and on an iPad and the application runs fine. I have not yet validated it against an App Store submission.
This is an example of a simple bond calculation being called from the QuantLib framework which I will go into more detail in the next post.
Sunday, 15 April 2012
Using QuantLib on the iPad: Part I - Build Boost
Using QuantLib on iOS is done in three steps:
So, to use QuantLib I first need to build the boost libraries. Fortunately there are a lot of blog posts around which describe what needs to be done to get this working on under iOS - I need to build it for the iOS simulator under i386 and on the iPad/iPhone under the arm chipset.
The best way to do this is to bundle the Boost libraries and header files in single package via a framework. Pete Goodliffe has an excellent guide to on how to do this and has provided the scripts on gitorious. However, the current version of Boost does not work correctly with Objective-C. Fortunately, Arne has provided a fix and has updated the scripts to work using the latest version of xcode (4.3) as Apple have completely changed where all the development executables live to /Application/Xcode.app/Contents/Developer. This version of the script is available on github.
It's not hard to obtain and build the Boost libraries using the script. This creates a framework (library) that can be included in an IOS application that makes development very simple.
Once built, the framework is then included in the build, as below.
There is no need to setup include paths and link libraries as the framework takes care of all this.
One thing to note is that the script builds the basic Boost library. If you want to build anything else, such as the boost unit test framework (UTF), you'll need to alter the script. It's not a configuration change in the script and requires some extra bjam commands to be run and the object files linked into the library. I'll do this at some point as QuantLib uses the UTF for it's unit testing, but at the moment it is not a priority for me.
Saturday, 14 April 2012
First Post
I created an option strategy risk calculator application last year on the iPad for several reasons. Partly to brush up on my programming skills which had been on the back-burner of late I also wanted to expand my skills and apply the knowledge I'd accumulated at LIFFE/NYSE. Having risen through the ranks as an analyst, developer, then architect, I am now hands off and manage software development teams for a living, so I do this in my own time.
I am currently working on a second application and this time I wanted to use it to expand my knowledge of finance. As part of this I am working on using the QuantLib quantitative finance library on the iPad.
I am currently working on a second application and this time I wanted to use it to expand my knowledge of finance. As part of this I am working on using the QuantLib quantitative finance library on the iPad.
Subscribe to:
Posts (Atom)