コード例 #1
0
 protected override double optionletPriceImp(Option.Type optionType, double effStrike,
                                             double forward, double stdDev)
 {
     return(Utils.bachelierBlackFormula(optionType,
                                        effStrike,
                                        forward,
                                        stdDev));
 }
コード例 #2
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));
            }
        }
コード例 #3
0
ファイル: CouponPricer.cs プロジェクト: zhangz/QLNet
        protected 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) * 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, effStrike));
                double shift     = capletVolatility().link.displacement();
                bool   shiftedLn = capletVolatility().link.volatilityType() == VolatilityType.ShiftedLognormal;
                double fixing    =
                    shiftedLn
                    ? Utils.blackFormula(optionType, effStrike, adjustedFixing(), stdDev, 1.0, shift)
                    : Utils.bachelierBlackFormula(optionType, effStrike, adjustedFixing(), stdDev, 1.0);
                return(fixing * accrualPeriod_ * discount_);
            }
        }
コード例 #4
0
ファイル: BlackSwaptionEngine.cs プロジェクト: igitur/qlnet
 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));
 }
コード例 #5
0
 protected override double optionletImpl(Option.Type type, double strike,
                                         double forward, double stdDev,
                                         double d)
 {
     return(Utils.bachelierBlackFormula(type, strike, forward, stdDev, d));
 }
コード例 #6
0
        public override void calculate()
        {
            double        value      = 0.0;
            double        vega       = 0.0;
            int           optionlets = arguments_.startDates.Count;
            List <double> values     = new InitializedList <double>(optionlets, 0.0);
            List <double> vegas      = new InitializedList <double>(optionlets, 0.0);
            List <double> stdDevs    = new InitializedList <double>(optionlets, 0.0);
            CapFloorType  type       = arguments_.type;
            Date          today      = vol_.link.referenceDate();
            Date          settlement = discountCurve_.link.referenceDate();

            for (int i = 0; i < optionlets; ++i)
            {
                Date paymentDate = arguments_.endDates[i];
                // handling of settlementDate, npvDate and includeSettlementFlows
                // should be implemented.
                // For the double being just discard expired caplets
                if (paymentDate > settlement)
                {
                    double d = arguments_.nominals[i] *
                               arguments_.gearings[i] *
                               discountCurve_.link.discount(paymentDate) *
                               arguments_.accrualTimes[i];

                    double forward = arguments_.forwards[i].Value;

                    Date   fixingDate = arguments_.fixingDates[i];
                    double sqrtTime   = 0.0;
                    if (fixingDate > today)
                    {
                        sqrtTime = Math.Sqrt(vol_.link.timeFromReference(fixingDate));
                    }

                    if (type == CapFloorType.Cap || type == CapFloorType.Collar)
                    {
                        double strike = arguments_.capRates[i].Value;
                        if (sqrtTime > 0.0)
                        {
                            stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike));
                            vegas[i]   = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d) * sqrtTime;
                        }
                        // include caplets with past fixing date
                        values[i] = Utils.bachelierBlackFormula(Option.Type.Call, strike, forward, stdDevs[i], d);
                    }
                    if (type == CapFloorType.Floor || type == CapFloorType.Collar)
                    {
                        double strike       = arguments_.floorRates[i].Value;
                        double floorletVega = 0.0;
                        if (sqrtTime > 0.0)
                        {
                            stdDevs[i]   = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike));
                            floorletVega = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d) * sqrtTime;
                        }
                        double floorlet = Utils.bachelierBlackFormula(Option.Type.Put, strike, forward, stdDevs[i], d);
                        if (type == CapFloorType.Floor)
                        {
                            values[i] = floorlet;
                            vegas[i]  = floorletVega;
                        }
                        else
                        {
                            // a collar is long a cap and short a floor
                            values[i] -= floorlet;
                            vegas[i]  -= floorletVega;
                        }
                    }
                    value += values[i];
                    vega  += vegas[i];
                }
            }
            results_.value = value;
            results_.additionalResults["vega"] = vega;

            results_.additionalResults["optionletsPrice"]      = values;
            results_.additionalResults["optionletsVega"]       = vegas;
            results_.additionalResults["optionletsAtmForward"] = arguments_.forwards;
            if (type != CapFloorType.Collar)
            {
                results_.additionalResults["optionletsStdDev"] = stdDevs;
            }
        }