}
private static VolatilitySurfaceData<Double, Double> getSurfaceFromPriceQuote(final VolatilitySurfaceSpecification specification,
final VolatilitySurfaceData<Number, Double> optionPrices, final NodalDoublesCurve futurePrices, final ZonedDateTime now, final String surfaceQuoteType,
final Calendar calendar) {
final BondFutureOptionExpiryCalculator expiryCalculator = BondFutureOptionExpiryCalculator.getInstance();
double callAboveStrike = 0;
if (specification.getSurfaceInstrumentProvider() instanceof CallPutSurfaceInstrumentProvider) {
callAboveStrike = ((CallPutSurfaceInstrumentProvider<?, ?>) specification.getSurfaceInstrumentProvider()).useCallAboveStrike();
}
final Map<Pair<Double, Double>, Double> volatilityValues = new HashMap<Pair<Double, Double>, Double>();
final DoubleArrayList txList = new DoubleArrayList();
final DoubleArrayList kList = new DoubleArrayList();
final LocalDate today = now.toLocalDate();
final Double[] futureExpiries = futurePrices.getXData();
final int nFutures = futureExpiries.length;
if (nFutures == 0) {
throw new OpenGammaRuntimeException("No future prices found for surface : " + specification.getName());
}
for (final Number x : optionPrices.getXs()) {
// Loop over option expiries
final int nFutureOption = x.intValue();
final LocalDate futureOptionExpiryDate = expiryCalculator.getExpiryDate(nFutureOption, today, calendar);
final Double optionExpiry = TimeCalculator.getTimeBetween(today, futureOptionExpiryDate);
int nFuture = 0;
while (optionExpiry > futureExpiries[nFuture]) {
nFuture++;
}