示例#1
0
        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);
                }
            }
        }