American options, the Barone-Adesi & Whaley approximation and QuantLib

In this post, we shall implement the widely-used Barone-Adesi & Whaley approximation using the QuantLib library.

Here, our interest lies in futures options. For example, we would like to price options on agricultural futures quoted on the CME markets.

As Barone-Adesi & Whaley (1987) explain in their seminal paper, the cost of carrying any futures position is equal to 0. We thus set the cost-of-carry b = 0 to work out the approximation method proposed by these authors.

Introducing remarks

Most of the code used here to implement the BAW approximation is derived from previous posts. Nevertheles, some improvements are made:

– The program gets by itself today’s date, and associates it with the date the option price is calculated. This is done throught :

Date today = QuantLib::Date::todaysDate();
		Settings::instance().evaluationDate() = today;

– Option parameters are now set by the user at running-time. This is easily done by a std::cout and std::cin series:

		cout << "Call or put option (c/p)?: \t\t";
		cin >> optionType;

– The code is wrapped in an infinite loop. This way the program can be actually used as a simple option pricer for American futures options:

bool loopEnd = false;
do
{
} while (loopEnd != true);


The code that implements the BAW approximation

#include <ql\quantlib.hpp>

using std::cout;
using std::cin;
using std::endl;
using std::setprecision;
using std::string;

using namespace QuantLib;

int main(int, char*[]){

	bool loopEnd = false;
	do
	{

	try{

		// Option Parameters
		Option::Type type;
		Real underlying;
		Real strike;
		Rate riskFreeRate;
		Spread dividendYield = 0;
		Volatility volatility;
		double optionValue;

		std::string optionType;
		std::string c;

		int maturityD;
		int maturityM;
		int maturityY;

		cout << "Call or put option (c/p)?: \t\t";
		cin >> optionType;

		cout << "Enter expiration date (dd mm yyyy): \t";
		cin >> maturityD >> maturityM >> maturityY;

		cout << "Enter strike: \t\t\t\t";
		cin >> strike;

		cout << "Enter underlying price: \t\t";
		cin >> underlying;

		cout << "Enter volatility (%): \t\t\t";
		cin >> volatility;

		cout << "Enter risk free rate (%): \t\t";
		cin >> riskFreeRate;

		if((optionType == ("c")) || (optionType == "C"))
			type=Option::Call;
		else
			type=Option::Put;

		// Calendar stuff
		Calendar calendar = TARGET();
		Date today = QuantLib::Date::todaysDate();
		Settings::instance().evaluationDate() = today;
		DayCounter dayCounter = Actual365Fixed();
		Date maturity(maturityD, Month (maturityM), maturityY);

		// American exercise style option handler
		boost::shared_ptr<Exercise> americanExercise(
			new AmericanExercise(
			today, maturity));

		// Underlying price handler
		Handle<Quote> underlyingH(
			boost::shared_ptr<Quote>(
			new SimpleQuote(underlying)));

		// Yield term structure handler
		Handle<YieldTermStructure> flatTermStructure(
			boost::shared_ptr<YieldTermStructure>(
			new FlatForward(
			today,
			riskFreeRate/100,
			dayCounter)));

		// Dividend handler
		Handle<YieldTermStructure> flatDividendTermStructure(
			boost::shared_ptr<YieldTermStructure>(
			new FlatForward(
			today,
			dividendYield,
			dayCounter)));

		// Volatility handler
		Handle<BlackVolTermStructure> flatVolTermStructure(
			boost::shared_ptr<BlackVolTermStructure>(
			new BlackConstantVol(
			today,
			calendar,
			volatility/100,
			dayCounter)));

		// Payoff handler
		boost::shared_ptr<StrikedTypePayoff> payoff(
			new PlainVanillaPayoff(
			type,
			strike));

		// Black Scholes
		boost::shared_ptr<BlackScholesMertonProcess> BSMProcess(
			new BlackScholesMertonProcess(
			underlyingH,
			flatDividendTermStructure,
			flatTermStructure,
			flatVolTermStructure));

		// Option characteristics
		VanillaOption americanOption(payoff, americanExercise);

		// Pricing Engine : in this case BS for European options
		americanOption.setPricingEngine(
			boost::shared_ptr<PricingEngine>(
			new BaroneAdesiWhaleyApproximationEngine(
			BSMProcess)));

		optionValue = americanOption.NPV();

		// Outputting
		cout << endl;
		cout << "Option price :\t" << setprecision(5) << optionValue << endl;
		cout << endl;

		}
		catch (std::exception& e)
		{
			std::cerr << e.what() << endl;
			return 1;
		}
		catch (...)
		{
			std::cerr << "unknown error" << endl;
			return 1;
		}		

} while (loopEnd != true);
}


Concluding comments

This option pricer has been written quite easily, as it grounds on previous codes. The point is that QuantLib has a large variety of classes allowing to implement as many numerical as well as analytical schemes to price options. And, it is quite straightforward to re-engineer a piece of code so that to implement another scheme.

9 pensamientos en “American options, the Barone-Adesi & Whaley approximation and QuantLib

    1. édouard Autor de la entrada

      Hi, Peter. Thank you for your comments. My point in this article was to implement the BAW class of QL, the BAW method being a quadratic approximation to price American-type options. Just tell me if this isn’t the answer you were expecting!😉

      Responder
      1. Dmitri

        I’ve tried the above code but unfortunately I get the “NPV not provided” error. Do you know why this could be? My data’s ok – the AnalyticEuropeanEngine works fine on the data.

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s