|
From: animesh s. <ani...@gm...> - 2010-08-31 12:17:57
|
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
|
|
From: Kakhkhor A. <kab...@gm...> - 2010-09-02 11:07:27
|
Forwarding... > 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 |
|
From: Luigi B. <lui...@gm...> - 2010-08-31 15:21:43
|
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" |
|
From: animesh s. <ani...@gm...> - 2010-08-31 19:40:36
|
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
|
|
From: animesh s. <ani...@gm...> - 2010-08-31 20:14:54
|
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 |
|
From: Luigi B. <lui...@gm...> - 2010-09-01 07:06:51
|
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 |
|
From: Luigi B. <lui...@gm...> - 2010-09-01 08:24:35
|
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" |
|
From: animesh s. <ani...@gm...> - 2010-09-02 10:20:58
|
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
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: animesh s. <ani...@gm...> - 2010-09-02 12:10:08
|
Thanks a lot. Just one minor thing I noticed in blackscholesprocess.hpp
dS(t, S) = (r(t) - q(t) - \frac{\sigma(t, S)^2}{2}) dt
+ \sigma dW_t.
The above process is not possible, coz you can't have sigma(t,S). The
above equation is derived only because sigma is constant. It's a bit
misleading, Can I make the change to the correct version
dS(t, S) = (r(t) - q(t) - \frac{\sigma^2}{2}) dt
+ \sigma dW_t
It's a one line change, In the last few lines of my blog I have given
the proof.
http://quantanalysis.wordpress.com/2010/08/21/
Just read the ending portion. /
/
On 9/2/10 4:37 PM, Kakhkhor Abdijalilov wrote:
> Forwarding...
>
>> 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
> ------------------------------------------------------------------------------
> 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-dev mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-dev
>
--
Regards,
Animesh Saxena
(http://quantanalysis.wordpress.com)
Ph: (+91)9920098221
|
|
From: Luigi B. <lui...@gm...> - 2010-09-10 15:10:45
|
On Thu, 2010-09-02 at 17:39 +0530, animesh saxena wrote:
> Thanks a lot. Just one minor thing I noticed in
> blackscholesprocess.hpp
>
> dS(t, S) = (r(t) - q(t) - \frac{\sigma(t, S)^2}{2}) dt
> + \sigma dW_t.
>
> The above process is not possible, coz you can't have sigma(t,S).
Except you do. If sigma is not constant, you might not derive all the
usual equations. But you can define the process above just the same.
Luigi
--
Any software problem can be solved by adding another layer of
indirection.
-- David J. Wheeler
|