
net.objectlab.kit.datecalc.common.CurrencyDateCalculatorBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datecalc-common Show documentation
Show all versions of datecalc-common Show documentation
Common Date Calculator Code
package net.objectlab.kit.datecalc.common;
import net.objectlab.kit.datecalc.common.ccy.CurrencyCalculatorConfig;
/**
* Provides enough information to create an immutable CurrencyDateCalculator.
*
*
CurrencyDateCalculatorBuilder<LocalDate> builder = new CurrencyDateCalculatorBuilder<LocalDate>() //
.currencyPair("EUR", "GBP", SpotLag.T_2) //
.ccy1Calendar(new DefaultHolidayCalendar<LocalDate>()) // empty
.ccy1Week(WorkingWeek.DEFAULT) // Mon-Fri
.ccy2Calendar(gbpCalendar) //
.ccy2Week(WorkingWeek.DEFAULT) // Mon-Fri
.crossCcy("USD") // the usual suspect
.crossCcyCalendar(usdCalendar) //
.crossCcyWeek(WorkingWeek.DEFAULT) // Mon-Fri;
.adjustStartDateWithCurrencyPair(true) // default is true, Move the startDate to a working date for ccy1 and ccy2
.tenorHolidayHandler(new LocalDateForwardHandler()) // Forward (or equivalent for your implementation)
.brokenDateAllowed(false) // use the CrossCcy holidays on Spot and Tenor Date
.currencyCalculatorConfig(new DefaultCurrencyCalculatorConfig()) // Will be used for finding Working Weeks IF NOT PROVIDED and Latin
// American ccy USD handling.
*
*
* @param JDK Date/Calendar, JDK8 LocalDate or Joda LocalDate
* @since 1.4.0
*/
public class CurrencyDateCalculatorBuilder {
private String ccy1;
private String ccy2;
private String crossCcy = CurrencyDateCalculator.USD_CODE;
private HolidayCalendar ccy1Calendar = new DefaultHolidayCalendar();
private HolidayCalendar ccy2Calendar = new DefaultHolidayCalendar();
private HolidayCalendar crossCcyCalendar = new DefaultHolidayCalendar();
private HolidayHandler tenorHolidayHandler;
private WorkingWeek ccy1Week;
private WorkingWeek ccy2Week;
private WorkingWeek crossCcyWeek;
private CurrencyCalculatorConfig currencyCalculatorConfig;
private boolean brokenDateAllowed = false;
private boolean adjustStartDateWithCurrencyPair = true;
private SpotLag spotLag = SpotLag.T_2;
/**
* Default values are:
*
* - crossCcy = USD
* - ccy1Calendar = Empty Calendar
* - ccy2Calendar = Empty Calendar
* - crossCcyCalendar = Empty Calendar
* - brokenDateAllowed = false
* - adjustStartDateWithCurrencyPair = true
* - spotLag = SpotLag.T_2
*
*/
public CurrencyDateCalculatorBuilder() {
}
/**
* Checks the builder and throws an IllegalArgumentException if there are issues e.g.
*
* - ccy1 or ccy2 missing
* - ccy1Week or ccy2Week missing
* - spotLag is missing
* - tenorHolidayHandler is missing
* - If brokenDate is not allowed, we need crossCcy, crossCcyWeek and crossCcyCalendar.
*
*/
public void checkValidity() {
StringBuilder b = new StringBuilder();
if (ccy1 == null || ccy1.length() == 0) {
b.append("ccy1 is required");
}
if (ccy2 == null || ccy2.length() == 0) {
append(b, "ccy2 is required");
}
if (getCcy1Week() == null) {
append(b, "ccy1Week is required");
}
if (getCcy2Week() == null) {
append(b, "ccy2Week is required");
}
if (!brokenDateAllowed) {
if (getCrossCcy() == null) {
append(b, "crossCcy is required");
}
if (getCrossCcyWeek() == null) {
append(b, "crossCcyWeek is required");
}
if (getCrossCcyCalendar() == null) {
append(b, "crossCcyCalendar is required");
}
}
if (spotLag == null) {
append(b, "spotLag is required");
}
if (tenorHolidayHandler == null) {
append(b, "tenorHolidayHandler is required");
}
if (b.length() > 0) {
throw new IllegalArgumentException(b.toString());
}
}
private void append(StringBuilder b, String string) {
if (b.length() > 0) {
b.append(",");
}
b.append(string);
}
public String getCcy1() {
return ccy1;
}
public String getCcy2() {
return ccy2;
}
public String getCrossCcy() {
return crossCcy;
}
public HolidayCalendar getCcy1Calendar() {
return ccy1Calendar;
}
public HolidayCalendar getCcy2Calendar() {
return ccy2Calendar;
}
public HolidayCalendar getCrossCcyCalendar() {
return crossCcyCalendar;
}
public HolidayHandler getTenorHolidayHandler() {
return tenorHolidayHandler;
}
public WorkingWeek getCcy1Week() {
return ccy1Week != null ? ccy1Week : currencyCalculatorConfig != null ? currencyCalculatorConfig.getWorkingWeek(ccy1) : null;
}
public WorkingWeek getCcy2Week() {
return ccy2Week != null ? ccy2Week : currencyCalculatorConfig != null ? currencyCalculatorConfig.getWorkingWeek(ccy2) : null;
}
public WorkingWeek getCrossCcyWeek() {
return crossCcyWeek != null ? crossCcyWeek : currencyCalculatorConfig != null ? currencyCalculatorConfig.getWorkingWeek(crossCcy) : null;
}
public CurrencyCalculatorConfig getCurrencyCalculatorConfig() {
return currencyCalculatorConfig;
}
public boolean isBrokenDateAllowed() {
return brokenDateAllowed;
}
/**
* This specialises the calculator to the given currency pair and the SpotLag (0, 1, 2). Given than some currencies can have different
* SpotLag depending on the business, this is something that the user will have to provide.
* @param ccy1
* @param ccy2
* @param spotLag
* @return the builder
*/
public CurrencyDateCalculatorBuilder currencyPair(final String ccy1, final String ccy2, final SpotLag spotLag) {
this.ccy1 = ccy1;
this.ccy2 = ccy2;
this.spotLag = spotLag;
return this;
}
public SpotLag getSpotLag() {
return spotLag;
}
public boolean isAdjustStartDateWithCurrencyPair() {
return adjustStartDateWithCurrencyPair;
}
/**
* If true, the startDate given to the calculator will be move to the NEXT working day for both currencies (e.g. it will skip weekends
* and any holidays).
* @param adjustStartDateWithCurrencyPair default true
* @return the builder
*/
public CurrencyDateCalculatorBuilder adjustStartDateWithCurrencyPair(final boolean adjustStartDateWithCurrencyPair) {
this.adjustStartDateWithCurrencyPair = adjustStartDateWithCurrencyPair;
return this;
}
/**
* If true, then the calculator can return a SpotDate/TenorDate where the cross currency is NOT a trading date (e.g. July 4 for EUR/GBP which
* usually would be skipped).
* @param brokenDateAllowed default false
* @return the builder
*/
public CurrencyDateCalculatorBuilder brokenDateAllowed(final boolean brokenDateAllowed) {
this.brokenDateAllowed = brokenDateAllowed;
return this;
}
/**
* Provides information about currencies subject to USD on T+1 and WorkingWeeks if not specified individually.
* @param currencyCalculatorConfig the config
* @return
*/
public CurrencyDateCalculatorBuilder currencyCalculatorConfig(final CurrencyCalculatorConfig currencyCalculatorConfig) {
this.currencyCalculatorConfig = currencyCalculatorConfig;
return this;
}
/**
* The holiday calendar for ccy1, if null or not set, then a default calendar will be used with NO holidays.
* @param ccy1Calendar the Calendar for ccy1
* @return the builder
*/
public CurrencyDateCalculatorBuilder ccy1Calendar(final HolidayCalendar ccy1Calendar) {
if (ccy1Calendar != null) {
this.ccy1Calendar = ccy1Calendar;
}
return this;
}
/**
* The holiday calendar for ccy2, if null or not set, then a default calendar will be used with NO holidays.
* @param ccy2Calendar the Calendar for ccy2
* @return the builder
*/
public CurrencyDateCalculatorBuilder ccy2Calendar(final HolidayCalendar ccy2Calendar) {
if (ccy2Calendar != null) {
this.ccy2Calendar = ccy2Calendar;
}
return this;
}
/**
* If brokenDate is not allowed, we do require to check the WorkingWeek and Holiday for the crossCcy when
* validating the SpotDate or a Tenor date; if null or not set, then a default calendar will be used with NO holidays.
* @param crossCcy the crossCcy (default USD).
* @return the builder
*/
public CurrencyDateCalculatorBuilder crossCcy(final String crossCcy) {
this.crossCcy = crossCcy;
return this;
}
/**
* If brokenDate is not allowed, we do require to check the WorkingWeek and Holiday for the crossCcy when
* validating the SpotDate or a Tenor date.
* @param crossCcyCalendar the set of holidays for the crossCcy
* @return the builder
*/
public CurrencyDateCalculatorBuilder crossCcyCalendar(final HolidayCalendar crossCcyCalendar) {
if (crossCcyCalendar != null) {
this.crossCcyCalendar = crossCcyCalendar;
}
return this;
}
/**
* Provides the holiday handler for the Tenor Date, note that Spot is ALWAYS using Forward.
* @param holidayHandler the Handler to work out what to do if a Tenor Date falls on a non WorkingDay.
* @return the builder
*/
public CurrencyDateCalculatorBuilder tenorHolidayHandler(final HolidayHandler holidayHandler) {
this.tenorHolidayHandler = holidayHandler;
return this;
}
/**
* Provides the definition of a working week for the currency; if not provided and the currencyCalculatorConfig is given, it
* will do a look up for this currency.
* @param ccy1Week WorkingWeek definition
* @return the builder
*/
public CurrencyDateCalculatorBuilder ccy1Week(final WorkingWeek ccy1Week) {
this.ccy1Week = ccy1Week;
return this;
}
/**
* Provides the definition of a working week for the currency; if not provided and the currencyCalculatorConfig is given, it
* will do a look up for this currency.
* @param ccy2Week WorkingWeek definition
* @return the builder
*/
public CurrencyDateCalculatorBuilder ccy2Week(final WorkingWeek ccy2Week) {
this.ccy2Week = ccy2Week;
return this;
}
/**
* If brokenDate is not allowed, we do require to check the WorkingWeek and Holiday for the crossCcy when
* validating the SpotDate or a Tenor date.
* @param crossCcyWeek the crossCcy WorkingWeek.
* @return the builder
*/
public CurrencyDateCalculatorBuilder crossCcyWeek(final WorkingWeek crossCcyWeek) {
this.crossCcyWeek = crossCcyWeek;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy