barrier options greeks lead to seg.fault.
Posted by Dirk Eddelbuettel on
URL: http://quantlib.414.s1.nabble.com/barrier-options-greeks-lead-to-seg-fault-tp10521.html
Hi all,
I spent some time rolling my RQuantLib package forward to new 0.3.5
standards. I generally followed the code I saw in test-suite. All in all,
things seems to be working now, and I am starting to get the hang of the
design: bloody elegant if I dare say so!
One problem, though, seems to be that I no longer get greeks for barriers:
edd@basebud:/tmp> g++ -Wall -o barrier_blows_up barrier_blows_up.cc -lQuantLib
edd@basebud:/tmp> ./barrier_blows_up
Value: 3.73825
Aborted (core dumped)
edd@basebud:/tmp>
which happens as soon as I call barrierOption.delta() I tried both the
default engine and the MC engine, but no luck.
A full example, trimmed down from the R interface code I had, is included.
I probably am doing something wromg. Just let me know what :)
Dirk
#include <ql/quantlib.hpp> // make QuantLib known
using namespace QuantLib;
extern "C" {
Handle<TermStructure> makeFlatCurve(const Handle<Quote>& forward,
DayCounter dc) {
Date today = Date::todaysDate();
return Handle<TermStructure>(
new FlatForward(today, today,
RelinkableHandle<Quote>(forward), dc));
}
Handle<BlackVolTermStructure> makeFlatVolatility(const Handle<Quote>& vol,
DayCounter dc) {
Date today = Date::todaysDate();
return Handle<BlackVolTermStructure>(
new BlackConstantVol(today,
RelinkableHandle<Quote>(vol), dc));
}
int main(void) {
char *barrType = "downin";
char *type = "call";
double underlying = 100;
double strike = 100;
Spread dividendYield = 0.02;
Rate riskFreeRate = 0.03;
Time maturity = 0.5;
int length = int(maturity * 360); // FIXME: this could be better
double volatility = 0.4;
double barrier = 90;
double rebate = 0.0;
Barrier::Type barrierType;
if (!strcmp(barrType, "downin")) {
barrierType = Barrier::DownIn;
} else if (!strcmp(barrType, "upin")) {
barrierType = Barrier::UpIn;
} else if (!strcmp(barrType, "downout")) {
barrierType = Barrier::DownOut;
} else if (!strcmp(barrType, "upout")) {
barrierType = Barrier::UpOut;
} else {
std::cerr << "Unexpected barrier type " << barrType << " aborting\n";
}
Option::Type optionType;
if (!strcmp(type, "call")) {
optionType = Option::Call;
} else if (!strcmp(type, "put")) {
optionType = Option::Put;
} else if (!strcmp(type, "straddle")) {
optionType = Option::Straddle;
} else {
std::cerr << "Unexpected option type " << type << " aborting\n";
}
// new QuantLib 0.3.5 framework
DayCounter dc = Actual360();
Handle<SimpleQuote> spot(new SimpleQuote(0.0));
Handle<SimpleQuote> qRate(new SimpleQuote(0.0));
Handle<TermStructure> qTS = makeFlatCurve(qRate, dc);
Handle<SimpleQuote> rRate(new SimpleQuote(0.0));
Handle<TermStructure> rTS = makeFlatCurve(rRate, dc);
Handle<SimpleQuote> vol(new SimpleQuote(0.0));
Handle<BlackVolTermStructure> volTS = makeFlatVolatility(vol, dc);
Date today = Date::todaysDate();
Date exDate = today.plusDays(length);
Handle<Exercise> exercise(new EuropeanExercise(exDate));
spot ->setValue(underlying);
qRate->setValue(dividendYield);
rRate->setValue(riskFreeRate);
vol ->setValue(volatility);
Handle<StrikedTypePayoff> payoff(new PlainVanillaPayoff(optionType, strike));
Handle<BlackScholesStochasticProcess>
stochProcess(new BlackScholesStochasticProcess(
RelinkableHandle<Quote>(spot),
RelinkableHandle<TermStructure>(qTS),
RelinkableHandle<TermStructure>(rTS),
RelinkableHandle<BlackVolTermStructure>(volTS)));
Size timeSteps = 1;
bool antitheticVariate = false;
bool controlVariate = false;
Size requiredSamples = 10000;
double requiredTolerance = 0.02;
Size maxSamples = 1000000;
bool isBiased = false;
Handle<PricingEngine> engine(new AnalyticBarrierEngine);
Handle<PricingEngine> mcEngine(
new MCBarrierEngine<PseudoRandom>(timeSteps, antitheticVariate,
controlVariate, requiredSamples,
requiredTolerance, maxSamples,
isBiased, 5));
BarrierOption barrierOption(barrierType,
barrier,
rebate,
stochProcess,
payoff,
exercise,
//mcEngine);
engine);
std::cout << "Value: " << barrierOption.NPV() << std::endl;
std::cout << "Delta: " << barrierOption.delta() << std::endl;
std::cout << "Gamma: " << barrierOption.gamma() << std::endl;
std::cout << "Vega: " << barrierOption.vega() << std::endl;
std::cout << "Theta: " << barrierOption.theta() << std::endl;
std::cout << "Rho: " << barrierOption.rho() << std::endl;
std::cout << "divRho:" << barrierOption.dividendRho() << std::endl;
}
}
--
The relationship between the computed price and reality is as yet unknown.
-- From the pac(8) manual page