protected override double CalcPv(IOption option, IMarketCondition market, double timeIncrement = 0.0) { var dayCount = market.DiscountCurve.Value.DayCount; var startDate = market.ValuationDate; var maturityDate = option.ExerciseDates.Last(); var t = dayCount.CalcDayCountFraction(market.ValuationDate, maturityDate) + timeIncrement; var bsProcess = new BlackScholesProcess( market.DiscountCurve.Value.ZeroRate(startDate, maturityDate), market.DividendCurves.Value.Values.First().ZeroRate(startDate, maturityDate), market.VolSurfaces.Value.Values.First().GetValue(maturityDate, option.Strike)); var pdeSolver = new SecondOrderPdeCrankNicolson( bsProcess.Drift, (t0, s) => 0.5 * Math.Pow(bsProcess.Diffusion(t0, s), 2.0), market.DiscountCurve.Value.GetSpotRate); double[] x; double[] xGrid; InitializeGrid(market.SpotPrices.Value.Values.First(), option.Strike, bsProcess.Diffusion(0, 0), t, out x, out xGrid); var dt = t / _steps; return(pdeSolver.Solve( Enumerable.Range(0, _steps + 1).Select(i => i * dt).ToArray(), xGrid, x, price => option.GetPayoff(new[] { price })[0].PaymentAmount )[0][_gridSize]); }
public LeisenReimerBinomialTree(BlackScholesProcess process, double x0, double strike, double tend, int steps = 200, int peizerPrattMethod = 1) : base(process, x0, tend, (steps % 2 == 0 ? steps + 1 : steps)) { _strike = strike; Dx = process.StdDeviation(0, X0, Dt); // sigma * sqrt(dt) var drift = process.Drift(0, X0, Dt); // r - q - 0.5 * sigma * sigma var sigma = process.Diffusion(0, X0); // sigma var d1 = (Math.Log(X0 / _strike) + (drift + sigma * sigma) * tend) / (sigma * Math.Sqrt(tend)); // d+ var d2 = (Math.Log(X0 / _strike) + drift * tend) / (sigma * Math.Sqrt(tend)); // d- var p1 = ProbabilityHelper(d1, NumberOfSteps, peizerPrattMethod); var p2 = ProbabilityHelper(d2, NumberOfSteps, peizerPrattMethod); var tmp = Math.Exp((drift + 0.5 * sigma * sigma) * Dt); var u = tmp * p1 / p2; var d = (tmp - p2 * u) / (1 - p2); PUp = p2; PDown = 1 - PUp; _steps = steps % 2 == 0 ? steps + 1 : steps; // only use odd number _stateValues = new double[_steps + 1][]; for (int i = 0; i < _steps + 1; ++i) { _stateValues[i] = new double[i + 1]; for (int j = 0; j < i + 1; ++j) { _stateValues[i][j] = X0 * Math.Pow(u, j) * Math.Pow(d, i - j); } } }
/// <summary> /// Initializes a new instance of the <see cref="BinomialTree"/> class. /// The underlying process shall be a Black-Schole process with constant r, sigma /// </summary> /// <param name="process">The process.</param> /// <param name="x0">The x0.</param> /// <param name="tend">The end time in years.</param> /// <param name="steps">The number of time steps.</param> //protected BinomialTree(BlackScholesProcess process, double x0, double tend, int steps = 200) protected BinomialTree(BlackScholesProcess process, double x0, double tend, int steps) { Process = process; X0 = x0; Dt = tend / steps; NumberOfSteps = steps; DriftPerStep = process.Drift(0, x0, Dt) * Dt; AllBranchDirections = new List <BranchDirection> { BranchDirection.Down, BranchDirection.Up }; }
private BinomialTree BuildTree(IMarketCondition market, double tEnd, double strike, double spotPrice, int steps, double vol, double r) { //most suitable arrangement to deal with both strike vol and moneyness vol var process = new BlackScholesProcess( r: r, q: 0.0, sigma: vol ); return(_binomialTreeType == BinomialTreeType.CoxRossRubinstein ? (BinomialTree) new CoxRossRubinsteinBinomialTree(process, spotPrice, tEnd, steps) : new LeisenReimerBinomialTree(process, spotPrice, strike, tEnd, steps)); }
private BinomialTree BuildTree(ConvertibleBond convertibleBond, IMarketCondition market) { var endDate = convertibleBond.UnderlyingMaturityDate; //assuming we use a strike vol var process = new BlackScholesProcess( market.DiscountCurve.Value.ZeroRate(market.ValuationDate, endDate), market.DividendCurves.Value.Values.First().ZeroRate(market.ValuationDate, endDate), market.VolSurfaces.Value.Values.First().GetValue(endDate, market.SpotPrices.Value.Values.First()) ); var dayCount = market.DiscountCurve.Value.DayCount; var tEnd = dayCount.CalcDayCountFraction(market.ValuationDate, convertibleBond.UnderlyingMaturityDate); return(new CoxRossRubinsteinBinomialTree(process, market.SpotPrices.Value.Values.First(), tEnd, _steps)); }
public CoxRossRubinsteinBinomialTree(BlackScholesProcess process, double x0, double tend, int steps = 200) : base(process, x0, tend, steps) { Dx = process.StdDeviation(0, X0, Dt); // sigma * sqrt(dt) // (exp(r*dt) - exp(-sigma*sqrt(dt)) / (exp(sigma*sqrt(dt)) - exp(-sigma*sqrt(dt))) PUp = 0.5 + 0.5 * DriftPerStep / Dx; //(Math.Exp((Process.GetDiscountRate(0.0) - Process.GetDividendRate(0.0)) * Dt) - Math.Exp(-Dx)) / (Math.Exp(Dx) - Math.Exp(-Dx)); PDown = 1 - PUp; _stateValues = new double[steps + 1][]; for (int i = 0; i < steps + 1; ++i) { _stateValues[i] = new double[i + 1]; for (int j = 0; j < i + 1; ++j) { _stateValues[i][j] = X0 * Math.Exp((2 * j - i) * Dx); } } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BlackScholesProcess obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BlackScholesProcess obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }