New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Caplet stripping by bootstrap #1422
Conversation
yukiiwashita
commented
Nov 28, 2016
•
edited
edited
- Two implementations of caplet stripping based on bootstrapping: SurfaceIborCapletFloorletVolatilityBootstrapper and SabrIborCapletFloorletVolatilityBootstrapper.
- Created IborCapletFloorletDefinition.
- Added a new metadata, GenericVolatilitySurfacePeriodParameterMetadata.
- Implemented StepUpperCurveInterpolator.
* The chi-square value. | ||
* <p> | ||
* The chi square is 0 if the volatilities are computed by root-finding. | ||
* The chi square is generally non-zeoro if the volatilities are computed by least square method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling 'non-zero'
* @param chiSquare the chi-square value | ||
* @return the instance | ||
*/ | ||
public static IborCapletFloorletVolatilityCalibrationResult ofLestSquare( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
method name spelling
* Default implementation. | ||
*/ | ||
public static final SabrIborCapletFloorletVolatilityBootstrapper DEFAULT = of( | ||
VolatilityIborCapFloorLegPricer.DEFAULT, SabrIborCapletFloorletPeriodPricer.DEFAULT, 1.0e-10, ReferenceData.standard()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need both leg and period pricer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first pricer is used to convert the market vols to prices, whereas the second pricer is used for calibration to SABR model, that is, the second one must be SABR rather than generic VolatilityIborCapletFloorletPeriodPricer
. In this case, 'validate(IborCapletFloorletVolatilities)' is overridden and the pricer works only when IborCapletFloorletVolatilities
is an instance of SabrIborCapletFloorletVolatilities
. Thus this pricer (or its leg version SabrIborCapFloorLegPricer
) can not be used for the vol-to-price conversion.
TRANSFORMS[0] = new SingleRangeLimitTransform(0, LimitType.GREATER_THAN); // alpha > 0 | ||
TRANSFORMS[1] = new DoubleRangeLimitTransform(0.0, 1.0); // 0 <= beta <= 1 | ||
TRANSFORMS[2] = new DoubleRangeLimitTransform(-RHO_LIMIT, RHO_LIMIT); // -1 <= rho <= 1 | ||
TRANSFORMS[3] = new SingleRangeLimitTransform(0, LimitType.GREATER_THAN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stability for large nu? See SabrModelFitter
/** | ||
* The period of the surface node. | ||
* <p> | ||
* This is the period to maturity that the node on the surface is defined as. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maturity or expiry?
* <p> | ||
* The caplet volatilities are computed by bootstrapping along the expiry time dimension. | ||
* The result is an interpolated surface spanned by expiry and strike. | ||
* The position of the node points on the resultant surface corresponds to market caps. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which part of the cap on the expiry dimension? Last expiry date?
/** | ||
* Definition of caplet volatilities calibration. | ||
*/ | ||
public interface IborCapletFloorletDefinition { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have 'Volatility' in the name?
DoubleArray strikeShifted = DoubleArray.of(nTotal, n -> strikeList.get(n) + shiftCurve.yValue(timeList.get(n))); | ||
DoubleArray volArray = DoubleArray.copyOf(volList); | ||
if (capFloorData.getDataType().equals(NORMAL_VOLATILITY)) { // correct initial surface | ||
metadata = Surfaces.blackVolatilityByExpiryStrike(bsDefinition.getName().getName(), bsDefinition.getDayCount()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If says 'NORMAL_VOLATILITY' but metadata is 'blackVolatility'? Calibrate only Black surfaces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added javadoc on input vol types and output vol types.
* The beta will be treated as one of the calibration parameters if this field is not specified. | ||
*/ | ||
@PropertyDefinition(get = "optional") | ||
private final Curve betaCurve; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about other curves? Beta and rho are usually not calibrated at the same time.
int[] startIndex = new int[nExpiries + 1]; | ||
for (int i = 0; i < nExpiries; ++i) { | ||
LocalDate endDate = baseDate.plus(expiries.get(i)); | ||
DoubleArray volatilityData = capFloorData.getData().row(i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the difference between Normal and Black dealt with?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The vol type difference is handled in volatilitiesFunction
created by volatilitiesFunction
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of javadoc comments.
* The result is an interpolated surface spanned by expiry and strike. | ||
* The position of the node points on the resultant surface corresponds to last expiry date of market caps. | ||
* The nodes should be interpolated by a local interpolation scheme along the time direction. | ||
* See {@link SurfaceIborCapletFloorletBootstrapDefinition} for detail. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name of this class has changed: 'SurfaceIborCapletFloorletVolatilityBootstrapDefinition'
* <p> | ||
* If the shift curve is not present in {@code SurfaceIborCapletFloorletBootstrapVolatilityDefinition}, | ||
* the resultant volatility type is the same as the input volatility type, i.e., | ||
* Black caplet volatilities are returned if Balck cap volatilities are plugged in, and normal caplet volatilities are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling: Balck
* The result is a complete set of curves for the SABR parameters spanned by the expiry time. | ||
* The position of the node points on the resultant curves corresponds to market cap expiries, | ||
* and are interpolated by a local interpolation scheme. | ||
* See {@link SabrIborCapletFloorletBootstrapDefinition} for detail. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name has changed to 'SabrIborCapletFloorletVolatilityBootstrapDefinition'