Login  Register

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_);