Re: FdDividendAmericanOption
Posted by Joseph Wang on Dec 30, 2004; 10:50pm
URL: http://quantlib.414.s1.nabble.com/FdDividendAmericanOption-tp3453p3458.html
I'm suspecting that rescaling the terms causes the operator to break.
Attached is a proposed
fix that calculates BSMOperator from a flexible grid, that seems to
cause the numbers to
be more reasonable......
assetSteps=20 price=2.17038 delta=0.518664 vega=7.74307
assetSteps=40 price=2.16897 delta=0.516824 vega=7.71849
assetSteps=60 price=2.21022 delta=0.534935 vega=7.28234
assetSteps=70 price=2.22188 delta=0.590997 vega=8.0055
assetSteps=80 price=2.20972 delta=0.580363 vega=7.96264
assetSteps=100 price=2.19306 delta=0.560017 vega=7.90149
Index: ql/FiniteDifferences/bsmoperator.cpp
===================================================================
RCS file: /cvsroot/quantlib/QuantLib/ql/FiniteDifferences/bsmoperator.cpp,v
retrieving revision 1.16
diff -u -r1.16 bsmoperator.cpp
--- ql/FiniteDifferences/bsmoperator.cpp 12 May 2004 09:46:11 -0000 1.16
+++ ql/FiniteDifferences/bsmoperator.cpp 31 Dec 2004 06:20:46 -0000
@@ -16,6 +16,7 @@
*/
#include <ql/FiniteDifferences/bsmoperator.hpp>
+#include <ql/Math/array.hpp>
namespace QuantLib {
@@ -30,4 +31,22 @@
setMidRows(pd,pm,pu);
}
+ BSMOperator::BSMOperator(const Array &grid, Rate r,
+ Rate q, Volatility sigma)
+ : TridiagonalOperator(grid.size()) {
+ Real sigma2 = sigma*sigma;
+ Real nu = r-q-sigma2/2;
+ Size grid_size = grid.size();
+ for (Size i=1; i < grid_size - 1; i++) {
+ Real dxm = grid[i] - grid[i-1];
+ Real dxp = grid[i+1] - grid[i];
+ Real dxtotal = dxm+dxp;
+
+ Real pd = -(sigma2/dxm-nu)/dxtotal;
+ Real pu = -(sigma2/dxp+nu)/dxtotal;
+ Real pm = sigma2/(dxm*dxp)+r;
+ setMidRow(i, pd,pm,pu);
+ }
+ }
+
}
Index: ql/FiniteDifferences/bsmoperator.hpp
===================================================================
RCS file: /cvsroot/quantlib/QuantLib/ql/FiniteDifferences/bsmoperator.hpp,v
retrieving revision 1.16
diff -u -r1.16 bsmoperator.hpp
--- ql/FiniteDifferences/bsmoperator.hpp 12 May 2004 09:46:11 -0000 1.16
+++ ql/FiniteDifferences/bsmoperator.hpp 31 Dec 2004 06:20:47 -0000
@@ -24,6 +24,8 @@
#include <ql/FiniteDifferences/tridiagonaloperator.hpp>
+class Array;
+
namespace QuantLib {
//! Black-Scholes-Merton differential operator
@@ -32,6 +34,7 @@
public:
BSMOperator() {}
BSMOperator(Size size, Real dx, Rate r, Rate q, Volatility sigma);
+ BSMOperator(const Array &grid, Rate r, Rate q, Volatility sigma);
};
}
Index: ql/Pricers/fdbsmoption.cpp
===================================================================
RCS file: /cvsroot/quantlib/QuantLib/ql/Pricers/fdbsmoption.cpp,v
retrieving revision 1.21
diff -u -r1.21 fdbsmoption.cpp
--- ql/Pricers/fdbsmoption.cpp 13 May 2004 11:41:46 -0000 1.21
+++ ql/Pricers/fdbsmoption.cpp 31 Dec 2004 06:20:47 -0000
@@ -93,7 +93,7 @@
}
void FdBsmOption::initializeOperator() const {
- finiteDifferenceOperator_ = BSMOperator(gridPoints_, gridLogSpacing_,
+ finiteDifferenceOperator_ = BSMOperator(grid_,
riskFreeRate_, dividendYield_,
volatility_);