public override void calculate()
        {
            // 1. Mesher
            StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff;

            double      maturity     = process_.time(arguments_.exercise.lastDate());
            Fdm1dMesher equityMesher =
                new FdmBlackScholesMesher(
                    xGrid_, process_, maturity, payoff.strike(),
                    null, null, 0.0001, 1.5,
                    new Pair <double?, double?>(payoff.strike(), 0.1));

            FdmMesher mesher =
                new FdmMesherComposite(equityMesher);

            // 2. Calculator
            FdmInnerValueCalculator calculator = new FdmLogInnerValue(payoff, mesher, 0);

            // 3. Step conditions
            FdmStepConditionComposite conditions = FdmStepConditionComposite.vanillaComposite(
                arguments_.cashFlow, arguments_.exercise,
                mesher, calculator,
                process_.riskFreeRate().currentLink().referenceDate(),
                process_.riskFreeRate().currentLink().dayCounter());

            // 4. Boundary conditions
            FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet();

            // 5. Solver
            FdmSolverDesc solverDesc = new FdmSolverDesc();

            solverDesc.mesher       = mesher;
            solverDesc.bcSet        = boundaries;
            solverDesc.condition    = conditions;
            solverDesc.calculator   = calculator;
            solverDesc.maturity     = maturity;
            solverDesc.dampingSteps = dampingSteps_;
            solverDesc.timeSteps    = tGrid_;

            FdmBlackScholesSolver solver =
                new FdmBlackScholesSolver(
                    new Handle <GeneralizedBlackScholesProcess>(process_),
                    payoff.strike(), solverDesc, schemeDesc_,
                    localVol_, illegalLocalVolOverwrite_);

            double spot = process_.x0();

            results_.value = solver.valueAt(spot);
            results_.delta = solver.deltaAt(spot);
            results_.gamma = solver.gammaAt(spot);
            results_.theta = solver.thetaAt(spot);
        }
        public override void calculate()
        {
            // 1. Mesher
            StrikedTypePayoff payoff   = arguments_.payoff as StrikedTypePayoff;
            double            maturity = process_.time(arguments_.exercise.lastDate());

            double?xMin = null;
            double?xMax = null;

            if (arguments_.barrierType == Barrier.Type.DownIn ||
                arguments_.barrierType == Barrier.Type.DownOut)
            {
                xMin = Math.Log(arguments_.barrier.Value);
            }
            if (arguments_.barrierType == Barrier.Type.UpIn ||
                arguments_.barrierType == Barrier.Type.UpOut)
            {
                xMax = Math.Log(arguments_.barrier.Value);
            }

            Fdm1dMesher equityMesher =
                new FdmBlackScholesMesher(xGrid_, process_, maturity,
                                          payoff.strike(), xMin, xMax);

            FdmMesher mesher =
                new FdmMesherComposite(equityMesher);

            // 2. Calculator
            StrikedTypePayoff rebatePayoff =
                new CashOrNothingPayoff(Option.Type.Call, 0.0, arguments_.rebate.Value);
            FdmInnerValueCalculator calculator =
                new FdmLogInnerValue(rebatePayoff, mesher, 0);

            // 3. Step conditions
            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European,
                             () => "only european style option are supported");

            FdmStepConditionComposite conditions =
                FdmStepConditionComposite.vanillaComposite(
                    arguments_.cashFlow, arguments_.exercise,
                    mesher, calculator,
                    process_.riskFreeRate().currentLink().referenceDate(),
                    process_.riskFreeRate().currentLink().dayCounter());

            // 4. Boundary conditions
            FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet();

            if (arguments_.barrierType == Barrier.Type.DownIn ||
                arguments_.barrierType == Barrier.Type.DownOut)
            {
                boundaries.Add(new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0,
                                                        FdmDirichletBoundary.Side.Lower));
            }
            if (arguments_.barrierType == Barrier.Type.UpIn ||
                arguments_.barrierType == Barrier.Type.UpOut)
            {
                boundaries.Add(new FdmDirichletBoundary(mesher, arguments_.rebate.Value, 0,
                                                        FdmDirichletBoundary.Side.Upper));
            }

            // 5. Solver
            FdmSolverDesc solverDesc = new FdmSolverDesc();

            solverDesc.mesher       = mesher;
            solverDesc.bcSet        = boundaries;
            solverDesc.condition    = conditions;
            solverDesc.calculator   = calculator;
            solverDesc.maturity     = maturity;
            solverDesc.dampingSteps = dampingSteps_;
            solverDesc.timeSteps    = tGrid_;

            FdmBlackScholesSolver solver =
                new FdmBlackScholesSolver(
                    new Handle <GeneralizedBlackScholesProcess>(process_),
                    payoff.strike(), solverDesc, schemeDesc_,
                    localVol_, illegalLocalVolOverwrite_);

            double spot = process_.x0();

            results_.value = solver.valueAt(spot);
            results_.delta = solver.deltaAt(spot);
            results_.gamma = solver.gammaAt(spot);
            results_.theta = solver.thetaAt(spot);
        }
Example #3
0
        public override void calculate()
        {
            // 0. Cash dividend model
            Date   exerciseDate   = arguments_.exercise.lastDate();
            double maturity       = process_.time(exerciseDate);
            Date   settlementDate = process_.riskFreeRate().currentLink().referenceDate();

            double           spotAdjustment   = 0.0;
            DividendSchedule dividendSchedule = new DividendSchedule();

            switch (cashDividendModel_)
            {
            case CashDividendModel.Spot:
                dividendSchedule = arguments_.cashFlow;
                break;

            case CashDividendModel.Escrowed:
                foreach (Dividend divIter in dividendSchedule)
                {
                    Date divDate = divIter.date();

                    if (divDate <= exerciseDate && divDate >= settlementDate)
                    {
                        double divAmount = divIter.amount();
                        double discount  =
                            process_.riskFreeRate().currentLink().discount(divDate) /
                            process_.dividendYield().currentLink().discount(divDate);

                        spotAdjustment -= divAmount * discount;
                    }
                }

                Utils.QL_REQUIRE(process_.x0() + spotAdjustment > 0.0,
                                 () => "spot minus dividends becomes negative");
                break;

            default:
                Utils.QL_FAIL("unknwon cash dividend model");
                break;
            }

            // 1. Mesher
            StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff;

            Fdm1dMesher equityMesher =
                new FdmBlackScholesMesher(
                    xGrid_, process_, maturity, payoff.strike(),
                    null, null, 0.0001, 1.5,
                    new Pair <double?, double?>(payoff.strike(), 0.1),
                    dividendSchedule, quantoHelper_,
                    spotAdjustment);

            FdmMesher mesher =
                new FdmMesherComposite(equityMesher);

            // 2. Calculator
            FdmInnerValueCalculator calculator = new FdmLogInnerValue(payoff, mesher, 0);

            // 3. Step conditions
            FdmStepConditionComposite conditions = FdmStepConditionComposite.vanillaComposite(
                arguments_.cashFlow, arguments_.exercise,
                mesher, calculator,
                process_.riskFreeRate().currentLink().referenceDate(),
                process_.riskFreeRate().currentLink().dayCounter());

            // 4. Boundary conditions
            FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet();

            // 5. Solver
            FdmSolverDesc solverDesc = new FdmSolverDesc();

            solverDesc.mesher       = mesher;
            solverDesc.bcSet        = boundaries;
            solverDesc.condition    = conditions;
            solverDesc.calculator   = calculator;
            solverDesc.maturity     = maturity;
            solverDesc.dampingSteps = dampingSteps_;
            solverDesc.timeSteps    = tGrid_;

            FdmBlackScholesSolver solver =
                new FdmBlackScholesSolver(
                    new Handle <GeneralizedBlackScholesProcess>(process_),
                    payoff.strike(), solverDesc, schemeDesc_,
                    localVol_, illegalLocalVolOverwrite_);

            double spot = process_.x0();

            results_.value = solver.valueAt(spot);
            results_.delta = solver.deltaAt(spot);
            results_.gamma = solver.gammaAt(spot);
            results_.theta = solver.thetaAt(spot);
        }
Example #4
0
        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);
        }