This example shows how to value an American equity option using all pricing methods for these options that are available in QuantLib. An American option is different from an European option in that it can be exercised by the holder at any time of their choosing (and spot price of underlying at that times is used to compute the pay-off). You can see a live interactive version at: http://quantpanel.bnikolic.co.uk/VanillaOption
This example uses the same data as one of the QuantLib C++ examples. It sets up an American option with a year-long maturity. A fixed volatility of 20% is assumed and the risk-free rate is taken to be 6%. A continuous dividend can be modelled by setting the “Dividend Yield” field – in this case however it set to zero.
The same option is valued with the full range of pricing engines that handle American options.
Evaluation Date |
1998-05-15 |
=qlSettingsSetEvaluationDate(RC[-1]) |
-> |
Evaluation Date |
1998-05-15 |
nil |
Settlement Date |
1998-05-17 |
nil |
-> |
Settlement Date |
1998-05-17 |
nil |
Calendar |
TARGET |
nil |
-> |
Calendar |
TARGET |
nil |
Volatility |
0.2 |
nil |
-> |
Volatility |
0.2 |
nil |
Day Counter |
Actual/365 (Fixed) |
nil |
-> |
Day Counter |
Actual/365 (Fixed) |
nil |
Volatility Object |
=qlBlackConstantVol(RC[-1],R[-4]C,R[-3]C,R[-2]C,R[-1]C) |
nil |
-> |
Volatility Object |
Volatility Object#0000 |
nil |
Underlying |
36 |
nil |
-> |
Underlying |
36 |
nil |
Strike |
40 |
nil |
-> |
Strike |
40 |
nil |
Dividend Yield |
0 |
nil |
-> |
Dividend Yield |
0 |
nil |
Risk Free Rate |
0.06 |
<-We lived in a different world then! |
-> |
Risk Free Rate |
0.06 |
<-We lived in a different world then! |
Maturity |
1999-05-17 |
nil |
-> |
Maturity |
1999-05-17 |
nil |
Stochastic Process |
=qlGeneralizedBlackScholesProcess(RC[-1],R[-6]C,R[-5]C,R[-7]C,R[-10]C,R[-2]C,R[-3]C) |
nil |
-> |
Stochastic Process |
Stochastic Process#0000 |
nil |
American |
=qlAmericanExercise(RC[-1],R[-11]C,R[-2]C,) |
nil |
-> |
American |
American#0000 |
nil |
Payoff type |
Vanilla |
nil |
-> |
Payoff type |
Vanilla |
nil |
Call/Put |
PUT |
nil |
-> |
Call/Put |
PUT |
nil |
Payoff obj |
=qlStrikedTypePayoff(RC[-1],R[-2]C,R[-1]C,R[-8]C) |
nil |
-> |
Payoff obj |
Payoff obj#0000 |
nil |
Pricint Engine |
=qlPricingEngine(RC[-1],”BAWA”,R[-5]C) |
nil |
-> |
Pricint Engine |
Pricint Engine #0000 |
nil |
Option |
=qlVanillaOption(RC[-1],R[-2]C,R[-5]C) |
nil |
-> |
Option |
Option#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4596276137764779 |
nil |
nil |
-> nil |
|||||
Bjerkund/Stesland |
nil |
nil |
-> |
Bjerkund/Stesland |
nil |
nil |
BSA Pricing |
=qlPricingEngine(RC[-1],”BSA”,R[-11]C) |
nil |
-> |
BSA Pricing |
BSA Pricing#0001 |
nil |
OptionBSA |
=qlVanillaOption(RC[-1],R[-8]C,R[-11]C) |
nil |
-> |
OptionBSA |
OptionBSA#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4530641751031776 |
nil |
nil |
-> nil |
|||||
Finite differences for American options |
nil |
nil |
-> |
Finite differences for American options |
nil |
nil |
FD pricer |
=qlBinomialPricingEngine(RC[-1],”FDA”,R[-17]C,50) |
nil |
-> |
FD pricer |
FD pricer#0002 |
nil |
OptionFD |
=qlVanillaOption(RC[-1],R[-14]C,R[-17]C) |
nil |
-> |
OptionFD |
OptionFD#0001 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4745748160235035 |
nil |
nil |
-> nil |
|||||
Jarrow Rudd |
nil |
nil |
-> |
Jarrow Rudd |
nil |
nil |
JR Pricer |
=qlBinomialPricingEngine(RC[-1],”JR”,R[-23]C,50) |
nil |
-> |
JR Pricer |
JR Pricer#0001 |
nil |
OptionJR |
=qlVanillaOption(RC[-1],R[-20]C,R[-23]C) |
nil |
-> |
OptionJR |
OptionJR#0001 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4886636278348471 |
nil |
nil |
-> nil |
|||||
Cox-Ross-Rubstein |
nil |
nil |
-> |
Cox-Ross-Rubstein |
nil |
nil |
CRR Pricer |
=qlBinomialPricingEngine(RC[-1],”CRR”,R[-29]C,50) |
nil |
-> |
CRR Pricer |
CRR Pricer#0000 |
nil |
OptionCRR |
=qlVanillaOption(RC[-1],R[-26]C,R[-29]C) |
nil |
-> |
OptionCRR |
OptionCRR#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4847672856576235 |
nil |
nil |
-> nil |
|||||
Additive EQP |
nil |
nil |
-> |
Additive EQP |
nil |
nil |
AEQP Pricer |
=qlBinomialPricingEngine(RC[-1],”AEQPB”,R[-35]C,50) |
nil |
-> |
AEQP Pricer |
AEQP Pricer#0000 |
nil |
OptionAEQP |
=qlVanillaOption(RC[-1],R[-32]C,R[-35]C) |
nil |
-> |
OptionAEQP |
OptionAEQP#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4629496731665164 |
nil |
nil |
-> nil |
|||||
Trigeorgis |
nil |
nil |
-> |
Trigeorgis |
nil |
nil |
Tri Pricer |
=qlBinomialPricingEngine(RC[-1],”TRI”,R[-41]C,50) |
nil |
-> |
Tri Pricer |
Tri Pricer#0000 |
nil |
OptionTRI |
=qlVanillaOption(RC[-1],R[-38]C,R[-41]C) |
nil |
-> |
OptionTRI |
OptionTRI#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4855240094847817 |
nil |
nil |
-> nil |
|||||
Tian binomial |
nil |
nil |
-> |
Tian binomial |
nil |
nil |
Tian pricer |
=qlBinomialPricingEngine(RC[-1],”TIAN”,R[-47]C,50) |
nil |
-> |
Tian pricer |
Tian pricer#0000 |
nil |
OptionTIAN |
=qlVanillaOption(RC[-1],R[-44]C,R[-47]C) |
nil |
-> |
OptionTIAN |
OptionTIAN#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4815100021527146 |
nil |
nil |
-> nil |
|||||
Binomial Leisen-Reimer |
nil |
nil |
-> |
Binomial Leisen-Reimer |
nil |
nil |
Lr pricer |
=qlBinomialPricingEngine(RC[-1],”LR”,R[-53]C,50) |
nil |
-> |
Lr pricer |
Lr pricer#0000 |
nil |
OptionLR |
=qlVanillaOption(RC[-1],R[-50]C,R[-53]C) |
nil |
-> |
OptionLR |
OptionLR#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4585109303899362 |
nil |
nil |
-> nil |
|||||
Binomial Joshi |
nil |
nil |
-> |
Binomial Joshi |
nil |
nil |
Joshi pricer |
=qlBinomialPricingEngine(RC[-1],”JOSHI”,R[-59]C,50) |
nil |
-> |
Joshi pricer |
Joshi pricer#0000 |
nil |
OptionJOSHI |
=qlVanillaOption(RC[-1],R[-56]C,R[-59]C) |
nil |
-> |
OptionJOSHI |
OptionJOSHI#0000 |
nil |
set engine |
=qlInstrumentSetPricingEngine(R[-1]C,R[-2]C) |
nil |
-> |
set engine |
nil |
nil |
NPV |
=qlInstrumentNPV(R[-2]C) |
nil |
-> |
NPV |
4.4585473771306097 |
nil |
Here is the same example in QLW – QuantLib-Addin like interface from Java and Python
// Copyright (C) 2012 Bojan Nikolic <bojan@bnikolic.co.uk>
//
import co.uk.bnikolic.qlw.property_t;
import co.uk.bnikolic.qlw.qlw;
import co.uk.bnikolic.qlw.StringVector;
import co.uk.bnikolic.qlw.LongVector;
import co.uk.bnikolic.qlw.PropertyVector;
public class AmericanOptionExample {
public static void main(String[] args) throws Exception {
property_t today=new property_t(35930);
property_t settlementdate=new property_t(35932);
property_t exercisedate=new property_t(36297);
property_t dcc=new property_t("Actual/365 (Fixed)");
qlw.qlSettingsSetEvaluationDate(today,
qlw.OH_NULL());
String payoff=qlw.qlStrikedTypePayoff("payoff",
"Vanilla",
"Put",
40.0,
qlw.OH_NULL(),
qlw.OH_NULL(),
qlw.OH_NULL(),
false
);
String exercise=qlw.qlAmericanExercise("exercise",
settlementdate,
exercisedate,
new property_t(false),
qlw.OH_NULL(),
qlw.OH_NULL(),
false);
String option=qlw.qlVanillaOption("option",
payoff,
exercise,
qlw.OH_NULL(),
qlw.OH_NULL(),
false);
String vol=qlw.qlBlackConstantVol("vol",
settlementdate,
"TARGET",
0.2,
dcc,
qlw.OH_NULL(),
qlw.OH_NULL(),
false);
String process=qlw.qlGeneralizedBlackScholesProcess("process",
"vol",
36.0,
dcc,
settlementdate,
0.06,
0.00,
qlw.OH_NULL(),
qlw.OH_NULL(),
false) ;
String AmericanEngines[] = { "BAWA", "BSA", "FDA", "JR", "CRR", "AEQPB", "TRI", "TIAN", "LR", "JOSHI"};
for (String ename : AmericanEngines ) {
String pengine;
if ( ename == "BAWA" || ename == "BSA")
{
pengine=qlw.qlPricingEngine("pengine-"+ename,
ename,
process,
qlw.OH_NULL(),
qlw.OH_NULL(),
false);
}
else
{
pengine=qlw.qlBinomialPricingEngine("pengine-"+ename,
ename,
process,
50,
qlw.OH_NULL(),
qlw.OH_NULL(),
false);
}
qlw.qlInstrumentSetPricingEngine(option, pengine,
qlw.OH_NULL());
System.out.println("NPV using " + ename +": "+ qlw.qlInstrumentNPV(option,
qlw.OH_NULL()));
}
}
}