You are here: TWiki > Quantlib Web > ProjectsToDo > FdDividendAmericanOptionInstability r4 - 18 Feb 2005 - 01:12 - TWikiGuest


Start of topic | Skip to actions
FdDividendAmericanOption seems to get unstable with large time grids....

#include <ql/quantlib.hpp>
#include <iostream>
 
 using namespace std;
 using namespace QuantLib;
 
 int main() {
   const unsigned timeSteps = 40;
   vector<unsigned> assetStepsA;
   assetStepsA.push_back(20);
   assetStepsA.push_back(40);
   assetStepsA.push_back(60);
   assetStepsA.push_back(70);
   assetStepsA.push_back(150);
   assetStepsA.push_back(300);


   vector<double> dividendA, dividendTimeA;
   dividendA.push_back(0.0);
   dividendTimeA.push_back(1e-4);
   vector<double> blankA, blankTimeA;


   double under=54.625;
   double strike=55;
   double dividendYield=0;
   //   double interestRate=0.052706;
   double interestRate=0.00;
   double expirationTime=0.126027;
   double sigma=0.282922;
 
 
   for (unsigned i=0; i<assetStepsA.size(); i++) {
     const unsigned assetSteps = assetStepsA[i];
 
     FdDividendAmericanOption opt(Option::Call, under,
                                  strike,
                                  dividendYield, interestRate,
                                  expirationTime, sigma,
                                  dividendA, dividendTimeA,
                                  timeSteps, assetSteps);
 
 
     cout << "assetSteps=" << assetSteps
          << " price=" << opt.value()
          << " delta=" << opt.delta()
          << " vega=" << opt.vega()
          << "\n";

     FdDividendAmericanOption opt1(Option::Call, under,
               strike,
               dividendYield, interestRate,
               expirationTime, sigma,
               blankA, blankTimeA,
               timeSteps, assetSteps);


     cout << "assetSteps=" << assetSteps
          << " price=" << opt1.value()
          << " delta=" << opt1.delta()
          << " vega=" << opt1.vega()
          << "\n";


   }
 
   return 0;
 }


The output says

assetSteps=20 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=20 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=40 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=40 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=60 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=60 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=70 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=70 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=150 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=150 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=300 price=-55928.3 delta=-3.58224e+06 vega=-290131
assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506


  • This still seems to happen when I put a return to not execute FdDividendOption?::executeIntermediateStep
  • The following are with executeIntermediateStep turned off

  • set dividendTimeA to zero - no problem
  • set to 0.1 - no problem
  • set to 1e-5 - Bug appears
assetSteps=300 price=-241141 delta=-1.64754e+07 vega=-1.80585e+06
assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506
  • set to 1e-4
assetSteps=300 price=-55928.3 delta=-3.58224e+06 vega=-290131
assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506
  • set to 1e-3 - Hmmm.... no bug....
  • set to 1e-6
assetSteps=300 price=-279253 delta=-1.92053e+07 vega=-2.15804e+06
assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506

  • Interesting thing is that it looks like that the bug is "switched on"


Almost there.....

I put a trace to see what numbers are being put into rollback

Calling rollback 0.126027 1e-06 40
Calling rollback 1e-06 0.00157534 40
Calling rollback 0.00157534 0 1
Calling rollback 0.126027 1e-06 40
Calling rollback 1e-06 0.00157534 40
Calling rollback 0.00157534 0 1
assetSteps=300 price=-279253 delta=-1.92053e+07 vega=-2.15804e+06
Calling rollback 0.126027 0.00315067 40
Calling rollback 0.00315067 0 1
Calling rollback 0.126027 0.00315067 40
Calling rollback 0.00315067 0 1
assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506
Notice how the wrong answer goes to 1e-06 and back up to 0.00157534

Hmmmmm!!!!!


GOT IT!!!!!

The problem is that

diff -u -r1.26 fdmultiperiodoption.cpp
--- fdmultiperiodoption.cpp     30 Dec 2004 11:44:17 -0000      1.26
+++ fdmultiperiodoption.cpp     18 Jan 2005 04:37:44 -0000
@@ -64,10 +64,11 @@
                        DecimalFormatter::toString(dates_[dateNumber_-1]) +
                        ", must be within the residual time of " +
                        DecimalFormatter::toString(residualTime) );
+            if (!firstDateIsZero_)
+                firstNonZeroDate_ = dates_[0];
+

             if (dateNumber_ >= 2){
-                if (!firstDateIsZero_)
-                    firstNonZeroDate_ = dates_[0];
                 for (Size j = 1; j < dateNumber_; j++)
                     QL_REQUIRE(dates_[j-1] < dates_[j],
                                "dates must be in increasing order:" +

firstNonZeroDate is not being called when there is only one dividend date. This causes the simulation to do a rollback step in reverse time, which of course destroys the simulation.

Here is the output from the corrected code

assetSteps=20 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=20 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=40 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=40 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=60 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=60 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=70 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=70 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=150 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=150 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506
assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506

Next step is to check in the patch and to include some TracingCode in quantlib that will help more quickly track down problems like this.


Post Mortem comments (JW)

  • I ended up going off on a few red herrings because of lack of familiarity with the code and with finance software in general. In hindsight, I was too quick to assume that the problem was an exotic issue rather than something more prosaic. There probably was a branch point which took me off to assume that the problem was in FdBsmOption? without actually testing it. Something that I probably should have done was to look at the test suite and see what paths worked.
  • Hopefully this wiki will save a lot of debugging time, because it will be possible to put all of the information in one place.
  • Personally, I think that trace facilities are pretty much essential. These sorts of weird and obscure bugs are going to start cropping up more and more frequently.
Edit | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r4 < r3 < r2 < r1 | More topic actions
Quantlib.FdDividendAmericanOptionInstability moved from Quantlib.FdAmericanOptionInstability on 17 Jan 2005 - 06:59 by TWikiGuest - put it back
Copyright ©2001-2008 by the contributors of Quantlib. Content released under the Modified BSD License.