예제 #1
0
    NonstandardSwap::NonstandardSwap(const VanillaSwap &fromVanilla)
        : Swap(2), type_((VanillaSwap::Type)fromVanilla.type()),
          fixedNominal_(std::vector<Real>(fromVanilla.fixedLeg().size(),
                                          fromVanilla.nominal())),
          floatingNominal_(std::vector<Real>(fromVanilla.floatingLeg().size(),
                                             fromVanilla.nominal())),
          fixedSchedule_(fromVanilla.fixedSchedule()),
          fixedRate_(std::vector<Real>(fromVanilla.fixedLeg().size(),
                                       fromVanilla.fixedRate())),
          fixedDayCount_(fromVanilla.fixedDayCount()),
          floatingSchedule_(fromVanilla.floatingSchedule()),
          iborIndex_(fromVanilla.iborIndex()),
          spread_(std::vector<Real>(fromVanilla.floatingLeg().size(), fromVanilla.spread())),
          gearing_(std::vector<Real>(fromVanilla.floatingLeg().size(), 1.0)),
          singleSpreadAndGearing_(true),
          floatingDayCount_(fromVanilla.floatingDayCount()),
          paymentConvention_(fromVanilla.paymentConvention()),
          intermediateCapitalExchange_(false), finalCapitalExchange_(false) {

        init();
    }
예제 #2
0
    void BlackStyleSwaptionEngine<Spec>::calculate() const {
        static const Spread basisPoint = 1.0e-4;

        Date exerciseDate = arguments_.exercise->date(0);

        // the part of the swap preceding exerciseDate should be truncated
        // to avoid taking into account unwanted cashflows
        VanillaSwap swap = *arguments_.swap;

        Rate strike = swap.fixedRate();

        // using the discounting curve
        // swap.iborIndex() might be using a different forwarding curve
        swap.setPricingEngine(boost::shared_ptr<PricingEngine>(new
            DiscountingSwapEngine(discountCurve_, false)));
        Rate atmForward = swap.fairRate();

        // Volatilities are quoted for zero-spreaded swaps.
        // Therefore, any spread on the floating leg must be removed
        // with a corresponding correction on the fixed leg.
        if (swap.spread()!=0.0) {
            Spread correction = swap.spread() *
                std::fabs(swap.floatingLegBPS()/swap.fixedLegBPS());
            strike -= correction;
            atmForward -= correction;
            results_.additionalResults["spreadCorrection"] = correction;
        } else {
            results_.additionalResults["spreadCorrection"] = 0.0;
        }
        results_.additionalResults["strike"] = strike;
        results_.additionalResults["atmForward"] = atmForward;

        // using the discounting curve
        swap.setPricingEngine(boost::shared_ptr<PricingEngine>(
                           new DiscountingSwapEngine(discountCurve_, false)));
        Real annuity;
        switch(arguments_.settlementType) {
          case Settlement::Physical: {
              annuity = std::fabs(swap.fixedLegBPS())/basisPoint;
              break;
          }
          case Settlement::Cash: {
              const Leg& fixedLeg = swap.fixedLeg();
              boost::shared_ptr<FixedRateCoupon> firstCoupon =
                  boost::dynamic_pointer_cast<FixedRateCoupon>(fixedLeg[0]);
              DayCounter dayCount = firstCoupon->dayCounter();
              Real fixedLegCashBPS =
                  CashFlows::bps(fixedLeg,
                                 InterestRate(atmForward, dayCount, Compounded, Annual),
                                 false, discountCurve_->referenceDate()) ;
              annuity = std::fabs(fixedLegCashBPS/basisPoint);
              break;
          }
          default:
            QL_FAIL("unknown settlement type");
        }
        results_.additionalResults["annuity"] = annuity;

        // the swap length calculation might be improved using the value date
        // of the exercise date
        Time swapLength =  vol_->swapLength(exerciseDate,
                                                   arguments_.floatingPayDates.back());
        results_.additionalResults["swapLength"] = swapLength;

        Real variance = vol_->blackVariance(exerciseDate,
                                                   swapLength,
                                                   strike);

        // once the deprecated methods allowing to override the displacement
        // are gone, we can avoid this and directly read the displacement
        // from the volatility structure
        Real displacement = displacement_ == Null<Real>()
                                ? vol_->shift(exerciseDate, swapLength)
                                : displacement_;

        Real stdDev = std::sqrt(variance);
        results_.additionalResults["stdDev"] = stdDev;
        Option::Type w = (arguments_.type==VanillaSwap::Payer) ?
                                                Option::Call : Option::Put;
        results_.value = Spec().value(w, strike, atmForward, stdDev, annuity,
                                                                displacement);

        Time exerciseTime = vol_->timeFromReference(exerciseDate);
        results_.additionalResults["vega"] = Spec().vega(
            strike, atmForward, stdDev, exerciseTime, annuity, displacement);
    }