|
From: Lukasz S. <luk...@su...> - 2023-05-22 13:38:15
|
Hi,
Could anyone here comment on the non-inclusion of
*CashFlows.npv(bond.cashflows(),...
in the derivative of the npv function, as I described
(in lenght, I admit) in my email some time ago?
QuantLib does not seem to include this factor,
but for Newton method to work for my example (independently),
I needed to define the derivative with the additional
CashFlows.npv factor included.
Am I missing some important point or reading QuantLib
code incorrectly?
Best regards,
Łukasz
On 8.05.2023 10:48, Lukasz Skowronek wrote:
>
> *Warning: This message originated from outside the organization. Use
> caution when following links or opening attachments.*
>
> Hi,
>
> My name is Lukasz and I'm currently working on a small summary screen
> for various bonds
>
> that uses QuantLib under the hood.
>
> I got an error report from our testers for the following inputs:
>
> request.CouponPaymentsPerYear=1;
> request.Coupon=0.0;
> request.RedemptionPrice=100.0;
> request.CleanPrice=1376.0;
> request.FaceValue=1000.0;
>
> ...
>
> request.ExpirationDate=newDateTime(2024, 6, 27);
> request.InvestmentDate=newDateTime(2023, 2, 9);
>
> In short, this input corresponds to a zero coupon bond priced
> extremely high (at 1376%).
>
> The error I'm getting says the solver cannot bracket the root of the
> target function.
>
> After shifting the dot in the clean price by one decimal place, I get
> the code to work
>
> as expected. Still, even if the testers did not intend to challenge my
> code with
>
> bonds priced at a 85% markup (that is, -85% yield), I would expect the
> solver to
>
> find the root for the original input.
>
> Digging into QuantLib's source code, I traced a few pieces related to
> how yield
>
> calculation is really done:
>
> In *bondfunctions.cpp (line 360):*
>
> Rate BondFunctions::yield(const Bond& bond, ...
>
> in *bondfunctions.hpp (line 160):*
>
> static Rate yield(const Solver& solver, ...
>
> in *cashflows.hpp (line 276):*
>
> static Rate yield(const Solver& solver, ...
>
> IrrFinder objFunction(leg, npv, dayCounter, compounding,
> frequency, includeSettlementDateFlows,
> settlementDate, npvDate);
> return solver.solve(objFunction, accuracy, guess, guess/10.0);
>
> and finally, in *cashflows.cpp (line 728):*
>
> CashFlows::IrrFinder::IrrFinder(const Leg& leg, ...
>
> Real CashFlows::IrrFinder::operator()(Rate y) const {
> InterestRate yield(y, dayCounter_, compounding_, frequency_);
> Real *NPV = CashFlows::npv(leg_, yield,**
> **includeSettlementDateFlows_,**
> ** settlementDate_, npvDate_);*
> return *npv_ - NPV*;
> }
>
> Real CashFlows::IrrFinder::derivative(Rate y) const {
> InterestRate yield(y, dayCounter_, compounding_, frequency_);
> return *modifiedDuration(leg_, yield,**
> **includeSettlementDateFlows_,**
> ** settlementDate_, npvDate_)*;
> }
>
> Is this target function + derivative correct?
>
> What worked on my side, when simulating the Newton method for finding
> the root
>
> separately, was:
>
> doublef(doublerate) {
> InterestRateir=newInterestRate(rate, dayCounter,
> Compounding.Compounded, frequency);
> return(cleanPrice+bond.accruedAmount(investmentDate))
> *bond.notional(investmentDate) /100.0-
> CashFlows.npv(bond.cashflows(), ir, false, investmentDate,
> investmentDate);
> }
> // <-- target function
> doubled(doublerate) {
> InterestRateir=newInterestRate(rate, dayCounter,
> Compounding.Compounded, frequency);
> returnCashFlows.modifiedDuration(bond.cashflows(), ir, false,
> investmentDate, investmentDate) *CashFlows.npv(bond.cashflows(), ir,
> false, investmentDate, investmentDate);
> }
> // <-- derivative
> (this is C# code that has QLNet as dependency)
>
> Hence, there is an additional multiplication by CashFlows.npv(...,
> which plays well with the
>
> definition of modified duration as -dPdy / P
>
> There does not seem to be a similar factor in QuantLib.
>
> Am I mistaken? Is the multiplication by NPV in the derivative handled
> some other way?
>
> Best regards,
>
> Lukasz Skowronek
>
>
>
>
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
|