public HullWhiteForwardProcess(Handle <YieldTermStructure> h, double a, double sigma) { process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0, 0.0, Compounding.Continuous, Frequency.NoFrequency).value()); h_ = h; a_ = a; sigma_ = sigma; }
public HullWhiteProcess(Handle <YieldTermStructure> h, double a, double sigma) { process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0, 0.0, Compounding.Continuous, Frequency.NoFrequency).value()); h_ = h; a_ = a; sigma_ = sigma; Utils.QL_REQUIRE(a_ >= 0.0, () => "negative a given"); Utils.QL_REQUIRE(sigma_ >= 0.0, () => "negative sigma given"); }
public override void calculate() { // 1. Term structure Handle <YieldTermStructure> ts = model_.currentLink().termStructure(); // 2. Mesher DayCounter dc = ts.currentLink().dayCounter(); Date referenceDate = ts.currentLink().referenceDate(); double maturity = dc.yearFraction(referenceDate, arguments_.exercise.lastDate()); OrnsteinUhlenbeckProcess process = new OrnsteinUhlenbeckProcess(model_.currentLink().a(), model_.currentLink().sigma()); Fdm1dMesher shortRateMesher = new FdmSimpleProcess1DMesher(xGrid_, process, maturity, 1, invEps_); FdmMesher mesher = new FdmMesherComposite(shortRateMesher); // 3. Inner Value Calculator List <Date> exerciseDates = arguments_.exercise.dates(); Dictionary <double, Date> t2d = new Dictionary <double, Date>(); for (int i = 0; i < exerciseDates.Count; ++i) { double t = dc.yearFraction(referenceDate, exerciseDates[i]); Utils.QL_REQUIRE(t >= 0, () => "exercise dates must not contain past date"); t2d.Add(t, exerciseDates[i]); } Handle <YieldTermStructure> disTs = model_.currentLink().termStructure(); Handle <YieldTermStructure> fwdTs = arguments_.swap.iborIndex().forwardingTermStructure(); Utils.QL_REQUIRE(fwdTs.currentLink().dayCounter() == disTs.currentLink().dayCounter(), () => "day counter of forward and discount curve must match"); Utils.QL_REQUIRE(fwdTs.currentLink().referenceDate() == disTs.currentLink().referenceDate(), () => "reference date of forward and discount curve must match"); HullWhite fwdModel = new HullWhite(fwdTs, model_.currentLink().a(), model_.currentLink().sigma()); FdmInnerValueCalculator calculator = new FdmAffineModelSwapInnerValue <HullWhite>( model_.currentLink(), fwdModel, arguments_.swap, t2d, mesher, 0); // 4. Step conditions FdmStepConditionComposite conditions = FdmStepConditionComposite.vanillaComposite( new DividendSchedule(), arguments_.exercise, mesher, calculator, referenceDate, dc); // 5. Boundary conditions FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet(); // 6. Solver FdmSolverDesc solverDesc = new FdmSolverDesc(); solverDesc.mesher = mesher; solverDesc.bcSet = boundaries; solverDesc.condition = conditions; solverDesc.calculator = calculator; solverDesc.maturity = maturity; solverDesc.timeSteps = tGrid_; solverDesc.dampingSteps = dampingSteps_; FdmHullWhiteSolver solver = new FdmHullWhiteSolver(model_, solverDesc, schemeDesc_); results_.value = solver.valueAt(0.0); }