Esempio n. 1
0
        public Fdm1DimSolver(FdmSolverDesc solverDesc,
                             FdmSchemeDesc schemeDesc,
                             FdmLinearOpComposite op)
        {
            solverDesc_     = solverDesc;
            schemeDesc_     = schemeDesc;
            op_             = op;
            thetaCondition_ = new FdmSnapshotCondition(
                0.99 * Math.Min(1.0 / 365.0,
                                solverDesc.condition.stoppingTimes().empty()
                            ? solverDesc.maturity
                            : solverDesc.condition.stoppingTimes().First()));

            conditions_ = FdmStepConditionComposite.joinConditions(thetaCondition_,
                                                                   solverDesc.condition);
            x_             = new InitializedList <double>(solverDesc.mesher.layout().size());
            initialValues_ = new InitializedList <double>(solverDesc.mesher.layout().size());
            resultValues_  = new Vector(solverDesc.mesher.layout().size());

            FdmMesher         mesher = solverDesc.mesher;
            FdmLinearOpLayout layout = mesher.layout();

            FdmLinearOpIterator endIter = layout.end();

            for (FdmLinearOpIterator iter = layout.begin(); iter != endIter;
                 ++iter)
            {
                initialValues_[iter.index()]
                    = solverDesc_.calculator.avgInnerValue(iter,
                                                           solverDesc.maturity);
                x_[iter.index()] = mesher.location(iter, 0);
            }
        }
Esempio n. 2
0
 public FdmHullWhiteSolver(
     Handle <HullWhite> model,
     FdmSolverDesc solverDesc,
     FdmSchemeDesc schemeDesc = null)
 {
     solverDesc_ = solverDesc;
     schemeDesc_ = schemeDesc ?? new FdmSchemeDesc().Hundsdorfer();
     model_      = model;
     model_.registerWith(update);
 }
        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);
        }
Esempio n. 4
0
 public FdmBlackScholesSolver(
     Handle <GeneralizedBlackScholesProcess> process,
     double strike,
     FdmSolverDesc solverDesc,
     FdmSchemeDesc schemeDesc        = null,
     bool localVol                   = false,
     double?illegalLocalVolOverwrite = null)
 {
     process_    = process;
     strike_     = strike;
     solverDesc_ = solverDesc;
     schemeDesc_ = schemeDesc ?? new FdmSchemeDesc().Douglas();
     localVol_   = localVol;
     illegalLocalVolOverwrite_ = illegalLocalVolOverwrite;
 }
Esempio n. 5
0
        public FdmBlackScholesSolver(
            Handle <GeneralizedBlackScholesProcess> process,
            double strike,
            FdmSolverDesc solverDesc,
            FdmSchemeDesc schemeDesc              = null,
            bool localVol                         = false,
            double?illegalLocalVolOverwrite       = null,
            Handle <FdmQuantoHelper> quantoHelper = null)
        {
            process_    = process;
            strike_     = strike;
            solverDesc_ = solverDesc;
            schemeDesc_ = schemeDesc ?? new FdmSchemeDesc().Douglas();
            localVol_   = localVol;
            illegalLocalVolOverwrite_ = illegalLocalVolOverwrite;
            quantoHelper_             = quantoHelper;
            quantoHelper_             = quantoHelper ?? new Handle <FdmQuantoHelper>();

            process_.registerWith(update);
            quantoHelper_.registerWith(update);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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
            FdmInnerValueCalculator calculator =
                new FdmLogInnerValue(payoff, mesher, 0);

            // 3. Step conditions
            List <IStepCondition <Vector> > stepConditions = new List <IStepCondition <Vector> >();
            List <List <double> >           stoppingTimes  = new List <List <double> >();

            // 3.1 Step condition if discrete dividends
            FdmDividendHandler dividendCondition =
                new FdmDividendHandler(arguments_.cashFlow, mesher,
                                       process_.riskFreeRate().currentLink().referenceDate(),
                                       process_.riskFreeRate().currentLink().dayCounter(), 0);

            if (!arguments_.cashFlow.empty())
            {
                stepConditions.Add(dividendCondition);
                stoppingTimes.Add(dividendCondition.dividendTimes());
            }

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

            FdmStepConditionComposite conditions =
                new FdmStepConditionComposite(stoppingTimes, stepConditions);

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

            // 6. Calculate vanilla option and rebate for in-barriers
            if (arguments_.barrierType == Barrier.Type.DownIn ||
                arguments_.barrierType == Barrier.Type.UpIn)
            {
                // Cast the payoff
                StrikedTypePayoff castedPayoff = arguments_.payoff as StrikedTypePayoff;

                // Calculate the vanilla option
                DividendVanillaOption vanillaOption =
                    new DividendVanillaOption(castedPayoff, arguments_.exercise,
                                              dividendCondition.dividendDates(),
                                              dividendCondition.dividends());

                vanillaOption.setPricingEngine(
                    new FdBlackScholesVanillaEngine(
                        process_, tGrid_, xGrid_,
                        0, // dampingSteps
                        schemeDesc_, localVol_, illegalLocalVolOverwrite_));

                // Calculate the rebate value
                DividendBarrierOption rebateOption =
                    new DividendBarrierOption(arguments_.barrierType,
                                              arguments_.barrier.Value,
                                              arguments_.rebate.Value,
                                              castedPayoff, arguments_.exercise,
                                              dividendCondition.dividendDates(),
                                              dividendCondition.dividends());

                int min_grid_size = 50;
                int rebateDampingSteps
                    = (dampingSteps_ > 0) ? Math.Min(1, dampingSteps_ / 2) : 0;

                rebateOption.setPricingEngine(new FdBlackScholesRebateEngine(
                                                  process_, tGrid_, Math.Max(min_grid_size, xGrid_ / 5),
                                                  rebateDampingSteps, schemeDesc_, localVol_,
                                                  illegalLocalVolOverwrite_));

                results_.value = vanillaOption.NPV() + rebateOption.NPV()
                                 - results_.value;
                results_.delta = vanillaOption.delta() + rebateOption.delta()
                                 - results_.delta;
                results_.gamma = vanillaOption.gamma() + rebateOption.gamma()
                                 - results_.gamma;
                results_.theta = vanillaOption.theta() + rebateOption.theta()
                                 - results_.theta;
            }
        }
Esempio n. 8
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);
        }
Esempio n. 9
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);
        }