Himalayan Option Worries

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Himalayan Option Worries

animesh
  Below is the sample code for Himalayan Option valuation. It works for
BlackScholes process but if I change it to slightly fancier
Merton76Process (Jumps), it throws out an ugly SIG ABORT exception. Can
anyone help me in figuring out the mistake. "Just copy paste the code
below to test it out".
Thanks in advance!

Date today = Settings::instance().evaluationDate();

     DayCounter dc = Actual360();
     std::vector<Date> fixingDates;
     for (Size i=0; i<5; ++i)
         fixingDates.push_back(today+i*90);

     Real strike = 100.0;
     HimalayaOption option(fixingDates, strike);

     Handle<YieldTermStructure> riskFreeRate(flatRate(today, 0.05, dc));

     std::vector<boost::shared_ptr<StochasticProcess1D> > processes(4);

     boost::shared_ptr<SimpleQuote> spot(new SimpleQuote(100));
     boost::shared_ptr<SimpleQuote> qRate(new SimpleQuote(0.01));
     boost::shared_ptr<YieldTermStructure> qTS = flatRate(today, qRate, dc);
     boost::shared_ptr<SimpleQuote> rRate(new SimpleQuote(0.05));
     boost::shared_ptr<YieldTermStructure> rTS = flatRate(today, rRate, dc);
     boost::shared_ptr<SimpleQuote> vol(new SimpleQuote(0.20));
     boost::shared_ptr<BlackVolTermStructure> volTS = flatVol(today,
vol, dc);


     boost::shared_ptr<SimpleQuote> jumpIntensity(new SimpleQuote(1));
     boost::shared_ptr<SimpleQuote> meanLogJump(new SimpleQuote(0.2));
     boost::shared_ptr<SimpleQuote> jumpVol(new SimpleQuote(0.2));

    processes[0]= boost::shared_ptr<StochasticProcess1D>(new
Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));
     processes[1]= boost::shared_ptr<StochasticProcess1D>(new
Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));
     processes[2]= boost::shared_ptr<StochasticProcess1D>(new
Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));
     processes[3]= boost::shared_ptr<StochasticProcess1D>(new
Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));



     Matrix correlation(4,4);
     correlation[0][1] = 0.29;
     correlation[0][2] = 0.29;
     correlation[0][3] = 0.39;
     correlation[1][0] = 0.49;
     correlation[1][2] = 0.59;
     correlation[1][3] = 0.69;

     correlation[2][2] = 0.19;
     correlation[2][3] = 0.29;

     correlation[3][0] = correlation[0][3];
     correlation[3][1] = correlation[1][3];
     correlation[3][2] = correlation[2][3];
     correlation[2][0] = correlation[0][2];
     correlation[2][1] = correlation[1][2];
     correlation[1][1] = 1.00;

     correlation[0][0] = 1.00;
     correlation[3][3] = 1.00;


     BigNatural seed = 42;
     int i_samples;
     i_samples = 4999;
     Size fixedSamples;
     boost::shared_ptr<StochasticProcessArray> process(new
StochasticProcessArray(processes, correlation));
     Real value;
     
option.setPricingEngine(MakeMCHimalayaEngine<PseudoRandom>(process).withSamples(fixedSamples).withSeed(seed));
     value = option.NPV();



--
Regards,
Animesh Saxena

(http://quantanalysis.wordpress.com)
Ph: (+91)9920098221


------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Pointer Casting

animesh
I located the error in the code. I think this is probably due to design.
Generally people would like to price options using different processes. For example Himalayan Option is priced using BlackScholes process in the example. When I change it to another process like Merton76Process (which also is Stochastic1D - as per the guidelines), I should be able to price it. The error is when it delegates to casting to generalized Black Scholes process, the following code in file mchimalayaengine.hpp.

    template <class RNG, class S>
    inline
    boost::shared_ptr<typename MCHimalayaEngine<RNG,S>::path_pricer_type>
    MCHimalayaEngine<RNG,S>::pathPricer() const {

        boost::shared_ptr<GeneralizedBlackScholesProcess> process =
            boost::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(
                                                      processes_->process(0));

        QL_REQUIRE(process, "Black-Scholes process required");

        return boost::shared_ptr<
                         typename MCHimalayaEngine<RNG,S>::path_pricer_type>(
            new HimalayaMultiPathPricer(arguments_.payoff,
                                        process->riskFreeRate()->discount(
                                           arguments_.exercise->lastDate())));
    }

The cast is throwing the error. If I change it to "STATIC CAST", the error is gone!
        boost::shared_ptr<GeneralizedBlackScholesProcess> process =

            boost::static_pointer_cast<GeneralizedBlackScholesProcess>(
                                                      processes_->process(0));


The developer's might have better suggestions. Any views on this?? Is this a design problem?
Thanks in advance.


On 8/31/10 1:57 AM, animesh saxena wrote:
 Below is the sample code for Himalayan Option valuation. It works for BlackScholes process but if I change it to slightly fancier Merton76Process (Jumps), it throws out an ugly SIG ABORT exception. Can anyone help me in figuring out the mistake. "Just copy paste the code below to test it out".
Thanks in advance!

Date today = Settings::instance().evaluationDate();

    DayCounter dc = Actual360();
    std::vector<Date> fixingDates;
    for (Size i=0; i<5; ++i)
        fixingDates.push_back(today+i*90);

    Real strike = 100.0;
    HimalayaOption option(fixingDates, strike);

    Handle<YieldTermStructure> riskFreeRate(flatRate(today, 0.05, dc));

    std::vector<boost::shared_ptr<StochasticProcess1D> > processes(4);

    boost::shared_ptr<SimpleQuote> spot(new SimpleQuote(100));
    boost::shared_ptr<SimpleQuote> qRate(new SimpleQuote(0.01));
    boost::shared_ptr<YieldTermStructure> qTS = flatRate(today, qRate, dc);
    boost::shared_ptr<SimpleQuote> rRate(new SimpleQuote(0.05));
    boost::shared_ptr<YieldTermStructure> rTS = flatRate(today, rRate, dc);
    boost::shared_ptr<SimpleQuote> vol(new SimpleQuote(0.20));
    boost::shared_ptr<BlackVolTermStructure> volTS = flatVol(today, vol, dc);


    boost::shared_ptr<SimpleQuote> jumpIntensity(new SimpleQuote(1));
    boost::shared_ptr<SimpleQuote> meanLogJump(new SimpleQuote(0.2));
    boost::shared_ptr<SimpleQuote> jumpVol(new SimpleQuote(0.2));

   processes[0]= boost::shared_ptr<StochasticProcess1D>(new Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));
    processes[1]= boost::shared_ptr<StochasticProcess1D>(new Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));
    processes[2]= boost::shared_ptr<StochasticProcess1D>(new Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));
    processes[3]= boost::shared_ptr<StochasticProcess1D>(new Merton76Process(Handle<Quote>(spot),Handle<YieldTermStructure>(qTS),Handle<YieldTermStructure>(rTS),Handle<BlackVolTermStructure>(volTS),Handle<Quote>(jumpIntensity),Handle<Quote>(meanLogJump),Handle<Quote>(jumpVol)));



    Matrix correlation(4,4);
    correlation[0][1] = 0.29;
    correlation[0][2] = 0.29;
    correlation[0][3] = 0.39;
    correlation[1][0] = 0.49;
    correlation[1][2] = 0.59;
    correlation[1][3] = 0.69;

    correlation[2][2] = 0.19;
    correlation[2][3] = 0.29;

    correlation[3][0] = correlation[0][3];
    correlation[3][1] = correlation[1][3];
    correlation[3][2] = correlation[2][3];
    correlation[2][0] = correlation[0][2];
    correlation[2][1] = correlation[1][2];
    correlation[1][1] = 1.00;

    correlation[0][0] = 1.00;
    correlation[3][3] = 1.00;


    BigNatural seed = 42;
    int i_samples;
    i_samples = 4999;
    Size fixedSamples;
    boost::shared_ptr<StochasticProcessArray> process(new StochasticProcessArray(processes, correlation));
    Real value;
    option.setPricingEngine(MakeMCHimalayaEngine<PseudoRandom>(process).withSamples(fixedSamples).withSeed(seed));
    value = option.NPV();




-- 
Regards,
Animesh Saxena

(http://quantanalysis.wordpress.com)
Ph: (+91)9920098221

------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: [Quantlib-dev] Pointer Casting

Luigi Ballabio
On Tue, 2010-08-31 at 17:47 +0530, animesh saxena wrote:
> I located the error in the code. I think this is probably due to
> design.
> Generally people would like to price options using different
> processes. For example Himalayan Option is priced using BlackScholes
> process in the example. When I change it to another process like
> Merton76Process (which also is Stochastic1D - as per the guidelines),
> I should be able to price it.

Yes, in principle. But while the path generation does work with a
generic process, the McHimalaya path pricer calls a method from the
BlackScholes interface, namely, riskFreeRate().  The method is not in
the Stochastic1D interface, so we need to cast.

> The cast is throwing the error.

It should.

>  If I change it to "STATIC CAST", the error is gone!
>         boost::shared_ptr<GeneralizedBlackScholesProcess> process =
>
> boost::static_pointer_cast<GeneralizedBlackScholesProcess>(
>
> processes_->process(0));

Honestly, I have no idea why this works. The process you're passing is
not a GeneralizedBlackScholesProcess, so the cast you're forcing should
not succeed.  It might just so happen that the bits align right, but
that's not guaranteed to be portable.

As for a better solution, I'm not sure I have it.  It could be that
instead of an array of Black-Scholes processes, the Himalaya engine
takes a generic process and a discount curve (so it doesn't have to
retrieve the risk-free curve.)

Luigi


--

Just remember what ol' Jack Burton does when the earth quakes, the
poison arrows fall from the sky, and the pillars of Heaven shake. Yeah,
Jack Burton just looks that big old storm right in the eye and says,
"Give me your best shot. I can take it."
-- Jack Burton, "Big trouble in Little China"



------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: [Quantlib-dev] Pointer Casting

animesh
  You are right, It compiled once and now it just gave out BAD_ACCESS
error.
Here's what I am trying to do just to get the simulation work. I added
the mchimalayanengine.hpp file to my project and changed it, and in my
main code I change the header file path to #include
"mchimalayanengine.hpp" (My new file).

In this I just changed....the class

         boost::shared_ptr<Merton76Process> process =
boost::dynamic_pointer_cast<Merton76Process>(processes_->process(0));
    //     QL_REQUIRE(process, "Black-Scholes process required");

         return boost::shared_ptr<typename
MCHimalayaEngine<RNG,S>::path_pricer_type>(new
HimalayaMultiPathPricer(arguments_.payoff,process->riskFreeRate()->discount(arguments_.exercise->lastDate())));

Now if I debug the code executes till after this line even with a
dynamic cast. I checked that merton76Process has a riskFreeRate method.
Now after all this it gives out a SIGABRT error. Still trying to
understand why it is so!


On 8/31/10 7:26 PM, Luigi Ballabio wrote:

> On Tue, 2010-08-31 at 17:47 +0530, animesh saxena wrote:
>> I located the error in the code. I think this is probably due to
>> design.
>> Generally people would like to price options using different
>> processes. For example Himalayan Option is priced using BlackScholes
>> process in the example. When I change it to another process like
>> Merton76Process (which also is Stochastic1D - as per the guidelines),
>> I should be able to price it.
> Yes, in principle. But while the path generation does work with a
> generic process, the McHimalaya path pricer calls a method from the
> BlackScholes interface, namely, riskFreeRate().  The method is not in
> the Stochastic1D interface, so we need to cast.
>
>> The cast is throwing the error.
> It should.
>
>>   If I change it to "STATIC CAST", the error is gone!
>>          boost::shared_ptr<GeneralizedBlackScholesProcess>  process =
>>
>> boost::static_pointer_cast<GeneralizedBlackScholesProcess>(
>>
>> processes_->process(0));
> Honestly, I have no idea why this works. The process you're passing is
> not a GeneralizedBlackScholesProcess, so the cast you're forcing should
> not succeed.  It might just so happen that the bits align right, but
> that's not guaranteed to be portable.
>
> As for a better solution, I'm not sure I have it.  It could be that
> instead of an array of Black-Scholes processes, the Himalaya engine
> takes a generic process and a discount curve (so it doesn't have to
> retrieve the risk-free curve.)
>
> Luigi
>
>

--
Regards,
Animesh Saxena

(http://quantanalysis.wordpress.com)
Ph: (+91)9920098221


------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: [Quantlib-dev] Pointer Casting

animesh
Also another thing I will point out. Maybe you can understand this better.
There is no evolve() method in merton76process.hpp.
So I think even when casting works perfectly as per the below mentioned changes, it can't price as it's trying to build up the path. Not sure why evolve method is not there. Without evolve the merton76process should not work at all for other things too. Am I missing something here?






On 9/1/10 1:10 AM, animesh saxena wrote:
 You are right, It compiled once and now it just gave out BAD_ACCESS error.
Here's what I am trying to do just to get the simulation work. I added the mchimalayanengine.hpp file to my project and changed it, and in my main code I change the header file path to #include "mchimalayanengine.hpp" (My new file).

In this I just changed....the class

        boost::shared_ptr<Merton76Process> process = boost::dynamic_pointer_cast<Merton76Process>(processes_->process(0));
   //     QL_REQUIRE(process, "Black-Scholes process required");

        return boost::shared_ptr<typename MCHimalayaEngine<RNG,S>::path_pricer_type>(new HimalayaMultiPathPricer(arguments_.payoff,process->riskFreeRate()->discount(arguments_.exercise->lastDate())));

Now if I debug the code executes till after this line even with a dynamic cast. I checked that merton76Process has a riskFreeRate method. Now after all this it gives out a SIGABRT error. Still trying to understand why it is so!


On 8/31/10 7:26 PM, Luigi Ballabio wrote:
On Tue, 2010-08-31 at 17:47 +0530, animesh saxena wrote:
I located the error in the code. I think this is probably due to
design.
Generally people would like to price options using different
processes. For example Himalayan Option is priced using BlackScholes
process in the example. When I change it to another process like
Merton76Process (which also is Stochastic1D - as per the guidelines),
I should be able to price it.
Yes, in principle. But while the path generation does work with a
generic process, the McHimalaya path pricer calls a method from the
BlackScholes interface, namely, riskFreeRate().  The method is not in
the Stochastic1D interface, so we need to cast.

The cast is throwing the error.
It should.

  If I change it to "STATIC CAST", the error is gone!
         boost::shared_ptr<GeneralizedBlackScholesProcess>  process =

boost::static_pointer_cast<GeneralizedBlackScholesProcess>(

processes_->process(0));
Honestly, I have no idea why this works. The process you're passing is
not a GeneralizedBlackScholesProcess, so the cast you're forcing should
not succeed.  It might just so happen that the bits align right, but
that's not guaranteed to be portable.

As for a better solution, I'm not sure I have it.  It could be that
instead of an array of Black-Scholes processes, the Himalaya engine
takes a generic process and a discount curve (so it doesn't have to
retrieve the risk-free curve.)

Luigi




-- 
Regards,
Animesh Saxena

(http://quantanalysis.wordpress.com)
Ph: (+91)9920098221

------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: [Quantlib-dev] Pointer Casting

Luigi Ballabio
On Wed, 2010-09-01 at 01:44 +0530, animesh saxena wrote:
> Also another thing I will point out. Maybe you can understand this
> better.
> There is no evolve() method in merton76process.hpp.

It inherits the generic implementation in StochasticProcess1D.

Luigi


--

Vin: It's like this fellow I knew in El Paso. One day, he just took
all his clothes off and jumped in a mess of cactus. I asked him that
same question, "Why?"
Calvera: And?
Vin: He said, "It seemed like a good idea at the time."
-- The Magnificent Seven



------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: [Quantlib-dev] Pointer Casting

Luigi Ballabio
On Wed, 2010-09-01 at 09:06 +0200, Luigi Ballabio wrote:
> On Wed, 2010-09-01 at 01:44 +0530, animesh saxena wrote:
> > Also another thing I will point out. Maybe you can understand this
> > better.
> > There is no evolve() method in merton76process.hpp.
>
> It inherits the generic implementation in StochasticProcess1D.

However, it lacks the methods such as drift() etc which are required by
evolve(). You're right, it's currently not usable as a process; it's
just a container for the curves and the other data.

Luigi


--

The first thing we do, let's kill all the lawyers.
-- W. Shakespeare, "King Henry VI, Part II"



------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: [Quantlib-dev] Pointer Casting

Kakhkhor Abdijalilov
static_pointer_cast on smart pointer will perform static_cast on the
contained pointer. static_cast will never fail at compiler time
(unless you try to cast away qualifiers such as const or volatile).
But if the conversion is illegal, the code will fail at runtime.
dynamic_cast will check at compile time if the pointer is being
downcast. If target is not inherited from the source, dynamic_cast
will refuse to compile.

static_cast cast is faster then dynamic_cast, but inherently unsafe.
In the above example it is used not in performance critical place.

Hope it help.

------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Open Discussion

animesh
  Thanks for your inputs.
I observed a pattern in some exotic options. Correct me if I am wrong.
Similar to himalayan option, in variance swap engine also we have the
following code
MCVarianceSwapEngine(
              const boost::shared_ptr<GeneralizedBlackScholesProcess>&
process

Since most of the engines are specifically using
GeneralizedBlackScholesProcess it's impossible to value the option using
any other process. Practically a person would like to value the
instrument using any possible process. After struggling with
Merton76Process for valuing Himalayan option I tried to get my head
around with HestonProcess. It wasn't even remotely possible. Yes I could
do the same in excel, but again excel can't do 9Million simulations
which Quantlib can do in seconds :). That's why I am trying to replace
my excel side of modeling with C++ QuantLib!

So what I want to try is "make the above dependency more generic". It
should be possible in some way. Any inputs from you guys will help a lot.

Thanks again,
Animesh Saxena

(http://quantanalysis.wordpress.com)
Ph: (+91)9920098221




On 9/1/10 5:09 PM, Kakhkhor Abdijalilov wrote:

> static_pointer_cast on smart pointer will perform static_cast on the
> contained pointer. static_cast will never fail at compiler time
> (unless you try to cast away qualifiers such as const or volatile).
> But if the conversion is illegal, the code will fail at runtime.
> dynamic_cast will check at compile time if the pointer is being
> downcast. If target is not inherited from the source, dynamic_cast
> will refuse to compile.
>
> static_cast cast is faster then dynamic_cast, but inherently unsafe.
> In the above example it is used not in performance critical place.
>
> Hope it help.
>
> ------------------------------------------------------------------------------
> This SF.net Dev2Dev email is sponsored by:
>
> Show off your parallel programming skills.
> Enter the Intel(R) Threading Challenge 2010.
> http://p.sf.net/sfu/intel-thread-sfd
> _______________________________________________
> QuantLib-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>



------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users