Example #1
0
 boost::shared_ptr<BlackVolTermStructure>
 flatVol(const Date& today,
         const boost::shared_ptr<Quote>& vol,
         const DayCounter& dc) {
     return boost::shared_ptr<BlackVolTermStructure>(new
         BlackConstantVol(today, NullCalendar(), Handle<Quote>(vol), dc));
 }
 ScenarioGenerator(const Calendar &calendar = NullCalendar(),
                   const DayCounter &dc = Actual365Fixed())
     : calendar_(calendar), dc_(dc), pathNumber_(0), validPath_(true),
       validHorizonDate_(true) {
     resetHorizonDate();
     baseDate_ = horizonDate_;
 }
Example #3
0
    FixedLocalVolSurface::FixedLocalVolSurface(
        const Date& referenceDate,
        const std::vector<Date>& dates,
        const std::vector<Real>& strikes,
        const boost::shared_ptr<Matrix>& localVolMatrix,
        const DayCounter& dayCounter,
        Extrapolation lowerExtrapolation,
        Extrapolation upperExtrapolation)
    : LocalVolTermStructure(
          referenceDate, NullCalendar(), Following, dayCounter),
      maxDate_(dates.back()),
      localVolMatrix_(localVolMatrix),
      strikes_(dates.size(),boost::make_shared<std::vector<Real> >(strikes)),
      localVolInterpol_(dates.size()),
      lowerExtrapolation_(lowerExtrapolation),
      upperExtrapolation_(upperExtrapolation) {

        QL_REQUIRE(dates[0]>=referenceDate,
                   "cannot have dates[0] < referenceDate");

        times_ = std::vector<Time>(dates.size());
        for (Size j=0; j<times_.size(); j++)
            times_[j] = timeFromReference(dates[j]);

        checkSurface();
        setInterpolation<Linear>();
    }
Example #4
0
    Real RiskyAssetSwap::recoveryValue() const {
        Real recoveryValue = 0;
        // simple Euler integral to evaluate the recovery value
        for (Size i = 1; i < fixedSchedule_.size(); i++) {
            TimeUnit stepSize = Days;
            Date d;
            if (fixedSchedule_[i-1] >= defaultTS_->referenceDate())
                d = fixedSchedule_[i-1];
            else
                d = defaultTS_->referenceDate();
            Date d0 = d;
            do {
                Real disc = yieldTS_->discount (d);
                Real dd   = defaultTS_->defaultDensity (d, true);
                Real dcf  = defaultTS_->dayCounter().yearFraction (d0, d);

                recoveryValue  += disc * dd * dcf;

                d0 = d;

                d = NullCalendar().advance (d0, 1, stepSize, Unadjusted);
            }
            while (d < fixedSchedule_[i]);
        }
        recoveryValue *= recoveryRate_;

        return recoveryValue;
    }
    Real HestonRNDCalculator::invcdf(Real p, Time t) const {
        const Real v0    = hestonProcess_->v0();
        const Real kappa = hestonProcess_->kappa();
        const Real theta = hestonProcess_->theta();

        const Volatility expVol
            = std::sqrt(theta + (v0-theta)*(1-std::exp(-kappa*t))/(t*kappa));

        const ext::shared_ptr<BlackScholesMertonProcess> bsmProcess(
            ext::make_shared<BlackScholesMertonProcess>(
                hestonProcess_->s0(),
                hestonProcess_->dividendYield(),
                hestonProcess_->riskFreeRate(),
                Handle<BlackVolTermStructure>(
                    ext::make_shared<BlackConstantVol>(
                            hestonProcess_->riskFreeRate()->referenceDate(),
                            NullCalendar(),
                            expVol,
                            hestonProcess_->riskFreeRate()->dayCounter()))));

        const Real guess = BSMRNDCalculator(bsmProcess).invcdf(p, t);

        return RiskNeutralDensityCalculator::InvCDFHelper(
            this, guess, 0.1*integrationEps_, maxIntegrationIterations_)
            .inverseCDF(p, t);
    }
   SABRVolTermStructure(Real alpha, Real beta, Real gamma, Real rho,
                        Real s0, Real r,
                        const Date& referenceDate, const DayCounter dc)
 : BlackVolatilityTermStructure(
       referenceDate, NullCalendar(), Following, dc),
   alpha_(alpha), beta_(beta),
   gamma_(gamma), rho_(rho),
   s0_(s0), r_(r) { }
Example #7
0
 BlackStyleSwaptionEngine<Spec>::BlackStyleSwaptionEngine(
     const Handle<YieldTermStructure> &discountCurve, Volatility vol,
     const DayCounter &dc, Real displacement)
     : discountCurve_(discountCurve),
       vol_(boost::shared_ptr<SwaptionVolatilityStructure>(
           new ConstantSwaptionVolatility(0, NullCalendar(), Following, vol,
                                          dc, Spec().type, displacement))),
       displacement_(displacement) {
     registerWith(discountCurve_);
 }
Example #8
0
 HestonBlackVolSurface::HestonBlackVolSurface(
     const Handle<HestonModel>& hestonModel)
 : BlackVolTermStructure(
       hestonModel->process()->riskFreeRate()->referenceDate(),
       NullCalendar(),
       Following,
       hestonModel->process()->riskFreeRate()->dayCounter()),
   hestonModel_(hestonModel),
   integration_(AnalyticHestonEngine::Integration::gaussLaguerre(164)) {
     registerWith(hestonModel_);
 }
 BlackCapFloorEngine::BlackCapFloorEngine(
                           const Handle<YieldTermStructure>& discountCurve,
                           Volatility v,
                           const DayCounter& dc,
                           Real displacement)
 : discountCurve_(discountCurve),
   vol_(boost::shared_ptr<OptionletVolatilityStructure>(new
       ConstantOptionletVolatility(0, NullCalendar(), Following, v, dc))),
   displacement_(displacement) {
     registerWith(discountCurve_);
 }
Example #10
0
	boost::shared_ptr<BlackVolTermStructure> ProcessInfo::ProcessParser_Impl::
			make_vol_ts(const std::string& keyName,
								std::map<std::string, std::string>& variable_map,
								std::map<std::string, std::vector<std::string>>& variable_array_map,
								std::map<std::string, Matrix>& variable_matrix_map)
	{
		boost::shared_ptr<BlackVolTermStructure> vol_ts;

		Date refDate = Settings::instance().evaluationDate();

		const std::string& vol_type = "TYPE";

		if (variable_map.find(keyName) != variable_map.end())
		{
			double value = std::stod(variable_map[keyName]);
			vol_ts = boost::shared_ptr<BlackConstantVol>(
				new BlackConstantVol(refDate, NullCalendar(), value, Actual365Fixed()));

			return vol_ts;
		}

		vol_ts = boost::shared_ptr<BlackConstantVol>(
			new BlackConstantVol(refDate, NullCalendar(), 0.3, Actual365Fixed()));
		
		//if (vol_type == "CONSTANT")
		//{
		//	vol_ts = boost::shared_ptr<BlackConstantVol>(
		//		new BlackConstantVol(refDate, NullCalendar(), 0.3, Actual365Fixed()));
		//}
		//else if (vol_type == "CURVE")
		//{
		//}
		//else if (vol_type == "SURFACE")
		//{
		//}
		//else
		//{
		//}

		return vol_ts;
	}
			QuantLib::Calendar calendar(const std::string& typeStr)
			{
				QuantLib::Calendar calendar;
				std::string upperStr = boost::to_upper_copy(typeStr);

				if(upperStr=="KOR") {
					calendar = SouthKorea();
				}
				else if(upperStr=="NULL") {
					calendar = NullCalendar();
				}
				else if(upperStr=="NULLCALENDAR") {
					calendar = NullCalendar();
				}
				else {
					QL_FAIL("unknown type calendar");
				}

				return calendar;

			}
Example #12
0
 BlackScholesProcess::BlackScholesProcess(
                           const Handle<Quote>& x0,
                           const Handle<YieldTermStructure>& riskFreeTS,
                           const Handle<BlackVolTermStructure>& blackVolTS,
                           const boost::shared_ptr<discretization>& d)
 : GeneralizedBlackScholesProcess(
          x0,
          // no dividend yield
          Handle<YieldTermStructure>(boost::shared_ptr<YieldTermStructure>(
               new FlatForward(0, NullCalendar(), 0.0, Actual365Fixed()))),
          riskFreeTS,
          blackVolTS,
          d) {}
Example #13
0
		boost::shared_ptr<EarlySeePricer> pricer()
		{
			// 잡다한거 받아서 여기서 세팅...?
			// 머 차수별 , 구조별 , 
			this->calendar_ = NullCalendar();

			boost::shared_ptr<EarlySeePricer> pricer =
				boost::shared_ptr<EarlySeePricer>(
					new EarlySeePricer(this->productInfo_,
										this->expense_leg(),
										this->premium_leg(),
										this->annuity_leg(),
										this->claim_leg()));

			return pricer;
		}
    SubPeriodsCoupon::SubPeriodsCoupon(
                                    const Date& paymentDate,
                                    Real nominal,
                                    const boost::shared_ptr<IborIndex>& index,
                                    const Date& startDate,
                                    const Date& endDate,
                                    Natural fixingDays,
                                    const DayCounter& dayCounter,
                                    Real gearing,
                                    Rate couponSpread,
                                    Rate rateSpread,
                                    const Date& refPeriodStart,
                                    const Date& refPeriodEnd)
    : FloatingRateCoupon(paymentDate, nominal, startDate, endDate,
                         fixingDays, index, gearing, couponSpread,
                         refPeriodStart, refPeriodEnd, dayCounter),
      rateSpread_(rateSpread) {
        const Handle<YieldTermStructure>& rateCurve =
            index->forwardingTermStructure();
        const Date& referenceDate = rateCurve->referenceDate();

        observationsSchedule_ = boost::shared_ptr<Schedule>(new
            Schedule(startDate, endDate,
                     index->tenor(),
                     NullCalendar(),
                     Unadjusted,
                     Unadjusted,
                     DateGeneration::Forward,
                     false));

        observationDates_ = observationsSchedule_->dates();
        observationDates_.pop_back();                       //remove end date
        observations_ = observationDates_.size();

        startTime_ = dayCounter.yearFraction(referenceDate, startDate);
        endTime_ = dayCounter.yearFraction(referenceDate, endDate);

        for (Size i=0; i<observations_; ++i) {
            observationTimes_.push_back(
                dayCounter.yearFraction(referenceDate, observationDates_[i]));
        }
     }
Example #15
0
    MakeSchedule::operator Schedule() const {
        // check for mandatory arguments
        QL_REQUIRE(effectiveDate_ != Date(), "effective date not provided");
        QL_REQUIRE(terminationDate_ != Date(), "termination date not provided");
        QL_REQUIRE(tenor_, "tenor/frequency not provided");

        // set dynamic defaults:
        BusinessDayConvention convention;
        // if a convention was set, we use it.
        if (convention_) {
            convention = *convention_;
        } else {
            if (!calendar_.empty()) {
                // ...if we set a calendar, we probably want it to be used;
                convention = Following;
            } else {
                // if not, we don't care.
                convention = Unadjusted;
            }
        }

        BusinessDayConvention terminationDateConvention;
        // if set explicitly, we use it;
        if (terminationDateConvention_) {
            terminationDateConvention = *terminationDateConvention_;
        } else {
            // Unadjusted as per ISDA specification
            terminationDateConvention = convention;
        }

        Calendar calendar = calendar_;
        // if no calendar was set...
        if (calendar.empty()) {
            // ...we use a null one.
            calendar = NullCalendar();
        }

        return Schedule(effectiveDate_, terminationDate_, *tenor_, calendar,
                        convention, terminationDateConvention,
                        rule_, endOfMonth_, firstDate_, nextToLastDate_);
    }
Example #16
0
    FixedLocalVolSurface::FixedLocalVolSurface(
        const Date& referenceDate,
        const std::vector<Time>& times,
        const std::vector<Real>& strikes,
        const boost::shared_ptr<Matrix>& localVolMatrix,
        const DayCounter& dayCounter,
        Extrapolation lowerExtrapolation,
        Extrapolation upperExtrapolation)
    : LocalVolTermStructure(
          referenceDate, NullCalendar(), Following, dayCounter),
      maxDate_(time2Date(referenceDate, dayCounter, times.back())),
      times_(times),
      localVolMatrix_(localVolMatrix),
      strikes_(times.size(),boost::make_shared<std::vector<Real> >(strikes)),
      localVolInterpol_(times.size()),
      lowerExtrapolation_(lowerExtrapolation),
      upperExtrapolation_(upperExtrapolation) {

        QL_REQUIRE(times_[0]>=0, "cannot have times[0] < 0");

        checkSurface();
        setInterpolation<Linear>();
    }
void VannaVolgaDoubleBarrierEngine::calculate() const {

    const Real sigmaShift_vega = 0.001;
    const Real sigmaShift_volga = 0.0001;
    const Real spotShift_delta = 0.0001 * spotFX_->value();
    const Real sigmaShift_vanna = 0.0001;

    Handle<Quote> x0Quote(  //used for shift
        boost::make_shared<SimpleQuote>(spotFX_->value()));
    Handle<Quote> atmVolQuote( //used for shift
        boost::make_shared<SimpleQuote>(atmVol_->value()));

    boost::shared_ptr<BlackVolTermStructure> blackVolTS =
        boost::make_shared<BlackConstantVol>(
            Settings::instance().evaluationDate(),
            NullCalendar(), atmVolQuote, Actual365Fixed());
    boost::shared_ptr<BlackScholesMertonProcess> stochProcess =
        boost::make_shared<BlackScholesMertonProcess>(
            x0Quote,
            foreignTS_,
            domesticTS_,
            Handle<BlackVolTermStructure>(blackVolTS));

    boost::shared_ptr<PricingEngine> engineBS =
        boost::make_shared<AnalyticDoubleBarrierEngine>(stochProcess,
                series_);

    BlackDeltaCalculator blackDeltaCalculatorAtm(
        Option::Call, atmVol_->deltaType(), x0Quote->value(),
        domesticTS_->discount(T_), foreignTS_->discount(T_),
        atmVol_->value() * sqrt(T_));
    Real atmStrike = blackDeltaCalculatorAtm.atmStrike(atmVol_->atmType());

    Real call25Vol = vol25Call_->value();
    Real put25Vol = vol25Put_->value();
    BlackDeltaCalculator blackDeltaCalculatorPut25(
        Option::Put, vol25Put_->deltaType(), x0Quote->value(),
        domesticTS_->discount(T_), foreignTS_->discount(T_),
        put25Vol * sqrt(T_));
    Real put25Strike = blackDeltaCalculatorPut25.strikeFromDelta(-0.25);
    BlackDeltaCalculator blackDeltaCalculatorCall25(
        Option::Call, vol25Call_->deltaType(), x0Quote->value(),
        domesticTS_->discount(T_), foreignTS_->discount(T_),
        call25Vol * sqrt(T_));
    Real call25Strike = blackDeltaCalculatorCall25.strikeFromDelta(0.25);

    //here use vanna volga interpolated smile to price vanilla
    std::vector<Real> strikes;
    std::vector<Real> vols;
    strikes.push_back(put25Strike);
    vols.push_back(put25Vol);
    strikes.push_back(atmStrike);
    vols.push_back(atmVol_->value());
    strikes.push_back(call25Strike);
    vols.push_back(call25Vol);
    VannaVolga vannaVolga(x0Quote->value(), foreignTS_->discount(T_), foreignTS_->discount(T_), T_);
    Interpolation interpolation = vannaVolga.interpolate(strikes.begin(), strikes.end(), vols.begin());
    interpolation.enableExtrapolation();
    const boost::shared_ptr<StrikedTypePayoff> payoff =
        boost::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
    Real strikeVol = interpolation(payoff->strike());
    //vannila option price
    Real vanillaOption = blackFormula(payoff->optionType(), payoff->strike(),
                                      x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                      strikeVol * sqrt(T_),
                                      domesticTS_->discount(T_));

    //already out
    if((x0Quote->value() > arguments_.barrier[1] || x0Quote->value() < arguments_.barrier[0])
            && arguments_.barrierType[0] == Barrier::DownOut) {
        results_.value = 0.0;
        results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierOutPrice"] = 0.0;
    }
    //already in
    else if((x0Quote->value() > arguments_.barrier[1] || x0Quote->value() < arguments_.barrier[0])
            && arguments_.barrierType[0] == Barrier::DownIn) {
        results_.value = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierOutPrice"] = 0.0;
    }
    else {

        //set up BS barrier option pricing
        //only calculate out barrier option price
        // in barrier price = vanilla - out barrier
        boost::shared_ptr<StrikedTypePayoff> payoff
            = boost::static_pointer_cast<StrikedTypePayoff> (arguments_.payoff);
        DoubleBarrierOption doubleBarrierOption(arguments_.barrierType,
                                                arguments_.barrier,
                                                arguments_.rebate,
                                                payoff,
                                                arguments_.exercise);

        doubleBarrierOption.setPricingEngine(engineBS);

        //BS price
        Real priceBS = doubleBarrierOption.NPV();

        Real priceAtmCallBS = blackFormula(Option::Call,atmStrike,
                                           x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                           atmVol_->value() * sqrt(T_),
                                           domesticTS_->discount(T_));
        Real price25CallBS = blackFormula(Option::Call,call25Strike,
                                          x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                          atmVol_->value() * sqrt(T_),
                                          domesticTS_->discount(T_));
        Real price25PutBS = blackFormula(Option::Put,put25Strike,
                                         x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                         atmVol_->value() * sqrt(T_),
                                         domesticTS_->discount(T_));

        //market price
        Real priceAtmCallMkt = blackFormula(Option::Call,atmStrike,
                                            x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                            atmVol_->value() * sqrt(T_),
                                            domesticTS_->discount(T_));
        Real price25CallMkt = blackFormula(Option::Call,call25Strike,
                                           x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                           call25Vol * sqrt(T_),
                                           domesticTS_->discount(T_));
        Real price25PutMkt = blackFormula(Option::Put,put25Strike,
                                          x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                          put25Vol * sqrt(T_),
                                          domesticTS_->discount(T_));

        //Analytical Black Scholes formula
        NormalDistribution norm;
        Real d1atm = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/atmStrike)
                      + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_));
        Real vegaAtm_Analytical = x0Quote->value() * norm(d1atm) * sqrt(T_) * foreignTS_->discount(T_);
        Real vannaAtm_Analytical = vegaAtm_Analytical/x0Quote->value() *(1.0 - d1atm/(atmVolQuote->value()*sqrt(T_)));
        Real volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value();

        Real d125call = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/call25Strike)
                         + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_));
        Real vega25Call_Analytical = x0Quote->value() * norm(d125call) * sqrt(T_) * foreignTS_->discount(T_);
        Real vanna25Call_Analytical = vega25Call_Analytical/x0Quote->value() *(1.0 - d125call/(atmVolQuote->value()*sqrt(T_)));
        Real volga25Call_Analytical = vega25Call_Analytical * d125call * (d125call - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value();

        Real d125Put = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/put25Strike)
                        + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_));
        Real vega25Put_Analytical = x0Quote->value() * norm(d125Put) * sqrt(T_) * foreignTS_->discount(T_);
        Real vanna25Put_Analytical = vega25Put_Analytical/x0Quote->value() *(1.0 - d125Put/(atmVolQuote->value()*sqrt(T_)));
        Real volga25Put_Analytical = vega25Put_Analytical * d125Put * (d125Put - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value();


        //BS vega
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega);
        doubleBarrierOption.recalculate();
        Real vegaBarBS = (doubleBarrierOption.NPV() - priceBS)/sigmaShift_vega;
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() - sigmaShift_vega);//setback

        //BS volga

        //vegaBar2
        //base NPV
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_volga);
        doubleBarrierOption.recalculate();
        Real priceBS2 = doubleBarrierOption.NPV();

        //shifted npv
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega);
        doubleBarrierOption.recalculate();
        Real vegaBarBS2 = (doubleBarrierOption.NPV() - priceBS2)/sigmaShift_vega;
        Real volgaBarBS = (vegaBarBS2 - vegaBarBS)/sigmaShift_volga;
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value()
                - sigmaShift_volga
                - sigmaShift_vega);//setback

        //BS Delta
        //base delta
        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//shift forth
        doubleBarrierOption.recalculate();
        Real priceBS_delta1 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);//shift back
        doubleBarrierOption.recalculate();
        Real priceBS_delta2 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() +  spotShift_delta);//set back
        Real deltaBar1 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta);

        //shifted vanna
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vanna);//shift sigma
        //shifted delta
        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//shift forth
        doubleBarrierOption.recalculate();
        priceBS_delta1 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);//shift back
        doubleBarrierOption.recalculate();
        priceBS_delta2 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() +  spotShift_delta);//set back
        Real deltaBar2 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta);

        Real vannaBarBS = (deltaBar2 - deltaBar1)/sigmaShift_vanna;

        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() - sigmaShift_vanna);//set back

        //Matrix
        Matrix A(3,3,0.0);

        //analytical
        A[0][0] = vegaAtm_Analytical;
        A[0][1] = vega25Call_Analytical;
        A[0][2] = vega25Put_Analytical;
        A[1][0] = vannaAtm_Analytical;
        A[1][1] = vanna25Call_Analytical;
        A[1][2] = vanna25Put_Analytical;
        A[2][0] = volgaAtm_Analytical;
        A[2][1] = volga25Call_Analytical;
        A[2][2] = volga25Put_Analytical;

        Array b(3,0.0);
        b[0] = vegaBarBS;
        b[1] = vannaBarBS;
        b[2] = volgaBarBS;
        Array q = inverse(A) * b;

        Real H = arguments_.barrier[1];
        Real L = arguments_.barrier[0];
        Real theta_tilt_minus = ((domesticTS_->zeroRate(T_, Continuous) - foreignTS_->zeroRate(T_, Continuous))/atmVol_->value() - atmVol_->value()/2.0)*std::sqrt(T_);
        Real h = 1.0/atmVol_->value() * std::log(H/x0Quote->value())/std::sqrt(T_);
        Real l = 1.0/atmVol_->value() * std::log(L/x0Quote->value())/std::sqrt(T_);
        CumulativeNormalDistribution cnd;

        Real doubleNoTouch = 0.0;
        for(int j = -series_; j< series_; j++ ) {
            Real e_minus = 2*j*(h-l) - theta_tilt_minus;
            doubleNoTouch += std::exp(-2.0*j*theta_tilt_minus*(h-l))*(cnd(h+e_minus) - cnd(l+e_minus))
                             - std::exp(-2.0*j*theta_tilt_minus*(h-l)+2.0*theta_tilt_minus*h)*(cnd(h-2.0*h+e_minus) - cnd(l-2.0*h+e_minus));
        }

        Real p_survival = doubleNoTouch;

        Real lambda = p_survival ;
        Real adjust = q[0]*(priceAtmCallMkt - priceAtmCallBS)
                      + q[1]*(price25CallMkt - price25CallBS)
                      + q[2]*(price25PutMkt - price25PutBS);
        Real outPrice = priceBS + lambda*adjust;//
        Real inPrice;

        //adapt Vanilla delta
        if(adaptVanDelta_ == true) {
            outPrice += lambda*(bsPriceWithSmile_ - vanillaOption);
            //capfloored by (0, vanilla)
            outPrice = std::max(0.0, std::min(bsPriceWithSmile_, outPrice));
            inPrice = bsPriceWithSmile_ - outPrice;
        }
        else {
            //capfloored by (0, vanilla)
            outPrice = std::max(0.0, std::min(vanillaOption , outPrice));
            inPrice = vanillaOption - outPrice;
        }

        if(arguments_.barrierType[0] == Barrier::DownOut)
            results_.value = outPrice;
        else
            results_.value = inPrice;
        results_.additionalResults["VanillaPrice"] = vanillaOption;
        results_.additionalResults["BarrierInPrice"] = inPrice;
        results_.additionalResults["BarrierOutPrice"] = outPrice;
        results_.additionalResults["lambda"] = lambda;
    }
}
Example #18
0
    Rate YoYInflationIndex::fixing(const Date& fixingDate,
                                   bool /*forecastTodaysFixing*/) const {

        Date today = Settings::instance().evaluationDate();
        Date todayMinusLag = today - availabilityLag_;
        std::pair<Date,Date> lim = inflationPeriod(todayMinusLag, frequency_);
        Date lastFix = lim.first-1;

        Date flatMustForecastOn = lastFix+1;
        Date interpMustForecastOn = lastFix+1 - Period(frequency_);


        if (interpolated() && fixingDate >= interpMustForecastOn) {
            return forecastFixing(fixingDate);
        }

        if (!interpolated() && fixingDate >= flatMustForecastOn) {
            return forecastFixing(fixingDate);
        }

        // four cases with ratio() and interpolated()

        const TimeSeries<Real>& ts = timeSeries();
        if (ratio()) {

            if(interpolated()){ // IS ratio, IS interpolated

                std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_);
                Date fixMinus1Y=NullCalendar().advance(fixingDate, -1*Years, ModifiedFollowing);
                std::pair<Date,Date> limBef = inflationPeriod(fixMinus1Y, frequency_);
                Real dp= lim.second + 1 - lim.first;
                Real dpBef=limBef.second + 1 - limBef.first;
                Real dl = fixingDate-lim.first;
                // potentially does not work on 29th Feb
                Real dlBef = fixMinus1Y - limBef.first;
                // get the four relevant fixings
                // recall that they are stored flat for every day
                Rate limFirstFix = ts[lim.first];
                QL_REQUIRE(limFirstFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.first );
                Rate limSecondFix = ts[lim.second+1];
                QL_REQUIRE(limSecondFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.second+1 );
                Rate limBefFirstFix = ts[limBef.first];
                QL_REQUIRE(limBefFirstFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << limBef.first );
                Rate limBefSecondFix =
                IndexManager::instance().getHistory(name())[limBef.second+1];
                QL_REQUIRE(limBefSecondFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << limBef.second+1 );

                Real linearNow = limFirstFix + (limSecondFix-limFirstFix)*dl/dp;
                Real linearBef = limBefFirstFix + (limBefSecondFix-limBefFirstFix)*dlBef/dpBef;
                Rate wasYES = linearNow / linearBef - 1.0;

                return wasYES;

            } else {    // IS ratio, NOT interpolated
                Rate pastFixing = ts[fixingDate];
                QL_REQUIRE(pastFixing != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << fixingDate);
                Date previousDate = fixingDate - 1*Years;
                Rate previousFixing = ts[previousDate];
                QL_REQUIRE(previousFixing != Null<Rate>(),
                           "Missing " << name() << " fixing for "
                           << previousDate );

                return pastFixing/previousFixing - 1.0;
            }

        } else {  // NOT ratio

            if (interpolated()) { // NOT ratio, IS interpolated

                std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_);
                Real dp= lim.second + 1 - lim.first;
                Real dl = fixingDate-lim.first;
                Rate limFirstFix = ts[lim.first];
                QL_REQUIRE(limFirstFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.first );
                Rate limSecondFix = ts[lim.second+1];
                QL_REQUIRE(limSecondFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.second+1 );
                Real linearNow = limFirstFix + (limSecondFix-limFirstFix)*dl/dp;

                return linearNow;

            } else { // NOT ratio, NOT interpolated
                    // so just flat

                Rate pastFixing = ts[fixingDate];
                QL_REQUIRE(pastFixing != Null<Rate>(),
                           "Missing " << name() << " fixing for "
                           << fixingDate);
                return pastFixing;

            }
        }

        // QL_FAIL("YoYInflationIndex::fixing, should never get here");

    }
Example #19
0
    void IntegralCDOEngine::calculate() const {
        Date today = Settings::instance().evaluationDate();

        results_.protectionValue = 0.0;
        results_.premiumValue = 0.0;
        results_.upfrontPremiumValue = 0.0;
        results_.error = 0;
        results_.expectedTrancheLoss.clear();
        // todo Should be remaining when considering realized loses
        results_.xMin = arguments_.basket->attachmentAmount();
        results_.xMax = arguments_.basket->detachmentAmount();
        results_.remainingNotional = results_.xMax - results_.xMin;
        const Real inceptionTrancheNotional = 
            arguments_.basket->trancheNotional();

        // compute expected loss at the beginning of first relevant period
        Real e1 = 0;
        // todo add includeSettlement date flows variable to engine.
        if (!arguments_.normalizedLeg[0]->hasOccurred(today)) 
             // cast to fixed rate coupon?
            e1 = arguments_.basket->expectedTrancheLoss(
                boost::dynamic_pointer_cast<Coupon>(
                    arguments_.normalizedLeg[0])->accrualStartDate()); 
        results_.expectedTrancheLoss.push_back(e1);// zero or realized losses?

        for (Size i = 0; i < arguments_.normalizedLeg.size(); i++) {
            if(arguments_.normalizedLeg[i]->hasOccurred(today)) {
                // add includeSettlement date flows variable to engine.
                results_.expectedTrancheLoss.push_back(0.);
                continue;
            }

            const boost::shared_ptr<Coupon> coupon =
                boost::dynamic_pointer_cast<Coupon>(
                    arguments_.normalizedLeg[i]);

            Date d1 = coupon->accrualStartDate();
            Date d2 = coupon->date();

            Date d, d0 = d1;
            Real e2;
            do {
                d = NullCalendar().advance(d0 > today ? d0 : today,
                                           stepSize_);
                if (d > d2) d = d2;

                e2 = arguments_.basket->expectedTrancheLoss(d);

                results_.premiumValue
                    // ..check for e2 including past/realized losses
                    += (inceptionTrancheNotional - e2)
                    * arguments_.runningRate
                    * arguments_.dayCounter.yearFraction(d0, d)
                    * discountCurve_->discount(d);

                // TO DO: Addd default coupon accrual value here-----

                if (e2 < e1) results_.error ++;

                results_.protectionValue
                    += (e2 - e1) * discountCurve_->discount(d);

                d0 = d;
                e1 = e2;
            }
            while (d < d2);
            results_.expectedTrancheLoss.push_back(e2);
        }

        // add includeSettlement date flows variable to engine.
        if (!arguments_.normalizedLeg[0]->hasOccurred(today))
            results_.upfrontPremiumValue
                = inceptionTrancheNotional * arguments_.upfrontRate
                    * discountCurve_->discount(
                        boost::dynamic_pointer_cast<Coupon>(
                            arguments_.normalizedLeg[0])->accrualStartDate());

        if (arguments_.side == Protection::Buyer) {
            results_.protectionValue *= -1;
            results_.premiumValue *= -1;
            results_.upfrontPremiumValue *= -1;
        }

        results_.value = results_.premiumValue - results_.protectionValue
            + results_.upfrontPremiumValue;
        results_.errorEstimate = Null<Real>();
        // Fair spread GIVEN the upfront
        Real fairSpread = 0.;
        if (results_.premiumValue != 0.0) {
            fairSpread =
                -(results_.protectionValue + results_.upfrontPremiumValue)
                  *arguments_.runningRate/results_.premiumValue;
        }

        results_.additionalResults["fairPremium"] = fairSpread;
        results_.additionalResults["premiumLegNPV"] = 
            results_.premiumValue + results_.upfrontPremiumValue;
        results_.additionalResults["protectionLegNPV"] = 
            results_.protectionValue;
    }
    //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    void IntegralCDOEngine::calculate() const {
        Date today = Settings::instance().evaluationDate();
        const vector<Date>& dates = arguments_.schedule.dates();

        results_.protectionValue = 0.0;
        results_.premiumValue = 0.0;
        results_.upfrontPremiumValue = 0.0;
        results_.error = 0;
        results_.expectedTrancheLoss.clear();
        results_.expectedTrancheLoss.resize(dates.size(), 0.0);

        // set remainingBasket_, results_.remainingNotional,
        // vector results_.expectedTrancheLoss for all schedule dates
        initialize();

        Real e1 = 0;
        if (arguments_.schedule.dates().front() > today)
            e1 = expectedTrancheLoss (arguments_.schedule.dates()[0]);

        for (Size i = 1; i < arguments_.schedule.size(); i++) {
            Date d2 = arguments_.schedule.dates()[i];
            if (d2 < today)
                continue;

            Date d1 = arguments_.schedule.dates()[i-1];

            Date d, d0 = d1;
            do {
                d = NullCalendar().advance (d0 > today ? d0 : today,
                                            stepSize_);
                if (d > d2) d = d2;

                Real e2 = expectedTrancheLoss (d);

                results_.premiumValue
                    += (results_.remainingNotional - e2)
                    * arguments_.runningRate
                    * arguments_.dayCounter.yearFraction (d0, d)
                    * arguments_.yieldTS->discount (d);

                if (e2 < e1) results_.error ++;

                results_.protectionValue
                    += (e2 - e1) * arguments_.yieldTS->discount (d);

                d0 = d;
                e1 = e2;
            }
            while (d < d2);
        }

        if (arguments_.schedule.dates().front() >= today)
            results_.upfrontPremiumValue
                = results_.remainingNotional * arguments_.upfrontRate
                * arguments_.yieldTS->discount(arguments_.schedule.dates()[0]);

        if (arguments_.side == Protection::Buyer) {
            results_.protectionValue *= -1;
            results_.premiumValue *= -1;
            results_.upfrontPremiumValue *= -1;
        }

        results_.value = results_.premiumValue - results_.protectionValue
            + results_.upfrontPremiumValue;

        results_.errorEstimate = Null<Real>();
    }
Example #21
0
 boost::shared_ptr<YieldTermStructure>
 flatRate(const boost::shared_ptr<Quote>& forward,
          const DayCounter& dc) {
     return boost::shared_ptr<YieldTermStructure>(
           new FlatForward(0, NullCalendar(), Handle<Quote>(forward), dc));
 }
Example #22
0
    Schedule::Schedule(Date effectiveDate,
                       const Date& terminationDate,
                       const Period& tenor,
                       const Calendar& cal,
                       BusinessDayConvention convention,
                       BusinessDayConvention terminationDateConvention,
                       DateGeneration::Rule rule,
                       bool endOfMonth,
                       const Date& first,
                       const Date& nextToLast)
    : tenor_(tenor), calendar_(cal), convention_(convention),
      terminationDateConvention_(terminationDateConvention), rule_(rule),
      endOfMonth_(allowsEndOfMonth(tenor) ? endOfMonth : false),
      firstDate_(first==effectiveDate ? Date() : first),
      nextToLastDate_(nextToLast==terminationDate ? Date() : nextToLast)
    {
        // sanity checks
        QL_REQUIRE(terminationDate != Date(), "null termination date");

        // in many cases (e.g. non-expired bonds) the effective date is not
        // really necessary. In these cases a decent placeholder is enough
        if (effectiveDate==Date() && first==Date()
                                  && rule==DateGeneration::Backward) {
            Date evalDate = Settings::instance().evaluationDate();
            QL_REQUIRE(evalDate < terminationDate, "null effective date");
            Natural y;
            if (nextToLast != Date()) {
                y = (nextToLast - evalDate)/366 + 1;
                effectiveDate = nextToLast - y*Years;
            } else {
                y = (terminationDate - evalDate)/366 + 1;
                effectiveDate = terminationDate - y*Years;
            }
        } else
            QL_REQUIRE(effectiveDate != Date(), "null effective date");

        QL_REQUIRE(effectiveDate < terminationDate,
                   "effective date (" << effectiveDate
                   << ") later than or equal to termination date ("
                   << terminationDate << ")");

        if (tenor.length()==0)
            rule_ = DateGeneration::Zero;
        else
            QL_REQUIRE(tenor.length()>0,
                       "non positive tenor (" << tenor << ") not allowed");

        if (firstDate_ != Date()) {
            switch (*rule_) {
              case DateGeneration::Backward:
              case DateGeneration::Forward:
                QL_REQUIRE(firstDate_ > effectiveDate &&
                           firstDate_ < terminationDate,
                           "first date (" << firstDate_ <<
                           ") out of effective-termination date range [" <<
                           effectiveDate << ", " << terminationDate << ")");
                // we should ensure that the above condition is still
                // verified after adjustment
                break;
              case DateGeneration::ThirdWednesday:
                  QL_REQUIRE(IMM::isIMMdate(firstDate_, false),
                             "first date (" << firstDate_ <<
                             ") is not an IMM date");
                break;
              case DateGeneration::Zero:
              case DateGeneration::Twentieth:
              case DateGeneration::TwentiethIMM:
              case DateGeneration::OldCDS:
              case DateGeneration::CDS:
                QL_FAIL("first date incompatible with " << *rule_ <<
                        " date generation rule");
              default:
                QL_FAIL("unknown rule (" << Integer(*rule_) << ")");
            }
        }
        if (nextToLastDate_ != Date()) {
            switch (*rule_) {
              case DateGeneration::Backward:
              case DateGeneration::Forward:
                QL_REQUIRE(nextToLastDate_ > effectiveDate &&
                           nextToLastDate_ < terminationDate,
                           "next to last date (" << nextToLastDate_ <<
                           ") out of effective-termination date range (" <<
                           effectiveDate << ", " << terminationDate << "]");
                // we should ensure that the above condition is still
                // verified after adjustment
                break;
              case DateGeneration::ThirdWednesday:
                QL_REQUIRE(IMM::isIMMdate(nextToLastDate_, false),
                           "next-to-last date (" << nextToLastDate_ <<
                           ") is not an IMM date");
                break;
              case DateGeneration::Zero:
              case DateGeneration::Twentieth:
              case DateGeneration::TwentiethIMM:
              case DateGeneration::OldCDS:
              case DateGeneration::CDS:
                QL_FAIL("next to last date incompatible with " << *rule_ <<
                        " date generation rule");
              default:
                QL_FAIL("unknown rule (" << Integer(*rule_) << ")");
            }
        }


        // calendar needed for endOfMonth adjustment
        Calendar nullCalendar = NullCalendar();
        Integer periods = 1;
        Date seed, exitDate;
        switch (*rule_) {

          case DateGeneration::Zero:
            tenor_ = 0*Years;
            dates_.push_back(effectiveDate);
            dates_.push_back(terminationDate);
            isRegular_.push_back(true);
            break;

          case DateGeneration::Backward:

            dates_.push_back(terminationDate);

            seed = terminationDate;
            if (nextToLastDate_ != Date()) {
                dates_.insert(dates_.begin(), nextToLastDate_);
                Date temp = nullCalendar.advance(seed,
                    -periods*(*tenor_), convention, *endOfMonth_);
                if (temp!=nextToLastDate_)
                    isRegular_.insert(isRegular_.begin(), false);
                else
                    isRegular_.insert(isRegular_.begin(), true);
                seed = nextToLastDate_;
            }

            exitDate = effectiveDate;
            if (firstDate_ != Date())
                exitDate = firstDate_;

            for (;;) {
                Date temp = nullCalendar.advance(seed,
                    -periods*(*tenor_), convention, *endOfMonth_);
                if (temp < exitDate) {
                    if (firstDate_ != Date() &&
                        (calendar_.adjust(dates_.front(),convention)!=
                         calendar_.adjust(firstDate_,convention))) {
                        dates_.insert(dates_.begin(), firstDate_);
                        isRegular_.insert(isRegular_.begin(), false);
                    }
                    break;
                } else {
                    // skip dates that would result in duplicates
                    // after adjustment
                    if (calendar_.adjust(dates_.front(),convention)!=
                        calendar_.adjust(temp,convention)) {
                        dates_.insert(dates_.begin(), temp);
                        isRegular_.insert(isRegular_.begin(), true);
                    }
                    ++periods;
                }
            }

            if (calendar_.adjust(dates_.front(),convention)!=
                calendar_.adjust(effectiveDate,convention)) {
                dates_.insert(dates_.begin(), effectiveDate);
                isRegular_.insert(isRegular_.begin(), false);
            }
            break;

          case DateGeneration::Twentieth:
          case DateGeneration::TwentiethIMM:
          case DateGeneration::ThirdWednesday:
          case DateGeneration::OldCDS:
          case DateGeneration::CDS:
            QL_REQUIRE(!*endOfMonth_,
                       "endOfMonth convention incompatible with " << *rule_ <<
                       " date generation rule");
          // fall through
          case DateGeneration::Forward:

            if (*rule_ == DateGeneration::CDS) {
                dates_.push_back(previousTwentieth(effectiveDate,
                                                   DateGeneration::CDS));
            } else {
                dates_.push_back(effectiveDate);
            }

            seed = dates_.back();

            if (firstDate_!=Date()) {
                dates_.push_back(firstDate_);
                Date temp = nullCalendar.advance(seed, periods*(*tenor_),
                                                 convention, *endOfMonth_);
                if (temp!=firstDate_)
                    isRegular_.push_back(false);
                else
                    isRegular_.push_back(true);
                seed = firstDate_;
            } else if (*rule_ == DateGeneration::Twentieth ||
                       *rule_ == DateGeneration::TwentiethIMM ||
                       *rule_ == DateGeneration::OldCDS ||
                       *rule_ == DateGeneration::CDS) {
                Date next20th = nextTwentieth(effectiveDate, *rule_);
                if (*rule_ == DateGeneration::OldCDS) {
                    // distance rule inforced in natural days
                    static const BigInteger stubDays = 30;
                    if (next20th - effectiveDate < stubDays) {
                        // +1 will skip this one and get the next
                        next20th = nextTwentieth(next20th + 1, *rule_);
                    }
                }
                if (next20th != effectiveDate) {
                    dates_.push_back(next20th);
                    isRegular_.push_back(false);
                    seed = next20th;
                }
            }

            exitDate = terminationDate;
            if (nextToLastDate_ != Date())
                exitDate = nextToLastDate_;

            for (;;) {
                Date temp = nullCalendar.advance(seed, periods*(*tenor_),
                                                 convention, *endOfMonth_);
                if (temp > exitDate) {
                    if (nextToLastDate_ != Date() &&
                        (calendar_.adjust(dates_.back(),convention)!=
                         calendar_.adjust(nextToLastDate_,convention))) {
                        dates_.push_back(nextToLastDate_);
                        isRegular_.push_back(false);
                    }
                    break;
                } else {
                    // skip dates that would result in duplicates
                    // after adjustment
                    if (calendar_.adjust(dates_.back(),convention)!=
                        calendar_.adjust(temp,convention)) {
                        dates_.push_back(temp);
                        isRegular_.push_back(true);
                    }
                    ++periods;
                }
            }

            if (calendar_.adjust(dates_.back(),terminationDateConvention)!=
                calendar_.adjust(terminationDate,terminationDateConvention)) {
                if (*rule_ == DateGeneration::Twentieth ||
                    *rule_ == DateGeneration::TwentiethIMM ||
                    *rule_ == DateGeneration::OldCDS ||
                    *rule_ == DateGeneration::CDS) {
                    dates_.push_back(nextTwentieth(terminationDate, *rule_));
                    isRegular_.push_back(true);
                } else {
                    dates_.push_back(terminationDate);
                    isRegular_.push_back(false);
                }
            }

            break;

          default:
            QL_FAIL("unknown rule (" << Integer(*rule_) << ")");
        }

        // adjustments
        if (*rule_==DateGeneration::ThirdWednesday)
            for (Size i=1; i<dates_.size()-1; ++i)
                dates_[i] = Date::nthWeekday(3, Wednesday,
                                             dates_[i].month(),
                                             dates_[i].year());

        if (*endOfMonth_ && calendar_.isEndOfMonth(seed)) {
            // adjust to end of month
            if (convention == Unadjusted) {
                for (Size i=1; i<dates_.size()-1; ++i)
                    dates_[i] = Date::endOfMonth(dates_[i]);
            } else {
                for (Size i=1; i<dates_.size()-1; ++i)
                    dates_[i] = calendar_.endOfMonth(dates_[i]);
            }
            if (terminationDateConvention != Unadjusted) {
                dates_.front() = calendar_.endOfMonth(dates_.front());
                dates_.back() = calendar_.endOfMonth(dates_.back());
            } else {
                // the termination date is the first if going backwards,
                // the last otherwise.
                if (*rule_ == DateGeneration::Backward)
                    dates_.back() = Date::endOfMonth(dates_.back());
                else
                    dates_.front() = Date::endOfMonth(dates_.front());
            }
        } else {
            // first date not adjusted for CDS schedules
            if (*rule_ != DateGeneration::OldCDS)
                dates_[0] = calendar_.adjust(dates_[0], convention);
            for (Size i=1; i<dates_.size()-1; ++i)
                dates_[i] = calendar_.adjust(dates_[i], convention);

            // termination date is NOT adjusted as per ISDA
            // specifications, unless otherwise specified in the
            // confirmation of the deal or unless we're creating a CDS
            // schedule
            if (terminationDateConvention != Unadjusted
                || *rule_ == DateGeneration::Twentieth
                || *rule_ == DateGeneration::TwentiethIMM
                || *rule_ == DateGeneration::OldCDS
                || *rule_ == DateGeneration::CDS) {
                dates_.back() = calendar_.adjust(dates_.back(),
                                                terminationDateConvention);
            }
        }

        // Final safety checks to remove extra next-to-last date, if
        // necessary.  It can happen to be equal or later than the end
        // date due to EOM adjustments (see the Schedule test suite
        // for an example).
        if (dates_.size() >= 2 && dates_[dates_.size()-2] >= dates_.back()) {
            isRegular_[dates_.size()-2] =
                (dates_[dates_.size()-2] == dates_.back());
            dates_[dates_.size()-2] = dates_.back();
            dates_.pop_back();
            isRegular_.pop_back();
        }
        if (dates_.size() >= 2 && dates_[1] <= dates_.front()) {
            isRegular_[1] =
                (dates_[1] == dates_.front());
            dates_[1] = dates_.front();
            dates_.erase(dates_.begin());
            isRegular_.erase(isRegular_.begin());
        }

        QL_ENSURE(dates_.size()>1,
            "degenerate single date (" << dates_[0] << ") schedule" <<
            "\n seed date: " << seed <<
            "\n exit date: " << exitDate <<
            "\n effective date: " << effectiveDate <<
            "\n first date: " << first <<
            "\n next to last date: " << nextToLast <<
            "\n termination date: " << terminationDate <<
            "\n generation rule: " << *rule_ <<
            "\n end of month: " << *endOfMonth_);

    }
Example #23
0
	boost::shared_ptr<CapFloorTermVolatilityStructure> ProcessInfo::ProcessParser_Impl::
			make_capfloor_vol_ts(std::map<std::string, std::string>& variable_map,
								std::map<std::string, std::vector<std::string>>& variable_array_map,
								std::map<std::string, Matrix>& variable_matrix_map)
	{
		boost::shared_ptr<CapFloorTermVolatilityStructure> capfloor_vol_ts;

		Date refDate = Settings::instance().evaluationDate();

		const Calendar& calendar = NullCalendar();
		BusinessDayConvention bdc = BusinessDayConvention::ModifiedFollowing;
		DayCounter daycounter = Actual365Fixed();

		std::string type_key = "CAPFLOOR_TYPE";

		if (variable_map.find(type_key) == variable_map.end())
			QL_FAIL(type_key << " does not exist.");

		std::string vol_type = variable_map[type_key];

		if (vol_type == "CONSTANT")
		{
			std::string cap_flat_vol_key = "CAP_VOL_CONSTANT";

			if (variable_array_map.find(cap_flat_vol_key) == variable_array_map.end())
				QL_FAIL(cap_flat_vol_key << " does not exist.");

			Real flatVol = 0.0;

			capfloor_vol_ts = boost::shared_ptr<CapFloorTermVolatilityStructure>(
				new ConstantCapFloorTermVolatility(refDate, calendar, bdc, flatVol, daycounter));

		}
		else if (vol_type == "CURVE")
		{
			std::string optionTenor_key = "CAP_VOL_CURVE_TENOR";
			std::string value_key = "CAP_VOL_SURFACE_VALUE";

			if (variable_array_map.find(optionTenor_key) == variable_array_map.end())
				QL_FAIL(optionTenor_key << " does not exist.");
			if (variable_array_map.find(value_key) == variable_array_map.end())
				QL_FAIL(value_key << " does not exist.");

			std::vector<std::string> optionTenors = variable_array_map[optionTenor_key];
			std::vector<std::string> values = variable_array_map[value_key];

			std::vector<Period> optionPeriod_data;
			std::vector<Real> data;

			// converting
			for (Size i = 0; i < optionTenors.size(); i++)
				optionPeriod_data.push_back(PeriodParser::parse(optionTenors[i]));

			for (Size i = 0; i < values.size(); i++)
				data.push_back(std::stod(values[i]));

			QL_REQUIRE(optionTenors.size() == data.size(), "tenor size must be same to value size");

			//std::string interpolatedID = "LINEAR";

			//if (variable_map.find(interpolation_key) != variable_map.end())
			//	interpolatedID = variable_map[interpolation_key];
			//QL_DEBUG(tenor_key << " does not exist. Linear interpolation is used");

			capfloor_vol_ts = boost::shared_ptr<CapFloorTermVolatilityStructure>(
				new CapFloorTermVolCurve(refDate, calendar, bdc, optionPeriod_data, data, daycounter));

		}
		else if (vol_type == "SURFACE")
		{
			std::string optionTenor_key = "CAP_VOL_SURFACE_OPTIONTENOR";
			std::string strikeTenor_key = "CAP_VOL_SURFACE_STRIKE";
			std::string value_key = "CAP_VOL_SURFACE_VALUE";

			// default bilinear
			//std::string interpolation_key = "CAP_VOL_CURVE_INTERPOLATION";

			if (variable_array_map.find(optionTenor_key) == variable_array_map.end())
				QL_FAIL(optionTenor_key << " does not exist.");
			if (variable_array_map.find(strikeTenor_key) == variable_array_map.end())
				QL_FAIL(strikeTenor_key << " does not exist.");
			if (variable_matrix_map.find(value_key) == variable_matrix_map.end())
				QL_FAIL(value_key << " does not exist.");

			std::vector<std::string> optionTenors = variable_array_map[optionTenor_key];
			std::vector<std::string> strikes = variable_array_map[strikeTenor_key];

			Matrix value_matrix = variable_matrix_map[value_key];

			std::vector<Period> optionPeriod_data;
			std::vector<Real> strike_data;

			for (Size i = 0; i < optionTenors.size(); i++)
				optionPeriod_data.push_back(PeriodParser::parse(optionTenors[i]));

			for (Size i = 0; i < optionTenors.size(); i++)
				strike_data.push_back(std::stod(strikes[i]));

			// converting

			QL_REQUIRE(optionTenors.size() * strikes.size() == value_matrix.rows() * value_matrix.columns(), "tenor * strike must be same to value matrix size");

			//std::string interpolatedID = "LINEAR";

			//if (variable_map.find(interpolation_key) != variable_map.end())
			//	interpolatedID = variable_map[interpolation_key];
			//QL_DEBUG(tenor_key << " does not exist. Linear interpolation is used");
			capfloor_vol_ts = boost::shared_ptr<CapFloorTermVolatilityStructure>(
				new CapFloorTermVolSurface(refDate, calendar, bdc, optionPeriod_data, strike_data, value_matrix, daycounter));

		}
		else
		{

		}

		return capfloor_vol_ts;

	}
Example #24
0
	boost::shared_ptr<SwaptionVolatilityStructure> ProcessInfo::ProcessParser_Impl::
			make_swaption_vol_ts(std::map<std::string, std::string>& variable_map,
								std::map<std::string, std::vector<std::string>>& variable_array_map,
								std::map<std::string, Matrix>& variable_matrix_map)
	{
		boost::shared_ptr<SwaptionVolatilityStructure> swaption_vol_ts;

		Date refDate = Settings::instance().evaluationDate();

		const Calendar& calendar = NullCalendar();
		BusinessDayConvention bdc = BusinessDayConvention::ModifiedFollowing;
		DayCounter daycounter = Actual365Fixed();

		std::string type_key = "SWAPTION_TYPE";

		if (variable_map.find(type_key) == variable_map.end())
			QL_FAIL(type_key << " does not exist.");

		std::string vol_type = variable_map[type_key];

		if (vol_type == "CONSTANT")
		{
			std::string swaption_flat_vol_key = "SWAP_VOL_CONSTANT";

			if (variable_array_map.find(swaption_flat_vol_key) == variable_array_map.end())
				QL_FAIL(swaption_flat_vol_key << " does not exist.");

			Real flatVol = 0.0;

			swaption_vol_ts = boost::shared_ptr<SwaptionVolatilityStructure>(
				new ConstantSwaptionVolatility(refDate, calendar, bdc, flatVol, daycounter));

		}
		else if (vol_type == "SURFACE")
		{
			std::string optionTenor_key = "SWAPTION_VOL_SURFACE_OPTIONTENOR";
			std::string swapTenor_key = "SWAPTION_VOL_SURFACE_SWAPTENOR";
			std::string value_key = "SWAPTION_VOL_SURFACE_VALUE";

			if (variable_array_map.find(optionTenor_key) == variable_array_map.end())
				QL_FAIL(optionTenor_key << " does not exist.");
			if (variable_array_map.find(swapTenor_key) == variable_array_map.end())
				QL_FAIL(swapTenor_key << " does not exist.");
			if (variable_matrix_map.find(value_key) == variable_matrix_map.end())
				QL_FAIL(value_key << " does not exist.");

			std::vector<std::string> optionTenors = variable_array_map[optionTenor_key];
			std::vector<std::string> swapTenors = variable_array_map[swapTenor_key];

			Matrix value_matrix = variable_matrix_map[value_key];

			std::vector<Period> optionPeriod_data;
			std::vector<Period> swapPeriod_data;

			for (Size i = 0; i < optionTenors.size(); i++)
				optionPeriod_data.push_back(PeriodParser::parse(optionTenors[i]));

			for (Size i = 0; i < swapTenors.size(); i++)
				swapPeriod_data.push_back(PeriodParser::parse(swapTenors[i]));

			// converting
			QL_REQUIRE(optionTenors.size() * swapTenors.size() == value_matrix.rows() * value_matrix.columns(), "tenor * strike must be same to value matrix size");

			//std::string interpolatedID = "LINEAR";

			//if (variable_map.find(interpolation_key) != variable_map.end())
			//	interpolatedID = variable_map[interpolation_key];
			//QL_DEBUG(tenor_key << " does not exist. Linear interpolation is used");
			swaption_vol_ts = boost::shared_ptr<SwaptionVolatilityStructure>(
				new SwaptionVolatilityMatrix(refDate, calendar, bdc, 
											optionPeriod_data, 
											swapPeriod_data, 
											value_matrix, 
											daycounter));

		
		}
		else if (vol_type == "CUBE")
		{
			QL_FAIL("not implemeted");
		}
		else
		{

		}

		return swaption_vol_ts;
	}