예제 #1
0
        public static void prepareBlackScholesInputs(
            double spotPrice,
            double riskfreeRateAtExerciseInput, double riskfreeRateAtMaturityInput, double dividendRateInput,
            double riskFreeCurveShiftInBp, double dividendCurveShiftInBp,
            Date maturityDate, Date exerciseDate, Date valuationDate,
            IOption trade,
            IDayCount curveDayCount,
            bool isOptionOnForward,
            bool isForwardFuturesOption,
            double strike,
            double sigma,
            out double nd1,  // P(x < d1)
            out double nd2,  // P(x < d2),
            out double riskfreeDfAtExercise,
            out double dfExerciseToMaturity,
            out double forwardPrice,
            double expiryDayRemainingLife = double.NaN,
            double timeIncrement          = 0.0
            )
        {
            double T = 0.0;

            if (!double.IsNaN(expiryDayRemainingLife))
            {
                T = expiryDayRemainingLife;
            }
            else
            {
                T = timeToMaturityFraction(valuationDate, exerciseDate, trade) + timeIncrement;
            }
            double riskfreeRateAtExercise, riskfreeRateAtMaturity;

            if (riskFreeCurveShiftInBp != 0.0)
            {
                riskfreeRateAtExercise = riskfreeRateAtExerciseInput + riskFreeCurveShiftInBp * 1e-4;
                riskfreeRateAtMaturity = riskfreeRateAtMaturityInput + riskFreeCurveShiftInBp * 1e-4;
            }
            else
            {
                riskfreeRateAtExercise = riskfreeRateAtExerciseInput;
                riskfreeRateAtMaturity = riskfreeRateAtMaturityInput;
            }
            var riskfreeDfAtMaturity = CalcDfFromZeroRate(riskfreeRateAtMaturity, maturityDate, valuationDate, curveDayCount);

            riskfreeDfAtExercise = CalcDfFromZeroRate(riskfreeRateAtExercise, exerciseDate, valuationDate, curveDayCount);

            double dividendRate;

            if (dividendCurveShiftInBp != 0.0)
            {
                dividendRate = dividendRateInput + dividendCurveShiftInBp / 1e4;
            }
            else
            {
                dividendRate = dividendRateInput;
            }

            //https://en.wikipedia.org/wiki/Black_model
            //if option on forward, discount to forward maturity day, and make sure maturity here is forward maturity, exercise is option exercise day
            //for other contracts,  pass maturity day = expiry day,  therefore _dfExerciseToMaturity = 1.0;
            dfExerciseToMaturity = (isOptionOnForward) ? riskfreeDfAtMaturity / riskfreeDfAtExercise : 1.0;

            var b = AnalyticalOptionPricerUtil.costOfCarry(isForwardFuturesOption, dividendRate, riskfreeRateAtExercise);

            forwardPrice = AnalyticalOptionPricerUtil.forwardPrice(
                isForwardFuturesOption,
                spotPrice,
                riskfreeDfAtExercise: riskfreeDfAtExercise,
                dividendRate: dividendRate,
                exerciseDate: exerciseDate,
                valuationDate: valuationDate,
                dayCount: trade.DayCount);

            var d1 = (Math.Log(spotPrice / strike) + (b + sigma * sigma / 2.0) * T) / (sigma * Math.Sqrt(T));
            var d2 = d1 - sigma * Math.Sqrt(T);

            nd1 = NormalCdf.NormalCdfHart(d1);  // P(x < d1)
            nd2 = NormalCdf.NormalCdfHart(d2);  // P(x < d2)

            //var nPrimceD1 = 1.0 / Math.Sqrt(2.0 * Math.PI) * Math.Exp(-d1 * d1 / 2.0); // derivative of N(d1)
            //var nPrimceD2 = 1.0 / Math.Sqrt(2.0 * Math.PI) * Math.Exp(-d2 * d2 / 2.0); // derivative of N(d2)
        }