Exemplo n.º 1
0
 void FDVanillaEngine::initializeOperator() const {
     finiteDifferenceOperator_ =
         OperatorFactory::getOperator(process_,
                                      intrinsicValues_.grid(),
                                      getResidualTime(),
                                      timeDependent_);
 }
Exemplo n.º 2
0
    void FDEuropeanEngine<Scheme>::calculate() const {
        setupArguments(&arguments_);
        setGridLimits();
        initializeInitialCondition();
        initializeOperator();
        initializeBoundaryConditions();

        FiniteDifferenceModel<Scheme<TridiagonalOperator> > model(
                                             finiteDifferenceOperator_, BCs_);

        prices_ = intrinsicValues_;

        model.rollback(prices_.values(), getResidualTime(),
                       0, timeSteps_);

        results_.value = prices_.valueAtCenter();
        results_.delta = prices_.firstDerivativeAtCenter();
        results_.gamma = prices_.secondDerivativeAtCenter();
        results_.theta = blackScholesTheta(process_,
                                           results_.value,
                                           results_.delta,
                                           results_.gamma);
        results_.additionalResults["priceCurve"] = prices_;
    }
    void FDStepConditionEngine<Scheme>::calculate(
                                            PricingEngine::results* r) const {
        OneAssetOption::results * results =
            dynamic_cast<OneAssetOption::results *>(r);
        setGridLimits();
        initializeInitialCondition();
        initializeOperator();
        initializeBoundaryConditions();
        initializeStepCondition();

        typedef FiniteDifferenceModel<ParallelEvolver<
                    Scheme<TridiagonalOperator> > > model_type;

        typename model_type::operator_type operatorSet;
        typename model_type::array_type arraySet;
        typename model_type::bc_set bcSet;
        typename model_type::condition_type conditionSet;

        prices_ = intrinsicValues_;

        controlPrices_ = intrinsicValues_;
        controlOperator_ = finiteDifferenceOperator_;
        controlBCs_[0] = BCs_[0];
        controlBCs_[1] = BCs_[1];

        operatorSet.push_back(finiteDifferenceOperator_);
        operatorSet.push_back(controlOperator_);

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

        bcSet.push_back(BCs_);
        bcSet.push_back(controlBCs_);

        conditionSet.push_back(stepCondition_);
        conditionSet.push_back(boost::shared_ptr<StandardStepCondition>(
                                                   new NullCondition<Array>));

        model_type model(operatorSet, bcSet);

        model.rollback(arraySet, getResidualTime(),
                       0.0, timeSteps_, conditionSet);

        prices_.values() = arraySet[0];
        controlPrices_.values() = arraySet[1];

        boost::shared_ptr<StrikedTypePayoff> striked_payoff =
            boost::dynamic_pointer_cast<StrikedTypePayoff>(payoff_);
        QL_REQUIRE(striked_payoff, "non-striked payoff given");

        Real variance =
            process_->blackVolatility()->blackVariance(
                                     exerciseDate_, striked_payoff->strike());
        DiscountFactor dividendDiscount =
            process_->dividendYield()->discount(exerciseDate_);
        DiscountFactor riskFreeDiscount =
            process_->riskFreeRate()->discount(exerciseDate_);
        Real spot = process_->stateVariable()->value();
        Real forwardPrice = spot * dividendDiscount / riskFreeDiscount;

        BlackCalculator black(striked_payoff, forwardPrice,
                              std::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_;
    }
Exemplo n.º 4
0
 void FDVanillaEngine::setGridLimits() const {
     setGridLimits(process_->stateVariable()->value(),
                   getResidualTime());
     ensureStrikeInGrid();
 }
Exemplo n.º 5
0
    void FDMultiPeriodEngine<Scheme>::calculate(
                                            PricingEngine::results* r) const {
        OneAssetOption::results *results =
            dynamic_cast<OneAssetOption::results *>(r);
        QL_REQUIRE(results, "incorrect argument type");
        Time beginDate, endDate;
        Size dateNumber = stoppingTimes_.size();
        bool lastDateIsResTime = false;
        Integer firstIndex = -1;
        Integer lastIndex = dateNumber - 1;
        bool firstDateIsZero = false;
        Time firstNonZeroDate = getResidualTime();

        Real dateTolerance = 1e-6;

        if (dateNumber > 0) {
            QL_REQUIRE(getDividendTime(0) >= 0,
                       "first date (" << getDividendTime(0)
                       << ") cannot be negative");
            if(getDividendTime(0) < getResidualTime() * dateTolerance ){
                firstDateIsZero = true;
                firstIndex = 0;
                if(dateNumber >= 2)
                    firstNonZeroDate = getDividendTime(1);
            }

            if (std::fabs(getDividendTime(lastIndex) - getResidualTime())
                < dateTolerance) {
                lastDateIsResTime = true;
                lastIndex = Integer(dateNumber) - 2;
            }

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

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

        Time 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_ = intrinsicValues_;
        if(lastDateIsResTime)
            executeIntermediateStep(dateNumber - 1);

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

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

            model_->rollback(prices_.values(),
                             beginDate, endDate,
                             timeStepPerPeriod_, *stepCondition_);
            if (j >= 0)
                executeIntermediateStep(j);
        } while (--j >= firstIndex);

        model_->rollback(prices_.values(), dt, 0, 1, *stepCondition_);

        if(firstDateIsZero)
            executeIntermediateStep(0);

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