american options delta leads to seg.fault.

Posted by Dirk Eddelbuettel on
URL: http://quantlib.414.s1.nabble.com/american-options-delta-leads-to-seg-fault-tp10543.html

All,

This is similar to the one I reported last week concerning barrier options.
In this case a simple delta() call on an American option leads to a
seg.fault.  There is a fair chance that I am setting this up the wrong --
suggestions would be welcome -- but I guess QL should not segfault.

Here is how I am building and running the example leading to the segfault:

edd@basebud:/tmp> g++ -Wall -o ao_segfault ao_segfault.cc -lQuantLib
edd@basebud:/tmp> ./ao_segfault
Value: 11.3656
Aborted (core dumped)
edd@basebud:/tmp>

The code is below.

Regards,  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));
  }

  enum EngineType { Analytic,
                    JR, CRR, EQP, TGEO, TIAN, LR,
                    PseudoMonteCarlo, QuasiMonteCarlo };

  Handle<VanillaOption>
  makeOption(const Handle<StrikedTypePayoff>& payoff,
             const Handle<Exercise>& exercise,
             const Handle<Quote>& u,
             const Handle<TermStructure>& q,
             const Handle<TermStructure>& r,
             const Handle<BlackVolTermStructure>& vol,
             EngineType engineType) {

    Size binomialSteps = 251;
    Handle<PricingEngine> engine;
    switch (engineType) {
    case Analytic:
      engine = Handle<PricingEngine>(new AnalyticEuropeanEngine);
      break;
    case JR:
      engine = Handle<PricingEngine>(
                 new BinomialVanillaEngine<JarrowRudd>(binomialSteps));
      break;
    case CRR:
      engine = Handle<PricingEngine>(
                new BinomialVanillaEngine<CoxRossRubinstein>(binomialSteps));
    case EQP:
      engine = Handle<PricingEngine>(
                new BinomialVanillaEngine<AdditiveEQPBinomialTree>(
                                                           binomialSteps));
      break;
    case TGEO:
      engine = Handle<PricingEngine>(
                new BinomialVanillaEngine<Trigeorgis>(binomialSteps));
      break;
    case TIAN:
      engine = Handle<PricingEngine>(
                new BinomialVanillaEngine<Tian>(binomialSteps));
      break;
    case LR:
      engine = Handle<PricingEngine>(
                new BinomialVanillaEngine<LeisenReimer>(binomialSteps));
      break;
    case PseudoMonteCarlo:
      engine = MakeMCEuropeanEngine<PseudoRandom>().withStepsPerYear(1)
        .withTolerance(0.05)
        .withSeed(42);
      break;
    case QuasiMonteCarlo:
      engine = MakeMCEuropeanEngine<LowDiscrepancy>().withStepsPerYear(1)
        .withSamples(1023);
      break;
    default:
      QL_FAIL("Unknown engine type");
    }


    Handle<BlackScholesStochasticProcess>
      stochProcess(new
         BlackScholesStochasticProcess(
             RelinkableHandle<Quote>(u),
             RelinkableHandle<TermStructure>(q),
             RelinkableHandle<TermStructure>(r),
             RelinkableHandle<BlackVolTermStructure>(vol)));

    return
      Handle<VanillaOption>(new
            VanillaOption(stochProcess, payoff, exercise, engine));
  }

  int main(void) {
   
    Option::Type optionType = Option::Call;
    Date today = Date::todaysDate();

    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;

    // new framework as per QuantLib 0.3.5
    DayCounter dc = Actual360();
    Handle<SimpleQuote> spot(new SimpleQuote(0.0));
    Handle<SimpleQuote> vol(new SimpleQuote(0.0));
    Handle<BlackVolTermStructure> volTS = makeFlatVolatility(vol,dc);
    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);

    Date exDate = today.plusDays(length);
    Handle<Exercise> exercise(new EuropeanExercise(exDate));
    //Handle<Exercise> exercise(new AmericanExercise(today, exDate));
    Handle<StrikedTypePayoff>
      payoff(new PlainVanillaPayoff(optionType, strike));
    Handle<VanillaOption> option = makeOption(payoff, exercise, spot,
                                              qTS, rTS, volTS,
                                              JR); // engine
                                              //TGEO); // engine
    spot->setValue(underlying);
    qRate->setValue(dividendYield);
    rRate->setValue(riskFreeRate);
    vol->setValue(volatility);


    std::cout << "Value: " << option->NPV() << std::endl;
    std::cout << "Delta: " << option->delta() << std::endl;

  }
}





--
The relationship between the computed price and reality is as yet unknown.  
                                             -- From the pac(8) manual page