|
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
assetSteps=300 price=-241141 delta=-1.64754e+07 vega=-1.80585e+06 assetSteps=300 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
assetSteps=300 price=-279253 delta=-1.92053e+07 vega=-2.15804e+06 assetSteps=300 price=2.01295 delta=0.49286 vega=7.73506
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.73506Notice 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.73506Next 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)
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
| ||||