Ejemplo n.º 1
0
        public FdmHestonEquityPart(FdmMesher mesher,
                                   YieldTermStructure rTS,
                                   YieldTermStructure qTS,
                                   FdmQuantoHelper quantoHelper      = null,
                                   LocalVolTermStructure leverageFct = null)
        {
            varianceValues_ = new Vector(0.5 * mesher.locations(1));
            dxMap_          = new FirstDerivativeOp(0, mesher);
            dxxMap_         = new SecondDerivativeOp(0, mesher).mult(0.5 * mesher.locations(1));
            mapT_           = new TripleBandLinearOp(0, mesher);
            mesher_         = mesher;
            rTS_            = rTS;
            qTS_            = qTS;
            quantoHelper_   = quantoHelper;
            leverageFct_    = leverageFct;

            // on the boundary s_min and s_max the second derivative
            // d^2V/dS^2 is zero and due to Ito's Lemma the variance term
            // in the drift should vanish.
            FdmLinearOpLayout   layout  = mesher_.layout();
            FdmLinearOpIterator endIter = layout.end();

            for (FdmLinearOpIterator iter = layout.begin(); iter != endIter;
                 ++iter)
            {
                if (iter.coordinates()[0] == 0 ||
                    iter.coordinates()[0] == layout.dim()[0] - 1)
                {
                    varianceValues_[iter.index()] = 0.0;
                }
            }
            volatilityValues_ = Vector.Sqrt(2 * varianceValues_);
        }
 public FdHestonVanillaEngine(
     HestonModel model,
     FdmQuantoHelper quantoHelper,
     int tGrid, int xGrid, int vGrid, int dampingSteps,
     FdmSchemeDesc schemeDesc,
     LocalVolTermStructure leverageFct)
     : base(model)
 {
     tGrid_              = tGrid;
     xGrid_              = xGrid;
     vGrid_              = vGrid;
     dampingSteps_       = dampingSteps;
     schemeDesc_         = schemeDesc;
     leverageFct_        = leverageFct;
     strikes_            = new List <double>();
     cachedArgs2results_ = new List <Pair <DividendVanillaOption.Arguments, OneAssetOption.Results> >();
     quantoHelper_       = quantoHelper;
 }
Ejemplo n.º 3
0
        public FdmHestonOp(FdmMesher mesher,
                           HestonProcess hestonProcess,
                           FdmQuantoHelper quantoHelper      = null,
                           LocalVolTermStructure leverageFct = null)
        {
            correlationMap_ = new SecondOrderMixedDerivativeOp(0, 1, mesher)
                              .mult(hestonProcess.rho() * hestonProcess.sigma()
                                    * mesher.locations(1));

            dyMap_ = new FdmHestonVariancePart(mesher,
                                               hestonProcess.riskFreeRate().currentLink(),
                                               hestonProcess.sigma(),
                                               hestonProcess.kappa(),
                                               hestonProcess.theta());
            dxMap_ = new FdmHestonEquityPart(mesher,
                                             hestonProcess.riskFreeRate().currentLink(),
                                             hestonProcess.dividendYield().currentLink(),
                                             quantoHelper,
                                             leverageFct);
        }
Ejemplo n.º 4
0
        public FdBlackScholesVanillaEngine(
            GeneralizedBlackScholesProcess process,
            FdmQuantoHelper quantoHelper = null,
            int tGrid = 100, int xGrid = 100, int dampingSteps = 0,
            FdmSchemeDesc schemeDesc            = null,
            bool localVol                       = false,
            double?illegalLocalVolOverwrite     = null,
            CashDividendModel cashDividendModel = CashDividendModel.Spot)
        {
            process_                  = process;
            tGrid_                    = tGrid;
            xGrid_                    = xGrid;
            dampingSteps_             = dampingSteps;
            schemeDesc_               = schemeDesc == null ? new FdmSchemeDesc().Douglas() : schemeDesc;
            localVol_                 = localVol;
            illegalLocalVolOverwrite_ = illegalLocalVolOverwrite;
            quantoHelper_             = quantoHelper;

            process_.registerWith(update);
        }
Ejemplo n.º 5
0
 public FdmBlackScholesOp(FdmMesher mesher,
                          GeneralizedBlackScholesProcess bsProcess,
                          double strike,
                          bool localVol = false,
                          double?illegalLocalVolOverwrite = null,
                          int direction = 0,
                          FdmQuantoHelper quantoHelper = null)
 {
     mesher_   = mesher;
     rTS_      = bsProcess.riskFreeRate().currentLink();
     qTS_      = bsProcess.dividendYield().currentLink();
     volTS_    = bsProcess.blackVolatility().currentLink();
     localVol_ = (localVol) ? bsProcess.localVolatility().currentLink()
              : null;
     x_      = (localVol) ? new Vector(Vector.Exp(mesher.locations(direction))) : null;
     dxMap_  = new FirstDerivativeOp(direction, mesher);
     dxxMap_ = new SecondDerivativeOp(direction, mesher);
     mapT_   = new TripleBandLinearOp(direction, mesher);
     strike_ = strike;
     illegalLocalVolOverwrite_ = illegalLocalVolOverwrite;
     direction_    = direction;
     quantoHelper_ = quantoHelper;
 }
 public MakeFdHestonVanillaEngine withQuantoHelper(
     FdmQuantoHelper quantoHelper)
 {
     quantoHelper_ = quantoHelper;
     return(this);
 }
Ejemplo n.º 7
0
 public MakeFdBlackScholesVanillaEngine withQuantoHelper(FdmQuantoHelper quantoHelper)
 {
     quantoHelper_ = quantoHelper;
     return(this);
 }
        public FdmBlackScholesMesher(int size,
                                     GeneralizedBlackScholesProcess process,
                                     double maturity, double strike,
                                     double?xMinConstraint = null,
                                     double?xMaxConstraint = null,
                                     double eps            = 0.0001,
                                     double scaleFactor    = 1.5,
                                     Pair <double?, double?> cPoint
                                     = null,
                                     DividendSchedule dividendSchedule = null,
                                     FdmQuantoHelper fdmQuantoHelper   = null,
                                     double spotAdjustment             = 0.0)
            : base(size)
        {
            double S = process.x0();

            Utils.QL_REQUIRE(S > 0.0, () => "negative or null underlying given");

            dividendSchedule = dividendSchedule == null ? new DividendSchedule() : dividendSchedule;
            List <pair_double> intermediateSteps = new List <pair_double>();

            for (int i = 0; i < dividendSchedule.Count &&
                 process.time(dividendSchedule[i].date()) <= maturity; ++i)
            {
                intermediateSteps.Add(
                    new pair_double(
                        process.time(dividendSchedule[i].date()),
                        dividendSchedule[i].amount()
                        ));
            }

            int intermediateTimeSteps = (int)Math.Max(2, 24.0 * maturity);

            for (int i = 0; i < intermediateTimeSteps; ++i)
            {
                intermediateSteps.Add(
                    new pair_double((i + 1) * (maturity / intermediateTimeSteps), 0.0));
            }

            intermediateSteps.Sort();

            Handle <YieldTermStructure> rTS = process.riskFreeRate();
            Handle <YieldTermStructure> qTS = fdmQuantoHelper != null
                                          ? new Handle <YieldTermStructure>(
                new QuantoTermStructure(process.dividendYield(),
                                        process.riskFreeRate(),
                                        new Handle <YieldTermStructure>(fdmQuantoHelper.foreignTermStructure()),
                                        process.blackVolatility(),
                                        strike,
                                        new Handle <BlackVolTermStructure>(fdmQuantoHelper.fxVolatilityTermStructure()),
                                        fdmQuantoHelper.exchRateATMlevel(),
                                        fdmQuantoHelper.equityFxCorrelation()))
                                          : process.dividendYield();

            double lastDivTime = 0.0;
            double fwd = S + spotAdjustment;
            double mi = fwd, ma = fwd;

            for (int i = 0; i < intermediateSteps.Count; ++i)
            {
                double divTime   = intermediateSteps[i].first;
                double divAmount = intermediateSteps[i].second;

                fwd = fwd / rTS.currentLink().discount(divTime) * rTS.currentLink().discount(lastDivTime)
                      * qTS.currentLink().discount(divTime) / qTS.currentLink().discount(lastDivTime);

                mi = Math.Min(mi, fwd); ma = Math.Max(ma, fwd);

                fwd -= divAmount;

                mi = Math.Min(mi, fwd); ma = Math.Max(ma, fwd);

                lastDivTime = divTime;
            }

            // Set the grid boundaries
            double normInvEps = new InverseCumulativeNormal().value(1 - eps);
            double sigmaSqrtT
                = process.blackVolatility().currentLink().blackVol(maturity, strike)
                  * Math.Sqrt(maturity);

            double?xMin = Math.Log(mi) - sigmaSqrtT * normInvEps * scaleFactor;
            double?xMax = Math.Log(ma) + sigmaSqrtT * normInvEps * scaleFactor;

            if (xMinConstraint != null)
            {
                xMin = xMinConstraint;
            }
            if (xMaxConstraint != null)
            {
                xMax = xMaxConstraint;
            }

            Fdm1dMesher helper;

            if (cPoint != null &&
                cPoint.first != null &&
                Math.Log(cPoint.first.Value) >= xMin && Math.Log(cPoint.first.Value) <= xMax)
            {
                helper = new Concentrating1dMesher(xMin.Value, xMax.Value, size,
                                                   new Pair <double?, double?>(Math.Log(cPoint.first.Value), cPoint.second));
            }
            else
            {
                helper = new Uniform1dMesher(xMin.Value, xMax.Value, size);
            }

            locations_ = helper.locations();
            for (int i = 0; i < locations_.Count; ++i)
            {
                dplus_[i]  = helper.dplus(i);
                dminus_[i] = helper.dminus(i);
            }
        }