Пример #1
0
        //! \name LazyObject interface
        //@{
        protected override void performCalculations()
        {
            //// optionletStripper data
            optionletDates_          = new List <Date>(stripper1_.optionletFixingDates());
            optionletPaymentDates_   = new List <Date>(stripper1_.optionletPaymentDates());
            optionletAccrualPeriods_ = new List <double>(stripper1_.optionletAccrualPeriods());
            optionletTimes_          = new List <double>(stripper1_.optionletFixingTimes());
            atmOptionletRate_        = new List <double>(stripper1_.atmOptionletRates());
            for (int i = 0; i < optionletTimes_.Count; ++i)
            {
                optionletStrikes_[i]      = new List <double>(stripper1_.optionletStrikes(i));
                optionletVolatilities_[i] = new List <double>(stripper1_.optionletVolatilities(i));
            }

            // atmCapFloorTermVolCurve data
            List <Period> optionExpiriesTenors = new List <Period>(atmCapFloorTermVolCurve_.link.optionTenors());
            List <double> optionExpiriesTimes  = new List <double>(atmCapFloorTermVolCurve_.link.optionTimes());

            for (int j = 0; j < nOptionExpiries_; ++j)
            {
                double atmOptionVol        = atmCapFloorTermVolCurve_.link.volatility(optionExpiriesTimes[j], 33.3333); // dummy strike
                BlackCapFloorEngine engine = new BlackCapFloorEngine(iborIndex_.forwardingTermStructure(), atmOptionVol, dc_);
                CapFloor            test   = new MakeCapFloor(CapFloorType.Cap, optionExpiriesTenors[j], iborIndex_, null,
                                                              new Period(0, TimeUnit.Days)).withPricingEngine(engine).value();
                caps_.Add(test);
                atmCapFloorStrikes_[j] = caps_[j].atmRate(iborIndex_.forwardingTermStructure());
                atmCapFloorPrices_[j]  = caps_[j].NPV();
            }

            spreadsVolImplied_ = spreadsVolImplied();

            StrippedOptionletAdapter adapter = new StrippedOptionletAdapter(stripper1_);

            double unadjustedVol, adjustedVol;

            for (int j = 0; j < nOptionExpiries_; ++j)
            {
                for (int i = 0; i < optionletVolatilities_.Count; ++i)
                {
                    if (i <= caps_[j].floatingLeg().Count)
                    {
                        unadjustedVol = adapter.volatility(optionletTimes_[i], atmCapFloorStrikes_[j]);
                        adjustedVol   = unadjustedVol + spreadsVolImplied_[j];

                        // insert adjusted volatility
                        //List<Rate>::const_iterator previous =
                        //      std::lower_bound(optionletStrikes_[i].begin(),
                        //                        optionletStrikes_[i].end(),
                        //                        atmCapFloorStrikes_[j]);
                        var previous    = optionletStrikes_[i].FindIndex(x => x >= atmCapFloorStrikes_[j]);
                        int insertIndex = (int)previous; // (int)optionletStrikes_[i].First();

                        optionletStrikes_[i].Insert(insertIndex, atmCapFloorStrikes_[j]);
                        optionletVolatilities_[i].Insert(insertIndex, adjustedVol);
                        //optionletStrikes_[i].Insert((int)atmCapFloorStrikes_[j], optionletStrikes_[i][insertIndex]);
                        //optionletVolatilities_[i].Insert((int)adjustedVol,optionletVolatilities_[i][insertIndex]);
                    }
                }
            }
        }
Пример #2
0
		public override double blackPrice( double sigma )
		{
			calculate();
			Quote vol = new SimpleQuote( sigma );
			IPricingEngine black = new BlackCapFloorEngine( termStructure_,
																		  new Handle<Quote>( vol ) );
			cap_.setPricingEngine( black );
			double value = cap_.NPV();
			//cap_.unregisterWith( update );
			cap_.setPricingEngine( engine_ );
			return value;
		}
Пример #3
0
        public override double blackPrice(double sigma)
        {
            Quote          vol   = new SimpleQuote(sigma);
            IPricingEngine black = new BlackCapFloorEngine(termStructure_,
                                                           new Handle <Quote>(vol));

            cap_.setPricingEngine(black);
            double value = cap_.NPV();

            cap_.unregisterWith(update);
            cap_.setPricingEngine(engine_);
            return(value);
        }
Пример #4
0
            public ObjectiveFunction(OptionletStripper1 optionletStripper1, CapFloor cap, double targetValue)
            {
                cap_         = cap;
                targetValue_ = targetValue;

                OptionletVolatilityStructure adapter = new StrippedOptionletAdapter(optionletStripper1);

                // set an implausible value, so that calculation is forced
                // at first operator()(Volatility x) call
                spreadQuote_ = new SimpleQuote(-1.0);

                OptionletVolatilityStructure spreadedAdapter = new SpreadedOptionletVolatility(
                    new Handle <OptionletVolatilityStructure>(adapter), new Handle <Quote>(spreadQuote_));

                BlackCapFloorEngine engine = new BlackCapFloorEngine(optionletStripper1.iborIndex().forwardingTermStructure(),
                                                                     new Handle <OptionletVolatilityStructure>(spreadedAdapter));

                cap_.setPricingEngine(engine);
            }
Пример #5
0
        public CapFloor value()
        {
            VanillaSwap swap = makeVanillaSwap_;

            List <CashFlow> leg = swap.floatingLeg();

            if (firstCapletExcluded_)
            {
                leg.RemoveAt(0);
            }

            // only leaves the last coupon
            if (asOptionlet_ && leg.Count > 1)
            {
                leg.RemoveRange(0, leg.Count - 2); // Sun Studio needs an lvalue
            }

            List <double> strikeVector;

            if (strike_ == null)
            {
                // temporary patch...
                // should be fixed for every CapFloor::Engine
                BlackCapFloorEngine temp = engine_ as BlackCapFloorEngine;
                Utils.QL_REQUIRE(temp != null, () => "cannot calculate ATM without a BlackCapFloorEngine");
                Handle <YieldTermStructure> discountCurve = temp.termStructure();
                strikeVector = new InitializedList <double>(1, CashFlows.atmRate(leg, discountCurve, false, discountCurve.link.referenceDate()));
                //strikeVector[0] = CashFlows.atmRate(leg,discountCurve,false,discountCurve.link.referenceDate());
            }
            else
            {
                strikeVector = new InitializedList <double>(1, strike_.Value);
            }

            CapFloor capFloor = new CapFloor(capFloorType_, leg, strikeVector);

            capFloor.setPricingEngine(engine_);
            return(capFloor);
        }
Пример #6
0
        //! \name LazyObject interface
        //@{
        protected override void performCalculations()
        {
            // update dates
            Date                referenceDate = termVolSurface_.referenceDate();
            DayCounter          dc            = termVolSurface_.dayCounter();
            BlackCapFloorEngine dummy         = new BlackCapFloorEngine( // discounting does not matter here
                iborIndex_.forwardingTermStructure(), 0.20, dc);

            for (int i = 0; i < nOptionletTenors_; ++i)
            {
                CapFloor temp = new MakeCapFloor(CapFloorType.Cap,
                                                 capFloorLengths_[i],
                                                 iborIndex_,
                                                 0.04, // dummy strike
                                                 new Period(0, TimeUnit.Days))
                                .withPricingEngine(dummy);
                FloatingRateCoupon lFRC = temp.lastFloatingRateCoupon();
                optionletDates_[i]          = lFRC.fixingDate();
                optionletPaymentDates_[i]   = lFRC.date();
                optionletAccrualPeriods_[i] = lFRC.accrualPeriod();
                optionletTimes_[i]          = dc.yearFraction(referenceDate,
                                                              optionletDates_[i]);
                atmOptionletRate_[i] = lFRC.indexFixing();
            }

            if (floatingSwitchStrike_ && capFlooMatrixNotInitialized_)
            {
                double averageAtmOptionletRate = 0.0;
                for (int i = 0; i < nOptionletTenors_; ++i)
                {
                    averageAtmOptionletRate += atmOptionletRate_[i];
                }
                switchStrike_ = averageAtmOptionletRate / nOptionletTenors_;
            }

            Handle <YieldTermStructure> discountCurve = discount_.empty()
            ? iborIndex_.forwardingTermStructure()
            : discount_;

            List <double> strikes = new List <double>(termVolSurface_.strikes());

            // initialize CapFloorMatrix
            if (capFlooMatrixNotInitialized_)
            {
                for (int i = 0; i < nOptionletTenors_; ++i)
                {
                    capFloors_[i] = new List <CapFloor>(nStrikes_);
                }
                // construction might go here
                for (int j = 0; j < nStrikes_; ++j)
                {
                    // using out-of-the-money options
                    CapFloorType capFloorType = strikes[j] < switchStrike_
                  ? CapFloorType.Floor
                  : CapFloorType.Cap;
                    for (int i = 0; i < nOptionletTenors_; ++i)
                    {
                        //volQuotes_[i][j] = new SimpleQuote();
                        if (volatilityType_ == VolatilityType.ShiftedLognormal)
                        {
                            BlackCapFloorEngine engine = new BlackCapFloorEngine(discountCurve,
                                                                                 new Handle <Quote>(volQuotes_[i][j]), dc, displacement_);
                            capFloors_[i].Add(new MakeCapFloor(capFloorType, capFloorLengths_[i], iborIndex_, strikes[j],
                                                               new Period(0, TimeUnit.Days)).withPricingEngine(engine));
                        }
                        else if (volatilityType_ == VolatilityType.Normal)
                        {
                            BachelierCapFloorEngine engine = new BachelierCapFloorEngine(discountCurve,
                                                                                         new Handle <Quote>(volQuotes_[i][j]), dc);
                            capFloors_[i].Add(new MakeCapFloor(capFloorType, capFloorLengths_[i], iborIndex_, strikes[j],
                                                               new Period(0, TimeUnit.Days)).withPricingEngine(engine));
                        }
                        else
                        {
                            Utils.QL_FAIL("unknown volatility type: " + volatilityType_);
                        }
                    }
                }
                capFlooMatrixNotInitialized_ = false;
            }

            for (int j = 0; j < nStrikes_; ++j)
            {
                Option.Type optionletType = strikes[j] < switchStrike_ ? Option.Type.Put : Option.Type.Call;

                double previousCapFloorPrice = 0.0;
                for (int i = 0; i < nOptionletTenors_; ++i)
                {
                    capFloorVols_[i, j] = termVolSurface_.volatility(capFloorLengths_[i], strikes[j], true);
                    volQuotes_[i][j].setValue(capFloorVols_[i, j]);

                    capFloorPrices_[i, j]  = capFloors_[i][j].NPV();
                    optionletPrices_[i, j] = capFloorPrices_[i, j] - previousCapFloorPrice;
                    previousCapFloorPrice  = capFloorPrices_[i, j];
                    double d = discountCurve.link.discount(optionletPaymentDates_[i]);
                    double optionletAnnuity = optionletAccrualPeriods_[i] * d;
                    try
                    {
                        if (volatilityType_ == VolatilityType.ShiftedLognormal)
                        {
                            optionletStDevs_[i, j] = Utils.blackFormulaImpliedStdDev(optionletType, strikes[j], atmOptionletRate_[i],
                                                                                     optionletPrices_[i, j], optionletAnnuity, displacement_, optionletStDevs_[i, j], accuracy_,
                                                                                     maxIter_);
                        }
                        else if (volatilityType_ == VolatilityType.Normal)
                        {
                            optionletStDevs_[i, j] = Math.Sqrt(optionletTimes_[i]) *
                                                     Utils.bachelierBlackFormulaImpliedVol(
                                optionletType, strikes[j], atmOptionletRate_[i],
                                optionletTimes_[i], optionletPrices_[i, j],
                                optionletAnnuity);
                        }
                        else
                        {
                            Utils.QL_FAIL("Unknown volatility type: " + volatilityType_);
                        }
                    }
                    catch (Exception e)
                    {
                        if (dontThrow_)
                        {
                            optionletStDevs_[i, j] = 0.0;
                        }
                        else
                        {
                            Utils.QL_FAIL("could not bootstrap optionlet:" +
                                          "\n type:    " + optionletType +
                                          "\n strike:  " + (strikes[j]) +
                                          "\n atm:     " + (atmOptionletRate_[i]) +
                                          "\n price:   " + optionletPrices_[i, j] +
                                          "\n annuity: " + optionletAnnuity +
                                          "\n expiry:  " + optionletDates_[i] +
                                          "\n error:   " + e.Message);
                        }
                    }
                    optionletVolatilities_[i][j] = optionletStDevs_[i, j] / Math.Sqrt(optionletTimes_[i]);
                }
            }
        }