Re: QuEP 5: using replaceable pricing engines.
Posted by Luigi Ballabio-4 on Dec 28, 2001; 7:03am
URL: http://quantlib.414.s1.nabble.com/QuEP-5-using-replaceable-pricing-engines-tp1827p1829.html
Tjena Johan,
thanks for the kind words.
At 03:25 PM 12/27/01 +0000, johan bosaeus wrote:
>A possible extension could be to make use of an abstract factory (Gang of
>Four, Design Patterns), in order to create "sets" of
><parameter, result, engine and instrument> objects. For example, one
>subclass of such a factory could be "EuropeanOptionWithXXEngineFactory".
>The create() method of that class should create all relevant objects and
>"link" them together the way you describe. What do you think?
Well, I think this is an external layer that can be easily added on top of
the design. Being lazy though, I wouldn't start writing factories for all
the XXXOptionWithYYYEngines---I would probably write each of them as I need it.
Also, the QuEP didn't mention the possibility to create an option with an
engine and change it later (mostly because I didn't give it much thought)
but it would be straightforward to do it. In this case, it might be a bit
confusing to create the option with a strategy hidden inside a factory, and
later change the calculation model by explicitly passing the engine. For
instance, the following code (with Handles removed for clarity)
// here the option parameters (real-world quantities) are well separated
// from the engine and its own parameters (implementation details)
EuropeanOption opt(Option::Call, underlying, strike, dividendYield,
termStructure, maturity, volatility,
EuropeanMCEngine(accuracy));
// now we reprice it with another engine
opt.setEngine(AnalyticEuropeanEngine())
looks to me more consistent and less confusing than
// option and calculation parameters are not separated
EuropeanOption opt = EuropeanOptionWithMCEngine::create(
Option::Call, underlying, strike, dividendYield,
termStructure, maturity, volatility, accuracy)
// now we reprice it with another engine
opt.setEngine(AnalyticEuropeanEngine())
// what is this engine thing now? I didn't see it when I created the option.
// and what happened to accuracy anyway? Is it still used or is it lost?
>You are using "degenerated" base classes for arguments and results. Have
>you considered using a template as the engine subclass instead. Where the
>template parameters indicate which type of parameters and results you are
>using as "strategies"? It's just an alternative, which, of my knowledge,
>is used extensively. (For example in ACE/TAO (www.cs.wustl.edu/¨schmidt)).
I admit that the template design you suggest is not entirely clear to me,
so please do correct me if I'm wrong. I kind of suspect that the
templatization would propagate to the given option class, i.e., the option
should be an EuropeanOption<ParameterType,ResultType> in order to be able
to interact with an EuropeanEngine<ParameterType,ResultType>. I'd rather
trade this for a bit more run-time flexibility---such as the possibility of
setting a different engine to an already constructed option. Also,
scripting languages come to mind towards which we export the library, such
as Python. The latter doesn't know about templates, which means that two
different instantiations of the same template class would have to be
exported as two different classes in Python. This would be against the goal
of having, e.g., a single "European option" concept.
However, it might just be that I misunderstood your proposal---wouldn't be
the first time, either :)
Thanks again for the feedback,
Luigi