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