
A step-by-step instruction to install Quantlib and Boost can be found on the official Quantlib site.
The main problem for me was that I couldn’t find any simple solution of how to run Quatlib and Boost with WinForm project in Visual Studio 10.
If you create New Project and run Windows Forms Application in VS 2010 with the code provided on the official Quanlib site to test Quanlib, you will surely get Errors because Boost is unmanaged C++ code.
One of the solutions is to compile C++ application as a DLL library and use it in .NET.
Another possible solution is to create CLR Project in Visual Studio 2010 so .NET components will be available as well, for example Math.Round function.
The purpose of this article is to show how to use Quantlib with graphical windows forms instead of using Console Application.
First of all, simple steps are taken in order to set up Quantlib and Boost and build the Solution:
1. Install Visual Studio.
2. Make a directory where you will install Boost and Quantlib.
3. Install Boost library in your directory, current release is 1.56.0. You download boost from: boost.org->downloads->on the sourceforge.net site go to Home directory->boost-binaries->1.56.0->choose the file that corresponds to your current version of Visual Studio-> run the .exe file.
4. Download Quantlib from the official site quantlib.org, install it in your directory, current version is 1.4.
5. I use Visual Studio 10 therefore I run Quantlib_vc10.sln in the quantlib-1.4 directory.
6. In the Solution Explorer choose all 15 projects. Open Properties, Configuration: All Configurations, Platforms: All platforms.
7. In the VC++ directories choose Include Directories and add the boost_1_56-0 folder.
8. In the Library Directories add lib32-msvc-10.0 from the boost_1_56-0 folder.
9. Build Solution (press F7). It should look like the picture below:
Now we want to test Quantlib and Boost. We need to create a form with a button. By clicking the button we will receive Black-Scholes option price and greeks.
1. Create an empty CLR Project:File->New->Project. My project name is C1.
2. Right click on Source files->Add->New Item-Visual C++->UI->Windows Form. Two files will be created: Form1.h and Form1.cpp
3. Add button, textbox and Label to the form. I add 12 labels and 12 textboxes
4. Add Quantlib (Solution Explorer, Project Property pages, VC++ Directories, Include directories)
5. Add Quantlib/lib (Solution Explorer, Project Property pages, Linker, General, Additional Library Directories)
6. In the VC++ directories choose Include Directories and add the boost_1_56-0 folder if it is not already there.
7. In the Library Directories add lib32-msvc-10.0 from the boost_1_56-0 folder if it is not already there.
8. Create an entry point for the application to run. Add Entry.cpp file to the Project Source Files with the following code:
#include <windows.h>
#include “Form1.h”
using namespace C1;
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew Form1());
return 0;
}
7. In the Form1.h modify button1_Click as follows:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e);
8. Implement button1_Click function in the Form1.cpp file and add EuropeanBS() function to price an European option. The code looks like this:
#include “Form1.h”
#include <ql/quantlib.hpp>
#include <math.h>
namespace C1 {
using namespace QuantLib;
using namespace System;
double* EuropeanBS(){
double* myarr = new double[12];
Calendar calendar = TARGET();
Date todaysDate(9, Aug, 2012);
Date settlementDate(9, Aug, 2012);
Settings::instance().evaluationDate() = todaysDate;
Option::Type type(Option::Call);
Real underlying = 57.83;
Real strike = 62.50;
Spread dividendYield = 0;
Rate riskFreeRate = 0.00275;
Volatility volatility = 0.1954;
Date maturity(22, Sep, 2012);
DayCounter dayCounter = Actual365Fixed();
std::string method;
boost::shared_ptr<Exercise> europeanExercise(new EuropeanExercise(maturity));
Handle<Quote> underlyingH(boost::shared_ptr<Quote>(new SimpleQuote(underlying)));
Handle<YieldTermStructure> flatTermStructure(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)));
Handle<YieldTermStructure> flatDividendTS(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)));
Handle<BlackVolTermStructure> flatVolTS(boost::shared_ptr<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility,dayCounter)));
boost::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(type, strike));
boost::shared_ptr<BlackScholesMertonProcess> bsmProcess(new BlackScholesMertonProcess(underlyingH, flatDividendTS,flatTermStructure, flatVolTS));
VanillaOption europeanOption(payoff, europeanExercise);
method = “Black-Scholes: “;
europeanOption.setPricingEngine(boost::shared_ptr<PricingEngine>(new AnalyticEuropeanEngine(bsmProcess)));
myarr[0] = europeanOption.NPV();
myarr[1] = europeanOption.delta();
myarr[2] = europeanOption.deltaForward();
myarr[3] = europeanOption.gamma();
myarr[4] = europeanOption.elasticity();
myarr[5] = europeanOption.theta();
myarr[6] = europeanOption.thetaPerDay();
myarr[7] = europeanOption.vega();
myarr[8] = europeanOption.rho();
myarr[9] = europeanOption.dividendRho();
myarr[10] = europeanOption.strikeSensitivity();
myarr[11] = europeanOption.itmCashProbability();
return myarr;
}
System::Void Form1::button1_Click(System::Object^ sender, System::EventArgs^ e)
{
double* myarr1 = new double[12];
myarr1=EuropeanBS();
textBox1->Text = Convert::ToString(Math::Round(myarr1[0],4));
textBox2->Text = Convert::ToString(Math::Round(myarr1[1],4));
textBox3->Text = Convert::ToString(Math::Round(myarr1[2],4));
textBox4->Text = Convert::ToString(Math::Round(myarr1[3],4));
textBox5->Text = Convert::ToString(Math::Round(myarr1[4],4));
textBox6->Text = Convert::ToString(Math::Round(myarr1[5],4));
textBox7->Text = Convert::ToString(Math::Round(myarr1[6],4));
textBox8->Text = Convert::ToString(Math::Round(myarr1[7],4));
textBox9->Text = Convert::ToString(Math::Round(myarr1[8],4));
textBox10->Text = Convert::ToString(Math::Round(myarr1[9],4));
textBox11->Text = Convert::ToString(Math::Round(myarr1[10],4));
textBox12->Text = Convert::ToString(Math::Round(myarr1[11],4));
}
/*
System::Void Form1::W6(String^ strText)
{
this->textBox1->Text = strText;
}
*/
}
Build and run your Project. You should see something like the print screen below.
Warning!
If you run Visual Studio 12, you may get an error:
error C1189: #error :
If you dig into the file C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\atomic you will notice these lines:
#ifdef _M_CEE
#error
#endif /* _M_CEE */
You can disable these lines so the compilation error will disappear.