cdm.event.common.functions.Create_QuantityChange Maven / Gradle / Ivy
package cdm.event.common.functions;
import cdm.base.math.NonNegativeQuantitySchedule;
import cdm.base.math.QuantityChangeDirectionEnum;
import cdm.base.math.metafields.FieldWithMetaNonNegativeQuantitySchedule;
import cdm.base.staticdata.identifier.Identifier;
import cdm.base.staticdata.party.AncillaryParty;
import cdm.base.staticdata.party.Counterparty;
import cdm.event.common.QuantityChangeInstruction;
import cdm.event.common.Trade;
import cdm.event.common.TradeState;
import cdm.event.common.TradeState.TradeStateBuilder;
import cdm.event.position.PositionStatusEnum;
import cdm.observable.asset.PriceSchedule;
import cdm.observable.asset.PriceTypeEnum;
import cdm.observable.asset.metafields.FieldWithMetaPriceSchedule;
import cdm.product.common.NotionalAdjustmentEnum;
import cdm.product.common.settlement.PriceQuantity;
import cdm.product.common.settlement.functions.UpdateAmountForEachMatchingQuantity;
import cdm.product.template.Product;
import cdm.product.template.TradableProduct;
import cdm.product.template.TradeLot;
import cdm.product.template.functions.AddTradeLot;
import cdm.product.template.functions.FilterTradeLot;
import cdm.product.template.functions.MergeTradeLot;
import com.google.inject.ImplementedBy;
import com.rosetta.model.lib.expression.CardinalityOperator;
import com.rosetta.model.lib.functions.ConditionValidator;
import com.rosetta.model.lib.functions.ModelObjectValidator;
import com.rosetta.model.lib.functions.RosettaFunction;
import com.rosetta.model.lib.mapper.Mapper;
import com.rosetta.model.lib.mapper.MapperC;
import com.rosetta.model.lib.mapper.MapperS;
import com.rosetta.model.lib.mapper.MapperUtils;
import java.math.BigDecimal;
import java.util.Optional;
import javax.inject.Inject;
import static com.rosetta.model.lib.expression.ExpressionOperators.*;
@ImplementedBy(Create_QuantityChange.Create_QuantityChangeDefault.class)
public abstract class Create_QuantityChange implements RosettaFunction {
@Inject protected ConditionValidator conditionValidator;
@Inject protected ModelObjectValidator objectValidator;
// RosettaFunction dependencies
//
@Inject protected AddTradeLot addTradeLot;
@Inject protected FilterTradeLot filterTradeLot;
@Inject protected MergeTradeLot mergeTradeLot;
@Inject protected UpdateAmountForEachMatchingQuantity updateAmountForEachMatchingQuantity;
/**
* @param instruction
* @param tradeState
* @return quantityChange
*/
public TradeState evaluate(QuantityChangeInstruction instruction, TradeState tradeState) {
// pre-conditions
conditionValidator.validate(() ->
MapperUtils.toComparisonResult(MapperUtils.runSingle(() -> {
if (areEqual(MapperS.of(instruction).map("getDirection", quantityChangeInstruction -> quantityChangeInstruction.getDirection()), MapperS.of(QuantityChangeDirectionEnum.DECREASE), CardinalityOperator.All).and(exists(MapperS.of(instruction).mapC("getChange", quantityChangeInstruction -> quantityChangeInstruction.getChange()).mapC("getPrice", priceQuantity -> priceQuantity.getPrice()).map("getValue", _f->_f.getValue()))).getOrDefault(false)) {
return areEqual(MapperS.of(instruction).mapC("getChange", quantityChangeInstruction -> quantityChangeInstruction.getChange()).mapC("getPrice", priceQuantity -> priceQuantity.getPrice()).map("getValue", _f->_f.getValue()).map("getPriceType", priceSchedule -> priceSchedule.getPriceType()), MapperS.of(PriceTypeEnum.CASH_PRICE), CardinalityOperator.All);
}
else {
return null;
}
})),
"Only termination where the termination price is specified as a cash price is supported for now.");
TradeState.TradeStateBuilder quantityChangeBuilder = doEvaluate(instruction, tradeState);
final TradeState quantityChange;
if (quantityChangeBuilder == null) {
quantityChange = null;
} else {
quantityChange = quantityChangeBuilder.build();
objectValidator.validate(TradeState.class, quantityChange);
}
return quantityChange;
}
protected abstract TradeState.TradeStateBuilder doEvaluate(QuantityChangeInstruction instruction, TradeState tradeState);
protected abstract Mapper extends TradableProduct> tradableProduct(QuantityChangeInstruction instruction, TradeState tradeState);
protected abstract Mapper extends TradeLot> tradeLot(QuantityChangeInstruction instruction, TradeState tradeState);
protected abstract Mapper extends PriceQuantity> newPriceQuantity(QuantityChangeInstruction instruction, TradeState tradeState);
protected abstract Mapper extends TradeLot> newTradeLots(QuantityChangeInstruction instruction, TradeState tradeState);
public static class Create_QuantityChangeDefault extends Create_QuantityChange {
@Override
protected TradeState.TradeStateBuilder doEvaluate(QuantityChangeInstruction instruction, TradeState tradeState) {
TradeState.TradeStateBuilder quantityChange = TradeState.builder();
return assignOutput(quantityChange, instruction, tradeState);
}
protected TradeState.TradeStateBuilder assignOutput(TradeState.TradeStateBuilder quantityChange, QuantityChangeInstruction instruction, TradeState tradeState) {
quantityChange = toBuilder(MapperS.of(tradeState).get());
quantityChange
.getOrCreateTrade()
.setTradableProduct(MapperS.of(TradableProduct.builder()
.setProduct(MapperS.of(tradableProduct(instruction, tradeState).get()).map("getProduct", _tradableProduct -> _tradableProduct.getProduct()).get())
.setTradeLot(MapperC.of(newTradeLots(instruction, tradeState).getMulti()).getMulti())
.setCounterparty(MapperS.of(tradableProduct(instruction, tradeState).get()).mapC("getCounterparty", _tradableProduct -> _tradableProduct.getCounterparty()).getMulti())
.setAncillaryParty(MapperS.of(tradableProduct(instruction, tradeState).get()).mapC("getAncillaryParty", _tradableProduct -> _tradableProduct.getAncillaryParty()).getMulti())
.setAdjustment(MapperS.of(tradableProduct(instruction, tradeState).get()).map("getAdjustment", _tradableProduct -> _tradableProduct.getAdjustment()).get())
.build())
.get());
quantityChange
.getOrCreateState()
.setPositionState(MapperUtils.runSingle(() -> {
if (areEqual(MapperC.of(newTradeLots(instruction, tradeState).getMulti()).mapC("getPriceQuantity", _tradeLot -> _tradeLot.getPriceQuantity()).mapC("getQuantity", priceQuantity -> priceQuantity.getQuantity()).map("getValue", _f->_f.getValue()).map("getValue", measureBase -> measureBase.getValue()), MapperS.of(Integer.valueOf(0)), CardinalityOperator.All).getOrDefault(false)) {
return MapperS.of(PositionStatusEnum.CLOSED);
}
else {
return null;
}
}).get());
return Optional.ofNullable(quantityChange)
.map(o -> o.prune())
.orElse(null);
}
@Override
protected Mapper extends TradableProduct> tradableProduct(QuantityChangeInstruction instruction, TradeState tradeState) {
return MapperS.of(tradeState).map("getTrade", _tradeState -> _tradeState.getTrade()).map("getTradableProduct", trade -> trade.getTradableProduct());
}
@Override
protected Mapper extends TradeLot> tradeLot(QuantityChangeInstruction instruction, TradeState tradeState) {
return MapperUtils.runSinglePolymorphic(() -> {
if (notEqual(MapperS.of(instruction).map("getDirection", quantityChangeInstruction -> quantityChangeInstruction.getDirection()), MapperS.of(QuantityChangeDirectionEnum.INCREASE), CardinalityOperator.Any).getOrDefault(false)) {
return MapperUtils.runSinglePolymorphic(() -> {
if (exists(MapperS.of(instruction).mapC("getLotIdentifier", quantityChangeInstruction -> quantityChangeInstruction.getLotIdentifier())).getOrDefault(false)) {
return MapperS.of(MapperC.of(filterTradeLot.evaluate(MapperS.of(tradableProduct(instruction, tradeState).get()).mapC("getTradeLot", _tradableProduct -> _tradableProduct.getTradeLot()).getMulti(), MapperS.of(instruction).mapC("getLotIdentifier", quantityChangeInstruction -> quantityChangeInstruction.getLotIdentifier()).getMulti())).get());
}
else {
return MapperS.of(MapperS.of(tradableProduct(instruction, tradeState).get()).mapC("getTradeLot", _tradableProduct -> _tradableProduct.getTradeLot()).get());
}
});
}
else {
return null;
}
});
}
@Override
protected Mapper extends PriceQuantity> newPriceQuantity(QuantityChangeInstruction instruction, TradeState tradeState) {
return MapperUtils.runMultiPolymorphic(() -> {
if (areEqual(MapperS.of(instruction).map("getDirection", quantityChangeInstruction -> quantityChangeInstruction.getDirection()), MapperS.of(QuantityChangeDirectionEnum.INCREASE), CardinalityOperator.All).getOrDefault(false)) {
return MapperS.of(instruction).mapC("getChange", quantityChangeInstruction -> quantityChangeInstruction.getChange());
}
else {
return MapperC.of(updateAmountForEachMatchingQuantity.evaluate(MapperS.of(tradeLot(instruction, tradeState).get()).mapC("getPriceQuantity", _tradeLot -> _tradeLot.getPriceQuantity()).getMulti(), MapperS.of(instruction).mapC("getChange", quantityChangeInstruction -> quantityChangeInstruction.getChange()).getMulti(), MapperS.of(instruction).map("getDirection", quantityChangeInstruction -> quantityChangeInstruction.getDirection()).get()));
}
});
}
@Override
protected Mapper extends TradeLot> newTradeLots(QuantityChangeInstruction instruction, TradeState tradeState) {
return MapperUtils.runMultiPolymorphic(() -> {
if (areEqual(MapperS.of(instruction).map("getDirection", quantityChangeInstruction -> quantityChangeInstruction.getDirection()), MapperS.of(QuantityChangeDirectionEnum.INCREASE), CardinalityOperator.All).getOrDefault(false)) {
return MapperS.of(addTradeLot.evaluate(MapperS.of(tradableProduct(instruction, tradeState).get()).get(), MapperS.of(TradeLot.builder()
.setLotIdentifier(MapperS.of(instruction).mapC("getLotIdentifier", quantityChangeInstruction -> quantityChangeInstruction.getLotIdentifier()).getMulti())
.setPriceQuantity(MapperC.of(newPriceQuantity(instruction, tradeState).getMulti()).getMulti())
.build())
.get())).mapC("getTradeLot", _tradableProduct -> _tradableProduct.getTradeLot());
}
else {
return MapperC.of(mergeTradeLot.evaluate(MapperS.of(tradableProduct(instruction, tradeState).get()).mapC("getTradeLot", _tradableProduct -> _tradableProduct.getTradeLot()).getMulti(), MapperS.of(TradeLot.builder()
.setLotIdentifier(MapperS.of(instruction).mapC("getLotIdentifier", quantityChangeInstruction -> quantityChangeInstruction.getLotIdentifier()).getMulti())
.setPriceQuantity(MapperC.of(newPriceQuantity(instruction, tradeState).getMulti()).getMulti())
.build())
.get()));
}
});
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy