Esempio n. 1
0
            public OneTouchCalculator(
                BinaryRebateType binaryRebateType,
                double strike,
                double spotPrice,
                double sigma,
                double dividendRate,
                double riskFreeRate,
                double cashOrNothingAmount,
                double exerciseInYears,
                InstrumentType underlyingInstrumentType,
                double notional = 1.0)
            {
                _X                   = strike;
                _S                   = spotPrice;
                _notional            = notional;
                _cashOrNothingAmount = cashOrNothingAmount;
                _sigma               = sigma;
                _T                   = exerciseInYears;
                _binaryRebateType    = binaryRebateType;

                _r                 = riskFreeRate;
                _dividendRate      = dividendRate;
                _isOptionOnFutures = AnalyticalOptionPricerUtil.isFuturesOption(underlyingInstrumentType);
                _isOptionOnForward = AnalyticalOptionPricerUtil.isForwardOption(underlyingInstrumentType);
                _b                 = AnalyticalOptionPricerUtil.costOfCarry(_isOptionOnFutures || _isOptionOnForward, dividendRate, riskFreeRate);
            }
        /// <summary>
        /// Initializes a new instance of the <see cref="BarrierOptionCalculator"/> class.
        /// </summary>
        /// <param name="optionType">Type of the option, Call or Put.</param>
        /// <param name="barrierType">UpAndIn, DownAndOut etc.</param>
        /// <param name="payoff">Option payoff, coupon/rebate/paticipationrate included.</param>
        /// <param name="barrier">Barrier level</param>
        /// <param name="secondarybarrier">Secondary barrier, only effective for double barrier options</param>
        /// <param name="strike">The strike.</param>
        /// <param name="spotPrice">The spot price.</param>
        /// <param name="exerciseInYears">The maturity in years.</param>
        /// <param name="standardDeviation">Volatility, measured by the standard deviation of the underlying.</param>
        /// <param name="riskFreeRate">Risk free rate</param>
        /// <param name="dividendRate">Continuous dividend rate</param>
        public BarrierOptionCalculator(OptionType optionType,
                                       BarrierType barrierType,
                                       double rebate,
                                       double barrier,
                                       double secondarybarrier,
                                       double strike,
                                       double spotPrice,
                                       double exerciseInYears,
                                       double standardDeviation,
                                       double riskFreeRate,
                                       double dividendRate,
                                       Date valuationDate,
                                       Date exerciseDate,
                                       Date underlyingMaturityDate,
                                       IDayCount dayCount,
                                       InstrumentType underlyingInstrumentType,
                                       double notional)
        {
            _isOptionOnFutures = AnalyticalOptionPricerUtil.isFuturesOption(underlyingInstrumentType);
            _isOptionOnForward = AnalyticalOptionPricerUtil.isForwardOption(underlyingInstrumentType);

            _optionType  = optionType;
            _barrierType = barrierType;
            _rebate      = rebate;
            _H           = barrier;
            _H2          = secondarybarrier;
            _X           = strike;
            _S           = spotPrice;
            _T           = exerciseInYears;
            _K           = rebate;
            _sigma       = standardDeviation;
            _r           = riskFreeRate;
            _dividend    = dividendRate;
            _b           = AnalyticalOptionPricerUtil.costOfCarry(_isOptionOnFutures || _isOptionOnForward, dividendRate, riskFreeRate);
            _dayCount    = dayCount;
            _notional    = notional;

            var riskfreeDfAtMaturity = CalcDfFromZeroRate(riskFreeRate, underlyingMaturityDate, valuationDate);
            var riskfreeDfAtExercise = CalcDfFromZeroRate(riskFreeRate, exerciseDate, valuationDate);

            _dfExerciseToMaturity = (_isOptionOnForward) ? riskfreeDfAtMaturity / riskfreeDfAtExercise : 1.0;

            // factors calculation
            switch (barrierType)
            {
            case BarrierType.DownAndIn:
            case BarrierType.DownAndOut:
                _yita = 1.0;
                break;

            case BarrierType.UpAndIn:
            case BarrierType.UpAndOut:
                _yita = -1.0;
                break;

            case BarrierType.DoubleTouchOut:
            case BarrierType.DoubleTouchIn:
                throw new PricingLibraryException("Double barrier shall use AnalyticalDoubleBarrierOptionEngine to calculate!");
            }

            _phi = optionType.Equals(OptionType.Call) ? 1.0 : -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)
        }