All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.finmath.smartcontract.valuation.marketdata.curvecalibration.CalibrationParserDataItems Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
package net.finmath.smartcontract.valuation.marketdata.curvecalibration;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.finmath.smartcontract.model.ExceptionId;
import net.finmath.smartcontract.model.MarketDataList;
import net.finmath.smartcontract.model.SDCException;
import net.finmath.smartcontract.product.xml.SDCXMLParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Parses calibration data points and converts it to calibration specs
 */
@SuppressWarnings("java:S125")
public class CalibrationParserDataItems implements CalibrationParser {

	private static final Logger logger = LoggerFactory.getLogger(CalibrationParserDataItems.class);

	@Override
	public Stream parse(final Stream datapoints) {
		return datapoints.map(this::parseDatapointIfPresent).filter(Optional::isPresent).map(Optional::get);
	}

	private Optional parseDatapointIfPresent(final CalibrationDataItem datapoint) {

		switch (datapoint.getCurveName()) {
			case "ESTR", "EONIA" -> {
				if (datapoint.getProductName().equals("Swap-Rate"))
					return Optional.of(new CalibrationSpecProviderOis(datapoint.getMaturity(), "annual", datapoint.getQuote()));
				else
					return Optional.empty();
			}
			case "Euribor6M" -> {
				if (datapoint.getProductName().equalsIgnoreCase("Swap-Rate"))
					return Optional.of(new CalibrationSpecProviderSwap("6M", "semiannual", datapoint.getMaturity(), datapoint.getQuote()));
				if (datapoint.getProductName().equalsIgnoreCase("Forward-Rate-Agreement")) {
					return Optional.of(new CalibrationSpecProviderFRA("6M", datapoint.getMaturity(), datapoint.getQuote()));
				}
				if (datapoint.getProductName().equalsIgnoreCase("Deposit") || datapoint.getProductName().equalsIgnoreCase("Deposit-Rate"))
					return Optional.of(new CalibrationSpecProviderDeposit("6M", datapoint.getMaturity(), datapoint.getQuote()));
				else
					return Optional.empty();
			}
			case "Euribor1M" -> {
				return Optional.of(new CalibrationSpecProviderSwap("1M", "monthly", datapoint.getMaturity(), datapoint.getQuote()));
			}
			case "Euribor3M" -> {
				return Optional.of(new CalibrationSpecProviderSwap("3M", "quarterly", datapoint.getMaturity(), datapoint.getQuote()));
			}
			default -> {
				logger.warn("Ignored data point.");
				return Optional.empty();
			}
		}
	}


	/**
	 * Static method which parses a json file from its file name and converts it to a list of market data scenarios
	 *
	 * @param fileName Name of the input file.
	 * @return List of IRMarketDataScenario
	 * @throws IOException                  File not found
	 * @throws UnsupportedEncodingException UnsupportedEncodingException
	 */
	public static List getScenariosFromJsonFile(final String fileName) throws IOException {

		final String content;
		try (InputStream inputStream = CalibrationParserDataItems.class.getResourceAsStream(fileName)) {
			content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
		} catch (IOException e) {
			logger.error("Please provide the market data file: {}.", fileName, e);
			throw e;
		}

		return getScenariosFromJsonString(content);

	}

	public static  CalibrationDataset getCalibrationDataSetFromXML(final String xmlString, List dataSpecs) {
		MarketDataList marketDataList =  SDCXMLParser.unmarshalXml(xmlString, MarketDataList.class);

		Set calibrationDataItems = new LinkedHashSet<>();

		dataSpecs.forEach(spec-> {
			/* Can be more than one, if we have data points of type fixing*/
			Set calibrationDataItemSet = marketDataList.getPoints().stream().filter(marketDataPoint -> marketDataPoint.getId().equals(spec.getKey())).map(point-> new CalibrationDataItem(spec, point.getValue(), point.getTimeStamp())).collect(Collectors.toSet());
			calibrationDataItems.addAll(calibrationDataItemSet);
		});

		if(calibrationDataItems.isEmpty())
			throw new SDCException(ExceptionId.SDC_CALIBRATION_DATA_EMPTY, "No calibration items detected.");

		return new CalibrationDataset(calibrationDataItems, marketDataList.getRequestTimeStamp());
	}

	/**
	 * Static method which parses a csv file - using jackson csv mapper - and converts it to a list of market data scenarios
	 *
	 * @param fileName Name of the input file.
	 * @return List of IRMarketDataScenario
	 * @throws IOException Thrown if market data file is not found.
	 */
	public static List getScenariosFromCSVFile(final String fileName) throws IOException {
		throw new IOException("to be implemented");
	}


	/**
	 * Static method which parses a json file from its string content and converts it to a list of market data scenarios
	 *
	 * @param content Content of the json.
	 * @return List of IRMarketDataScenario
	 * @throws IllegalArgumentException If the JSON format is incorrect.
	 */
	public static final List getScenariosFromJsonString(final String content) {
		final Map>>>> timeSeriesDatamap;
		try {
			final ObjectMapper mapper = new ObjectMapper();
			timeSeriesDatamap = mapper.readValue(content, new LinkedHashMap>>>>().getClass());
		}
		catch(JsonProcessingException e) {
			throw new IllegalArgumentException("Bad format.", e);
		}

		return timeSeriesDatamap.entrySet().stream()
				.map(
						scenarioData -> {
							final String timeStampStr = scenarioData.getKey();
							final LocalDateTime dateTime = parseTimestampString(timeStampStr);
							Set quotes = scenarioData.getValue().get("Quotes").entrySet().stream().map(entry -> getCalibrationDataItemSet(entry.getKey(), entry.getValue(), dateTime)).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
							CalibrationDataset scenario = new CalibrationDataset(quotes, dateTime);
							if (scenarioData.getValue().containsKey("Fixings")) {
								Set fixings = scenarioData.getValue().get("Fixings").entrySet().stream().map(entry -> getFixingDataItemSet(entry.getKey(), entry.getValue(), dateTime)).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
								scenario = scenario.getClonedFixingsAdded(fixings);
							}

							return scenario;
						})
				.sorted((scenario1, scenario2) -> scenario1.getDate().compareTo(scenario2.getDate()))
				.toList();
	}

	private static LocalDateTime parseTimestampString(String timeStampString) {
		DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss");

		LocalDateTime localDateTime;
		try {
			localDateTime = LocalDateTime.parse(timeStampString, dateTimeFormatter);
		} catch (Exception e) {
			// Fall back to 17:00
			final LocalDate date = LocalDate.parse(timeStampString, dateFormatter);
			localDateTime = date.atTime(17, 0);
		}

		return localDateTime;
	}


	private static Set getCalibrationDataItemSet(final String curveKey, final Map> typeCurveMap, final LocalDateTime timestamp) {
		return typeCurveMap.entrySet().stream().flatMap(entry -> entry.getValue().entrySet().stream().map(
				curvePointEntry -> {
					String specKey = curveKey + "_" + entry.getKey() + "_" + curvePointEntry.getKey();
					CalibrationDataItem.Spec spec = new CalibrationDataItem.Spec(specKey, curveKey, entry.getKey(), curvePointEntry.getKey());
					return new CalibrationDataItem(spec, curvePointEntry.getValue(), timestamp);
				})).collect(Collectors.toCollection(LinkedHashSet::new));
	}

	private static Set getFixingDataItemSet(final String curveKey, final Map> typeCurveMap, final LocalDateTime timestamp) {

		return typeCurveMap.entrySet().stream().flatMap(entry -> entry.getValue().entrySet().stream().map(
				curvePointEntry -> {
					LocalDate fixingDate = LocalDate.parse(curvePointEntry.getKey(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
					String specKey = curveKey + "_" + entry.getKey() + "_" + curvePointEntry.getKey();
					CalibrationDataItem.Spec spec = new CalibrationDataItem.Spec(specKey, curveKey, entry.getKey(), "1D");
					return new CalibrationDataItem(spec, curvePointEntry.getValue(), fixingDate.atStartOfDay());
				})).collect(Collectors.toCollection(LinkedHashSet::new));
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy