public FDEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent)
            : base(process, timeSteps, gridPoints, timeDependent)
        {
            prices_ = new SampledCurve(gridPoints);

            process.registerWith(update);
        }
        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_);
        }
        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 #4
0
        public FDEuropeanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent)
            : base(process, timeSteps, gridPoints, timeDependent)
        {
            prices_ = new SampledCurve(gridPoints);

            process.registerWith(update);
        }
Exemple #5
0
 //public FDVanillaEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints,
 //                       bool timeDependent = false)
 public FDVanillaEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent)
 {
     process_         = process;
     timeSteps_       = timeSteps;
     gridPoints_      = gridPoints;
     timeDependent_   = timeDependent;
     intrinsicValues_ = new SampledCurve(gridPoints);
     BCs_             = new InitializedList <BoundaryCondition <IOperator> >(2);
 }
Exemple #6
0
        public void testConstruction()
        {
            //("Testing sampled curve construction...");

             SampledCurve curve = new SampledCurve(Utils.BoundedGrid(-10.0, 10.0, 100));
             FSquared f2 = new FSquared();
             curve.sample(f2.value);
             double expected = 100.0;
             if (Math.Abs(curve.value(0) - expected) > 1e-5)
             {
            Assert.Fail("function sampling failed");
             }

             curve.setValue(0, 2.0);
             if (Math.Abs(curve.value(0) - 2.0) > 1e-5)
             {
            Assert.Fail("curve value setting failed");
             }

             Vector value = curve.values();
             value[1] = 3.0;
             if (Math.Abs(curve.value(1) - 3.0) > 1e-5)
             {
            Assert.Fail("curve value grid failed");
             }

             curve.shiftGrid(10.0);
             if (Math.Abs(curve.gridValue(0) - 0.0) > 1e-5)
             {
            Assert.Fail("sample curve shift grid failed");
             }
             if (Math.Abs(curve.value(0) - 2.0) > 1e-5)
             {
            Assert.Fail("sample curve shift grid - value failed");
             }

             curve.sample(f2.value);
             curve.regrid(Utils.BoundedGrid(0.0, 20.0, 200));
             double tolerance = 1.0e-2;
             for (int i = 0; i < curve.size(); i++)
             {
            double grid = curve.gridValue(i);
            double v = curve.value(i);
            double exp = f2.value(grid);
            if (Math.Abs(v - exp) > tolerance)
            {
               Assert.Fail("sample curve regriding failed" +
                           "\n    at " + (i + 1) + " point " + "(x = " + grid + ")" +
                           "\n    grid value: " + v +
                           "\n    expected:   " + exp);
            }
             }
        }
Exemple #7
0
        protected void setGridLimits(double center, double t)
        {
            Utils.QL_REQUIRE(center > 0.0, () => "negative or null underlying given");
            Utils.QL_REQUIRE(t > 0.0, () => "negative or zero residual time");
            center_ = center;
            int newGridPoints = safeGridPoints(gridPoints_, t);

            if (newGridPoints > intrinsicValues_.size())
            {
                intrinsicValues_ = new SampledCurve(newGridPoints);
            }

            double volSqrtTime = Math.Sqrt(process_.blackVolatility().link.blackVariance(t, center_));

            // the prefactor fine tunes performance at small volatilities
            double prefactor    = 1.0 + 0.02 / volSqrtTime;
            double minMaxFactor = Math.Exp(4.0 * prefactor * volSqrtTime);

            sMin_ = center_ / minMaxFactor; // underlying grid min value
            sMax_ = center_ * minMaxFactor; // underlying grid max value
        }
        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_;
        }
 //public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints,
 //     bool timeDependent = false)
 public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent)
     : base(process, timeSteps, gridPoints, timeDependent)
 {
     controlBCs_    = new InitializedList <BoundaryCondition <IOperator> >(2);
     controlPrices_ = new SampledCurve(gridPoints);
 }
Exemple #10
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_);
        }
Exemple #11
0
 //public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints,
 //     bool timeDependent = false)
 public FDStepConditionEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent)
     : base(process, timeSteps, gridPoints, timeDependent)
 {
     controlBCs_ = new InitializedList<BoundaryCondition<IOperator>>(2);
     controlPrices_ = new SampledCurve(gridPoints);
 }