pricing cash settled swaptions

Posted by Nils Tobias Kramer on
URL: http://quantlib.414.s1.nabble.com/pricing-cash-settled-swaptions-tp14943.html

Hi there,

I'm using QuantLib to price cash settled swaptions in C# using the swig interface and I'm using Quantlib 1.2.1.

When pricing a cash settled swaption I expect the cashflows of the swap to be discounted using the constant swap rate looking from the swaption expiration date (=swap start date). So I expected the discount factor used to calculate the annuity factor in front of the black scholes formula used to price physical swaptions to be Sum_i[(1+YF*SR)^(i)] (where YF is the year fraction between the swap's payments, SR is the swap par rate calculated at my valuation date, and i is an integer for the swap's payment dates).

However I think QuantLib uses a different time span, namely the time between swap payments and the discount curve reference date and not swaption expiry date.

In order to fix this I calculate the swaptions NPV and then multiply this by (1+SR)^(YF), where YF is the year fraction between evaluation date and the swap

start date using 30/360 day count convention. This way the pricing is in line with http://developers.opengamma.com/quantitative-research/Swaption-

Pricing-OpenGamma.pdf p.3, 5.1, where G(S) is defined at the top of p. 2.

The problem I have is that I need to calculate the swap par rate and therefore I need to create a swap and price this swap which I actually don't need.

Here are the relevant lines:
1) blackswaptionengine.cpp:
          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;
          }

-> especially CashFlows::bps(fixedLeg, InterestRate(atmForward, dayCount, Compounded, Annual), false, discountCurve_->referenceDate());

2) cashflows.cpp:
   Real CashFlows::bps(const Leg& leg,
                        const YieldTermStructure& discountCurve,
                        bool includeSettlementDateFlows,
                        Date settlementDate,
                        Date npvDate) {
        if (leg.empty())
            return 0.0;

        if (settlementDate == Date())
            settlementDate = Settings::instance().evaluationDate();

        if (npvDate == Date())
            npvDate = settlementDate;

        BPSCalculator calc(discountCurve);
        for (Size i=0; i<leg.size(); ++i) {
            if (!leg[i]->hasOccurred(settlementDate,
                                     includeSettlementDateFlows))
                leg[i]->accept(calc);
        }
        return basisPoint_*calc.bps()/discountCurve.discount(npvDate);
    }

-> especially return basisPoint_*calc.bps()/discountCurve.discount(npvDate);

This surprises me as discountCurve.discount(npvDate) is equal to discountCurve.discount(discountCurve_->referenceDate()) which should be 1, right?

Anyways I'm a bit confused and every suggestion is appreciated.

Thanks
Toby

------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users