Skip to content
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

Create OvernightOvernightSwapConventions #2686

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Copyright (C) 2024 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.product.swap.type;

import java.time.LocalDate;
import java.time.Period;

import org.joda.convert.FromString;
import org.joda.convert.ToString;

import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.ReferenceDataNotFoundException;
import com.opengamma.strata.basics.date.Tenor;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.named.ExtendedEnum;
import com.opengamma.strata.collect.named.Named;
import com.opengamma.strata.product.TradeInfo;
import com.opengamma.strata.product.common.BuySell;
import com.opengamma.strata.product.swap.SwapTrade;

/**
* A market convention for Overnight-Overnight swap trades.
* <p>
* This defines the market convention for an Overnight-Overnight single currency swap.
* The convention is formed by combining two swap leg conventions in the same currency.
* <p>
* To manually create a convention, see {@link ImmutableOvernightOvernightSwapConvention}.
* To register a specific convention, see {@code OvernightOvernightSwapConvention.ini}.
*/
public interface OvernightOvernightSwapConvention extends SingleCurrencySwapConvention, Named {

/**
* Obtains an instance from the specified unique name.
*
* @param uniqueName the unique name
* @return the convention
* @throws IllegalArgumentException if the name is not known
*/
@FromString
public static OvernightOvernightSwapConvention of(String uniqueName) {
ArgChecker.notNull(uniqueName, "uniqueName");
return extendedEnum().lookup(uniqueName);
}

/**
* Gets the extended enum helper.
* <p>
* This helper allows instances of the convention to be looked up.
* It also provides the complete set of available instances.
*
* @return the extended enum helper
*/
public static ExtendedEnum<OvernightOvernightSwapConvention> extendedEnum() {
return OvernightOvernightSwapConventions.ENUM_LOOKUP;
}

//-----------------------------------------------------------------------
/**
* Gets the market convention of the spread leg.
*
* @return the spread leg convention
*/
public abstract OvernightRateSwapLegConvention getSpreadLeg();

/**
* Gets the market convention of the flat leg.
*
* @return the flat leg convention
*/
public abstract OvernightRateSwapLegConvention getFlatLeg();

//-------------------------------------------------------------------------
/**
* Creates a spot-starting trade based on this convention.
* <p>
* This returns a trade based on the specified tenor. For example, a tenor
* of 5 years creates a swap starting on the spot date and maturing 5 years later.
* <p>
* The notional is unsigned, with buy/sell determining the direction of the trade.
* If buying the swap, the rate of the flat leg is received from the counterparty,
* with the rate of the spread leg being paid. If selling the swap, the opposite occurs.
*
* @param tradeDate the date of the trade
* @param tenor the tenor of the swap
* @param buySell the buy/sell flag
* @param notional the notional amount
* @param spread the spread, typically derived from the market
* @param refData the reference data, used to resolve the trade dates
* @return the trade
* @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data
*/
@Override
public default SwapTrade createTrade(
LocalDate tradeDate,
Tenor tenor,
BuySell buySell,
double notional,
double spread,
ReferenceData refData) {

// override for Javadoc
return SingleCurrencySwapConvention.super.createTrade(tradeDate, tenor, buySell, notional, spread, refData);
}

/**
* Creates a forward-starting trade based on this convention.
* <p>
* This returns a trade based on the specified period and tenor. For example, a period of
* 3 months and a tenor of 5 years creates a swap starting three months after the spot date
* and maturing 5 years later.
* <p>
* The notional is unsigned, with buy/sell determining the direction of the trade.
* If buying the swap, the rate of the flat leg is received from the counterparty,
* with the rate of the spread leg being paid. If selling the swap, the opposite occurs.
*
* @param tradeDate the date of the trade
* @param periodToStart the period between the spot date and the start date
* @param tenor the tenor of the swap
* @param buySell the buy/sell flag
* @param notional the notional amount
* @param spread the spread, typically derived from the market
* @param refData the reference data, used to resolve the trade dates
* @return the trade
* @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data
*/
@Override
public default SwapTrade createTrade(
LocalDate tradeDate,
Period periodToStart,
Tenor tenor,
BuySell buySell,
double notional,
double spread,
ReferenceData refData) {

// override for Javadoc
return SingleCurrencySwapConvention.super.createTrade(tradeDate, periodToStart, tenor, buySell, notional, spread, refData);
}

/**
* Creates a trade based on this convention.
* <p>
* This returns a trade based on the specified dates.
* <p>
* The notional is unsigned, with buy/sell determining the direction of the trade.
* If buying the swap, the rate of the flat leg is received from the counterparty,
* with the rate of the spread leg being paid. If selling the swap, the opposite occurs.
*
* @param tradeDate the date of the trade
* @param startDate the start date
* @param endDate the end date
* @param buySell the buy/sell flag
* @param notional the notional amount
* @param spread the spread, typically derived from the market
* @return the trade
*/
@Override
public default SwapTrade toTrade(
LocalDate tradeDate,
LocalDate startDate,
LocalDate endDate,
BuySell buySell,
double notional,
double spread) {

// override for Javadoc
return SingleCurrencySwapConvention.super.toTrade(tradeDate, startDate, endDate, buySell, notional, spread);
}

/**
* Creates a trade based on this convention.
* <p>
* This returns a trade based on the specified dates.
* <p>
* The notional is unsigned, with buy/sell determining the direction of the trade.
* If buying the swap, the rate of the flat leg is received from the counterparty,
* with the rate of the spread leg being paid. If selling the swap, the opposite occurs.
*
* @param tradeInfo additional information about the trade
* @param startDate the start date
* @param endDate the end date
* @param buySell the buy/sell flag
* @param notional the notional amount
* @param spread the spread, typically derived from the market
* @return the trade
*/
@Override
public abstract SwapTrade toTrade(
TradeInfo tradeInfo,
LocalDate startDate,
LocalDate endDate,
BuySell buySell,
double notional,
double spread);

//-------------------------------------------------------------------------
/**
* Gets the name that uniquely identifies this convention.
* <p>
* This name is used in serialization and can be parsed using {@link #of(String)}.
*
* @return the unique name
*/
@ToString
@Override
public abstract String getName();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2024 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.product.swap.type;

import com.opengamma.strata.collect.named.ExtendedEnum;

/**
* Market standard Overnight-Overnight swap conventions.
*/
public final class OvernightOvernightSwapConventions {

/**
* The extended enum lookup from name to instance.
*/
static final ExtendedEnum<OvernightOvernightSwapConvention> ENUM_LOOKUP =
ExtendedEnum.of(OvernightOvernightSwapConvention.class);

//-------------------------------------------------------------------------
/**
* The 'USD-SOFR-3M-FED-FUND-3M' swap convention.
* <p>
* USD SOFR v USD Fed Fund 3M swap.
* <p>
* The spot date offset is 2 days.
*/
public static final OvernightOvernightSwapConvention USD_FED_FUND_SOFR_3M =
OvernightOvernightSwapConvention.of(StandardOvernightOvernightSwapConventions.USD_FED_FUND_SOFR_3M.getName());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name USD_FED_FUND_SOFR_3M does not match USD-SOFR-3M-FED-FUND-3M. While painfully long, it is better to be consistent.


//-------------------------------------------------------------------------
/**
* Restricted constructor.
*/
private OvernightOvernightSwapConventions() {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
*/
package com.opengamma.strata.product.swap.type;

import static com.opengamma.strata.basics.date.DayCounts.ACT_360;
import static com.opengamma.strata.basics.date.DayCounts.ACT_365F;
import static com.opengamma.strata.basics.index.IborIndices.GBP_LIBOR_3M;
import static com.opengamma.strata.basics.index.IborIndices.USD_LIBOR_3M;
import static com.opengamma.strata.basics.index.OvernightIndices.GBP_SONIA;
Expand All @@ -16,7 +14,6 @@
import static com.opengamma.strata.product.swap.OvernightAccrualMethod.AVERAGED;
import static com.opengamma.strata.product.swap.OvernightAccrualMethod.COMPOUNDED;

import com.opengamma.strata.basics.date.DayCount;
import com.opengamma.strata.basics.date.DaysAdjustment;
import com.opengamma.strata.basics.date.HolidayCalendarId;
import com.opengamma.strata.basics.index.IborIndex;
Expand All @@ -39,7 +36,7 @@ final class StandardOvernightIborSwapConventions {
* The spot date offset is 2 days and the cut-off period is 2 days.
*/
public static final OvernightIborSwapConvention USD_FED_FUND_AA_LIBOR_3M =
makeConvention("USD-FED-FUND-AA-LIBOR-3M", USD_FED_FUND, USD_LIBOR_3M, ACT_360, P3M, 0, 2, AVERAGED);
makeConvention("USD-FED-FUND-AA-LIBOR-3M", USD_FED_FUND, USD_LIBOR_3M, P3M, 0, 2, AVERAGED);

/**
* GBP Sonia compounded 1Y v LIBOR 3M .
Expand All @@ -48,15 +45,14 @@ final class StandardOvernightIborSwapConventions {
* The spot date offset is 0 days and payment offset is 0 days.
*/
public static final OvernightIborSwapConvention GBP_SONIA_OIS_1Y_LIBOR_3M =
makeConvention("GBP-SONIA-OIS-1Y-LIBOR-3M", GBP_SONIA, GBP_LIBOR_3M, ACT_365F, P12M, 0, 0, COMPOUNDED);
makeConvention("GBP-SONIA-OIS-1Y-LIBOR-3M", GBP_SONIA, GBP_LIBOR_3M, P12M, 0, 0, COMPOUNDED);

//-------------------------------------------------------------------------
// build conventions
private static OvernightIborSwapConvention makeConvention(
String name,
OvernightIndex onIndex,
IborIndex iborIndex,
DayCount dayCount,
Frequency frequency,
int paymentLag,
int cutOffDays,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2024 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.product.swap.type;

import static com.opengamma.strata.basics.index.OvernightIndices.USD_FED_FUND;
import static com.opengamma.strata.basics.index.OvernightIndices.USD_SOFR;
import static com.opengamma.strata.basics.schedule.Frequency.P3M;

import com.opengamma.strata.basics.date.DaysAdjustment;
import com.opengamma.strata.basics.date.HolidayCalendarId;
import com.opengamma.strata.basics.index.OvernightIndex;
import com.opengamma.strata.basics.schedule.Frequency;

/**
* Market standard Overnight-Overnight swap conventions.
*/
final class StandardOvernightOvernightSwapConventions {

/**
* USD SOFR vs USD Fed Fund 3M swap.
* <p>
* The spot date offset is 2 days.
*/
public static final OvernightOvernightSwapConvention USD_FED_FUND_SOFR_3M =
makeConvention("USD-SOFR-3M-FED-FUND-3M", USD_SOFR, USD_FED_FUND, P3M, 2, 2);

//-------------------------------------------------------------------------
// build conventions
private static OvernightOvernightSwapConvention makeConvention(
String name,
OvernightIndex spreadIndex,
OvernightIndex flatIndex,
Frequency frequency,
int paymentLag,
int spotLag) {

HolidayCalendarId calendar = spreadIndex.getFixingCalendar();
DaysAdjustment spotDateOffset = DaysAdjustment.ofBusinessDays(spotLag, calendar);
return ImmutableOvernightOvernightSwapConvention.of(
name,
OvernightRateSwapLegConvention.of(spreadIndex, frequency, paymentLag),
OvernightRateSwapLegConvention.of(flatIndex, frequency, paymentLag),
spotDateOffset);
}

//-------------------------------------------------------------------------

/**
* Restricted constructor.
*/
private StandardOvernightOvernightSwapConventions() {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# OvernightOvernightSwapConvention configuration

# The providers are the classes that define the enum
# The key is of the form 'provider.full.class.name'
# The value is either
# 'constants', the public static final constants from the class
# 'lookup', the class implements NamedLookup with a no-args constructor
# 'instance', the class has a static field named INSTANCE that is of type NamedLookup
[providers]
com.opengamma.strata.product.swap.type.StandardOvernightOvernightSwapConventions = constants

# The set of alternate names
# The key is the alternate name
# The value is the standard name (loaded by a provider)
[alternates]
Loading