QuantLib icon indicating copy to clipboard operation
QuantLib copied to clipboard

MCDiscreteArithmeticASEngine is insensitive to exercise date

Open machalejm opened this issue 5 years ago • 7 comments

Average strike option should have payoff H = max(0, S(T) - sum(S(t_i))) where 1<=i<=n.

Currently T == t_n always, and the valuation is independent of the exercise date of the option. I don't think this is right (or necessary) but I'm open to correction.

This behaviour can be seen in the testsuite in the 1st test case in testMCDiscreteArithmeticAverageStrike. Set r = q = 0, and run the test twice. First time normally, second time increasing the exercise date by e.g. 1 year.

machalejm avatar Jun 15 '19 23:06 machalejm

If you set r=0, the discount factor is 1 at each future date, and that's why the price no longer depends on the exercise date. With r != 0, changing the exercise date changes the price.

lballabio avatar Aug 13 '19 12:08 lballabio

Hi Luigi, Average Strike (call) option pays max(0, Spot at exercise - average over a set of dates). The last of the averaging dates does not need to coincide with the exercise date. i.e. the exercise date is an observation date for the spot and (assuming vol>0) changing this date should affect the price even when r=q=0. Here's the description for FINCAD and on investopedia. As it stands I think it's not possible to support the general case directly due to MCDiscreteAveragingAsianEngine<RNG,S>::timeGrid() not taking in the exercise date.

machalejm avatar Aug 13 '19 16:08 machalejm

Ok, now I actually see what you wrote. You're saying that the average doesn't include the exercise date, but the final spot observation to be compared with the resulting strike is at the exercise date, is that correct? In that case, yes, the engine doesn't support that and should be fixed.

lballabio avatar Aug 13 '19 16:08 lballabio

Hi Luigi,

You're saying that the average doesn't include the exercise date, but the final spot observation to be compared with the resulting strike is at the exercise date, is that correct?

Yes, this is what I mean. I'd be happy to do this myself, if you agree it's something that should be supported.

machalejm avatar Aug 13 '19 17:08 machalejm

Yes, I agree. I'm not sure if the current behavior is useful at all; but it would be nice if, for a few releases, there was a boolean parameter allowing to switch between the old and new behavior, so that users can analyze the changes in numbers and switch in their own time.

lballabio avatar Aug 14 '19 14:08 lballabio

I think it would make more sense for such a flag to be a part of the Asian option itself, rather some kind of configuration being passed to the pricing engine.

If that seems reasonable, then the change to DiscreteAveragingAsianOption could be as simple as:

DiscreteAveragingAsianOption::DiscreteAveragingAsianOption(
        Average::Type averageType,
        Real runningAccumulator,
        Size pastFixings,
        const std::vector<Date>& fixingDates,
        const ext::shared_ptr<StrikedTypePayoff>& payoff,
        const ext::shared_ptr<Exercise>& exercise,
        bool lastFixingAtExpiry=false)
    : OneAssetOption(payoff, exercise),
      averageType_(averageType), runningAccumulator_(runningAccumulator),
      pastFixings_(pastFixings), fixingDates_(fixingDates) {
		
		if(lastFixingAtExpiry)
		{
			fixingDates_.push_back(exercise->lastDate());
		}
		
        std::sort(fixingDates_.begin(), fixingDates_.end());
    }

Such a change should maintain backwards compatibility as far as I can tell.

FlyingTwigster avatar Nov 09 '19 19:11 FlyingTwigster

No, that wouldn't work as suggested in the issue. The price at the exercise date should be forecast and compared with the strike, but the exercise date itself shouldn't be included in the fixing dates (because the corresponding price shouldn't be included in the average).

lballabio avatar Dec 13 '19 14:12 lballabio