For learning purpose, I'm trying to price, with quantlib, an European option using the Cox-Ross-Rubinstein tree approach.
Some examples are provided in the file EquityOption.cpp
that is part of the library.
However I would like to price it, without using dates (that is to say, without any day convention, calendar, expiration date ...) but using only a fraction of year as maturity (ex : with T = 0.5
).
As far I read, all examples only consider the case with dates
expressed as "real" dates (ex : 11/01/2016) and not expressed as time
to maturity (ex: T= 0.1), i.e. the standard textbook case.
Since the library relies heavily on engines, and that those engines are mainly designed with dates, I have some difficulties to get rid off the dates.
For the BS analytical formula, it is easy since the core of the engine relies on the BlackScholesCalculator that is dates independent (see a full example here) .
However for the binomial case, there is no such date-independent routine (no BinomialCalculator..), and the DiscretizedVanillaOption
class requires an engine's variable as input to instantiate it..
One plausible solution that came to my mind is to find two "fakes" dates, by playing with a pseudo .yearFraction(FakeStartDate, FakeEndDate);
function to find two optimal dates that match the fraction I want. Then to use these two dates to compute the price. However this strategy seems quiet cumbersome for a such simple request.
How can I compute the value of an option using the binomial approach with a maturity expressed as a fraction of year in quantlib ?
Please see below what I have done so far, I'm stuck to the line that instantiate the DiscretizedVanillaOption
.
Date t0(1);
Option::Type type = Option::Put;
Real S0 = spot_;
Real K = strike_;
Spread q = dividendYield_;
Rate r = interestRate_;
Volatility sigma = volatility_;
Settings::instance().evaluationDate() = t0;
Handle<Quote> underlyingH((boost::static_pointer_cast<Quote>(boost::make_shared<SimpleQuote>(S0))));
Handle<YieldTermStructure> flatDividendTS((boost::static_pointer_cast<YieldTermStructure>(boost::make_shared<FlatForward>(t0, q, dayCounter))));
Handle<YieldTermStructure> flatTermStructure((boost::static_pointer_cast<YieldTermStructure>(boost::make_shared<FlatForward>(t0, r, dayCounter))));
Handle<BlackVolTermStructure> flatVolTS((boost::static_pointer_cast<BlackVolTermStructure>(boost::make_shared<BlackConstantVol>(t0, calendar, sigma, dayCounter))));
boost::shared_ptr<BlackScholesMertonProcess> bsmProcess(new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS));
boost::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(type, K));
Size timeSteps_ = 200;
Time maturity = 0.2;
TimeGrid grid(maturity, timeSteps_);
boost::shared_ptr<CoxRossRubinstein> tree(new CoxRossRubinstein(bsmProcess, maturity, timeSteps_, payoff->strike()));
boost::shared_ptr<BlackScholesLattice<CoxRossRubinstein> > lattice( new BlackScholesLattice<CoxRossRubinstein>(tree, r, maturity, timeSteps_));
DiscretizedVanillaOption option(/* ????*/,bsmProcess, grid);//<--------- First argument Here ?
option.initialize(lattice, maturity);
double price = option.presentValue();