Skip to content

Commit

Permalink
Merge pull request #17 from SolumXplain/SXSD-6480-remove-static-refdata
Browse files Browse the repository at this point in the history
SXSD-6480: Remove reference to ReferenceData.standard() from customised classes.
  • Loading branch information
gbodenSolum authored Sep 19, 2023
2 parents cccdb07 + ab82fcb commit f3f18f2
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 34 deletions.
2 changes: 1 addition & 1 deletion examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-examples</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<packaging>jar</packaging>
<name>Strata-Examples</name>
<description>Example code to demonstrate use of Strata</description>
Expand Down
8 changes: 7 additions & 1 deletion modules/basics/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-basics</artifactId>
Expand All @@ -21,6 +21,12 @@
<artifactId>strata-collect</artifactId>
</dependency>

<!-- Third Party -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>

<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright (C) 2023 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.basics;

import java.util.function.Supplier;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opengamma.strata.collect.ArgChecker;

/**
* Associates {@link ReferenceData} with the current execution thread.
* <p>
* This class provides a series of static methods that delegate to {@link InheritableThreadLocalReferenceDataHolderStrategy}.
* This strategy uses an {@link InheritableThreadLocal} to store {@code ReferenceData} against a thread.
*
* </p>
*/
public class ReferenceDataHolder {
private ReferenceDataHolder() {
// prevent instantiation
}

private static final InheritableThreadLocalReferenceDataHolderStrategy STRATEGY = new InheritableThreadLocalReferenceDataHolderStrategy();

/**
* Sets the current reference data for this thread.
*
* @param refData the new value to hold (should never be null).
* @throws IllegalArgumentException if {@code refData} is null.
*/
public static void setReferenceData(ReferenceData refData) {
ArgChecker.notNull(refData, "refData");
STRATEGY.setReferenceData(refData);
}

/**
* Gets the current reference data for this thread.
* If it has not previously been set for this thread then it will be null.
*
* @return current reference data
*/
public static ReferenceData getReferenceData() {
return STRATEGY.getReferenceData();
}

/**
* Gets the current reference data for this thread and, if it is not set, return a fallback value instead.
*
* @param other the fallback value to return if the reference data has not been set for this thread (should never be null).
* @return the reference data for this thread, or the provided fallback value
* @throws IllegalArgumentException if {@code other} is null.
*/
public static ReferenceData getReferenceDataWithFallback(ReferenceData other) {
ArgChecker.notNull(other, "other");
return STRATEGY.getReferenceDataWithFallback(other);
}

/**
* Executes a function to return a value with reference data set for the duration of the function and then
* cleared afterwards.
*
* @param referenceData the new value to hold (should never be null).
* @param fn the function to call to return a value
* @return the value returned from the function
* @param <T> type of value
*/
public static <T> T withReferenceData(ReferenceData referenceData, Supplier<T> fn) {
setReferenceData(referenceData);
try {
T result = fn.get();
return result;
} finally {
clearReferenceData();
}
}

/**
* Executes a function that returns no value with reference data set for the duration of the function and then
* cleared afterwards.
*
* @param referenceData the new value to hold (should never be null).
* @param fn the function to call
*/
public static void withReferenceData(ReferenceData referenceData, Runnable fn) {
setReferenceData(referenceData);
try {
fn.run();
} finally {
clearReferenceData();
}
}

/**
* Clears the current reference data for this thread.
*/
public static void clearReferenceData() {
STRATEGY.clearReferenceData();
}

private static class InheritableThreadLocalReferenceDataHolderStrategy {
private Logger log = LoggerFactory.getLogger(ReferenceDataHolder.class);
private static final ThreadLocal<ReferenceData> HOLDER = new InheritableThreadLocal<>();

public void clearReferenceData() {
HOLDER.remove();
}

public ReferenceData getReferenceData() {
return HOLDER.get();
}

public void setReferenceData(ReferenceData refData) {
HOLDER.set(refData);
}

public ReferenceData getReferenceDataWithFallback(ReferenceData other) {
final ReferenceData result = getReferenceData();
if (result == null) {
log.warn("No reference data saved in thread, falling back to default.");
return other;
}
return result;
}
}
}
2 changes: 1 addition & 1 deletion modules/calc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-calc</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.google.common.collect.Sets;
import com.opengamma.strata.basics.CalculationTarget;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.ReferenceDataHolder;
import com.opengamma.strata.basics.ReferenceDataNotFoundException;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyPair;
Expand Down Expand Up @@ -231,7 +232,9 @@ private Map<Measure, Result<?>> calculate(ScenarioMarketData marketData, Referen
Set<Measure> measures = Sets.intersection(requestedMeasures, supportedMeasures);
Map<Measure, Result<?>> map = ImmutableMap.of();
if (!measures.isEmpty()) {
map = function.calculate(target, measures, parameters, marketData, refData);
// TODO: everything should ideally be resolved in the CalculationFunction, not relying on ReferenceDataHolder lower down.
map = ReferenceDataHolder.withReferenceData(refData,
() -> function.calculate(target, measures, parameters, marketData, refData));
}
// check if result does not contain all requested measures
if (!map.keySet().containsAll(requestedMeasures)) {
Expand Down
2 changes: 1 addition & 1 deletion modules/collect/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-collect</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion modules/data/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-data</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion modules/loader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-loader</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion modules/market/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-market</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion modules/math/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-math</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion modules/measure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-measure</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion modules/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<packaging>pom</packaging>
<name>Strata-Parent</name>
<description>OpenGamma Strata Parent</description>
Expand Down
2 changes: 1 addition & 1 deletion modules/pricer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.opengamma.strata</groupId>
<artifactId>strata-parent</artifactId>
<version>2.12.22-xplain-2</version>
<version>2.12.22-xplain-3</version>
<relativePath>..</relativePath>
</parent>
<artifactId>strata-pricer</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.joda.beans.impl.direct.DirectPrivateBeanBuilder;

import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.ReferenceDataHolder;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.CurrencyPair;
Expand Down Expand Up @@ -152,7 +153,8 @@ public LocalDate getValuationDate() {
private LocalDate spotDate() {
try {
FxSwapConvention fxSwapConvention = FxSwapConvention.of(currencyPair);
return fxSwapConvention.calculateSpotDateFromTradeDate(valuationDate, ReferenceData.standard());
ReferenceData refData = ReferenceDataHolder.getReferenceDataWithFallback(ReferenceData.standard());
return fxSwapConvention.calculateSpotDateFromTradeDate(valuationDate, refData);
} catch (IllegalArgumentException e) {
return valuationDate;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import java.time.LocalDate;

import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.ReferenceDataHolder;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.CurrencyPair;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.market.explain.ExplainKey;
import com.opengamma.strata.market.explain.ExplainMapBuilder;
Expand All @@ -19,7 +19,6 @@
import com.opengamma.strata.pricer.fx.FxIndexRates;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.pricer.swap.SwapPaymentEventPricer;
import com.opengamma.strata.product.fx.type.FxSwapConvention;
import com.opengamma.strata.product.swap.FxResetNotionalExchange;

/**
Expand Down Expand Up @@ -109,6 +108,17 @@ public void explainPresentValue(FxResetNotionalExchange event, RatesProvider pro
}

//-------------------------------------------------------------------------
/**
* Calculates the currency exposure of a single payment event.
* <p>
* If {@link ReferenceDataHolder} has been populated for this thread, it will be used to obtain the calendar
* for calculating the spot date from the valuation date. Otherwise the {@link ReferenceData#standard() standard}
* calendar will be used instead.
*
* @param event the event
* @param provider the rates provider
* @return the currency exposure
*/
@Override
public MultiCurrencyAmount currencyExposure(FxResetNotionalExchange event, RatesProvider provider) {
double dfCounterMaturity = provider.discountFactor(event.getCurrency(), event.getPaymentDate());
Expand All @@ -120,21 +130,17 @@ public MultiCurrencyAmount currencyExposure(FxResetNotionalExchange event, Rates
return MultiCurrencyAmount.of(CurrencyAmount.of(event.getCurrency(), event.getNotional() * dfCounterMaturity * fxRate));
}

ReferenceData refData = ReferenceDataHolder.getReferenceDataWithFallback(ReferenceData.standard());
Currency baseCurrency = event.getReferenceCurrency();
Currency counterCurrency = event.getCurrency();
LocalDate valuationDate = provider.getValuationDate();
LocalDate spotDate = FxSwapConvention.of(CurrencyPair.of(baseCurrency, counterCurrency)).calculateSpotDateFromTradeDate(valuationDate,
ReferenceData.standard());

double dfCounterSpot = provider.discountFactor(counterCurrency, spotDate);
double dfReferenceSpot = provider.discountFactor(baseCurrency, spotDate);
double dfScaled = FxDfScaler.scaledDf(provider, refData, baseCurrency, counterCurrency, dfCounterMaturity);

LocalDate maturityDate = event.getObservation().getMaturityDate();
double fxRateSpotSensitivity =
rates.getFxForwardRates().rateFxSpotSensitivity(event.getReferenceCurrency(), maturityDate);
return MultiCurrencyAmount.of(
CurrencyAmount.of(event.getReferenceCurrency(), event.getNotional() *
fxRateSpotSensitivity * (dfCounterMaturity / dfCounterSpot) * dfReferenceSpot));
fxRateSpotSensitivity * dfScaled));
}

@Override
Expand Down
Loading

0 comments on commit f3f18f2

Please sign in to comment.