public void calculate()
        {
            setupArguments(arguments_);
            setGridLimits();
            initializeInitialCondition();
            initializeOperator();
            initializeBoundaryConditions();

            var model = new FiniteDifferenceModel <CrankNicolson <TridiagonalOperator> >(finiteDifferenceOperator_, BCs_);

            prices_ = (SampledCurve)intrinsicValues_.Clone();

            // this is a workaround for pointers to avoid unsafe code
            // in the grid calculation Vector temp goes through many operations
            object temp = prices_.values();

            model.rollback(ref temp, getResidualTime(), 0, timeSteps_);
            prices_.setValues((Vector)temp);

            results_.value = prices_.valueAtCenter();
            results_.delta = prices_.firstDerivativeAtCenter();
            results_.gamma = prices_.secondDerivativeAtCenter();
            results_.theta = Utils.blackScholesTheta(process_,
                                                     results_.value.GetValueOrDefault(),
                                                     results_.delta.GetValueOrDefault(),
                                                     results_.gamma.GetValueOrDefault());
            results_.additionalResults.Add("priceCurve", prices_);
        }
Exemple #2
0
 protected virtual void initializeModel()
 {
     model_ = new FiniteDifferenceModel <CrankNicolson <TridiagonalOperator> >(finiteDifferenceOperator_, BCs_);
 }
        public override void calculate(IPricingEngineResults r)
        {
            OneAssetOption.Results results = r as OneAssetOption.Results;
            setGridLimits();
            initializeInitialCondition();
            initializeOperator();
            initializeBoundaryConditions();
            initializeStepCondition();

            List <IOperator>          operatorSet  = new List <IOperator>();
            List <Vector>             arraySet     = new List <Vector>();
            BoundaryConditionSet      bcSet        = new BoundaryConditionSet();
            StepConditionSet <Vector> conditionSet = new StepConditionSet <Vector>();

            prices_ = (SampledCurve)intrinsicValues_.Clone();

            controlPrices_   = (SampledCurve)intrinsicValues_.Clone();
            controlOperator_ = (TridiagonalOperator)finiteDifferenceOperator_.Clone();
            controlBCs_[0]   = BCs_[0];
            controlBCs_[1]   = BCs_[1];

            operatorSet.Add(finiteDifferenceOperator_);
            operatorSet.Add(controlOperator_);

            arraySet.Add(prices_.values());
            arraySet.Add(controlPrices_.values());

            bcSet.Add(BCs_);
            bcSet.Add(controlBCs_);

            conditionSet.Add(stepCondition_);
            conditionSet.Add(new NullCondition <Vector>());

            var model = new FiniteDifferenceModel <ParallelEvolver <CrankNicolson <TridiagonalOperator> > >(operatorSet, bcSet);

            object temp = arraySet;

            model.rollback(ref temp, getResidualTime(), 0.0, timeSteps_, conditionSet);
            arraySet = (List <Vector>)temp;

            prices_.setValues(arraySet[0]);
            controlPrices_.setValues(arraySet[1]);

            StrikedTypePayoff striked_payoff = payoff_ as StrikedTypePayoff;

            Utils.QL_REQUIRE(striked_payoff != null, () => "non-striked payoff given");

            double variance         = process_.blackVolatility().link.blackVariance(exerciseDate_, striked_payoff.strike());
            double dividendDiscount = process_.dividendYield().link.discount(exerciseDate_);
            double riskFreeDiscount = process_.riskFreeRate().link.discount(exerciseDate_);
            double spot             = process_.stateVariable().link.value();
            double forwardPrice     = spot * dividendDiscount / riskFreeDiscount;

            BlackCalculator black = new BlackCalculator(striked_payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount);

            results.value = prices_.valueAtCenter()
                            - controlPrices_.valueAtCenter()
                            + black.value();
            results.delta = prices_.firstDerivativeAtCenter()
                            - controlPrices_.firstDerivativeAtCenter()
                            + black.delta(spot);
            results.gamma = prices_.secondDerivativeAtCenter()
                            - controlPrices_.secondDerivativeAtCenter()
                            + black.gamma(spot);
            results.additionalResults["priceCurve"] = prices_;
        }
Exemple #4
0
        public void rollback(ref object a,
                             double from, double to,
                             int steps, int dampingSteps)
        {
            double deltaT    = from - to;
            int    allSteps  = steps + dampingSteps;
            double dampingTo = from - (deltaT * dampingSteps) / allSteps;

            if (dampingSteps > 0 &&
                schemeDesc_.type != FdmSchemeDesc.FdmSchemeType.ImplicitEulerType)
            {
                ImplicitEulerScheme implicitEvolver = new ImplicitEulerScheme(map_, bcSet_);
                FiniteDifferenceModel <ImplicitEulerScheme> dampingModel
                    = new FiniteDifferenceModel <ImplicitEulerScheme>(implicitEvolver, condition_.stoppingTimes());

                dampingModel.rollback(ref a, from, dampingTo,
                                      dampingSteps, condition_);
            }

            switch (schemeDesc_.type)
            {
            case FdmSchemeDesc.FdmSchemeType.HundsdorferType:
            {
                HundsdorferScheme hsEvolver = new HundsdorferScheme(schemeDesc_.theta, schemeDesc_.mu,
                                                                    map_, bcSet_);
                FiniteDifferenceModel <HundsdorferScheme>
                hsModel = new FiniteDifferenceModel <HundsdorferScheme>(hsEvolver, condition_.stoppingTimes());
                hsModel.rollback(ref a, dampingTo, to, steps, condition_);
            }
            break;

            case FdmSchemeDesc.FdmSchemeType.DouglasType:
            {
                DouglasScheme dsEvolver = new DouglasScheme(schemeDesc_.theta, map_, bcSet_);
                FiniteDifferenceModel <DouglasScheme>
                dsModel = new FiniteDifferenceModel <DouglasScheme>(dsEvolver, condition_.stoppingTimes());
                dsModel.rollback(ref a, dampingTo, to, steps, condition_);
            }
            break;

            case FdmSchemeDesc.FdmSchemeType.CraigSneydType:
            {
                CraigSneydScheme csEvolver = new CraigSneydScheme(schemeDesc_.theta, schemeDesc_.mu,
                                                                  map_, bcSet_);
                FiniteDifferenceModel <CraigSneydScheme>
                csModel = new FiniteDifferenceModel <CraigSneydScheme>(csEvolver, condition_.stoppingTimes());
                csModel.rollback(ref a, dampingTo, to, steps, condition_);
            }
            break;

            case FdmSchemeDesc.FdmSchemeType.ModifiedCraigSneydType:
            {
                ModifiedCraigSneydScheme csEvolver = new ModifiedCraigSneydScheme(schemeDesc_.theta,
                                                                                  schemeDesc_.mu,
                                                                                  map_, bcSet_);
                FiniteDifferenceModel <ModifiedCraigSneydScheme>
                mcsModel = new FiniteDifferenceModel <ModifiedCraigSneydScheme>(csEvolver, condition_.stoppingTimes());
                mcsModel.rollback(ref a, dampingTo, to, steps, condition_);
            }
            break;

            case FdmSchemeDesc.FdmSchemeType.ImplicitEulerType:
            {
                ImplicitEulerScheme implicitEvolver = new ImplicitEulerScheme(map_, bcSet_);
                FiniteDifferenceModel <ImplicitEulerScheme>
                implicitModel = new FiniteDifferenceModel <ImplicitEulerScheme>(implicitEvolver, condition_.stoppingTimes());
                implicitModel.rollback(ref a, from, to, allSteps, condition_);
            }
            break;

            case FdmSchemeDesc.FdmSchemeType.ExplicitEulerType:
            {
                ExplicitEulerScheme explicitEvolver = new ExplicitEulerScheme(map_, bcSet_);
                FiniteDifferenceModel <ExplicitEulerScheme>
                explicitModel = new FiniteDifferenceModel <ExplicitEulerScheme>(explicitEvolver, condition_.stoppingTimes());
                explicitModel.rollback(ref a, dampingTo, to, steps, condition_);
            }
            break;

            default:
                Utils.QL_FAIL("Unknown scheme type");
                break;
            }
        }