
com.opengamma.strata.product.SecurityPriceInfo Maven / Gradle / Ivy
Show all versions of strata-product Show documentation
/*
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.product;
import java.io.Serializable;
import java.util.Map;
import java.util.NoSuchElementException;
import org.joda.beans.Bean;
import org.joda.beans.BeanBuilder;
import org.joda.beans.ImmutableBean;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaBean;
import org.joda.beans.MetaProperty;
import org.joda.beans.gen.BeanDefinition;
import org.joda.beans.gen.DerivedProperty;
import org.joda.beans.gen.ImmutableConstructor;
import org.joda.beans.gen.PropertyDefinition;
import org.joda.beans.impl.direct.DirectMetaBean;
import org.joda.beans.impl.direct.DirectMetaProperty;
import org.joda.beans.impl.direct.DirectMetaPropertyMap;
import org.joda.beans.impl.direct.DirectPrivateBeanBuilder;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.collect.ArgChecker;
/**
* Defines the meaning of the security price.
*
* A value of a security is measured in terms of a price which is not typically a monetary amount.
* Instead the price is an arbitrary number that can be converted to a monetary amount.
* The price will move up and down in ticks. This class provides the size and monetary
* value of each tick, allowing changes in the price to be converted to a monetary amount.
*
* Three properties define the necessary information:
* Tick size is the minimum movement in the price of the security (the tick).
* Tick value is the monetary value gained or lost when the price changes by one tick.
* Contract size is the quantity of the underlying present in each derivative contract,
* which acts as a multiplier.
*
* For example, the price of an ICE Brent Crude future is based on the price of a barrel of crude oil in USD.
* The tick size of this contract is 0.01 (equivalent to 1 cent).
* The contract size is 1,000 barrels.
* Therefore the tick value is 0.01 * 1,000 = 10 USD.
*/
@BeanDefinition(builderScope = "private")
public final class SecurityPriceInfo
implements ImmutableBean, Serializable {
/**
* The size of each tick.
*
* Tick size is the minimum movement in the price of the security.
* For example, the price might move up or down in units of 0.01
* It must be a positive decimal number.
*/
@PropertyDefinition(validate = "ArgChecker.notNegativeOrZero")
private final double tickSize;
/**
* The monetary value of one tick.
*
* Tick value is the monetary value of the minimum movement in the price of the security.
* When the price changes by one tick, this amount is gained or lost.
*/
@PropertyDefinition(validate = "notNull")
private final CurrencyAmount tickValue;
/**
* The size of each contract.
*
* Contract size is the quantity of the underlying present in each derivative contract.
* For example, an equity option typically consists of 100 shares.
*/
@PropertyDefinition(validate = "ArgChecker.notNegativeOrZero")
private final double contractSize;
/**
* Multiplier to apply to the price.
*/
private final transient double tradeUnitValue; // derived, not a property
//-------------------------------------------------------------------------
/**
* Obtains an instance from the tick size and tick value.
*
* The contract size will be set to 1.
*
* @param tickSize the size of each tick, not negative or zero
* @param tickValue the value of each tick
* @return the security price information
*/
public static SecurityPriceInfo of(double tickSize, CurrencyAmount tickValue) {
return new SecurityPriceInfo(tickSize, tickValue, 1);
}
/**
* Obtains an instance from the tick size, tick value and contract size.
*
* @param tickSize the size of each tick, not negative or zero
* @param tickValue the value of each tick
* @param contractSize the contract size
* @return the security price information
*/
public static SecurityPriceInfo of(double tickSize, CurrencyAmount tickValue, double contractSize) {
return new SecurityPriceInfo(tickSize, tickValue, contractSize);
}
/**
* Obtains an instance from the currency and the value of a single tradeable unit.
*
* @param currency the currency in which the security is traded
* @param tradeUnitValue the value of a single tradeable unit of the security
* @return the security price information
*/
public static SecurityPriceInfo of(Currency currency, double tradeUnitValue) {
return new SecurityPriceInfo(1, CurrencyAmount.of(currency, 1), tradeUnitValue);
}
/**
* Obtains an instance from the currency.
*
* This sets the tick size and tick value to the minor unit of the currency.
* For example, for USD this will set the tick size to 0.01 and the tick value to $0.01.
* This typically matches the conventions of equities and bonds.
*
* @param currency the currency to derive the price information from
* @return the security price information
*/
public static SecurityPriceInfo ofCurrencyMinorUnit(Currency currency) {
int digits = currency.getMinorUnitDigits();
double unitAmount = Math.pow(10, -digits);
return new SecurityPriceInfo(unitAmount, CurrencyAmount.of(currency, unitAmount), 1);
}
@ImmutableConstructor
private SecurityPriceInfo(
double tickSize,
CurrencyAmount tickValue,
double contractSize) {
ArgChecker.notNegativeOrZero(tickSize, "tickSize");
JodaBeanUtils.notNull(tickValue, "tickValue");
ArgChecker.notNegativeOrZero(contractSize, "contractSize");
this.tickSize = tickSize;
this.tickValue = tickValue;
this.contractSize = contractSize;
this.tradeUnitValue = (tickValue.getAmount() * contractSize) / tickSize;
}
// ensure standard constructor is invoked
private Object readResolve() {
return new SecurityPriceInfo(tickSize, tickValue, contractSize);
}
//-----------------------------------------------------------------------
/**
* Gets the currency that the security is traded in.
*
* The currency is derived from the tick value.
*
* @return the currency
*/
@DerivedProperty
public Currency getCurrency() {
return tickValue.getCurrency();
}
//-------------------------------------------------------------------------
/**
* Calculates the monetary value of the specified quantity and price.
*
* This calculates a monetary value using the stored price information.
* For equities, this is the premium that will be paid.
* For bonds, this will be the premium if the price specified is the dirty price.
* For margined ETDs, the profit or loss per day is the monetary difference
* between two calls to this method with the price on each day.
*
* This returns {@link #calculateMonetaryValue(double, double)} as a {@link CurrencyAmount}.
*
* @param quantity the quantity, such as the number of shares or number of future contracts
* @param price the price, typically from the market
* @return the monetary value combining the tick size, tick value, contract size, quantity and price.
*/
public CurrencyAmount calculateMonetaryAmount(double quantity, double price) {
return CurrencyAmount.of(tickValue.getCurrency(), calculateMonetaryValue(quantity, price));
}
/**
* Calculates the monetary value of the specified quantity and price.
*
* This calculates a monetary value using the stored price information.
* For equities, this is the premium that will be paid.
* For bonds, this will be the premium if the price specified is the dirty price.
* For margined ETDs, the profit or loss per day is the monetary difference
* between two calls to this method with the price on each day.
*
* @param quantity the quantity, such as the number of shares or number of future contracts
* @param price the price, typically from the market
* @return the monetary value combining the tick size, tick value, contract size, quantity and price.
*/
public double calculateMonetaryValue(double quantity, double price) {
return price * quantity * tradeUnitValue;
}
/**
* Returns the value of a single tradeable unit of the security.
*
* The monetary value of a position in a security is
*
tradeUnitValue * price * quantity
*
* This value is normally derived from the tick size, tick value and contract size:
*
tradeUnitValue = tickValue * contractSize / tickSize
*
* @return the value of a single tradeable unit of the security
*/
public double getTradeUnitValue() {
return tradeUnitValue;
}
//------------------------- AUTOGENERATED START -------------------------
/**
* The meta-bean for {@code SecurityPriceInfo}.
* @return the meta-bean, not null
*/
public static SecurityPriceInfo.Meta meta() {
return SecurityPriceInfo.Meta.INSTANCE;
}
static {
MetaBean.register(SecurityPriceInfo.Meta.INSTANCE);
}
/**
* The serialization version id.
*/
private static final long serialVersionUID = 1L;
@Override
public SecurityPriceInfo.Meta metaBean() {
return SecurityPriceInfo.Meta.INSTANCE;
}
//-----------------------------------------------------------------------
/**
* Gets the size of each tick.
*
* Tick size is the minimum movement in the price of the security.
* For example, the price might move up or down in units of 0.01
* It must be a positive decimal number.
* @return the value of the property
*/
public double getTickSize() {
return tickSize;
}
//-----------------------------------------------------------------------
/**
* Gets the monetary value of one tick.
*
* Tick value is the monetary value of the minimum movement in the price of the security.
* When the price changes by one tick, this amount is gained or lost.
* @return the value of the property, not null
*/
public CurrencyAmount getTickValue() {
return tickValue;
}
//-----------------------------------------------------------------------
/**
* Gets the size of each contract.
*
* Contract size is the quantity of the underlying present in each derivative contract.
* For example, an equity option typically consists of 100 shares.
* @return the value of the property
*/
public double getContractSize() {
return contractSize;
}
//-----------------------------------------------------------------------
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj != null && obj.getClass() == this.getClass()) {
SecurityPriceInfo other = (SecurityPriceInfo) obj;
return JodaBeanUtils.equal(tickSize, other.tickSize) &&
JodaBeanUtils.equal(tickValue, other.tickValue) &&
JodaBeanUtils.equal(contractSize, other.contractSize);
}
return false;
}
@Override
public int hashCode() {
int hash = getClass().hashCode();
hash = hash * 31 + JodaBeanUtils.hashCode(tickSize);
hash = hash * 31 + JodaBeanUtils.hashCode(tickValue);
hash = hash * 31 + JodaBeanUtils.hashCode(contractSize);
return hash;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder(160);
buf.append("SecurityPriceInfo{");
buf.append("tickSize").append('=').append(JodaBeanUtils.toString(tickSize)).append(',').append(' ');
buf.append("tickValue").append('=').append(JodaBeanUtils.toString(tickValue)).append(',').append(' ');
buf.append("contractSize").append('=').append(JodaBeanUtils.toString(contractSize)).append(',').append(' ');
buf.append("currency").append('=').append(JodaBeanUtils.toString(getCurrency()));
buf.append('}');
return buf.toString();
}
//-----------------------------------------------------------------------
/**
* The meta-bean for {@code SecurityPriceInfo}.
*/
public static final class Meta extends DirectMetaBean {
/**
* The singleton instance of the meta-bean.
*/
static final Meta INSTANCE = new Meta();
/**
* The meta-property for the {@code tickSize} property.
*/
private final MetaProperty tickSize = DirectMetaProperty.ofImmutable(
this, "tickSize", SecurityPriceInfo.class, Double.TYPE);
/**
* The meta-property for the {@code tickValue} property.
*/
private final MetaProperty tickValue = DirectMetaProperty.ofImmutable(
this, "tickValue", SecurityPriceInfo.class, CurrencyAmount.class);
/**
* The meta-property for the {@code contractSize} property.
*/
private final MetaProperty contractSize = DirectMetaProperty.ofImmutable(
this, "contractSize", SecurityPriceInfo.class, Double.TYPE);
/**
* The meta-property for the {@code currency} property.
*/
private final MetaProperty currency = DirectMetaProperty.ofDerived(
this, "currency", SecurityPriceInfo.class, Currency.class);
/**
* The meta-properties.
*/
private final Map> metaPropertyMap$ = new DirectMetaPropertyMap(
this, null,
"tickSize",
"tickValue",
"contractSize",
"currency");
/**
* Restricted constructor.
*/
private Meta() {
}
@Override
protected MetaProperty> metaPropertyGet(String propertyName) {
switch (propertyName.hashCode()) {
case 1936822078: // tickSize
return tickSize;
case -85538348: // tickValue
return tickValue;
case -1402368973: // contractSize
return contractSize;
case 575402001: // currency
return currency;
}
return super.metaPropertyGet(propertyName);
}
@Override
public BeanBuilder extends SecurityPriceInfo> builder() {
return new SecurityPriceInfo.Builder();
}
@Override
public Class extends SecurityPriceInfo> beanType() {
return SecurityPriceInfo.class;
}
@Override
public Map> metaPropertyMap() {
return metaPropertyMap$;
}
//-----------------------------------------------------------------------
/**
* The meta-property for the {@code tickSize} property.
* @return the meta-property, not null
*/
public MetaProperty tickSize() {
return tickSize;
}
/**
* The meta-property for the {@code tickValue} property.
* @return the meta-property, not null
*/
public MetaProperty tickValue() {
return tickValue;
}
/**
* The meta-property for the {@code contractSize} property.
* @return the meta-property, not null
*/
public MetaProperty contractSize() {
return contractSize;
}
/**
* The meta-property for the {@code currency} property.
* @return the meta-property, not null
*/
public MetaProperty currency() {
return currency;
}
//-----------------------------------------------------------------------
@Override
protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
switch (propertyName.hashCode()) {
case 1936822078: // tickSize
return ((SecurityPriceInfo) bean).getTickSize();
case -85538348: // tickValue
return ((SecurityPriceInfo) bean).getTickValue();
case -1402368973: // contractSize
return ((SecurityPriceInfo) bean).getContractSize();
case 575402001: // currency
return ((SecurityPriceInfo) bean).getCurrency();
}
return super.propertyGet(bean, propertyName, quiet);
}
@Override
protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
metaProperty(propertyName);
if (quiet) {
return;
}
throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
}
}
//-----------------------------------------------------------------------
/**
* The bean-builder for {@code SecurityPriceInfo}.
*/
private static final class Builder extends DirectPrivateBeanBuilder {
private double tickSize;
private CurrencyAmount tickValue;
private double contractSize;
/**
* Restricted constructor.
*/
private Builder() {
}
//-----------------------------------------------------------------------
@Override
public Object get(String propertyName) {
switch (propertyName.hashCode()) {
case 1936822078: // tickSize
return tickSize;
case -85538348: // tickValue
return tickValue;
case -1402368973: // contractSize
return contractSize;
default:
throw new NoSuchElementException("Unknown property: " + propertyName);
}
}
@Override
public Builder set(String propertyName, Object newValue) {
switch (propertyName.hashCode()) {
case 1936822078: // tickSize
this.tickSize = (Double) newValue;
break;
case -85538348: // tickValue
this.tickValue = (CurrencyAmount) newValue;
break;
case -1402368973: // contractSize
this.contractSize = (Double) newValue;
break;
default:
throw new NoSuchElementException("Unknown property: " + propertyName);
}
return this;
}
@Override
public SecurityPriceInfo build() {
return new SecurityPriceInfo(
tickSize,
tickValue,
contractSize);
}
//-----------------------------------------------------------------------
@Override
public String toString() {
StringBuilder buf = new StringBuilder(160);
buf.append("SecurityPriceInfo.Builder{");
buf.append("tickSize").append('=').append(JodaBeanUtils.toString(tickSize)).append(',').append(' ');
buf.append("tickValue").append('=').append(JodaBeanUtils.toString(tickValue)).append(',').append(' ');
buf.append("contractSize").append('=').append(JodaBeanUtils.toString(contractSize)).append(',').append(' ');
buf.append("currency").append('=').append(JodaBeanUtils.toString(null));
buf.append('}');
return buf.toString();
}
}
//-------------------------- AUTOGENERATED END --------------------------
}