public LongstaffSchwartzPathPricer(TimeGrid times, IEarlyExercisePathPricer <PathType, double> pathPricer, YieldTermStructure termStructure) { calibrationPhase_ = true; pathPricer_ = pathPricer; coeff_ = new InitializedList <Vector>(times.size() - 1); dF_ = new InitializedList <double>(times.size() - 1); v_ = pathPricer_.basisSystem(); for (int i = 0; i < times.size() - 1; ++i) { dF_[i] = termStructure.discount(times[i + 1]) / termStructure.discount(times[i]); } }
public MultiPathGenerator(StochasticProcess process, TimeGrid times, GSG generator, bool brownianBridge) { brownianBridge_ = brownianBridge; process_ = process; generator_ = generator; next_ = new Sample <IPath>(new MultiPath(process.size(), times), 1.0); Utils.QL_REQUIRE(generator_.dimension() == process.factors() * (times.size() - 1), () => "dimension (" + generator_.dimension() + ") is not equal to (" + process.factors() + " * " + (times.size() - 1) + ") the number of factors " + "times the number of time steps"); Utils.QL_REQUIRE(times.size() > 1, () => "no times given"); }
public override Lattice tree(TimeGrid grid) { TermStructureFittingParameter phi = new TermStructureFittingParameter(termStructure()); ShortRateDynamics numericDynamics = new Dynamics(phi, a(), sigma()); TrinomialTree trinomial = new TrinomialTree(numericDynamics.process(), grid); ShortRateTree numericTree = new ShortRateTree(trinomial, numericDynamics, grid); TermStructureFittingParameter.NumericalImpl impl = (TermStructureFittingParameter.NumericalImpl)phi.implementation(); impl.reset(); double value = 1.0; double vMin = -50.0; double vMax = 50.0; for (int i = 0; i < (grid.size() - 1); i++) { double discountBond = termStructure().link.discount(grid[i + 1]); double xMin = trinomial.underlying(i, 0); double dx = trinomial.dx(i); Helper finder = new Helper(i, xMin, dx, discountBond, numericTree); Brent s1d = new Brent(); s1d.setMaxEvaluations(1000); value = s1d.solve(finder, 1e-7, value, vMin, vMax); impl.setvalue(grid[i], value); } return(numericTree); }
public override Lattice tree(TimeGrid grid) { TermStructureFittingParameter phi = new TermStructureFittingParameter(termStructure()); ShortRateDynamics numericDynamics = new Dynamics(phi, a(), sigma()); TrinomialTree trinomial = new TrinomialTree(numericDynamics.process(), grid); ShortRateTree numericTree = new ShortRateTree(trinomial, numericDynamics, grid); TermStructureFittingParameter.NumericalImpl impl = (TermStructureFittingParameter.NumericalImpl)phi.implementation(); impl.reset(); for (int i = 0; i < (grid.size() - 1); i++) { double discountBond = termStructure().link.discount(grid[i + 1]); Vector statePrices = numericTree.statePrices(i); int size = numericTree.size(i); double dt = numericTree.timeGrid().dt(i); double dx = trinomial.dx(i); double x = trinomial.underlying(i, 0); double value = 0.0; for (int j = 0; j < size; j++) { value += statePrices[j] * Math.Exp(-x * dt); x += dx; } value = Math.Log(value / discountBond) / dt; impl.setvalue(grid[i], value); } return(numericTree); }
protected override IPathGenerator <IRNG> pathGenerator() { TimeGrid grid = timeGrid(); IRNG gen = new RNG().make_sequence_generator(grid.size() - 1, seed_); return(new PathGenerator <IRNG>(process_, grid, gen, brownianBridge_)); }
public LatticeShortRateModelEngine(ShortRateModel model, TimeGrid timeGrid) : base(model) { timeGrid_ = new TimeGrid(timeGrid.Last(), timeGrid.size() - 1 /*timeGrid.dt(1) - timeGrid.dt(0)*/); timeGrid_ = timeGrid; timeSteps_ = 0; lattice_ = this.model_.link.tree(timeGrid); }
public PathGenerator(StochasticProcess process, TimeGrid timeGrid, GSG generator, bool brownianBridge) { brownianBridge_ = brownianBridge; generator_ = generator; dimension_ = generator_.dimension(); timeGrid_ = timeGrid; process_ = process as StochasticProcess1D; next_ = new Sample <IPath>(new Path(timeGrid_), 1.0); temp_ = new InitializedList <double>(dimension_); bb_ = new BrownianBridge(timeGrid_); Utils.QL_REQUIRE(dimension_ == timeGrid_.size() - 1, () => "sequence generator dimensionality (" + dimension_ + ") != timeSteps (" + (timeGrid_.size() - 1) + ")"); }
protected override PathPricer <IPath> pathPricer() { PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); TimeGrid grid = timeGrid(); List <double> discounts = new InitializedList <double>(grid.size()); for (int i = 0; i < grid.size(); i++) { discounts[i] = process_.riskFreeRate().currentLink().discount(grid[i]); } // do this with template parameters? if (isBiased_) { return(new BiasedBarrierPathPricer(arguments_.barrierType, arguments_.barrier, arguments_.rebate, payoff.optionType(), payoff.strike(), discounts)); } else { IRNG sequenceGen = new RandomSequenceGenerator <MersenneTwisterUniformRng>(grid.size() - 1, 5); return(new BarrierPathPricer(arguments_.barrierType, arguments_.barrier, arguments_.rebate, payoff.optionType(), payoff.strike(), discounts, process_, sequenceGen)); } }
//! generic times public BrownianBridge(TimeGrid timeGrid) { size_ = timeGrid.size() - 1; t_ = new InitializedList <double>(size_); sqrtdt_ = new InitializedList <double>(size_); sqrtdt_ = new InitializedList <double>(size_); bridgeIndex_ = new InitializedList <int>(size_); leftIndex_ = new InitializedList <int>(size_); rightIndex_ = new InitializedList <int>(size_); leftWeight_ = new InitializedList <double>(size_); rightWeight_ = new InitializedList <double>(size_); stdDev_ = new InitializedList <double>(size_); for (int i = 0; i < size_; ++i) { t_[i] = timeGrid[i + 1]; } initialize(); }
//! Tree build-up + numerical fitting to term-structure public ShortRateTree(TrinomialTree tree, ShortRateDynamics dynamics, TermStructureFittingParameter.NumericalImpl theta, TimeGrid timeGrid) : base(timeGrid, tree.size(1)) { tree_ = tree; dynamics_ = dynamics; theta.reset(); double value = 1.0; double vMin = -100.0; double vMax = 100.0; for (int i = 0; i < (timeGrid.size() - 1); i++) { double discountBond = theta.termStructure().link.discount(t_[i + 1]); Helper finder = new Helper(i, discountBond, theta, this); Brent s1d = new Brent(); s1d.setMaxEvaluations(1000); value = s1d.solve(finder, 1e-7, value, vMin, vMax); theta.change(value); } }
protected override IPathGenerator <IRNG> pathGenerator() { int dimensions = process_.factors(); TimeGrid grid = timeGrid(); IRNG generator = (IRNG)FastActivator <RNG> .Create().make_sequence_generator(dimensions * (grid.size() - 1), seed_); return(new PathGenerator <IRNG>(process_, grid, generator, brownianBridge_)); }
protected override IPathGenerator <IRNG> controlPathGenerator() { int dimensions = process_.factors(); TimeGrid grid = this.timeGrid(); IRNG generator = (IRNG) new RNG().make_sequence_generator(dimensions * (grid.size() - 1), this.seed_); HybridHestonHullWhiteProcess process = process_ as HybridHestonHullWhiteProcess; Utils.QL_REQUIRE(process != null, () => "invalid process"); HybridHestonHullWhiteProcess cvProcess = new HybridHestonHullWhiteProcess(process.hestonProcess(), process.hullWhiteProcess(), 0.0, process.discretization()); return(new MultiPathGenerator <IRNG>(cvProcess, grid, generator, false)); }
public override void calculate() { // this is an european option pricer Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option"); // plain vanilla PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); double v0 = model_.link.v0(); double spotPrice = model_.link.s0(); Utils.QL_REQUIRE(spotPrice > 0.0, () => "negative or null underlying given"); double strike = payoff.strike(); double term = model_.link.riskFreeRate().link.dayCounter().yearFraction( model_.link.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate()); double riskFreeDiscount = model_.link.riskFreeRate().link.discount(arguments_.exercise.lastDate()); double dividendDiscount = model_.link.dividendYield().link.discount(arguments_.exercise.lastDate()); //average values TimeGrid timeGrid = model_.link.timeGrid(); int n = timeGrid.size() - 1; double kappaAvg = 0.0, thetaAvg = 0.0, sigmaAvg = 0.0, rhoAvg = 0.0; for (int i = 1; i <= n; ++i) { double t = 0.5 * (timeGrid[i - 1] + timeGrid[i]); kappaAvg += model_.link.kappa(t); thetaAvg += model_.link.theta(t); sigmaAvg += model_.link.sigma(t); rhoAvg += model_.link.rho(t); } kappaAvg /= n; thetaAvg /= n; sigmaAvg /= n; rhoAvg /= n; double c_inf = Math.Min(10.0, Math.Max(0.0001, Math.Sqrt(1.0 - Math.Pow(rhoAvg, 2)) / sigmaAvg)) * (v0 + kappaAvg * thetaAvg * term); double p1 = integration_.calculate(c_inf, new Fj_Helper(model_, term, strike, 1).value) / Const.M_PI; double p2 = integration_.calculate(c_inf, new Fj_Helper(model_, term, strike, 2).value) / Const.M_PI; switch (payoff.optionType()) { case Option.Type.Call: results_.value = spotPrice * dividendDiscount * (p1 + 0.5) - strike * riskFreeDiscount * (p2 + 0.5); break; case Option.Type.Put: results_.value = spotPrice * dividendDiscount * (p1 - 0.5) - strike * riskFreeDiscount * (p2 - 0.5); break; default: Utils.QL_FAIL("unknown option type"); break; } }
public int length() { return(timeGrid_.size()); }