A simple FX-Option Example in QuantLib
Originally published September 2009, updated 10 May 2020 (move to Jekyll, add the link to online calculator.)
An online, Python, QuantPanel version of this calculation is available at http://quantpanel.bnikolic.co.uk/FxOption.
Here is a simple, bare-bones example of pricing an American FX vanilla option in QuantLib:
/**
Copyright (C) 2008, 2009 Bojan Nikolic <bojan@bnikolic.co.uk>
Simple bare-bones example of using QuantLib to price an FX option
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
Comments welcome at bojan@bnikolic.co.uk
*/
#include <iostream>
#include <ql/quantlib.hpp>
struct OptionInputs
{
QuantLib::Real S;
QuantLib::Real K;
/// Foreign rate
QuantLib::Spread f;
/// Domestic rate
QuantLib::Rate r;
QuantLib::Volatility vol;
QuantLib::Date maturity;
QuantLib::DayCounter dayCounter;
};
double
CRRPricing(QuantLib::VanillaOption &o,
boost::shared_ptr<QuantLib::GarmanKohlagenProcess> process,
QuantLib::Size timeSteps)
{
using namespace QuantLib;
boost::shared_ptr<PricingEngine> pe(new BinomialVanillaEngine<CoxRossRubinstein>(process,
timeSteps));
o.setPricingEngine(pe);
return o.NPV();
}
void FxOptEx(const OptionInputs &in,
const QuantLib::Date &todaysDate,
const QuantLib::Date &settlementDate)
{
using namespace QuantLib;
// set up dates
Calendar calendar = TARGET();
Settings::instance().evaluationDate() = todaysDate;
boost::shared_ptr<Exercise>
americanExercise(new AmericanExercise(settlementDate,
in.maturity));
Handle<Quote>
underlyingH(boost::shared_ptr<Quote>(new SimpleQuote(in.S)));
Handle<YieldTermStructure>
rTS(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate,
in.r,
in.dayCounter)));
Handle<YieldTermStructure>
fTS(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate,
in.f,
in.dayCounter)));
Handle<BlackVolTermStructure>
flatVolTS(boost::shared_ptr<BlackVolTermStructure>(new BlackConstantVol(settlementDate,
calendar,
in.vol,
in.dayCounter)));
boost::shared_ptr<StrikedTypePayoff>
payoff(new PlainVanillaPayoff(Option::Call,
in.K));
boost::shared_ptr<GarmanKohlagenProcess>
process(new GarmanKohlagenProcess(underlyingH,
fTS,
rTS,
flatVolTS));
VanillaOption amerOpt(payoff,
americanExercise);
double npv=CRRPricing(amerOpt,
process,
100);
std::cout<<"Option value:"
<<npv
<<std::endl;
}
int main(int, char* [])
{
using namespace QuantLib;
OptionInputs in;
in.S=100;
in.K=100;
in.f=0.05;
in.r=0.02;
in.vol=0.20;
in.maturity= Date(17, May, 1999);
in.dayCounter = Actual365Fixed();
FxOptEx(in,
Date(15, May, 1998),
Date(17, May, 1998));
}