//! \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]); } } } }
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); }