Product Model

The product model in Strata, defined in strata-product, provides Java classes representing a broad range of common asset classes. It is a data only design. There is little to no behaviour in the classes. Logic for pricing and risk is provided separately in the strata-pricer project. Applications will typically use strata-measure to access risk measures.

Concepts

The Strata product model has four basic concepts: products, securities, trades and positions.

Product

A product is the financial details of the instrument. A product typically contains enough information to be priced, such as the dates, holidays, indices, currencies and amounts. There is an implementation of Product for each distinct type of financial instrument.

The Product interface is a marker and has no methods:

public interface Product {
}

Security

A security is a standard contract that is traded, such as an equity share or futures contract. Securities are typically created once and shared using an identifier, represented by a SecurityId. They are often referred to as reference data.

A security always has an associated product. The security refers to any underlying securities by identifier. By contrast, the associated product refers to any underlying products directly, as embedded objects.

The Security interface is as follows:

public interface Security {

  SecurityInfo getInfo();
  SecurityId getSecurityId();
  Currency getCurrency();
  ImmutableSet<SecurityId> getUnderlyingIds();

  SecuritizedProduct createProduct(ReferenceData refData);
  Trade createTrade(TradeInfo tradeInfo, double quantity, double tradePrice, ReferenceData refData);

}

The SecurityInfo instance provides a place to add information about the trade, such as the identifier and currency, which are also exposed directly. The underlying identifiers can be obtained, which is useful for securities that are based on other securities. The last two methods allow the product and trade to be obtained from the security.

Trade

A trade is the basic element of finance, a transaction between two counterparties.

The Trade interface is minimal:

public interface Trade extends CalculationTarget {

  TradeInfo getInfo();

}

The TradeInfo instance provides a place to add information about the trade, such as the counterparty and trade date. The CalculationTarget super-interface allows trades to be processed by the Calculation API.

Position

A position consists of a quantity of a security. It is used with securities as there is no need to distinguish individual security trades from one another in most cases.

The Position interface is as follows:

public interface Position extends SecurityQuantity, CalculationTarget {

  PositionInfo getInfo();
  SecurityId getSecurityId();
  double getQuantity();

}

The PositionInfo instance provides a place to add information about the trade, such as the position identifier. The position also provides access to the security identifier and quantity. The CalculationTarget super-interface allows trades to be processed by the Calculation API.

Design

The key to understanding the design is appreciating the separation of products from trades and securities.

OTC trades

An OTC trade directly embeds the product it refers to. As such, OTC trades implement ProductTrade.

For example, consider an OTC instrument such as an interest rate swap. The object model consists of a SwapTrade that directly contains a Swap, where SwapTrade implements ProductTrade.

Listed trades (in securities)

A listed trade can be defined in three different ways.

The first approach is to use SecurityTrade. A SecurityTrade stores just the security identifier, quantity and trade price. When the trade needs to be priced, the identifier can be resolved to a Security using ReferenceData. The reference data could be backed by an in-memory store or a database.

The second approach is to use the generic security trade GenericSecurityTrade. This contains a GenericSecurity, which has just enough information about the security to be able to convert the market quote to a monetary value. This approach avoids the need to use reference data.

The third approach is to use a more specific trade type, such as BondFutureTrade. These types include the product details directly so that no reference data is needed.

For example, consider a bond future. In the first approach, the application would create a SecurityTrade using the identifier of the future. The reference data would be populated, mapping the identifier to an instance of BondFutureSecurity and additional identifiers for each of the underlying FixedCouponBondSecurity instances.

In the second approach, the application would create a GenericSecurityTrade wrapping a GenericSecurity. The GenericSecurity would be created with the correct data to describe relationship between the price of the security and a monetary value.

In the third approach, the trade would be defined using BondFutureTrade. In this case, the trade directly holds the product model of the BondFuture and each underlying FixedCouponBond. There is thus no need to populate the reference data with securities.

Positions (in securities)

A position in a security can be thought of as an aggregated quantity of an underlying security. Two approaches are supported for positions.

The first approach is to use SecurityPosition. A SecurityPosition stores just the security identifier and quantity. When the trade needs to be priced, the identifier can be resolved to a Security using ReferenceData. The reference data could be backed by an in-memory store or a database.

The second approach is to use the generic security position GenericSecurityPosition. This contains a GenericSecurity, which has just enough information about the security to be able to convert the market quote to a monetary value. This approach avoids the need to use reference data.

Resolved form

In most cases, each trade and product has a parallel resolved form. For example, Swap and ResolvedSwap.

The unresolved form is a description of the trade or product that could live in long-term persistence, such as a database. The resolved form is a short-lived representation designed for pricing.

Conversion from the unresolved to resolved form requires a ReferenceData instance. This is primarily used to resolve holiday calendars and securities.