Beispiel #1
0
 public BasketOptionTwoData(BasketType _basketType, Option.Type _type, double _strike, double _s1, double _s2, double _q1,
                            double _q2, double _r, double _t, double _v1, double _v2, double _rho, double _result, double _tol)
 {
     basketType = _basketType;
     type       = _type;
     strike     = _strike;
     s1         = _s1;
     s2         = _s2;
     q1         = _q1;
     q2         = _q2;
     r          = _r;
     t          = _t; // years
     v1         = _v1;
     v2         = _v2;
     rho        = _rho;
     result     = _result;
     tol        = _tol;
 }
Beispiel #2
0
        public double      result; // expected result

        public AmericanOptionData(Option.Type type_,
                                  double strike_,
                                  double s_,
                                  double q_,
                                  double r_,
                                  double t_,
                                  double v_,
                                  double result_)
        {
            type   = type_;
            strike = strike_;
            s      = s_;
            q      = q_;
            r      = r_;
            t      = t_;
            v      = v_;
            result = result_;
        }
        ///<summary>
        ///</summary>
        ///<param name="optionType"></param>
        ///<param name="underlying"></param>
        ///<param name="strike"></param>
        ///<param name="discountFactor"></param>
        ///<param name="useAntitheticVariance"></param>
        ///<exception cref="ArgumentException"></exception>
        public BasketPathPricer(Option.Type optionType, SparseVector underlying,
                                double strike, double discountFactor, bool useAntitheticVariance)
            : base(discountFactor, useAntitheticVariance)
        {
            if (underlying.Min() <= 0.0)
            {
                throw new ArgumentException("TODO: Price of underlying(s) must be positive.");
            }

            if (strike <= 0.0)
            {
                throw new ArgumentException("TODO: Strike price must be positive.");
            }

            _optionType = optionType;
            _underlying = underlying;
            _strike     = strike;
        }
Beispiel #4
0
        public virtual double optionPrice(double strike, Option.Type type = Option.Type.Call, double discount = 1.0)
        {
            double?atm = atmLevel();

            Utils.QL_REQUIRE(atm != null, () => "smile section must provide atm level to compute option price");
            // if lognormal or shifted lognormal,
            // for strike at -shift, return option price even if outside
            // minstrike, maxstrike interval
            if (volatilityType() == VolatilityType.ShiftedLognormal)
            {
                return(Utils.blackFormula(type, strike, atm.Value, Math.Abs(strike + shift()) < Const.QL_EPSILON ?
                                          0.2 : Math.Sqrt(variance(strike)), discount, shift()));
            }
            else
            {
                return(Utils.bachelierBlackFormula(type, strike, atm.Value, Math.Sqrt(variance(strike)), discount));
            }
        }
Beispiel #5
0
        public double discountBondOption(Option.Type type,
                                         double strike, double maturity,
                                         double bondMaturity)
        {
            List <double> accrualStartTimes
                = process_.accrualStartTimes();
            List <double> accrualEndTimes
                = process_.accrualEndTimes();

            Utils.QL_REQUIRE(accrualStartTimes.First() <= maturity && accrualStartTimes.Last() >= maturity, () =>
                             "capet maturity does not fit to the process");

            int i = accrualStartTimes.BinarySearch(maturity);

            if (i < 0)
            {
                // The lower_bound() algorithm finds the first position in a sequence that value can occupy
                // without violating the sequence's ordering
                // if BinarySearch does not find value the value, the index of the prev minor item is returned
                i = ~i + 1;
            }

            // impose limits. we need the one before last at max or the first at min
            i = Math.Max(Math.Min(i, accrualStartTimes.Count - 1), 0);

            Utils.QL_REQUIRE(i < process_.size() &&
                             Math.Abs(maturity - accrualStartTimes[i]) < 100 * Const.QL_EPSILON &&
                             Math.Abs(bondMaturity - accrualEndTimes[i]) < 100 * Const.QL_EPSILON, () =>
                             "irregular fixings are not (yet) supported");

            double tenor   = accrualEndTimes[i] - accrualStartTimes[i];
            double forward = process_.initialValues()[i];
            double capRate = (1.0 / strike - 1.0) / tenor;
            double var     = covarProxy_.integratedCovariance(i, i, process_.fixingTimes()[i]);
            double dis     = process_.index().forwardingTermStructure().link.discount(bondMaturity);

            double black = Utils.blackFormula(
                (type == Option.Type.Put ? Option.Type.Call : Option.Type.Put),
                capRate, forward, Math.Sqrt(var));

            double npv = dis * tenor * black;

            return(npv / (1.0 + capRate * tenor));
        }
Beispiel #6
0
        public BiasedBarrierPathPricer(Barrier.Type barrierType,
                                       double?barrier,
                                       double?rebate,
                                       Option.Type type,
                                       double strike,
                                       List <double> discounts)
            : base()
        {
            barrierType_ = barrierType;
            barrier_     = barrier;
            rebate_      = rebate;
            payoff_      = new PlainVanillaPayoff(type, strike);
            discounts_   = discounts;

            Utils.QL_REQUIRE(strike >= 0.0,
                             () => "strike less than zero not allowed");
            Utils.QL_REQUIRE(barrier > 0.0,
                             () => "barrier less/equal zero not allowed");
        }
Beispiel #7
0
            public double tol;            // tolerance

            public DoubleBarrierFxOptionData(DoubleBarrier.Type barrierType, double barrier1, double barrier2, double rebate, Option.Type type, double strike, double s, double q, double r, double t, double vol25Put, double volAtm, double vol25Call, double v, double result, double tol)
            {
                this.barrierType = barrierType;
                this.barrier1    = barrier1;
                this.barrier2    = barrier2;
                this.rebate      = rebate;
                this.type        = type;
                this.strike      = strike;
                this.s           = s;
                this.q           = q;
                this.r           = r;
                this.t           = t;
                this.vol25Put    = vol25Put;
                this.volAtm      = volAtm;
                this.vol25Call   = vol25Call;
                this.v           = v;
                this.result      = result;
                this.tol         = tol;
            }
Beispiel #8
0
        /*! Approximated Bachelier implied volatility
         *
         * It is calculated using  the analytic implied volatility approximation
         * of J. Choi, K Kim and M. Kwak (2009), “Numerical Approximation of the
         * Implied Volatility Under Arithmetic Brownian Motion”,
         * Applied Math. Finance, 16(3), pp. 261-268.
         */
        public static double bachelierBlackFormulaImpliedVol(Option.Type optionType,
                                                             double strike,
                                                             double forward,
                                                             double tte,
                                                             double bachelierPrice,
                                                             double discount = 1.0)
        {
            double SQRT_QL_EPSILON = Math.Sqrt(Const.QL_Epsilon);

            Utils.QL_REQUIRE(tte > 0.0, () => "tte (" + tte + ") must be positive");

            double forwardPremium = bachelierPrice / discount;

            double straddlePremium;

            if (optionType == Option.Type.Call)
            {
                straddlePremium = 2.0 * forwardPremium - (forward - strike);
            }
            else
            {
                straddlePremium = 2.0 * forwardPremium + (forward - strike);
            }

            double nu = (forward - strike) / straddlePremium;

            Utils.QL_REQUIRE(nu <= 1.0, () => "nu (" + nu + ") must be <= 1.0");
            Utils.QL_REQUIRE(nu >= -1.0, () => "nu (" + nu + ") must be >= -1.0");

            nu = Math.Max(-1.0 + Const.QL_Epsilon, Math.Min(nu, 1.0 - Const.QL_Epsilon));

            // nu / arctanh(nu) -> 1 as nu -> 0
            double atanh = (Math.Log(1 + nu) - Math.Log(1 - nu)) / 2;                   // c# dont have atanh

            double eta = (Math.Abs(nu) < SQRT_QL_EPSILON) ? 1.0 : nu / atanh;

            double heta = h(eta);

            double impliedBpvol = Math.Sqrt(M_PI / (2 * tte)) * straddlePremium * heta;

            return(impliedBpvol);
        }
Beispiel #9
0
 private static void ReportParameters(Option.Type optionType,
                                      double underlyingPrice,
                                      double strikePrice,
                                      double dividendYield,
                                      double riskFreeRate,
                                      double volatility,
                                      Date maturityDate)
 {
     Console.WriteLine();
     Console.WriteLine("Option type = {0}", optionType);
     Console.WriteLine("Maturity = {0} {1} {2}", maturityDate.year(),
                       maturityDate.month(), maturityDate.dayOfMonth());
     Console.WriteLine("Underlying price = ${0}", underlyingPrice);
     Console.WriteLine("Strike = ${0}", strikePrice);
     Console.WriteLine("Risk-free interest rate = {0}%",
                       riskFreeRate * 100.0);
     Console.WriteLine("Dividend yield = {0}%", dividendYield * 100.0);
     Console.WriteLine("Volatility = {0}%", volatility * 100);
     Console.WriteLine();
 }
Beispiel #10
0
 public BarrierPathPricer(
     Barrier.Type barrierType,
     double?barrier,
     double?rebate,
     Option.Type type,
     double strike,
     List <double> discounts,
     StochasticProcess1D diffProcess,
     IRNG sequenceGen)
 {
     barrierType_ = barrierType;
     barrier_     = barrier;
     rebate_      = rebate;
     diffProcess_ = diffProcess;
     sequenceGen_ = sequenceGen;
     payoff_      = new PlainVanillaPayoff(type, strike);
     discounts_   = discounts;
     Utils.QL_REQUIRE(strike >= 0.0, () => "strike less than zero not allowed");
     Utils.QL_REQUIRE(barrier > 0.0, () => "barrier less/equal zero not allowed");
 }
Beispiel #11
0
        /*! Black 1976 formula
         * \warning instead of volatility it uses standard deviation,
         *         i.e. volatility*sqrt(timeToMaturity)
         */
        public static double blackFormula(Option.Type optionType,
                                          double strike,
                                          double forward,
                                          double stdDev,
                                          double discount     = 1.0,
                                          double displacement = 0.0)
        {
            checkParameters(strike, forward, displacement);
            Utils.QL_REQUIRE(stdDev >= 0.0, () => "stdDev (" + stdDev + ") must be non-negative");
            Utils.QL_REQUIRE(discount > 0.0, () => "discount (" + discount + ") must be positive");

            if (stdDev.IsEqual(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.IsEqual(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);

            Utils.QL_REQUIRE(result >= 0.0, () =>
                             "negative value (" + result + ") for " +
                             stdDev + " stdDev, " +
                             optionType + " option, " +
                             strike + " strike , " +
                             forward + " forward");
            return(result);
        }
Beispiel #12
0
        public override void calculate()
        {
            if (!(arguments_.settlementType == Settlement.Type.Physical))
            {
                throw new ApplicationException("cash-settled swaptions not priced with Lfm engine");
            }

            double basisPoint = 1.0e-4;

            VanillaSwap    swap = arguments_.swap;
            IPricingEngine pe   = new DiscountingSwapEngine(discountCurve_);

            swap.setPricingEngine(pe);

            double correction = swap.spread *
                                Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS());
            double fixedRate = swap.fixedRate - correction;
            double fairRate  = swap.fairRate() - correction;

            SwaptionVolatilityMatrix volatility =
                model_.getSwaptionVolatilityMatrix();

            Date       referenceDate = volatility.referenceDate();
            DayCounter dayCounter    = volatility.dayCounter();

            double exercise = dayCounter.yearFraction(referenceDate,
                                                      arguments_.exercise.date(0));
            double swapLength =
                dayCounter.yearFraction(referenceDate,
                                        arguments_.fixedPayDates.Last())
                - dayCounter.yearFraction(referenceDate,
                                          arguments_.fixedResetDates[0]);

            Option.Type w = arguments_.type == VanillaSwap.Type.Payer ?
                            Option.Type.Call : Option.Type.Put;
            double vol = volatility.volatility(exercise, swapLength,
                                               fairRate, true);

            results_.value = (swap.fixedLegBPS() / basisPoint) *
                             Utils.blackFormula(w, fixedRate, fairRate, vol * Math.Sqrt(exercise));
        }
Beispiel #13
0
      public override double discountBondOption(Option.Type type,
                                                double strike,
                                                double maturity,
                                                double bondMaturity)
      {
         double _a = a();
         double v;
         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 = termStructure().link.discount(bondMaturity);
         double k = termStructure().link.discount(maturity) * strike;

         return Utils.blackFormula(type, k, f, v);
      }
Beispiel #14
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);
        }
Beispiel #15
0
            public double       v;  // volatility

            public NewBarrierOptionData(Barrier.Type _barrierType,
                                        double _barrier,
                                        double _rebate,
                                        Option.Type _type,
                                        double _strike,
                                        double _s,
                                        double _q,
                                        double _r,
                                        double _t,
                                        double _v)
            {
                barrierType = _barrierType;
                barrier     = _barrier;
                rebate      = _rebate;
                type        = _type;
                strike      = _strike;
                s           = _s;
                q           = _q;
                r           = _r;
                t           = _t;
                v           = _v;
            }
Beispiel #16
0
        //@}

        //! car 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
                if (capletVolatility().empty())
                {
                    throw new ApplicationException("missing optionlet volatility");
                }

                double stdDev =
                    Math.Sqrt(capletVolatility().link.totalVariance(fixingDate, effStrike));

                double fixing = optionletPriceImp(optionType,
                                                  effStrike,
                                                  adjustedFixing(),
                                                  stdDev);
                return(fixing * coupon_.accrualPeriod() * discount_);
            }
        }
Beispiel #17
0
        /*! Black 1976 probability of being in the money (in the bond martingale measure), i.e. N(d2).
         *    It is a risk-neutral probability, not the real world one.
         *     \warning instead of volatility it uses standard deviation, i.e. volatility*sqrt(timeToMaturity)
         */
        public static double blackFormulaCashItmProbability(Option.Type optionType,
                                                            double strike,
                                                            double forward,
                                                            double stdDev,
                                                            double displacement = 0.0)
        {
            checkParameters(strike, forward, displacement);
            if (stdDev.IsEqual(0.0))
            {
                return(forward * (int)optionType > strike * (int)optionType ? 1.0 : 0.0);
            }

            forward = forward + displacement;
            strike  = strike + displacement;
            if (strike.IsEqual(0.0))
            {
                return(optionType == Option.Type.Call ? 1.0 : 0.0);
            }
            double d2 = Math.Log(forward / strike) / stdDev - 0.5 * stdDev;
            CumulativeNormalDistribution phi = new CumulativeNormalDistribution();

            return(phi.value((int)optionType * d2));
        }
Beispiel #18
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.settlementMethod != Settlement.Method.ParYieldCurve, () =>
                             "cash-settled (ParYieldCurve) swaptions not priced with Lfm engine");

            VanillaSwap    swap = arguments_.swap;
            IPricingEngine pe   = new DiscountingSwapEngine(discountCurve_);

            swap.setPricingEngine(pe);

            double correction = swap.spread *
                                Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS());
            double fixedRate = swap.fixedRate - correction;
            double fairRate  = swap.fairRate() - correction;

            SwaptionVolatilityMatrix volatility =
                model_.link.getSwaptionVolatilityMatrix();

            Date       referenceDate = volatility.referenceDate();
            DayCounter dayCounter    = volatility.dayCounter();

            double exercise = dayCounter.yearFraction(referenceDate,
                                                      arguments_.exercise.date(0));
            double swapLength =
                dayCounter.yearFraction(referenceDate,
                                        arguments_.fixedPayDates.Last())
                - dayCounter.yearFraction(referenceDate,
                                          arguments_.fixedResetDates[0]);

            Option.Type w = arguments_.type == VanillaSwap.Type.Payer ?
                            Option.Type.Call : Option.Type.Put;
            double vol = volatility.volatility(exercise, swapLength,
                                               fairRate, true);

            results_.value = (swap.fixedLegBPS() / Const.BASIS_POINT) *
                             Utils.blackFormula(w, fixedRate, fairRate, vol * Math.Sqrt(exercise));
        }
 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;
 }
Beispiel #20
0
        public override double optionletPrice(Option.Type optionType, double effectiveStrike)
        {
            Date fixingDate = coupon_.fixingDate();

            if (fixingDate <= Settings.Instance.evaluationDate())
            {
                // the amount is determined
                double a;
                double b;
                if (optionType == Option.Type.Call)
                {
                    a = coupon_.indexFixing();
                    b = effectiveStrike;
                }
                else
                {
                    a = effectiveStrike;
                    b = coupon_.indexFixing();
                }
                return(Math.Max(a - b, 0.0) * accrualPeriod_ * discount_);
            }
            else
            {
                // not yet determined, use Black model
                Utils.QL_REQUIRE(!capletVolatility().empty(), () => "missing optionlet volatility");

                double stdDev    = Math.Sqrt(capletVolatility().link.blackVariance(fixingDate, effectiveStrike));
                double shift     = capletVolatility().link.displacement();
                bool   shiftedLn = capletVolatility().link.volatilityType() == VolatilityType.ShiftedLognormal;
                double fixing    =
                    shiftedLn
               ? Utils.blackFormula(optionType, effectiveStrike, adjustedFixing(), stdDev, 1.0, shift)
               : Utils.bachelierBlackFormula(optionType, effectiveStrike, adjustedFixing(), stdDev, 1.0);
                return(fixing * accrualPeriod_ * discount_);
            }
        }
Beispiel #21
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);
        }
Beispiel #22
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));
        }
Beispiel #23
0
 //! usually only need implement this (of course they may need
 //! to re-implement initialize too ...)
 protected virtual double optionletPriceImp(Option.Type t, double strike,
                                            double forward, double stdDev)
 {
     throw new ApplicationException("you must implement this to get a vol-dependent price");
 }
Beispiel #24
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;
 }
 public ArithmeticASOPathPricer(Option.Type type,
                                double discount)
     : this(type, discount, 0.0, 0)
 {
 }
 public ArithmeticASOPathPricer(Option.Type type,
                                double discount,
                                double runningSum)
     : this(type, discount, runningSum, 0)
 {
 }
Beispiel #27
0
        public override void calculate()
        {
            double basisPoint = 1.0e-4;

            Date exerciseDate = arguments_.exercise.date(0);

            // the part of the swap preceding exerciseDate should be truncated
            // to avoid taking into account unwanted cashflows
            // for the moment we add a check avoiding this situation
            VanillaSwap swap = arguments_.swap;

            double          strike      = swap.fixedRate;
            List <CashFlow> fixedLeg    = swap.fixedLeg();
            FixedRateCoupon firstCoupon = fixedLeg[0] as FixedRateCoupon;

            Utils.QL_REQUIRE(firstCoupon != null, () => "wrong coupon type");

            Utils.QL_REQUIRE(firstCoupon.accrualStartDate() >= exerciseDate,
                             () => "swap start (" + firstCoupon.accrualStartDate() + ") before exercise date ("
                             + exerciseDate + ") not supported in Black swaption engine");

            // using the forecasting curve
            swap.setPricingEngine(new DiscountingSwapEngine(swap.iborIndex().forwardingTermStructure()));
            double atmForward = swap.fairRate();

            // Volatilities are quoted for zero-spreaded swaps.
            // Therefore, any spread on the floating leg must be removed
            // with a corresponding correction on the fixed leg.
            if (swap.spread.IsNotEqual(0.0))
            {
                double correction = swap.spread * Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS());
                strike     -= correction;
                atmForward -= correction;
                results_.additionalResults["spreadCorrection"] = correction;
            }
            else
            {
                results_.additionalResults["spreadCorrection"] = 0.0;
            }
            results_.additionalResults["strike"]     = strike;
            results_.additionalResults["atmForward"] = atmForward;

            // using the discounting curve
            swap.setPricingEngine(new DiscountingSwapEngine(discountCurve_, false));
            double annuity = 0;

            switch (arguments_.settlementType)
            {
            case Settlement.Type.Physical:
            {
                annuity = Math.Abs(swap.fixedLegBPS()) / basisPoint;
                break;
            }

            case Settlement.Type.Cash:
            {
                DayCounter dayCount = firstCoupon.dayCounter();

                // we assume that the cash settlement date is equal
                // to the swap start date
                Date discountDate = model_ == CashAnnuityModel.DiscountCurve
                                   ? firstCoupon.accrualStartDate()
                                   : discountCurve_.link.referenceDate();

                double fixedLegCashBPS =
                    CashFlows.bps(fixedLeg,
                                  new InterestRate(atmForward, dayCount, Compounding.Compounded, Frequency.Annual), false,
                                  discountDate);

                annuity = Math.Abs(fixedLegCashBPS / basisPoint) * discountCurve_.link.discount(discountDate);
                break;
            }

            default:
                Utils.QL_FAIL("unknown settlement type");
                break;
            }
            results_.additionalResults["annuity"] = annuity;

            double swapLength = vol_.link.swapLength(swap.floatingSchedule().dates().First(),
                                                     swap.floatingSchedule().dates().Last());

            results_.additionalResults["swapLength"] = swapLength;

            double variance = vol_.link.blackVariance(exerciseDate,
                                                      swapLength,
                                                      strike);
            double displacement = displacement_ == null
                               ? vol_.link.shift(exerciseDate, swapLength)
                               : Convert.ToDouble(displacement_);

            double stdDev = Math.Sqrt(variance);

            results_.additionalResults["stdDev"] = stdDev;
            Option.Type w = (arguments_.type == VanillaSwap.Type.Payer) ? Option.Type.Call : Option.Type.Put;
            results_.value = new Spec().value(w, strike, atmForward, stdDev, annuity, displacement);

            double exerciseTime = vol_.link.timeFromReference(exerciseDate);

            results_.additionalResults["vega"] =
                new Spec().vega(strike, atmForward, stdDev, exerciseTime, annuity, displacement);
        }
Beispiel #28
0
 public double value(Option.Type type, double strike, double atmForward, double stdDev, double annuity,
                     double displacement = 0.0)
 {
     return(Utils.bachelierBlackFormula(type, strike, atmForward, stdDev, annuity));
 }
Beispiel #29
0
 public TypePayoff(Option.Type type) {
     type_ = type;
 }
Beispiel #30
0
 public GeometricAPOPathPricer(Option.Type type,
                               double strike,
                               double discount)
     : this(type, strike, discount, 1.0, 0)
 {
 }
 protected override double optionletPrice(Option.Type t, double d)
 {
     throw new ApplicationException("optionletPrice not available");
 }
Beispiel #32
0
        public void calculate(double[] p, GBMParaViewModel para)
        {
            this.xData_ = p;
            this.yData_ = new double[p.Length];

            double sellBuySign = 1.0;

            if (this.sellBuy_ == "매도")
            {
                sellBuySign = -1.0;
            }
            else
            {
            }

            // set up dates
            Calendar calendar = new TARGET();
            //Date todaysDate = new Date(DateTime.Now);
            Date settlementDate = new Date(para.ReferenceDate_);

            Settings.setEvaluationDate(settlementDate);

            // our options
            Option.Type type = this.callPutEnum_;

            double underlying    = para.CurrentPrice_;
            double strike        = this.strike_;
            double dividendYield = para.Dividend_ / 100;
            double riskFreeRate  = para.Drift_ / 100;

            if (this.callPutEnum_ == Option.Type.Call)
            {
                this.imVol_ = para.Call_Interpolation_.value(this.strike_);
            }
            else if (this.callPutEnum_ == Option.Type.Put)
            {
                this.imVol_ = para.Put_Interpolation_.value(this.strike_);
            }

            double volatility = (this.imVol_) / 100;

            Date maturity = new Date(this.maturiry_.AddDays(1));


            if (this.callPutEnum_ == 0)
            {
                this.deltaCal_ = 1.0;
                this.gammaCal_ = 0.0;
                this.vegaCal_  = 0.0;
                this.thetaCal_ = 0.0;
                this.rhoCal_   = 0.0;

                this.deltaPosition_ = sellBuySign * this.unit_ * 500000 * underlying;

                this.deltaRisk_ = this.deltaPosition_ * 0.09;
                this.gammaRisk_ = 0.0;
                this.vegaRisk_  = 0.0;

                this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_;
                this.deepOTM_   = 0.0;

                //this.remainDays_ = maturity - settlementDate;
                this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1;

                return;
            }

            DayCounter dayCounter = new Actual365Fixed();

            Exercise europeanExercise = new EuropeanExercise(maturity);

            SimpleQuote quote = new SimpleQuote(underlying);

            Handle <Quote> underlyingH = new Handle <Quote>(quote);

            // bootstrap the yield/dividend/vol curves
            var flatTermStructure    = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));
            var flatDividendTS       = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            var flatVolTS            = new Handle <BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter));
            StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike);
            var bsmProcess           = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

            // options
            VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise);

            // Analytic formulas:
            // Black-Scholes for European
            europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess));

            this.npv_      = Math.Round(europeanOption.NPV(), 6);
            this.deltaCal_ = sellBuySign * Math.Round(europeanOption.delta(), 6);
            this.gammaCal_ = sellBuySign * Math.Round(europeanOption.gamma(), 6);
            this.vegaCal_  = sellBuySign * Math.Round(europeanOption.vega() / 100, 6);
            this.thetaCal_ = sellBuySign * Math.Round(europeanOption.theta() / 365, 6);
            this.rhoCal_   = sellBuySign * Math.Round(europeanOption.rho() / 100, 6);

            this.deltaPosition_ = Math.Round(this.deltaCal_ * this.unit_ * 500000 * underlying, 0);
            this.deltaRisk_     = Math.Round(this.deltaPosition_ * 0.09, 0);
            this.gammaRisk_     = Math.Round(0.5 * this.gammaCal_ * (underlying * underlying * 0.08 * 0.08) * this.unit_ * 500000, 0);
            this.vegaRisk_      = Math.Round(this.vegaCal_ * this.imVol_ * 0.25 * this.unit_ * 500000, 0);

            this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_;

            this.deepOTM_ = 0.0;
            //this.remainDays_ = maturity - settlementDate;
            this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1;


            for (int i = 0; i < this.xData_.Length; i++)
            {
                quote.setValue(this.xData_[i]);
                this.yData_[i] = 500000.0 * (double)this.unit_ * europeanOption.NPV();
            }
        }
Beispiel #33
0
            public double tol;    // tolerance

            public NewBarrierOptionData(DoubleBarrier.Type barrierType, double barrierlo, double barrierhi, Option.Type type, Exercise.Type exType, double strike, double s, double q, double r, double t, double v, double result, double tol)
            {
                this.barrierType = barrierType;
                this.barrierlo   = barrierlo;
                this.barrierhi   = barrierhi;
                this.type        = type;
                this.exType      = exType;
                this.strike      = strike;
                this.s           = s;
                this.q           = q;
                this.r           = r;
                this.t           = t;
                this.v           = v;
                this.result      = result;
                this.tol         = tol;
            }