コード例 #1
0
        public static double DeltaToStrike(OptionType optionType, double delta, double spotPrice,
                                           double maturityInYears, double standardDeviation, double riskFreeRate, double dividendRate)
        {
            double S     = spotPrice;
            double T     = maturityInYears;
            double sigma = standardDeviation;
            double r     = riskFreeRate;
            double q     = dividendRate;
            double b     = riskFreeRate - dividendRate;

            double phi   = optionType.Equals(OptionType.Call) ? 1.0 : -1.0;
            double theta = (r - q) / sigma + sigma / 2;

            double K = S * Math.Exp(-phi * NormalCdf.NormSInv(phi * delta * Math.Exp(q * T)) * sigma * Math.Sqrt(T) + sigma * theta * T);

            return(K);
        }
コード例 #2
0
        /// <summary>
        /// Indicates whether some other object is equal to this option series by its attributes.
        /// </summary>
        /// <param name="o"></param>
        /// <returns>another object to compare with.</returns>
        public override bool Equals(object o)
        {
            if (this == o)
            {
                return(true);
            }
            if (!(o is OptionSeries))
            {
                return(false);
            }
            OptionSeries that = (OptionSeries)o;

            return(Expiration == that.Expiration &&
                   LastTrade == that.LastTrade &&
                   Multiplier.CompareTo(that.Multiplier) == 0 &&
                   SPC.CompareTo(that.SPC) == 0 &&
                   AdditionalUnderlyings.Equals(that.AdditionalUnderlyings) &&
                   ExpirationStyle.Equals(that.ExpirationStyle) &&
                   MMY.Equals(that.MMY) &&
                   OptionType.Equals(that.OptionType) &&
                   CFI.Equals(that.CFI) &&
                   SettlementStyle.Equals(that.SettlementStyle));
        }
コード例 #3
0
        /// <summary>
        /// Returns true if Instrument instances are equal
        /// </summary>
        /// <param name="other">Instance of Instrument to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(Instrument other)
        {
            if (other is null)
            {
                return(false);
            }
            if (ReferenceEquals(this, other))
            {
                return(true);
            }

            return
                ((
                     QuoteCurrency == other.QuoteCurrency ||

                     QuoteCurrency.Equals(other.QuoteCurrency)
                     ) &&
                 (
                     Kind == other.Kind ||

                     Kind.Equals(other.Kind)
                 ) &&
                 (
                     TickSize == other.TickSize ||
                     TickSize != null &&
                     TickSize.Equals(other.TickSize)
                 ) &&
                 (
                     ContractSize == other.ContractSize ||
                     ContractSize != null &&
                     ContractSize.Equals(other.ContractSize)
                 ) &&
                 (
                     IsActive == other.IsActive ||
                     IsActive != null &&
                     IsActive.Equals(other.IsActive)
                 ) &&
                 (
                     OptionType == other.OptionType ||

                     OptionType.Equals(other.OptionType)
                 ) &&
                 (
                     MinTradeAmount == other.MinTradeAmount ||
                     MinTradeAmount != null &&
                     MinTradeAmount.Equals(other.MinTradeAmount)
                 ) &&
                 (
                     InstrumentName == other.InstrumentName ||
                     InstrumentName != null &&
                     InstrumentName.Equals(other.InstrumentName)
                 ) &&
                 (
                     SettlementPeriod == other.SettlementPeriod ||

                     SettlementPeriod.Equals(other.SettlementPeriod)
                 ) &&
                 (
                     Strike == other.Strike ||
                     Strike != null &&
                     Strike.Equals(other.Strike)
                 ) &&
                 (
                     BaseCurrency == other.BaseCurrency ||

                     BaseCurrency.Equals(other.BaseCurrency)
                 ) &&
                 (
                     CreationTimestamp == other.CreationTimestamp ||
                     CreationTimestamp != null &&
                     CreationTimestamp.Equals(other.CreationTimestamp)
                 ) &&
                 (
                     ExpirationTimestamp == other.ExpirationTimestamp ||
                     ExpirationTimestamp != null &&
                     ExpirationTimestamp.Equals(other.ExpirationTimestamp)
                 ));
        }
コード例 #4
0
        private double CalcPV(Double S, Double sigma, Double T, Double r)
        {
            //TODO:  get risk free rate from curve,  here
            var b = _isOptionOnFutures ? 0.0 : r - _dividend;

            _mu     = (b - sigma * sigma / 2.0) / Math.Pow(sigma, 2.0);
            _lambda = _isOptionOnFutures ?
                      Math.Sqrt(_mu * _mu) :
                      Math.Sqrt(_mu * _mu + 2.0 * r / sigma / sigma);

            _z = Math.Log(_H / S) / sigma / Math.Sqrt(T) + _lambda * sigma * Math.Sqrt(T);

            _x1 = Math.Log(S / _X) / sigma / Math.Sqrt(T) + (1 + _mu) * sigma * Math.Sqrt(T);
            _x2 = Math.Log(S / _H) / sigma / Math.Sqrt(T) + (1 + _mu) * sigma * Math.Sqrt(T);
            _y1 = Math.Log(_H * _H / S / _X) / sigma / Math.Sqrt(T) + (1 + _mu) * sigma * Math.Sqrt(T);
            _y2 = Math.Log(_H / S) / sigma / Math.Sqrt(T) + (1 + _mu) * sigma * Math.Sqrt(T);

            _d1 = _isOptionOnFutures ?
                  (Math.Log(S / _X) + 0.5 * Math.Pow(sigma, 2.0) * T) / (sigma * Math.Sqrt(T)) :
                  (Math.Log(S / _X) + (b + 0.5 * Math.Pow(sigma, 2.0)) * T) / (sigma * Math.Sqrt(T)); //black scholes

            _d2 = _d1 - sigma * Math.Sqrt(T);

            //Note: given yield curve infra, we could
            //1. replace Math.Exp((b - r) * T)  with  market.DividendCurve.Value.GetDf(T)
            //2. replace Math.Exp(( -r) * T)  with  market.DiscountCurve.Value.GetDf(T)
            _A = _phi * S * Math.Exp((b - r) * T) * NormalCdf.NormalCdfHart(_phi * _x1) -
                 _phi * _X * Math.Exp(-r * T) * NormalCdf.NormalCdfHart(_phi * _x1 - _phi * sigma * Math.Sqrt(T));
            _B = _phi * S * Math.Exp((b - r) * T) * NormalCdf.NormalCdfHart(_phi * _x2) -
                 _phi * _X * Math.Exp(-r * T) * NormalCdf.NormalCdfHart(_phi * _x2 - _phi * sigma * Math.Sqrt(T));
            _C = _phi * S * Math.Exp((b - r) * T) * Math.Pow(_H / S, 2 * (_mu + 1)) * NormalCdf.NormalCdfHart(_yita * _y1) -
                 _phi * _X * Math.Exp(-r * T) * Math.Pow(_H / S, 2 * _mu) * NormalCdf.NormalCdfHart(_yita * _y1 - _yita * sigma * Math.Sqrt(T));
            _D = _phi * S * Math.Exp((b - r) * T) * Math.Pow(_H / S, 2 * (_mu + 1)) * NormalCdf.NormalCdfHart(_yita * _y2) -
                 _phi * _X * Math.Exp(-r * T) * Math.Pow(_H / S, 2 * _mu) * NormalCdf.NormalCdfHart(_yita * _y2 - _yita * sigma * Math.Sqrt(T));
            _E = _K * Math.Exp(-r * T) *
                 (NormalCdf.NormalCdfHart(_yita * _x2 - _yita * sigma * Math.Sqrt(T)) -
                  Math.Pow(_H / S, 2 * _mu) * NormalCdf.NormalCdfHart(_yita * _y2 - _yita * sigma * Math.Sqrt(T)));
            _F = _K *
                 (Math.Pow(_H / S, _mu + _lambda) * NormalCdf.NormalCdfHart(_yita * _z) +
                  Math.Pow(_H / S, _mu - _lambda) * NormalCdf.NormalCdfHart(_yita * _z - 2 * _yita * _lambda * sigma * Math.Sqrt(T)));

            _Gcall = Math.Exp(-r * T) * (S * Math.Exp(b * T) * NormalCdf.NormalCdfHart(_d1) - _X * NormalCdf.NormalCdfHart(_d2));
            _Gput  = -1.0 * Math.Exp(-r * T) * (S * Math.Exp(b * T) * NormalCdf.NormalCdfHart(-_d1) - _X * NormalCdf.NormalCdfHart(-_d2));

            //price here
            if (_barrierType.Equals(BarrierType.DownAndIn) && _optionType.Equals(OptionType.Call))
            {
                if (S <= _H)
                {
                    return(_notional * _Gcall);
                }
                if (_X >= _H)
                {
                    return(_notional * (_C + _E));
                }
                if (_X < _H)
                {
                    return(_notional * (_A - _B + _D + _E));
                }
            }
            if (_barrierType.Equals(BarrierType.UpAndIn) && _optionType.Equals(OptionType.Call))
            {
                if (S >= _H)
                {
                    return(_notional * _Gcall);
                }
                if (_X > _H)
                {
                    return(_notional * (_A + _E));
                }
                if (_X <= _H)
                {
                    return(_notional * (_B - _C + _D + _E));
                }
            }
            if (_barrierType.Equals(BarrierType.DownAndIn) && _optionType.Equals(OptionType.Put))
            {
                if (S <= _H)
                {
                    return(_notional * _Gput);
                }
                if (_X >= _H)
                {
                    return(_notional * (_B - _C + _D + _E));
                }
                if (_X < _H)
                {
                    return(_notional * (_A + _E));
                }
            }
            if (_barrierType.Equals(BarrierType.UpAndIn) && _optionType.Equals(OptionType.Put))
            {
                if (S >= _H)
                {
                    return(_notional * _Gput);
                }
                if (_X > _H)
                {
                    return(_notional * (_A - _B + _D + _E));
                }
                if (_X <= _H)
                {
                    return(_notional * (_C + _E));
                }
            }
            if (_barrierType.Equals(BarrierType.DownAndOut) && _optionType.Equals(OptionType.Call))
            {
                if (S <= _H)
                {
                    return(_notional * _rebate);         // already knocked out
                }
                if (_X >= _H)
                {
                    return(_notional * (_A - _C + _F));
                }
                if (_X < _H)
                {
                    return(_notional * (_B - _D + _F));
                }
            }
            if (_barrierType.Equals(BarrierType.UpAndOut) && _optionType.Equals(OptionType.Call))
            {
                if (S >= _H)
                {
                    return(_notional * _rebate);         // already knocked out
                }
                if (_X > _H)
                {
                    return(_notional * _F);
                }
                if (_X <= _H)
                {
                    return(_notional * (_A - _B + _C - _D + _F));
                }
            }
            if (_barrierType.Equals(BarrierType.DownAndOut) && _optionType.Equals(OptionType.Put))
            {
                if (S <= _H)
                {
                    return(_notional * _rebate);         // already knocked out
                }
                if (_X >= _H)
                {
                    return(_notional * (_A - _B + _C - _D + _F));
                }
                if (_X < _H)
                {
                    return(_notional * _F);
                }
            }
            if (_barrierType.Equals(BarrierType.UpAndOut) && _optionType.Equals(OptionType.Put))
            {
                if (S >= _H)
                {
                    return(_notional * _rebate);          // already knocked out
                }
                if (_X > _H)
                {
                    return(_notional * (_B - _D + _F));
                }
                if (_X <= _H)
                {
                    return(_notional * (_A - _C + _F));
                }
            }

            throw new PricingBaseException("Code should not reach here. Something is wrong.");
        }
コード例 #5
0
        /// <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;
        }
コード例 #6
0
        /// <summary>
        /// Determines whether the specified Object is equal to the current Object.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }
            if (Object.ReferenceEquals(this, obj))
            {
                return(true);
            }
            if (this.GetType() != obj.GetType())
            {
                return(false);
            }


            var other = (VLQuestionOption)obj;

            //reference types
            if (!Object.Equals(OptionText, other.OptionText))
            {
                return(false);
            }
            if (!Object.Equals(CustomId, other.CustomId))
            {
                return(false);
            }
            if (!Object.Equals(SkipToWebUrl, other.SkipToWebUrl))
            {
                return(false);
            }
            //value types
            if (!Survey.Equals(other.Survey))
            {
                return(false);
            }
            if (!Question.Equals(other.Question))
            {
                return(false);
            }
            if (!OptionId.Equals(other.OptionId))
            {
                return(false);
            }
            if (!OptionType.Equals(other.OptionType))
            {
                return(false);
            }
            if (!DisplayOrder.Equals(other.DisplayOrder))
            {
                return(false);
            }
            if (!OptionValue.Equals(other.OptionValue))
            {
                return(false);
            }
            if (!AttributeFlags.Equals(other.AttributeFlags))
            {
                return(false);
            }
            if (!SkipTo.Equals(other.SkipTo))
            {
                return(false);
            }
            if (!SkipToPage.Equals(other.SkipToPage))
            {
                return(false);
            }
            if (!SkipToQuestion.Equals(other.SkipToQuestion))
            {
                return(false);
            }

            return(true);
        }