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