public InterpolatedPiecewiseZeroSpreadedTermStructure(Handle <YieldTermStructure> h,
                                                              List <Handle <Quote> > spreads,
                                                              List <Date> dates,
                                                              Compounding compounding = Compounding.Continuous,
                                                              Frequency frequency     = Frequency.NoFrequency,
                                                              DayCounter dc           = default(DayCounter),
                                                              Interpolator factory    = default(Interpolator))
        {
            originalCurve_ = h;
            spreads_       = spreads;
            dates_         = dates;
            times_         = new InitializedList <double>(dates.Count);
            spreadValues_  = new InitializedList <double>(dates.Count);
            compounding_   = compounding;
            frequency_     = frequency;
            dc_            = dc ?? new DayCounter();
            factory_       = factory ?? FastActivator <Interpolator> .Create();

            Utils.QL_REQUIRE(!spreads_.empty(), () => "no spreads given");
            Utils.QL_REQUIRE(spreads_.Count == dates_.Count, () => "spread and date vector have different sizes");

            originalCurve_.registerWith(update);

            for (int i = 0; i < spreads_.Count; i++)
            {
                spreads_[i].registerWith(update);
            }

            if (!originalCurve_.empty())
            {
                updateInterpolation();
            }
        }
Example #2
0
        public virtual void setCapletVolatility(Handle <YoYOptionletVolatilitySurface> capletVol)
        {
            Utils.QL_REQUIRE(!capletVol.empty(), () => "empty capletVol handle");

            capletVol_ = capletVol;
            capletVol_.registerWith(update);
        }
        protected SwaptionVolatilityCube(Handle <SwaptionVolatilityStructure> atmVol,
                                         List <Period> optionTenors,
                                         List <Period> swapTenors,
                                         List <double> strikeSpreads,
                                         List <List <Handle <Quote> > > volSpreads,
                                         SwapIndex swapIndexBase,
                                         SwapIndex shortSwapIndexBase,
                                         bool vegaWeightedSmileFit)
            : base(optionTenors, swapTenors, 0, atmVol.link.calendar(), atmVol.link.businessDayConvention(),
                   atmVol.link.dayCounter())
        {
            atmVol_               = atmVol;
            nStrikes_             = strikeSpreads.Count;
            strikeSpreads_        = strikeSpreads;
            localStrikes_         = new InitializedList <double>(nStrikes_);
            localSmile_           = new List <double>(nStrikes_);
            volSpreads_           = volSpreads;
            swapIndexBase_        = swapIndexBase;
            shortSwapIndexBase_   = shortSwapIndexBase;
            vegaWeightedSmileFit_ = vegaWeightedSmileFit;

            Utils.QL_REQUIRE(!atmVol_.empty(), () => "atm vol handle not linked to anything");
            for (int i = 1; i < nStrikes_; ++i)
            {
                Utils.QL_REQUIRE(strikeSpreads_[i - 1] < strikeSpreads_[i], () =>
                                 "non increasing strike spreads: " + i + " is " + strikeSpreads_[i - 1] + ", " +
                                 (i + 1) + " is " + strikeSpreads_[i]);
            }

            Utils.QL_REQUIRE(!volSpreads_.empty(), () => "empty vol spreads matrix");

            Utils.QL_REQUIRE(nOptionTenors_ * nSwapTenors_ == volSpreads_.Count, () =>
                             "mismatch between number of option tenors * swap tenors (" +
                             nOptionTenors_ * nSwapTenors_ + ") and number of rows (" +
                             volSpreads_.Count + ")");

            for (int i = 0; i < volSpreads_.Count; i++)
            {
                Utils.QL_REQUIRE(nStrikes_ == volSpreads_[i].Count, () =>
                                 "mismatch between number of strikes (" + nStrikes_ +
                                 ") and number of columns (" + volSpreads_[i].Count +
                                 ") in the " + (i + 1) + " row");
            }

            atmVol_.registerWith(update);
            atmVol_.link.enableExtrapolation();

            swapIndexBase_.registerWith(update);
            shortSwapIndexBase_.registerWith(update);

            Utils.QL_REQUIRE(shortSwapIndexBase_.tenor() < swapIndexBase_.tenor(), () =>
                             "short index tenor (" + shortSwapIndexBase_.tenor() +
                             ") is not less than index tenor (" +
                             swapIndexBase_.tenor() + ")");

            registerWithVolatilitySpread();
            Settings.Instance.registerWith(update);
            evaluationDate_ = Settings.Instance.evaluationDate();
        }
Example #4
0
        public double forecastFixing(Date d1, Date d2, double t)
        {
            Utils.QL_REQUIRE(!termStructure_.empty(), () => "null term structure set to this instance of " + name());
            double disc1 = termStructure_.link.discount(d1);
            double disc2 = termStructure_.link.discount(d2);

            return((disc1 / disc2 - 1.0) / t);
        }
Example #5
0
        public SpreadFittingMethod(FittedBondDiscountCurve.FittingMethod method, Handle <YieldTermStructure> discountCurve)
            : base(method != null ? method.constrainAtZero() : true,
                   method != null ? method.weights() : null,
                   method != null ? method.optimizationMethod() : null)
        {
            method_           = method;
            discountingCurve_ = discountCurve;

            Utils.QL_REQUIRE(method != null, () => "Fitting method is empty");
            Utils.QL_REQUIRE(!discountingCurve_.empty(), () => "Discounting curve cannot be empty");
        }
        public CPICouponPricer(Handle <CPIVolatilitySurface> capletVol = null)
        {
            if (capletVol == null)
            {
                capletVol = new Handle <CPIVolatilitySurface>();
            }

            capletVol_ = capletVol;

            if (!capletVol_.empty())
            {
                capletVol_.registerWith(update);
            }
        }
 public override void update()
 {
     if (!curve1_.empty() && !curve2_.empty())
     {
         base.update();
         enableExtrapolation(curve1_.link.allowsExtrapolation() && curve2_.link.allowsExtrapolation());
     }
     else
     {
         /* The implementation inherited from YieldTermStructure
          * asks for our reference date, which we don't have since
          * the original curve is still not set. Therefore, we skip
          * over that and just call the base-class behavior. */
         base.update();
     }
 }
 protected new void update()
 {
     if (!originalCurve_.empty())
     {
         updateInterpolation();
         base.update();
     }
     else
     {
         /* The implementation inherited from YieldTermStructure
          * asks for our reference date, which we don't have since
          * the original curve is still not set. Therefore, we skip
          * over that and just call the base-class behavior. */
         base.update();
     }
 }
Example #9
0
        public LognormalCmsSpreadPricer(
            CmsCouponPricer cmsPricer1,
            CmsCouponPricer cmsPricer2,
            Handle <Quote> correlation,
            Handle <YieldTermStructure> couponDiscountCurve = null,
            int integrationPoints         = 16,
            VolatilityType volatilityType = VolatilityType.None,
            double?shift1 = null,
            double?shift2 = null)
            : base(correlation)
        {
            correlation_.registerWith(update);
            cmsPricer1_ = cmsPricer1;
            cmsPricer2_ = cmsPricer2;

            couponDiscountCurve_ = couponDiscountCurve;

            if (couponDiscountCurve_ != null && !couponDiscountCurve_.empty())
            {
                couponDiscountCurve_.registerWith(update);
            }

            cmsPricer1_.registerWith(update);
            cmsPricer2_.registerWith(update);

            Utils.QL_REQUIRE(integrationPoints >= 4,
                             () => "at least 4 integration points should be used ("
                             + integrationPoints + ")");
            integrator_ = new GaussHermiteIntegration(integrationPoints);

            cnd_ = new CumulativeNormalDistribution(0.0, 1.0);

            if (volatilityType == VolatilityType.None)
            {
                Utils.QL_REQUIRE(shift1 == null && shift2 == null,
                                 () => "if volatility type is inherited, no shifts should be specified");
                inheritedVolatilityType_ = true;
                volType_ = cmsPricer1.swaptionVolatility().currentLink().volatilityType();
            }
            else
            {
                shift1_ = shift1 == null ? 0.0 : shift1.Value;
                shift2_ = shift2 == null ? 0.0 : shift2.Value;
                inheritedVolatilityType_ = false;
                volType_ = volatilityType;
            }
        }
        public VannaVolgaDoubleBarrierEngine(Handle <DeltaVolQuote> atmVol,
                                             Handle <DeltaVolQuote> vol25Put,
                                             Handle <DeltaVolQuote> vol25Call,
                                             Handle <Quote> spotFX,
                                             Handle <YieldTermStructure> domesticTS,
                                             Handle <YieldTermStructure> foreignTS,
                                             GetOriginalEngine getEngine,
                                             bool adaptVanDelta      = false,
                                             double bsPriceWithSmile = 0.0,
                                             int series = 5)
            : base()

        {
            atmVol_            = atmVol;
            vol25Put_          = vol25Put;
            vol25Call_         = vol25Call;
            T_                 = atmVol_.link.maturity();
            spotFX_            = spotFX;
            domesticTS_        = domesticTS;
            foreignTS_         = foreignTS;
            adaptVanDelta_     = adaptVanDelta;
            bsPriceWithSmile_  = bsPriceWithSmile;
            series_            = series;
            getOriginalEngine_ = getEngine;

            Utils.QL_REQUIRE(vol25Put_.link.delta().IsEqual(-0.25), () => "25 delta put is required by vanna volga method");
            Utils.QL_REQUIRE(vol25Call_.link.delta().IsEqual(0.25), () => "25 delta call is required by vanna volga method");

            Utils.QL_REQUIRE(vol25Put_.link.maturity().IsEqual(vol25Call_.link.maturity()) &&
                             vol25Put_.link.maturity().IsEqual(atmVol_.link.maturity()), () =>
                             "Maturity of 3 vols are not the same");

            Utils.QL_REQUIRE(!domesticTS_.empty(), () => "domestic yield curve is not defined");
            Utils.QL_REQUIRE(!foreignTS_.empty(), () => "foreign yield curve is not defined");

            atmVol_.registerWith(update);
            vol25Put_.registerWith(update);
            vol25Call_.registerWith(update);
            spotFX_.registerWith(update);
            domesticTS_.registerWith(update);
            foreignTS_.registerWith(update);
        }
        public CompositeZeroYieldStructure(Handle <YieldTermStructure> h1,
                                           Handle <YieldTermStructure> h2,
                                           Func <double, double, double> f,
                                           Compounding comp = Compounding.Continuous,
                                           Frequency freq   = Frequency.NoFrequency)

        {
            curve1_ = h1;
            curve2_ = h2;
            f_      = f;
            comp_   = comp;
            freq_   = freq;

            if (!curve1_.empty() && !curve2_.empty())
            {
                enableExtrapolation(curve1_.link.allowsExtrapolation() && curve2_.link.allowsExtrapolation());
            }

            curve1_.registerWith(update);
            curve2_.registerWith(update);
        }
        public override double swapletRate()
        {
            OvernightIndex index = coupon_.index() as OvernightIndex;

            List <Date>   fixingDates = coupon_.fixingDates();
            List <double> dt          = coupon_.dt();

            int n = dt.Count;
            int i = 0;

            double compoundFactor = 1.0;

            // already fixed part
            Date today = Settings.Instance.evaluationDate();

            while (fixingDates[i] < today && i < n)
            {
                // rate must have been fixed
                double?pastFixing = IndexManager.Instance.getHistory(index.name())[fixingDates[i]];

                Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + index.name() + " fixing for " + fixingDates[i].ToString());

                compoundFactor *= (1.0 + pastFixing.GetValueOrDefault() * dt[i]);
                ++i;
            }

            // today is a border case
            if (fixingDates[i] == today && i < n)
            {
                // might have been fixed
                try
                {
                    double?pastFixing = IndexManager.Instance.getHistory(index.name())[fixingDates[i]];

                    if (pastFixing != null)
                    {
                        compoundFactor *= (1.0 + pastFixing.GetValueOrDefault() * dt[i]);
                        ++i;
                    }
                    else
                    {
                        // fall through and forecast
                    }
                }
                catch (Exception)
                {
                    // fall through and forecast
                }
            }

            // forward part using telescopic property in order
            // to avoid the evaluation of multiple forward fixings
            if (i < n)
            {
                Handle <YieldTermStructure> curve = index.forwardingTermStructure();
                Utils.QL_REQUIRE(!curve.empty(), () => "null term structure set to this instance of" + index.name());

                List <Date> dates         = coupon_.valueDates();
                double      startDiscount = curve.link.discount(dates[i]);
                double      endDiscount   = curve.link.discount(dates[n]);

                compoundFactor *= startDiscount / endDiscount;
            }

            double rate = (compoundFactor - 1.0) / coupon_.accrualPeriod();

            return(coupon_.gearing() * rate + coupon_.spread());
        }
Example #13
0
        public OvernightIndexedSwap value()
        {
            Date startDate;

            if (effectiveDate_ != null)
            {
                startDate = effectiveDate_;
            }
            else
            {
                Date refDate = Settings.Instance.evaluationDate();
                // if the evaluation date is not a business day
                // then move to the next business day
                refDate = calendar_.adjust(refDate);
                Date spotDate = calendar_.advance(refDate, new Period(settlementDays_, TimeUnit.Days));
                startDate = spotDate + forwardStart_;
                if (forwardStart_.length() < 0)
                {
                    startDate = calendar_.adjust(startDate, BusinessDayConvention.Preceding);
                }
                else
                {
                    startDate = calendar_.adjust(startDate, BusinessDayConvention.Following);
                }
            }

            // OIS end of month default
            bool usedEndOfMonth =
                isDefaultEOM_ ? calendar_.isEndOfMonth(startDate) : endOfMonth_;

            Date endDate = terminationDate_;

            if (endDate == null)
            {
                if (usedEndOfMonth)
                {
                    endDate = calendar_.advance(startDate,
                                                swapTenor_,
                                                BusinessDayConvention.ModifiedFollowing,
                                                usedEndOfMonth);
                }
                else
                {
                    endDate = startDate + swapTenor_;
                }
            }



            Schedule schedule = new Schedule(startDate, endDate,
                                             new Period(paymentFrequency_),
                                             calendar_,
                                             BusinessDayConvention.ModifiedFollowing,
                                             BusinessDayConvention.ModifiedFollowing,
                                             rule_,
                                             usedEndOfMonth);

            double?usedFixedRate = fixedRate_;

            if (fixedRate_ == null)
            {
                OvernightIndexedSwap temp = new OvernightIndexedSwap(type_, nominal_,
                                                                     schedule,
                                                                     0.0, // fixed rate
                                                                     fixedDayCount_,
                                                                     overnightIndex_, overnightSpread_);
                if (engine_ == null)
                {
                    Handle <YieldTermStructure> disc = overnightIndex_.forwardingTermStructure();
                    Utils.QL_REQUIRE(!disc.empty(), () => "null term structure set to this instance of " +
                                     overnightIndex_.name());
                    bool           includeSettlementDateFlows = false;
                    IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows);
                    temp.setPricingEngine(engine);
                }
                else
                {
                    temp.setPricingEngine(engine_);
                }

                usedFixedRate = temp.fairRate();
            }

            OvernightIndexedSwap ois = new OvernightIndexedSwap(type_, nominal_,
                                                                schedule,
                                                                usedFixedRate.Value, fixedDayCount_,
                                                                overnightIndex_, overnightSpread_);

            if (engine_ == null)
            {
                Handle <YieldTermStructure> disc          = overnightIndex_.forwardingTermStructure();
                bool           includeSettlementDateFlows = false;
                IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows);
                ois.setPricingEngine(engine);
            }
            else
            {
                ois.setPricingEngine(engine_);
            }

            return(ois);
        }
        //! set up the interpolations for capPrice_ and floorPrice_
        //! since we know ATM, and we have single flows,
        //! we can use put/call parity to extend the surfaces
        //! across all strikes
        protected override void performCalculations()
        {
            allStrikes_ = new List <double>();
            int nMat  = cfMaturities_.Count,
                ncK   = cStrikes_.Count,
                nfK   = fStrikes_.Count,
                nK    = ncK + nfK;
            Matrix cP = new Matrix(nK, nMat),
                   fP = new Matrix(nK, nMat);
            Handle <ZeroInflationTermStructure> zts = zii_.link.zeroInflationTermStructure();
            Handle <YieldTermStructure>         yts = this.nominalTermStructure();

            Utils.QL_REQUIRE(!zts.empty(), () => "Zts is empty!!!");
            Utils.QL_REQUIRE(!yts.empty(), () => "Yts is empty!!!");

            for (int i = 0; i < nfK; i++)
            {
                allStrikes_.Add(fStrikes_[i]);
                for (int j = 0; j < nMat; j++)
                {
                    Period mat       = cfMaturities_[j];
                    double df        = yts.link.discount(cpiOptionDateFromTenor(mat));
                    double atm_quote = zts.link.zeroRate(cpiOptionDateFromTenor(mat));
                    double atm       = Math.Pow(1.0 + atm_quote, mat.length());
                    double S         = atm * df;
                    double K_quote   = fStrikes_[i] / 100.0;
                    double K         = Math.Pow(1.0 + K_quote, mat.length());
                    cP[i, j] = fPrice_[i, j] + S - K * df;
                    fP[i, j] = fPrice_[i, j];
                }
            }
            for (int i = 0; i < ncK; i++)
            {
                allStrikes_.Add(cStrikes_[i]);
                for (int j = 0; j < nMat; j++)
                {
                    Period mat       = cfMaturities_[j];
                    double df        = yts.link.discount(cpiOptionDateFromTenor(mat));
                    double atm_quote = zts.link.zeroRate(cpiOptionDateFromTenor(mat));
                    double atm       = Math.Pow(1.0 + atm_quote, mat.length());
                    double S         = atm * df;
                    double K_quote   = cStrikes_[i] / 100.0;
                    double K         = Math.Pow(1.0 + K_quote, mat.length());
                    cP[i + nfK, j] = cPrice_[i, j];
                    fP[i + nfK, j] = cPrice_[i, j] + K * df - S;
                }
            }

            // copy to store
            cPriceB_ = cP;
            fPriceB_ = fP;

            cfMaturityTimes_ = new List <double>();
            for (int i = 0; i < cfMaturities_.Count; i++)
            {
                cfMaturityTimes_.Add(timeFromReference(cpiOptionDateFromTenor(cfMaturities_[i])));
            }

            capPrice_ = interpolator2d_.interpolate(cfMaturityTimes_, cfMaturityTimes_.Count,
                                                    allStrikes_, allStrikes_.Count, cPriceB_);

            capPrice_.enableExtrapolation();

            floorPrice_ = interpolator2d_.interpolate(cfMaturityTimes_, cfMaturityTimes_.Count,
                                                      allStrikes_, allStrikes_.Count, fPriceB_);

            floorPrice_.enableExtrapolation();
        }
        // Instrument interface
        public override void calculate()
        {
            Utils.QL_REQUIRE(!discountCurve_.empty(), () => "discounting term structure handle is empty");

            results_.value         = results_.cash = 0;
            results_.errorEstimate = null;

            Date refDate = discountCurve_.link.referenceDate();

            Date settlementDate = settlementDate_;

            if (settlementDate_ == null)
            {
                settlementDate = refDate;
            }
            else
            {
                Utils.QL_REQUIRE(settlementDate >= refDate, () =>
                                 "settlement date (" + settlementDate + ") before " +
                                 "discount curve reference date (" + refDate + ")");
            }

            results_.valuationDate = npvDate_;
            if (npvDate_ == null)
            {
                results_.valuationDate = refDate;
            }
            else
            {
                Utils.QL_REQUIRE(npvDate_ >= refDate, () =>
                                 "npv date (" + npvDate_ + ") before " +
                                 "discount curve reference date (" + refDate + ")");
            }

            results_.npvDateDiscount = discountCurve_.link.discount(results_.valuationDate);

            int n = arguments_.legs.Count;

            results_.legNPV         = new InitializedList <double?>(n);
            results_.legBPS         = new InitializedList <double?>(n);
            results_.startDiscounts = new InitializedList <double?>(n);
            results_.endDiscounts   = new InitializedList <double?>(n);

            bool includeRefDateFlows =
                includeSettlementDateFlows_.HasValue ?
                includeSettlementDateFlows_.Value :
                Settings.Instance.includeReferenceDateEvents;

            for (int i = 0; i < n; ++i)
            {
                try
                {
                    YieldTermStructure discount_ref = discountCurve_.currentLink();
                    double             npv = 0, bps = 0;
                    CashFlows.npvbps(arguments_.legs[i],
                                     discount_ref,
                                     includeRefDateFlows,
                                     settlementDate,
                                     results_.valuationDate,
                                     out npv,
                                     out bps);
                    results_.legNPV[i] = npv * arguments_.payer[i];
                    results_.legBPS[i] = bps * arguments_.payer[i];

                    if (!arguments_.legs[i].empty())
                    {
                        Date d1 = CashFlows.startDate(arguments_.legs[i]);
                        if (d1 >= refDate)
                        {
                            results_.startDiscounts[i] = discountCurve_.link.discount(d1);
                        }
                        else
                        {
                            results_.startDiscounts[i] = null;
                        }

                        Date d2 = CashFlows.maturityDate(arguments_.legs[i]);
                        if (d2 >= refDate)
                        {
                            results_.endDiscounts[i] = discountCurve_.link.discount(d2);
                        }
                        else
                        {
                            results_.endDiscounts[i] = null;
                        }
                    }
                    else
                    {
                        results_.startDiscounts[i] = null;
                        results_.endDiscounts[i]   = null;
                    }
                }
                catch (Exception e)
                {
                    Utils.QL_FAIL((i + 1) + " leg: " + e.Message);
                }
                results_.value += results_.legNPV[i];
            }
        }
Example #16
0
 protected override void performCalculations()
 {
     Utils.QL_REQUIRE(!quote_.empty(), () => "null quote set");
     NPV_ = quote_.link.value();
 }