oar
February 14, 2017, 12:14pm
1
Hello,
The root finding fails in the following yield calculation:
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.StandardId;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.Payment;
import com.opengamma.strata.basics.date.*;
import com.opengamma.strata.basics.schedule.*;
import com.opengamma.strata.pricer.bond.DiscountingFixedCouponBondProductPricer;
import com.opengamma.strata.product.SecurityId;
import com.opengamma.strata.product.bond.FixedCouponBond;
import com.opengamma.strata.product.bond.FixedCouponBondYieldConvention;
import com.opengamma.strata.product.bond.ResolvedFixedCouponBond;
import java.time.LocalDate;
import java.util.HashMap;
import static com.opengamma.strata.product.SecurityId.of;
import static com.opengamma.strata.product.bond.FixedCouponBondYieldConvention.DE_BONDS;
public class Example {
public static final void bondYield(){
// set up the bond
SecurityId wkn = SecurityId.of(StandardId.of("UTF-8","111111"));
StandardId legalEntityID = StandardId.of("UTF-8","Borrowers United");
// build the periodic schedule of bond payments
LocalDate startDate = LocalDate.of(2015,10,13);
LocalDate endDate = LocalDate.of(2020,10,13);
HolidayCalendar holCal = HolidayCalendars.SAT_SUN;
BusinessDayConvention bdc = BusinessDayConventions.FOLLOWING;
BusinessDayAdjustment bdAdj = BusinessDayAdjustment.of(bdc,holCal.getId());
Frequency frequency = Frequency.P12M;
StubConvention stubConvention = StubConvention.NONE;
RollConvention rollConvention = RollConventions.DAY_13;
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(startDate)
.endDate(endDate)
.businessDayAdjustment(bdAdj)
.frequency(frequency)
.stubConvention(stubConvention)
.rollConvention(rollConvention)
.build();
// days adjustment for settlement date offset
DaysAdjustment settlementDateOffset = DaysAdjustment.ofBusinessDays(2,holCal.getId());
// get a bond builder
FixedCouponBond.Builder bondBuilder = FixedCouponBond.builder();
// set the bond attributes
bondBuilder.securityId(wkn)
.legalEntityId(legalEntityID)
.yieldConvention(FixedCouponBondYieldConvention.DE_BONDS)
.accrualSchedule(accrualSchedule)
.fixedRate(0.01)
.notional(100.0)
.settlementDateOffset(settlementDateOffset)
.dayCount(DayCounts.ACT_ACT_ICMA)
.currency(Currency.EUR)
;
FixedCouponBond theBond = bondBuilder.build();
// Turn the bond into a resolved bond via the required ReferenceData.
ReferenceData refDataStandard = ReferenceData.standard();
ResolvedFixedCouponBond resolvedBond = theBond.resolve(refDataStandard);
// get the bond pricer
DiscountingFixedCouponBondProductPricer pricer = DiscountingFixedCouponBondProductPricer.DEFAULT;
// yield from dirty price of 98 at settlement date 2016-01-01
LocalDate settlementDate = LocalDate.of(2016,1,1);
Double dirtyPrice = 98.0;
Double yield = pricer.yieldFromDirtyPrice(resolvedBond,settlementDate,dirtyPrice);
String msg = "Yield at dirty price of "+dirtyPrice+" settled on "+settlementDate+" is: "+yield;
System.out.println(msg);
}
}
ToyinA
February 14, 2017, 12:24pm
2
Hi,
Have you tried with :
Double dirtyPrice = 0.98;
Best.
stephen
February 14, 2017, 12:34pm
4
Yes, as per the docs , we use decimal prices:
* <h4>Price</h4>
* Strata uses <i>decimal prices</i> for bonds in the trade model, pricers and market data.
* For example, a price of 99.32% is represented in Strata by 0.9932.
oar
February 14, 2017, 12:35pm
5
Thanks for the beautiful library.
It’s a pleasure to use.
oar
February 15, 2017, 8:47am
6
I ran into another problem with the root finder. it is supposed to be a zero coupon bond.
Is it OK if I post such code here?
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.StandardId;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.Payment;
import com.opengamma.strata.basics.date.*;
import com.opengamma.strata.basics.schedule.*;
import com.opengamma.strata.pricer.bond.DiscountingFixedCouponBondProductPricer;
import com.opengamma.strata.product.SecurityId;
import com.opengamma.strata.product.bond.FixedCouponBond;
import com.opengamma.strata.product.bond.FixedCouponBondYieldConvention;
import com.opengamma.strata.product.bond.ResolvedFixedCouponBond;
import java.time.LocalDate;
import java.util.HashMap;
import static com.opengamma.strata.product.SecurityId.of;
import static com.opengamma.strata.product.bond.FixedCouponBondYieldConvention.DE_BONDS;
/**
* Created by vagrant on 15.02.17.
*/
public class Examples {
public static final void yieldExample(){
SecurityId wkn = SecurityId.of(StandardId.of("UTF-8","111111"));
StandardId legalEntityID = StandardId.of("UTF-8","Borrowers United");
LocalDate startDate = LocalDate.of(2016,6,21);
LocalDate endDate = LocalDate.of(2017,4,7);
HolidayCalendar holCal = HolidayCalendars.SAT_SUN;
BusinessDayConvention bdc = BusinessDayConventions.FOLLOWING;
BusinessDayAdjustment bdAdj = BusinessDayAdjustment.of(bdc,holCal.getId());
Frequency frequency = Frequency.TERM;
StubConvention stubConvention = StubConvention.NONE;
RollConvention rollConvention = RollConventions.NONE;
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(startDate)
.endDate(endDate)
.businessDayAdjustment(bdAdj)
.frequency(frequency)
.stubConvention(stubConvention)
.rollConvention(rollConvention)
.build();
DaysAdjustment settlementDateOffset = DaysAdjustment.ofBusinessDays(2,holCal.getId());
FixedCouponBond.Builder bondBuilder = FixedCouponBond.builder();
bondBuilder.securityId(wkn)
.legalEntityId(legalEntityID)
.yieldConvention(FixedCouponBondYieldConvention.DE_BONDS)
.accrualSchedule(accrualSchedule)
.fixedRate(0.01)
.notional(1.0)
.settlementDateOffset(settlementDateOffset)
.dayCount(DayCounts.ACT_ACT_ICMA)
.currency(Currency.EUR)
;
FixedCouponBond theBond = bondBuilder.build();
ReferenceData refDataStandard = ReferenceData.standard();
ResolvedFixedCouponBond resolvedBond = theBond.resolve(refDataStandard);
DiscountingFixedCouponBondProductPricer pricer = DiscountingFixedCouponBondProductPricer.DEFAULT;
LocalDate settlementDate = LocalDate.of(2016,10,21);
Double dirtyPrice = 0.98;
Double yield = pricer.yieldFromDirtyPrice(resolvedBond,settlementDate,dirtyPrice);
String msg = "Yield at dirty price of "+dirtyPrice+" settled on "+settlementDate+" is: "+yield;
System.out.println(msg);
}
}
oar
February 15, 2017, 8:52am
7
From my experience DayCounts.ACT_ACT_ICMA is incompatible with Frequency.TERM but the problem persists with other day counts.
oar
February 15, 2017, 12:22pm
8
After reading the Opengamma document on bond pricing it seems to me that no root bracketing is needed, if the yield is computed for a settlement date in the last period.
In case of yield conventions US_STRRET or DE_BONDS the same is true if the settlement date is in the second to last period.
In this case simple algebraic equations have to be solved yielding exact solutions.
stephen
February 15, 2017, 1:08pm
9
As of now, Strata does not properly support zero coupon bonds, as they have subtly different conventions and rules. As might be imagined, you may be able to tweak FixedCouponBond
to come close, see also this thread .
We do not currently have Zero Coupon bonds on our roadmap, but feel free to contact us directly if it is of commercial interest .