Пример #1
0
        public override void calculate(IPricingEngineResults r)
        {
            OneAssetOption.Results results = r as OneAssetOption.Results;
            setGridLimits();
            initializeInitialCondition();
            initializeOperator();
            initializeBoundaryConditions();
            initializeStepCondition();

            // typedef StandardSystemFiniteDifferenceModel model_type;

            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;

            if (striked_payoff == null)
            {
                throw new ApplicationException("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.Add("priceCurve", prices_);
        }
Пример #2
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.CrankNicolsonType:
            {
                CrankNicolsonScheme cnEvolver = new CrankNicolsonScheme(schemeDesc_.theta, map_, bcSet_);
                FiniteDifferenceModel <CrankNicolsonScheme>
                cnModel = new FiniteDifferenceModel <CrankNicolsonScheme>(cnEvolver, condition_.stoppingTimes());
                cnModel.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;

            case FdmSchemeDesc.FdmSchemeType.MethodOfLinesType:
            {
                MethodOfLinesScheme methodOfLines = new MethodOfLinesScheme(schemeDesc_.theta, schemeDesc_.mu, map_, bcSet_);
                FiniteDifferenceModel <MethodOfLinesScheme>
                molModel = new FiniteDifferenceModel <MethodOfLinesScheme>(methodOfLines, condition_.stoppingTimes());
                molModel.rollback(ref a, dampingTo, to, steps, condition_);
            }
            break;

            case FdmSchemeDesc.FdmSchemeType.TrBDF2Type:
            {
                FdmSchemeDesc    trDesc    = new FdmSchemeDesc().CraigSneyd();
                CraigSneydScheme hsEvolver = new CraigSneydScheme(trDesc.theta, trDesc.mu, map_, bcSet_);

                TrBDF2Scheme <CraigSneydScheme> trBDF2 = new TrBDF2Scheme <CraigSneydScheme>(
                    schemeDesc_.theta, map_, hsEvolver, bcSet_, schemeDesc_.mu);

                FiniteDifferenceModel <TrBDF2Scheme <CraigSneydScheme> >
                trBDF2Model = new FiniteDifferenceModel <TrBDF2Scheme <CraigSneydScheme> >(trBDF2, condition_.stoppingTimes());
                trBDF2Model.rollback(ref a, dampingTo, to, steps, condition_);
            }
            break;

            default:
                Utils.QL_FAIL("Unknown scheme type");
                break;
            }
        }
Пример #3
0
        public override void calculate(IPricingEngineResults r)
        {
            OneAssetOption.Results results = r as OneAssetOption.Results;
            if (results == null)
            {
                throw new ApplicationException("incorrect results type");
            }

            double beginDate, endDate;
            int    dateNumber        = stoppingTimes_.Count;
            bool   lastDateIsResTime = false;
            int    firstIndex        = -1;
            int    lastIndex         = dateNumber - 1;
            bool   firstDateIsZero   = false;
            double firstNonZeroDate  = getResidualTime();

            double dateTolerance = 1e-6;
            int    j;

            if (dateNumber > 0)
            {
                if (!(getDividendTime(0) >= 0))
                {
                    throw new ApplicationException("first date (" + getDividendTime(0) + ") cannot be negative");
                }
                if (getDividendTime(0) < getResidualTime() * dateTolerance)
                {
                    firstDateIsZero = true;
                    firstIndex      = 0;
                    if (dateNumber >= 2)
                    {
                        firstNonZeroDate = getDividendTime(1);
                    }
                }

                if (Math.Abs(getDividendTime(lastIndex) - getResidualTime()) < dateTolerance)
                {
                    lastDateIsResTime = true;
                    lastIndex         = dateNumber - 2;
                }

                if (!firstDateIsZero)
                {
                    firstNonZeroDate = getDividendTime(0);
                }

                if (dateNumber >= 2)
                {
                    for (j = 1; j < dateNumber; j++)
                    {
                        if (!(getDividendTime(j - 1) < getDividendTime(j)))
                        {
                            throw new ApplicationException("dates must be in increasing order: "
                                                           + getDividendTime(j - 1) + " is not strictly smaller than " + getDividendTime(j));
                        }
                    }
                }
            }

            double dt = getResidualTime() / (timeStepPerPeriod_ * (dateNumber + 1));

            // Ensure that dt is always smaller than the first non-zero date
            if (firstNonZeroDate <= dt)
            {
                dt = firstNonZeroDate / 2.0;
            }

            setGridLimits();
            initializeInitialCondition();
            initializeOperator();
            initializeBoundaryConditions();
            initializeModel();
            initializeStepCondition();

            prices_ = (SampledCurve)intrinsicValues_.Clone();
            if (lastDateIsResTime)
            {
                executeIntermediateStep(dateNumber - 1);
            }

            j = lastIndex;
            object temp;

            do
            {
                if (j == dateNumber - 1)
                {
                    beginDate = getResidualTime();
                }
                else
                {
                    beginDate = getDividendTime(j + 1);
                }

                if (j >= 0)
                {
                    endDate = getDividendTime(j);
                }
                else
                {
                    endDate = dt;
                }

                temp = prices_.values();
                model_.rollback(ref temp, beginDate, endDate, timeStepPerPeriod_, stepCondition_);
                prices_.setValues((Vector)temp);

                if (j >= 0)
                {
                    executeIntermediateStep(j);
                }
            } while (--j >= firstIndex);

            temp = prices_.values();
            model_.rollback(ref temp, dt, 0, 1, stepCondition_);
            prices_.setValues((Vector)temp);

            if (firstDateIsZero)
            {
                executeIntermediateStep(0);
            }

            results.value = prices_.valueAtCenter();
            results.delta = prices_.firstDerivativeAtCenter();
            results.gamma = prices_.secondDerivativeAtCenter();
            results.additionalResults["priceCurve"] = prices_;
        }