0

I try to build a pyd-file with QuantLib and Boost where I want to calculate the NPV for a barrier option. However the QuantLib pyd throws:

RuntimeError: end must be large than start

The error originates from the following Quantlib class in uniform1dmesher.hpp:

class Uniform1dMesher : public Fdm1dMesher {
public:
    Uniform1dMesher(Real start, Real end, Size size)
    : Fdm1dMesher(size) {
        QL_REQUIRE(end > start, "end must be large than start");

        const Real dx = (end-start)/(size-1);

        for (Size i=0; i < size-1; ++i) {
            locations_[i] = start + i*dx;
            dplus_[i] = dminus_[i+1] = dx;
        }

        locations_.back() = end;
        dplus_.back() = dminus_.front() = Null<Real>();
    }
};

My c++-code is the following:

struct OptionInputs
{
  QuantLib::Real S;
  QuantLib::Real K;
  QuantLib::Spread f;
  QuantLib::Rate r;
  QuantLib::Volatility vol;
  QuantLib::Date maturity;
  QuantLib::DayCounter dayCounter;
};

double FxOptEx(const OptionInputs &in,
          const QuantLib::Date &todaysDate,
          const QuantLib::Date &settlementDate)
{
  using namespace QuantLib;

  Calendar calendar = TARGET();
  Settings::instance().evaluationDate() = todaysDate;
  QuantLib::Real rebate = 0.05;

  Size timeGird = 365;
  Size underlyingGird = 100;
  Size dampingSteps = 0;
  Real theta = 0.05;
  bool localVolatility = true;

  boost::shared_ptr<Exercise> europeanExercise(
            new EuropeanExercise(
                in.maturity));
  Handle<Quote>
    underlyingH(boost::shared_ptr<Quote>(new SimpleQuote(in.S)));

  Handle<YieldTermStructure>
    rTS(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate,
                                                           in.r,
                                                           in.dayCounter)));
  Handle<YieldTermStructure>
    fTS(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate,
                                                           in.f,
                                                           in.dayCounter)));
  Handle<BlackVolTermStructure>
    flatVolTS(boost::shared_ptr<BlackVolTermStructure>(new BlackConstantVol(settlementDate,
                                                                         calendar,
                                                                         in.vol,
                                                                         in.dayCounter)));

  boost::shared_ptr<StrikedTypePayoff>
    payoff(new PlainVanillaPayoff(Option::Put,
                               in.K));

  boost::shared_ptr<BlackScholesMertonProcess> blackScholesMertonProcess(new BlackScholesMertonProcess(
                                        underlyingH,
                                        fTS,
                                            rTS,
                                        flatVolTS));


        BarrierOption barrierOption(
            QuantLib::Barrier::UpIn,
            QuantLib::Option::Put,
            rebate,
            payoff, 
            europeanExercise);

        barrierOption.setPricingEngine(
            boost::shared_ptr<PricingEngine>(
                new FdBlackScholesBarrierEngine (
                    blackScholesMertonProcess,
                    timeGird,
                    underlyingGird,
                    dampingSteps,
                    FdmSchemeDesc::ImplicitEuler(),
                    localVolatility,
                    -Null< Real >())));


  return barrierOption.NPV();
}

struct FXOption
{
  double value;
  void set(int S, int K, double f, double r, double vol, std::string maturity, std::string dayCounter)
  {
    OptionInputs in;
    in.S=S;
    in.K=K;
    in.f=f;
    in.r=r;
    in.vol=vol;
    in.maturity=QuantLib::DateParser::parseISO(maturity);
    if (dayCounter == "Actual365Fixed")
    {
        in.dayCounter = Actual365Fixed();
    }
    value = FxOptEx(in, Date(15, May, 1998), Date(17, May, 1998));
  }

  double get()
  {
      return value;
  }

};


using namespace boost::python;
BOOST_PYTHON_MODULE(quant)
{

    class_<FXOption>("FXOption")
        .def("get", &FXOption::get)
        .def("set", &FXOption::set)
    ;
}

Any idea why this error is thrown?

johansson.lc
  • 322
  • 2
  • 12
  • Well, obviously, `end` is not greater than `start`. It would help if you discover where the constructor of `Uniform1dMesher` is called. You should really try with a debugger. – rodrigo Apr 23 '14 at 21:28
  • Where are you using `Uniform1dMesher`? It's not used in the code you've posted. – ooga Apr 23 '14 at 21:28
  • @ooga: I would guess that `Uniform1dMesher` is a subclass of some of the classes instantiated in the posted code, but not sure which one... – rodrigo Apr 23 '14 at 21:29
  • @rodrigo Right. That makes sense. – ooga Apr 23 '14 at 21:31
  • I believe it is more of a QuantLib specific question so I removed the Boost-python and C++ tags – johansson.lc Apr 24 '14 at 09:03

1 Answers1

0

Sorry I'm late to the party.

Difficult to say without seeing the actual invocation, but could it be that the maturity of the option is earlier than the settlement date?

Luigi Ballabio
  • 4,128
  • 21
  • 29