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