Questions: FdBlackScholesBarrierEngine

Posted by Sepp Imboden on
URL: http://quantlib.414.s1.nabble.com/Questions-FdBlackScholesBarrierEngine-tp8399.html

Dear all

I have two newbie problems.

I want to price a European D&I Put for an equity paying discrete dividends. For this purpose I took "QuantLib-1.2/test-suite/barrieroption.cpp" as a frame for my own piece of source (see bottom of this mail; "utilities.hpp" and "utilities.cpp" can be found in the dirctory "QuantLib-1.2/test-suite" of the QL source tree).

IR, volatility and the underlying's spot are defined as "SimpleQuote", the barrier option is of type "DividendBarrierOption" (see line 88 of code below).

1. Problem
-----------------
When running through the for-loop (line 121) I expected that changing the underlying's spot price (e.g. "spot -> setValue(123.4)", see line 124 of code below) would have an impact on calculated values of the barrier option (  e.g. "dividendBarrierOption.NPV()" ), but whenever I change the value of the underlying's spot, the calculated quantities remain unchanged.

As I use the Pricing Engine "FdBlackScholesBarrierEngine", I realized that in the file "ql/pricingengines/barrier/fdblackscholesbarrierengine.cpp" the constructor "FdBlackScholesBarrierEngine" is not defined as an Observer of the "GeneralizedBlackScholesProcess", which is the first argumet of the constructor.

Hence, I added a "registerWith(process_);" to the constructor "FdBlackScholesBarrierEngine" and the calculated quantities of my "dividendBarrierOption" became spot price sensitive.

Is adding "registerWith(process_);" to the constructor a reliable/reasonable/good way to obtain values sensitive to the spot price???
If not, can you give me some hints?


2. Problem
------------------
After having "solved" (?) my above 1st problem, I added an additional option of type "BarrierOption" but without any dividends (see line 65 of code), and set its "PricingEngine" to the very same copy of the PricingEngine (see lines 98 & 99 of code).

I then realized that QuantLib produces the very same NPV() etc. for the two options, ignoring that the one option is modeled with dividends while the other is modeled without dividends.
When creating two independent copies of the same PricingEngine (see line 58 - 63) and relating them to the two options (i.e. replacing one of the two "fdEngine" in lines 98 & 99 by "engine"), things seem to be fine.

Do I really have to have seperate pricing engines for the two barrier options?


Many thanks & kind regards,
Paul


<-------------------------------------------------- Source Code -------------------------------------------------->
#include "utilities.hpp"
#include <ql/time/calendars/switzerland.hpp>
#include <ql/time/daycounters/actual360.hpp>
#include <ql/time/date.hpp>
#include <ql/quotes/simplequote.hpp>
#include <ql/exercise.hpp>
#include <ql/processes/blackscholesprocess.hpp>
#include <ql/pricingengines/barrier/analyticbarrierengine.hpp>
#include <ql/pricingengines/barrier/mcbarrierengine.hpp>
#include <ql/pricingengines/barrier/fdblackscholesbarrierengine.hpp>
#include <ql/instruments/dividendbarrieroption.hpp>
#include <iostream>
#include <iomanip>

int main(){

    using namespace QuantLib;

    Calendar cal = Switzerland();
    DayCounter dc = Actual360();

    Date today = Date(30,Aug,2012);
    Date maturity = Date(20,Sep,2013);

    boost::shared_ptr<SimpleQuote> spot(new SimpleQuote(0.0));

    boost::shared_ptr<SimpleQuote> qRate(new SimpleQuote(0.0));
    boost::shared_ptr<YieldTermStructure> qTS =
                                   flatRate(today, qRate, dc);
    boost::shared_ptr<SimpleQuote> rRate(new SimpleQuote(0.0));

    boost::shared_ptr<YieldTermStructure> rTS =
                                   flatRate(today, rRate, dc);

    boost::shared_ptr<SimpleQuote> vol(new SimpleQuote(0.0));
    boost::shared_ptr<BlackVolTermStructure> volTS =
                                   flatVol(today, vol, dc);


    boost::shared_ptr<Exercise> exercise(new EuropeanExercise(maturity));

    spot -> setValue(8.835);
    qRate -> setValue(0.0);
    rRate ->setValue(0.0024890168);
    vol ->setValue(0.27183378);

    boost::shared_ptr<StrikedTypePayoff> payoff(
                 new PlainVanillaPayoff(Option::Put,8.75));

    boost::shared_ptr<BlackScholesMertonProcess> stochProcess(new
                BlackScholesMertonProcess(
                    Handle<Quote>(spot),
                    Handle<YieldTermStructure>(qTS),
                    Handle<YieldTermStructure>(rTS),
                    Handle<BlackVolTermStructure>(volTS)));


    boost::shared_ptr<PricingEngine> engine(
               new FdBlackScholesBarrierEngine(stochProcess, 400, 800));


    boost::shared_ptr<PricingEngine> fdEngine(
               new FdBlackScholesBarrierEngine(stochProcess, 400, 800));

    BarrierOption barrierOption(
                    Barrier::DownIn,
                    6.13,
                    0.0,
                    payoff,
                    exercise);

    std::vector<Date> dividendDates;
    std::vector<double> dividends;

    dividendDates.push_back(Date(14,Sep,2012));
    dividends.push_back(0.24);
    dividendDates.push_back(Date(14,Dec,2012));
    dividends.push_back(0.24);
    dividendDates.push_back(Date(14,Mar,2013));
    dividends.push_back(0.24);
    dividendDates.push_back(Date(14,May,2013));
    dividends.push_back(0.24);
    dividendDates.push_back(Date(14,Jul,2013));
    dividends.push_back(0.24);
    dividendDates.push_back(Date(14,Sep,2013));
    dividends.push_back(0.24);

    DividendBarrierOption dividendBarrierOption(
                    Barrier::DownIn,
                    6.13,
                    0.0,
                    payoff,
                    exercise,
                    dividendDates,
                    dividends);


    barrierOption.setPricingEngine(fdEngine);
    dividendBarrierOption.setPricingEngine(fdEngine);




    Real pvBarrier,deltaBarrier,gammaBarrier;
    Real pvDividendBarrier,deltaDividendBarrier,gammaDividendBarrier;



    Size width[] = {10,18,18,18,18,18,18};

    std::cout << std::setw(width[0]) << "Spot"
              << std::setw(width[1]) << "PV(no div.)"
              << std::setw(width[2]) << "PV(with div.)"
              << std::setw(width[3]) << "Delta(no div.)"
              << std::setw(width[4]) << "Delta(with div.)"
              << std::setw(width[5]) << "Gamma(no div.)"
              << std::setw(width[6]) << "Gamma(with div.)"
              << std::endl;


    for(int loop = 0;loop < 5;loop++)
    {
        Real loopS = 6.13+loop*0.1;
        spot->setValue(loopS);

        pvBarrier = barrierOption.NPV();
        deltaBarrier = barrierOption.delta();
        gammaBarrier = barrierOption.gamma();

        pvDividendBarrier = dividendBarrierOption.NPV();
        deltaDividendBarrier = dividendBarrierOption.delta();
        gammaDividendBarrier = dividendBarrierOption.gamma();

        std::cout << std::fixed;
        std::cout << std::setprecision(4);

        std::cout << std::setw(width[0]) << loopS
                  << std::setw(width[1]) << pvBarrier
                  << std::setw(width[2]) << pvDividendBarrier
                  << std::setw(width[3]) << deltaBarrier
                  << std::setw(width[4]) << deltaDividendBarrier
                  << std::setw(width[5]) << gammaBarrier
                  << std::setw(width[6]) << gammaDividendBarrier
                  << std::endl;
    }

    return 0;
}



------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users