Наследование: QLNet.Instrument
Пример #1
0
        public static double bachelierBlackFormula( Option.Type optionType,
            double strike,
            double forward,
            double stdDev,
            double discount)
        {
            if ( stdDev < 0.0 )
                throw new ArgumentException( "stdDev (" + stdDev + ") must be non-negative" );

            if ( discount <= 0.0 )
                throw new ArgumentException( "discount (" + discount + ") must be positive" );

            double d = ( forward - strike ) * (int)optionType;
            double h = d / stdDev;

            if ( stdDev == 0.0 )
                return discount * Math.Max( d, 0.0 );

            CumulativeNormalDistribution phi = new CumulativeNormalDistribution();

            double result = discount * ( stdDev * phi.derivative( h ) + d * phi.value( h ) );

            if ( !( result >= 0.0 ) )
                throw new ApplicationException( "negative value (" + result + ") for " +
                        stdDev + " stdDev, " +
                        optionType + " option, " +
                        strike + " strike , " +
                        forward + " forward" );

            return result;
        }
Пример #2
0
		public static double blackFormula( Option.Type optionType, double strike, double forward, double stdDev,
													 double discount, double displacement )
		{
			checkParameters( strike, forward, displacement );
			if ( !( stdDev >= 0.0 ) )
				throw new ApplicationException( "stdDev (" + stdDev + ") must be non-negative" );
			if ( !( discount > 0.0 ) )
				throw new ApplicationException( "discount (" + discount + ") must be positive" );

			if ( stdDev == 0.0 )
				return Math.Max( ( forward - strike ) * (int)optionType, 0.0 ) * discount;

			forward = forward + displacement;
			strike = strike + displacement;

			// since displacement is non-negative strike==0 iff displacement==0
			// so returning forward*discount is OK 
			if ( strike == 0.0 )
				return ( optionType == Option.Type.Call ? forward * discount : 0.0 );

			double d1 = Math.Log( forward / strike ) / stdDev + 0.5 * stdDev;
			double d2 = d1 - stdDev;
			CumulativeNormalDistribution phi = new CumulativeNormalDistribution();
			double nd1 = phi.value( (int)optionType * d1 );
			double nd2 = phi.value( (int)optionType * d2 );
			double result = discount * (int)optionType * ( forward * nd1 - strike * nd2 );
			if ( !( result >= 0.0 ) )
				throw new ApplicationException( "negative value (" + result + ") for " +
						stdDev + " stdDev, " +
						optionType + " option, " +
						strike + " strike , " +
						forward + " forward" );
			return result;
		}
Пример #3
0
        /*! Black style formula when forward is normal rather than
                  log-normal. This is essentially the model of Bachelier.

                  \warning Bachelier model needs absolute volatility, not
                              percentage volatility. Standard deviation is
                              absoluteVolatility*sqrt(timeToMaturity)
        */
        public static double bachelierBlackFormula( Option.Type optionType,
            double strike,
            double forward,
            double stdDev
            )
        {
            return bachelierBlackFormula( optionType, strike, forward, stdDev, 1 );
        }
Пример #4
0
 protected override double optionletPriceImp(Option.Type optionType, double effStrike,
                                           double forward, double stdDev)
 {
     return Utils.blackFormula(optionType,
                            effStrike,
                            forward,
                            stdDev);
 }
Пример #5
0
        public override double discountBondOption(Option.Type type,
                                        double strike,
                                        double maturity,
                                        double bondMaturity)
        {
            if (!(strike > 0.0))
                throw new ApplicationException("strike must be positive");
            double discountT = discountBond(0.0, maturity, x0());
            double discountS = discountBond(0.0, bondMaturity, x0());

            if (maturity < Const.QL_EPSILON)
            {
                switch (type){
                    case Option.Type.Call:
                        return Math.Max(discountS - strike, 0.0);
                    case Option.Type.Put:
                        return Math.Max(strike - discountS, 0.0);
                    default:
                       throw new ApplicationException("unsupported option type");
                }
            }
            double sigma2 = sigma()*sigma();
            double h = Math.Sqrt(k()*k() + 2.0*sigma2);
            double b = B(maturity,bondMaturity);

            double rho = 2.0*h/(sigma2*(Math.Exp(h*maturity) - 1.0));
            double psi = (k() + h)/sigma2;

            double df = 4.0*k()*theta()/sigma2;
            double ncps = 2.0*rho*rho*x0()*Math.Exp(h*maturity)/(rho+psi+b);
            double ncpt = 2.0*rho*rho*x0()*Math.Exp(h*maturity)/(rho+psi);

            NonCentralChiSquareDistribution chis = new NonCentralChiSquareDistribution(df, ncps);
            NonCentralChiSquareDistribution chit = new NonCentralChiSquareDistribution(df, ncpt);

            double z = Math.Log(A(maturity,bondMaturity)/strike)/b;
            double call = discountS*chis.value(2.0*z*(rho+psi+b)) -
                strike*discountT*chit.value(2.0*z*(rho+psi));

            if (type == Option.Type.Call)
                return call;
            else
                return call - discountS + strike*discountT;
        }
Пример #6
0
        public override double discountBondOption(Option.Type type,
                                        double strike,
                                        double maturity,
                                        double bondMaturity) {
            double v;
            double _a = a();
            if (Math.Abs(maturity) < Const.QL_EPSILON){
                v = 0.0;
            }
            else if (_a < Math.Sqrt(Const.QL_EPSILON)){
                v = sigma()*B(maturity, bondMaturity)* Math.Sqrt(maturity);
            } else {
                v = sigma()*B(maturity, bondMaturity)*
                    Math.Sqrt(0.5*(1.0 - Math.Exp(-2.0*_a*maturity))/_a);
            }
            double f = discountBond(0.0, bondMaturity, r0_);
            double k = discountBond(0.0, maturity, r0_)*strike;

            return Utils.blackFormula(type, k, f, v);
        }
Пример #7
0
        //Hagan, 3.5b, 3.5c
        protected override double optionletPrice(Option.Type optionType, double strike)
        {
            double variance = swaptionVolatility().link.blackVariance(fixingDate_, swapTenor_, swapRateValue_);
            double firstDerivativeOfGAtForwardValue = gFunction_.firstDerivative(swapRateValue_);
            double price = 0;

            double CK = vanillaOptionPricer_.value(strike, optionType, annuity_);
            price += (discount_ / annuity_) * CK;
            double sqrtSigma2T = Math.Sqrt(variance);
            double lnRoverK = Math.Log(swapRateValue_ / strike);
            double d32 = (lnRoverK + 1.5 * variance) / sqrtSigma2T;
            double d12 = (lnRoverK + .5 * variance) / sqrtSigma2T;
            double dminus12 = (lnRoverK - .5 * variance) / sqrtSigma2T;

            CumulativeNormalDistribution cumulativeOfNormal = new CumulativeNormalDistribution();
            double N32 = cumulativeOfNormal.value(((int)optionType) * d32);
            double N12 = cumulativeOfNormal.value(((int)optionType) * d12);
            double Nminus12 = cumulativeOfNormal.value(((int)optionType) * dminus12);

            price += ((int)optionType) * firstDerivativeOfGAtForwardValue * annuity_ * swapRateValue_ * (swapRateValue_ * Math.Exp(variance) * N32 - (swapRateValue_ + strike) * N12 + strike * Nminus12);
            price *= coupon_.accrualPeriod();
            return price;
        }
 public DiscreteAverageData(Option.Type Type,
                             double Underlying,
                             double Strike,
                             double DividendYield,
                             double RiskFreeRate,
                             double First,
                             double Length,
                             int Fixings,
                             double Volatility,
                             bool ControlVariate,
                             double Result)
 {
     type = Type;
     underlying = Underlying;
     strike = Strike;
     dividendYield = DividendYield;
     riskFreeRate = RiskFreeRate;
     first = First;
     length = Length;
     fixings = Fixings;
     volatility = Volatility;
     controlVariate = ControlVariate;
     result = Result;
 }
Пример #9
0
 public abstract double discountBondOption(Option.Type type, double strike, double maturity, double bondMaturity);
Пример #10
0
 public CashOrNothingPayoff(Option.Type type, double strike, double cashPayoff)
     : base(type, strike)
 {
     _cashPayoff = cashPayoff;
 }
Пример #11
0
 //! usually only need implement this (of course they may need
 //! to re-implement initialize too ...)
 protected virtual double optionletPriceImp(Option.Type optionType, double strike, double forward, double stdDev)
 {
    Utils.QL_FAIL("you must implement this to get a vol-dependent price");
    return strike * forward * stdDev * (int)optionType;
 }
Пример #12
0
      //@}


      //! can replace this if really required
      protected virtual double optionletPrice(Option.Type optionType, double effStrike)
      {
         Date fixingDate = coupon_.fixingDate();
         if (fixingDate <= Settings.evaluationDate()) 
         {
            // the amount is determined
            double a, b;
            if (optionType==Option.Type.Call) 
            {
                  a = coupon_.indexFixing();
                  b = effStrike;
            } 
            else 
            {
                  a = effStrike;
                  b = coupon_.indexFixing();
            }
            return Math.Max(a - b, 0.0)* coupon_.accrualPeriod()*discount_;
         } 
         else 
         {
            // not yet determined, use Black/DD1/Bachelier/whatever from Impl
            Utils.QL_REQUIRE( !capletVolatility().empty(), () => "missing optionlet volatility" );
            double stdDev = Math.Sqrt(capletVolatility().link.totalVariance(fixingDate, effStrike));
            double fixing = optionletPriceImp(optionType,
                                              effStrike,
                                              adjustedFixing(),
                                              stdDev);
            return fixing * coupon_.accrualPeriod() * discount_;
         }
      }
Пример #13
0
 public PercentageStrikePayoff(Option.Type type, double moneyness)
     : base(type, moneyness)
 {
 }
Пример #14
0
 public PlainVanillaPayoff(Option.Type type, double strike) : base(type, strike) {}
Пример #15
0
        protected override double optionletPrice(Option.Type optionType, double effStrike)
        {
            Date fixingDate = coupon_.fixingDate();
            if (fixingDate <= Settings.evaluationDate()) {
                // the amount is determined
                double a;
                double b;
                if (optionType == Option.Type.Call) {
                    a = coupon_.indexFixing();
                    b = effStrike;
                } else {
                    a = effStrike;
                    b = coupon_.indexFixing();
                }
                return Math.Max(a - b, 0.0) * coupon_.accrualPeriod() * discount_;
            } else {
                // not yet determined, use Black model
                if (!(!capletVolatility().empty()))
                    throw new ApplicationException("missing optionlet volatility");

                double stdDev = Math.Sqrt(capletVolatility().link.blackVariance(fixingDate, effStrike));
                double fixing = Utils.blackFormula(optionType, effStrike, adjustedFixing(), stdDev);
                return fixing * coupon_.accrualPeriod() * discount_;
            }
        }
Пример #16
0
 public ConundrumIntegrand(VanillaOptionPricer o, YieldTermStructure curve, GFunction gFunction, Date fixingDate, Date paymentDate, double annuity, double forwardValue, double strike, Option.Type optionType) {
     vanillaOptionPricer_ = o;
     forwardValue_ = forwardValue;
     annuity_ = annuity;
     fixingDate_ = fixingDate;
     paymentDate_ = paymentDate;
     strike_ = strike;
     optionType_ = optionType;
     gFunction_ = gFunction;
 }
Пример #17
0
 public abstract double value(double strike, Option.Type optionType, double deflator);
Пример #18
0
 // a.k.a. payoff strike
 public GapPayoff(Option.Type type, double strike, double secondStrike)
     : base(type, strike)
 {
     _secondStrike = secondStrike;
 }
Пример #19
0
 protected override double optionletPrice(Option.Type t, double d)
 { throw new ApplicationException("optionletPrice not available"); }
Пример #20
0
		protected override double optionletImpl( Option.Type type, double strike,
											  double forward, double stdDev,
											  double d )
		{
			// could use displacement parameter in blackFormula but this is clearer
			return Utils.blackFormula( type, strike + 1.0,  forward + 1.0, stdDev, d );
		}
Пример #21
0
        public virtual double discountBondOption(Option.Type type,
            double strike,
            double maturity,
            double bondMaturity)
        {
            double v = sigmaP(maturity, bondMaturity);
            double f = termStructure().link.discount(bondMaturity);
            double k = termStructure().link.discount(maturity) * strike;

            return Utils.blackFormula(type, k, f, v);
        }
Пример #22
0
		protected override double optionletImpl( Option.Type type, double strike,
											  double forward, double stdDev,
											  double d )
		{
			return Utils.bachelierBlackFormula( type, strike, forward, stdDev, d );
		}
Пример #23
0
 public AssetOrNothingPayoff(Option.Type type, double strike)
     : base(type, strike)
 {
 }
Пример #24
0
 public GapPayoff(Option.Type type, double strike, double secondStrike) // a.k.a. payoff strike
     : base(type, strike) {
     secondStrike_ = secondStrike;
 }
Пример #25
0
        protected override double optionletPrice(Option.Type optionType, double strike) {
            ConundrumIntegrand integrand = new ConundrumIntegrand(vanillaOptionPricer_, rateCurve_, gFunction_, fixingDate_, paymentDate_, annuity_, swapRateValue_, strike, optionType);
            stdDeviationsForUpperLimit_ = requiredStdDeviations_;
            double a;
            double b;
            double integralValue;
            if (optionType == Option.Type.Call) {
                upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
                //    while(upperLimit_ <= strike){
                //        stdDeviationsForUpperLimit_ += 1.;
                //        upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
                //    }
                integralValue = integrate(strike, upperLimit_, integrand);
                //refineIntegration(integralValue, *integrand);
            } else {
                a = Math.Min(strike, lowerLimit_);
                b = strike;
                integralValue = integrate(a, b, integrand);
            }

            double dFdK = integrand.firstDerivativeOfF(strike);
            double swaptionPrice = vanillaOptionPricer_.value(strike, optionType, annuity_);

            // v. HAGAN, Conundrums..., formule 2.17a, 2.18a
            return coupon_.accrualPeriod() * (discount_ / annuity_) * ((1 + dFdK) * swaptionPrice + ((int)optionType) * integralValue);
        }
Пример #26
0
 public TypePayoff(Option.Type type) {
     type_ = type;
 }
Пример #27
0
 public override double value(double strike, Option.Type optionType, double deflator)
 {
     double variance = _smile.variance(strike);
     return deflator * Utils.blackFormula(optionType, strike, _forwardValue, Math.Sqrt(variance));
 }
Пример #28
0
 public FloatingTypePayoff(Option.Type type) : base(type) {}
Пример #29
0
 protected abstract double optionletPrice(Option.Type optionType, double effStrike);
Пример #30
0
 public StrikedTypePayoff(Option.Type type, double strike) : base(type) {
     strike_ = strike;
 }