Posted by
Peter Caspers-4 on
URL: http://quantlib.414.s1.nabble.com/pricing-cash-settled-swaptions-tp14943p14946.html
Hi Toby,
my understanding is, that the BlackSwaptionEngine implements the
standard market formula for cash settled swaptions as e.g. derived in
Brigo/Mercurio 6.7.2, which is the physical delivery formula with the
annuity A(0) replaced by the cash annuity G(S(0)). The latter is by
definition the annuity (at time t=0) computed on a flat yield curve
with rate
InterestRate(atmForward, dayCount, Compounded, Annual)
which can be computed using
Real CashFlows::bps(const Leg& leg,
const InterestRate& yield,
bool includeSettlementDateFlows,
Date settlementDate,
Date npvDate)
(note that in 2) you refer to a different signature of the bps method
taking a curve instead of a single yield). In the call of bps the
settlementDate is set to discountCurve_->referenceDate(), and since
the npvDate is not given it is defaulted to the same date. This means
that the annuity and therefore in the end the npv of the swaption is
computed w.r.t. the reference date of the discountCurve_ of the
pricing engine.
What I am not toally sure about at the moment is the exact market
definition of G(S), we have at least
- Brigo/Mercurio 6.7.2 = QuantLib::BlackSwaptionEngine
- the OpenGamma paper you mention, 2.2
- Andersen / Piterbarg 5.10.1
all of which being slightly different for certain date scenarios. Can
someone clarify ?
Also I believe the implied volatility quotes you can get on VCAP for
EUR are for cash settled swaptions. Can someone confirm ? If true, how
do you price physical delivered swaptions, with the same volatility ?
Or do you imply a "physical" smile from the "cash" smile (say by
"inverting" a replication model for the cash settled swaptions) ?
best regards
Peter
On 6 February 2014 14:13, Nils Tobias Kramer <
[hidden email]> wrote:
> 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>
------------------------------------------------------------------------------
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