00001
00020
#include <ql/quantlib.hpp>
00021
00022
using namespace QuantLib;
00023
00024
00025
int main(
int,
char* [])
00026 {
00027
try {
00028
QL_IO_INIT
00029
00030 std::cout <<
"Using " <<
QL_VERSION << std::endl << std::endl;
00031
00032
00033 Option::Type type(Option::Put);
00034
Real underlying = 36;
00035
Real strike = 40;
00036
Spread dividendYield = 0.00;
00037
Rate riskFreeRate = 0.06;
00038
Volatility volatility = 0.20;
00039
00040 Date todaysDate(15, May, 1998);
00041 Date settlementDate(17, May, 1998);
00042 Date exerciseDate(17, May, 1999);
00043 DayCounter rateDayCounter = Actual365();
00044
Time maturity = rateDayCounter.yearFraction(settlementDate,
00045 exerciseDate);
00046
00047 std::cout <<
"option type = " << OptionTypeFormatter::toString(type)
00048 << std::endl;
00049 std::cout <<
"Time to maturity = " << maturity
00050 << std::endl;
00051 std::cout <<
"Underlying price = " << underlying
00052 << std::endl;
00053 std::cout <<
"Strike = " << strike
00054 << std::endl;
00055 std::cout <<
"Risk-free interest rate = " << riskFreeRate
00056 << std::endl;
00057 std::cout <<
"dividend yield = " << dividendYield
00058 << std::endl;
00059 std::cout <<
"Volatility = " << volatility
00060 << std::endl;
00061 std::cout << std::endl;
00062
00063 std::string method;
00064
00065
Real value, discrepancy, rightValue, relativeDiscrepancy;
00066 rightValue = (type == Option::Put ? 4.48667344 : 2.17372645);
00067
00068 std::cout << std::endl ;
00069
00070
00071 std::cout <<
"Method\t\t\t\t Value\t\tDiscrepancy"
00072
"\tRel. Discr." << std::endl;
00073
00074 Date midlifeDate(19, November, 1998);
00075 std::vector<Date> exDates(2);
00076 exDates[0]=midlifeDate;
00077 exDates[1]=exerciseDate;
00078
00079 boost::shared_ptr<Exercise> exercise(
00080
new EuropeanExercise(exerciseDate));
00081 boost::shared_ptr<Exercise> amExercise(
00082
new AmericanExercise(settlementDate,
00083 exerciseDate));
00084 boost::shared_ptr<Exercise> berExercise(
new BermudanExercise(exDates));
00085
00086
00087 RelinkableHandle<Quote> underlyingH(
00088 boost::shared_ptr<Quote>(
new SimpleQuote(underlying)));
00089
00090
00091 RelinkableHandle<TermStructure> flatTermStructure(
00092 boost::shared_ptr<TermStructure>(
00093
new FlatForward(todaysDate, settlementDate,
00094 riskFreeRate, rateDayCounter)));
00095 RelinkableHandle<TermStructure> flatDividendTS(
00096 boost::shared_ptr<TermStructure>(
00097
new FlatForward(todaysDate, settlementDate,
00098 dividendYield, rateDayCounter)));
00099 RelinkableHandle<BlackVolTermStructure> flatVolTS(
00100 boost::shared_ptr<BlackVolTermStructure>(
00101
new BlackConstantVol(settlementDate, volatility)));
00102
00103 std::vector<Date> dates(4);
00104 dates[0] = settlementDate.plusMonths(1);
00105 dates[1] = exerciseDate;
00106 dates[2] = exerciseDate.plusMonths(6);
00107 dates[3] = exerciseDate.plusMonths(12);
00108 std::vector<Real> strikes(4);
00109 strikes[0] = underlying*0.9;
00110 strikes[1] = underlying;
00111 strikes[2] = underlying*1.1;
00112 strikes[3] = underlying*1.2;
00113
00114 Matrix vols(4,4);
00115 vols[0][0] = volatility*1.1; vols[0][1] = volatility;
00116 vols[0][2] = volatility*0.9; vols[0][3] = volatility*0.8;
00117 vols[1][0] = volatility*1.1; vols[1][1] = volatility;
00118 vols[1][2] = volatility*0.9; vols[1][3] = volatility*0.8;
00119 vols[2][0] = volatility*1.1; vols[2][1] = volatility;
00120 vols[2][2] = volatility*0.9; vols[2][3] = volatility*0.8;
00121 vols[3][0] = volatility*1.1; vols[3][1] = volatility;
00122 vols[3][2] = volatility*0.9; vols[3][3] = volatility*0.8;
00123 RelinkableHandle<BlackVolTermStructure> blackSurface(
00124 boost::shared_ptr<BlackVolTermStructure>(
00125
new BlackVarianceSurface(settlementDate, dates,
00126 strikes, vols)));
00127
00128 boost::shared_ptr<StrikedTypePayoff> payoff(
new
00129 PlainVanillaPayoff(type, strike));
00130
00131 boost::shared_ptr<BlackScholesProcess> stochasticProcess(
new
00132 BlackScholesProcess(
00133 underlyingH,
00134 flatDividendTS,
00135 flatTermStructure,
00136 flatVolTS));
00137
00138
00139 VanillaOption euroOption(stochasticProcess, payoff, exercise,
00140 boost::shared_ptr<PricingEngine>(
new AnalyticEuropeanEngine()));
00141
00142
00143 method =
"equivalent European option ";
00144 value = euroOption.NPV();
00145 std::cout << method <<
" "
00146 << DecimalFormatter::toString(value, 6) <<
"\t"
00147 <<
"N/A\t\t"
00148 <<
"N/A\t\t"
00149 << std::endl;
00150
00151
00152 VanillaOption option(stochasticProcess, payoff, amExercise);
00153
00154
Size timeSteps = 801;
00155
00156
00157 method =
"Binomial Jarrow-Rudd ";
00158 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00159
new BinomialVanillaEngine<JarrowRudd>(timeSteps)));
00160 value = option.NPV();
00161 discrepancy =
QL_FABS(value-rightValue);
00162 relativeDiscrepancy = discrepancy/rightValue;
00163 std::cout << method <<
" "
00164 << DecimalFormatter::toString(value, 6) <<
"\t"
00165 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00166 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00167 << std::endl;
00168
00169
00170 method =
"Binomial Cox-Ross-Rubinstein ";
00171 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00172
new BinomialVanillaEngine<CoxRossRubinstein>(timeSteps)));
00173 value = option.NPV();
00174 discrepancy =
QL_FABS(value-rightValue);
00175 relativeDiscrepancy = discrepancy/rightValue;
00176 std::cout << method <<
" "
00177 << DecimalFormatter::toString(value, 6) <<
"\t"
00178 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00179 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00180 << std::endl;
00181
00182
00183 method =
"Additive equiprobabilities ";
00184 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00185
new BinomialVanillaEngine<AdditiveEQPBinomialTree>(timeSteps)));
00186 value = option.NPV();
00187 discrepancy =
QL_FABS(value-rightValue);
00188 relativeDiscrepancy = discrepancy/rightValue;
00189 std::cout << method <<
" "
00190 << DecimalFormatter::toString(value, 6) <<
"\t"
00191 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00192 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00193 << std::endl;
00194
00195
00196 method =
"Binomial Trigeorgis ";
00197 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00198
new BinomialVanillaEngine<Trigeorgis>(timeSteps)));
00199 value = option.NPV();
00200 discrepancy =
QL_FABS(value-rightValue);
00201 relativeDiscrepancy = discrepancy/rightValue;
00202 std::cout << method <<
" "
00203 << DecimalFormatter::toString(value, 6) <<
"\t"
00204 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00205 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00206 << std::endl;
00207
00208
00209 method =
"Binomial Tian ";
00210 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00211
new BinomialVanillaEngine<Tian>(timeSteps)));
00212 value = option.NPV();
00213 discrepancy =
QL_FABS(value-rightValue);
00214 relativeDiscrepancy = discrepancy/rightValue;
00215 std::cout << method <<
" "
00216 << DecimalFormatter::toString(value, 6) <<
"\t"
00217 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00218 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00219 << std::endl;
00220
00221
00222 method =
"Binomial Leisen-Reimer ";
00223 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00224
new BinomialVanillaEngine<LeisenReimer>(timeSteps)));
00225 value = option.NPV();
00226 discrepancy =
QL_FABS(value-rightValue);
00227 relativeDiscrepancy = discrepancy/rightValue;
00228 std::cout << method <<
" "
00229 << DecimalFormatter::toString(value, 6) <<
"\t"
00230 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00231 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00232 << std::endl;
00233
00234
00235 method =
"Barone-Adesi and Whaley approx. ";
00236 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00237
new BaroneAdesiWhaleyApproximationEngine));
00238 value = option.NPV();
00239 discrepancy =
QL_FABS(value-rightValue);
00240 relativeDiscrepancy = discrepancy/rightValue;
00241 std::cout << method <<
" "
00242 << DecimalFormatter::toString(value, 6) <<
"\t"
00243 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00244 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00245 << std::endl;
00246
00247
00248 method =
"Bjerksund and Stensland approx. ";
00249 option.setPricingEngine(boost::shared_ptr<PricingEngine>(
00250
new BjerksundStenslandApproximationEngine));
00251 value = option.NPV();
00252 discrepancy =
QL_FABS(value-rightValue);
00253 relativeDiscrepancy = discrepancy/rightValue;
00254 std::cout << method <<
" "
00255 << DecimalFormatter::toString(value, 6) <<
"\t"
00256 << DecimalFormatter::toString(discrepancy, 6) <<
"\t"
00257 << DecimalFormatter::toString(relativeDiscrepancy, 6)
00258 << std::endl;
00259
00260
return 0;
00261 }
catch (std::exception& e) {
00262 std::cout << e.what() << std::endl;
00263
return 1;
00264 }
catch (...) {
00265 std::cout <<
"unknown error" << std::endl;
00266
return 1;
00267 }
00268 }