cdm.event.position.functions.FxMarkToMarket Maven / Gradle / Ivy
package cdm.event.position.functions;
import cdm.base.math.NonNegativeQuantitySchedule;
import cdm.base.math.UnitType;
import cdm.base.math.functions.FilterQuantityByCurrency;
import cdm.base.math.metafields.FieldWithMetaNonNegativeQuantitySchedule;
import cdm.event.common.Trade;
import cdm.observable.asset.PriceQuantity;
import cdm.observable.asset.PriceSchedule;
import cdm.observable.asset.metafields.FieldWithMetaPriceSchedule;
import cdm.product.template.EconomicTerms;
import cdm.product.template.NonTransferableProduct;
import cdm.product.template.Payout;
import cdm.product.template.SettlementPayout;
import cdm.product.template.TradeLot;
import com.google.inject.ImplementedBy;
import com.rosetta.model.lib.expression.MapperMaths;
import com.rosetta.model.lib.functions.ConditionValidator;
import com.rosetta.model.lib.functions.RosettaFunction;
import com.rosetta.model.lib.mapper.MapperC;
import com.rosetta.model.lib.mapper.MapperS;
import com.rosetta.model.metafields.FieldWithMetaString;
import java.math.BigDecimal;
import javax.inject.Inject;
import static com.rosetta.model.lib.expression.ExpressionOperators.*;
@ImplementedBy(FxMarkToMarket.FxMarkToMarketDefault.class)
public abstract class FxMarkToMarket implements RosettaFunction {
@Inject protected ConditionValidator conditionValidator;
// RosettaFunction dependencies
//
@Inject protected FilterQuantityByCurrency filterQuantityByCurrency;
@Inject protected InterpolateForwardRate interpolateForwardRate;
/**
* @param trade
* @return value
*/
public BigDecimal evaluate(Trade trade) {
// pre-conditions
conditionValidator.validate(() -> exists(MapperS.of(trade).map("getProduct", _trade -> _trade.getProduct()).map("getEconomicTerms", nonTransferableProduct -> nonTransferableProduct.getEconomicTerms()).mapC("getPayout", economicTerms -> economicTerms.getPayout()).map("getSettlementPayout", payout -> payout.getSettlementPayout())),
"The settlementPayout on the contract must exist.");
BigDecimal value = doEvaluate(trade);
return value;
}
protected abstract BigDecimal doEvaluate(Trade trade);
protected abstract MapperS extends SettlementPayout> settlementPayout(Trade trade);
protected abstract MapperS quotedCurrency(Trade trade);
protected abstract MapperS baseCurrency(Trade trade);
protected abstract MapperC quantities(Trade trade);
protected abstract MapperS quotedQuantity(Trade trade);
protected abstract MapperS baseQuantity(Trade trade);
protected abstract MapperS interpolatedRate(Trade trade);
public static class FxMarkToMarketDefault extends FxMarkToMarket {
@Override
protected BigDecimal doEvaluate(Trade trade) {
BigDecimal value = null;
return assignOutput(value, trade);
}
protected BigDecimal assignOutput(BigDecimal value, Trade trade) {
value = MapperMaths.multiply(MapperMaths.subtract(MapperMaths.divide(quotedQuantity(trade), interpolatedRate(trade)), baseQuantity(trade)), interpolatedRate(trade)).get();
return value;
}
@Override
protected MapperS extends SettlementPayout> settlementPayout(Trade trade) {
return MapperS.of(MapperS.of(trade).map("getProduct", _trade -> _trade.getProduct()).map("getEconomicTerms", nonTransferableProduct -> nonTransferableProduct.getEconomicTerms()).mapC("getPayout", economicTerms -> economicTerms.getPayout()).map("getSettlementPayout", payout -> payout.getSettlementPayout()).get());
}
@Override
protected MapperS quotedCurrency(Trade trade) {
return MapperS.of(distinct(MapperS.of(trade).mapC("getTradeLot", _trade -> _trade.getTradeLot()).mapC("getPriceQuantity", tradeLot -> tradeLot.getPriceQuantity()).mapC("getPrice", priceQuantity -> priceQuantity.getPrice()).map("Type coercion", fieldWithMetaPriceSchedule -> fieldWithMetaPriceSchedule.getValue()).map("getUnit", priceSchedule -> priceSchedule.getUnit()).map("getCurrency", unitType -> unitType.getCurrency())).get());
}
@Override
protected MapperS baseCurrency(Trade trade) {
return MapperS.of(distinct(MapperS.of(trade).mapC("getTradeLot", _trade -> _trade.getTradeLot()).mapC("getPriceQuantity", tradeLot -> tradeLot.getPriceQuantity()).mapC("getPrice", priceQuantity -> priceQuantity.getPrice()).map("Type coercion", fieldWithMetaPriceSchedule -> fieldWithMetaPriceSchedule.getValue()).map("getPerUnitOf", priceSchedule -> priceSchedule.getPerUnitOf()).map("getCurrency", unitType -> unitType.getCurrency())).get());
}
@Override
protected MapperC quantities(Trade trade) {
return MapperS.of(MapperS.of(trade).mapC("getTradeLot", _trade -> _trade.getTradeLot()).get()).mapC("getPriceQuantity", tradeLot -> tradeLot.getPriceQuantity()).mapC("getQuantity", priceQuantity -> priceQuantity.getQuantity());
}
@Override
protected MapperS quotedQuantity(Trade trade) {
final FieldWithMetaString fieldWithMetaString = quotedCurrency(trade).get();
return MapperS.of(MapperC.of(filterQuantityByCurrency.evaluate(quantities(trade).map("Type coercion", fieldWithMetaNonNegativeQuantitySchedule -> fieldWithMetaNonNegativeQuantitySchedule.getValue()).getMulti(), (fieldWithMetaString == null ? null : fieldWithMetaString.getValue()))).get()).map("getValue", quantitySchedule -> quantitySchedule.getValue());
}
@Override
protected MapperS baseQuantity(Trade trade) {
final FieldWithMetaString fieldWithMetaString = baseCurrency(trade).get();
return MapperS.of(MapperC.of(filterQuantityByCurrency.evaluate(quantities(trade).map("Type coercion", fieldWithMetaNonNegativeQuantitySchedule -> fieldWithMetaNonNegativeQuantitySchedule.getValue()).getMulti(), (fieldWithMetaString == null ? null : fieldWithMetaString.getValue()))).get()).map("getValue", quantitySchedule -> quantitySchedule.getValue());
}
@Override
protected MapperS interpolatedRate(Trade trade) {
return MapperS.of(interpolateForwardRate.evaluate(settlementPayout(trade).get()));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy