diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyByCompanyAndTcrAlreadyPresent.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyByCompanyAndTcrAlreadyPresent.java new file mode 100644 index 000000000..4ce2f42d1 --- /dev/null +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyByCompanyAndTcrAlreadyPresent.java @@ -0,0 +1,39 @@ +package ru.spcex.clearing.dflt.management.component.validation; + +import java.util.Collection; +import java.util.Optional; +import ru.clearing.classes.statics.data.misc.OrderCurrency; +import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyNewRequest; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +public class OrderCurrencyByCompanyAndTcrAlreadyPresent implements IValidationRule> { + public static final OrderCurrencyByCompanyAndTcrAlreadyPresent INSTANCE = new OrderCurrencyByCompanyAndTcrAlreadyPresent(); + + @Override + public Optional validate(ImdgValidationContext ctx) { + OrderCompanyNewRequest validatedObject = ctx.getValidatedObject(); + Imdg imdg = ctx.obtainMap(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); + ImdgPredicateBuilder pb = imdg.predicateBuilder(); + Collection orders = imdg.getCollectionObjectsByPredicate( + pb.and( + pb.equals("tradingClearingRegistryId", validatedObject.getTradingClearingRegistryId()), + pb.equals("companyId", validatedObject.getCompanyId()) + ) + ); + if (!orders.isEmpty()) { + return of(DefaultManagementErrors.RecordAlreadyPresent); + } + return empty(); + } + + @Override + public String ruleName() { + return "OrderCurrencyByCompanyAndTcrAlreadyPresent"; + } +} diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyPLBLCheck.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyPLBLCheck.java new file mode 100644 index 000000000..01c61237c --- /dev/null +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyPLBLCheck.java @@ -0,0 +1,28 @@ +package ru.spcex.clearing.dflt.management.component.validation; + +import java.util.Optional; +import ru.clearing.classes.statics.data.misc.OrderCurrency; +import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors; +import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyNewRequest; +import ru.spcex.platform.enumeration.OrderAffil; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +public class OrderCurrencyPLBLCheck implements IValidationRule> { + public static final OrderCurrencyPLBLCheck INSTANCE = new OrderCurrencyPLBLCheck(); + + @Override + public Optional validate(ImdgValidationContext ctx) { + OrderCurrency order = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency); + if (!OrderAffil.PLBL.equalsByKey(order.getType())) { + return of(DefaultManagementErrors.OnlyBalancingOrdersAllowed); + } + return empty(); + } + + @Override + public String ruleName() { + return "OrderCurrencyPLBLCheck"; + } +} diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyValidationStored.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyValidationStored.java index 6661ad587..69da78a35 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyValidationStored.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OrderCurrencyValidationStored.java @@ -1,5 +1,5 @@ package ru.spcex.clearing.dflt.management.component.validation; public enum OrderCurrencyValidationStored { - OrderCurrency, Company, TCR + OrderCurrency, OrderCurrencySpotPair, Registry, Company, TCR } diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OvernightTypeChanged.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OvernightTypeChanged.java new file mode 100644 index 000000000..062d00079 --- /dev/null +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/OvernightTypeChanged.java @@ -0,0 +1,32 @@ +package ru.spcex.clearing.dflt.management.component.validation; + +import java.util.Optional; +import ru.clearing.classes.statics.data.misc.OrderCurrency; +import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors; +import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCurrencyUpdateRequest; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +public class OvernightTypeChanged implements IValidationRule> { + public static final OvernightTypeChanged INSTANCE = new OvernightTypeChanged(); + + @Override + public Optional validate(ImdgValidationContext ctx) { + OrderCurrencyUpdateRequest validatedObject = ctx.getValidatedObject(); + OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency); + if (oc.getOvernightType() == null) { + return of(DefaultManagementErrors.GeneralError); //не понятно че с ним делать... + } + if (oc.getOvernightType().equalsIgnoreCase(validatedObject.getOvernightType())) { + return of(DefaultManagementErrors.GeneralError); //todo нормальную ошибку + } + + return empty(); + } + + @Override + public String ruleName() { + return "QuantityLotGreaterThanZero"; + } +} diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/SpotPairPresent.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/SpotPairPresent.java new file mode 100644 index 000000000..1d520d7d0 --- /dev/null +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/component/validation/SpotPairPresent.java @@ -0,0 +1,49 @@ +package ru.spcex.clearing.dflt.management.component.validation; + +import java.util.Optional; +import ru.clearing.classes.statics.data.misc.OrderCurrency; +import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCurrencyUpdateRequest; +import ru.spcex.platform.enumeration.OvernightType; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +public class SpotPairPresent implements IValidationRule> { + public static final SpotPairPresent INSTANCE = new SpotPairPresent(); + + @Override + public Optional validate(ImdgValidationContext ctx) { + OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency); + if (!OvernightType.SPOT.equalsByKey(oc.getOvernightType())) { + return empty(); + } + Imdg ocImdg = ctx.obtainMap(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); + ImdgPredicateBuilder pb = ocImdg.predicateBuilder(); + OrderCurrency pairOc = ocImdg.getSingleObjectByPredicate( + pb.and( + pb.equals("overnightType", oc.getOvernightType()), + pb.equals("registryId", oc.getRegistryId()), + pb.equals("companyId", oc.getCompanyId()), + pb.equals("tradingClearingRegistryId", oc.getTradingClearingRegistryId()), + pb.equals("counterPartyId", oc.getCounterPartyId()), + pb.not( + pb.equals("id", oc.getId()) + ) + ) + ); + if (pairOc == null) { + return of(DefaultManagementErrors.GeneralError); //todo нормальная ошибка + } + ctx.storeObject(OrderCurrencyValidationStored.OrderCurrencySpotPair, pairOc); + return empty(); + } + + @Override + public String ruleName() { + return "SpotPairPresent"; + } +} diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/ValidationConfig.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/ValidationConfig.java index fe4872282..13c8467ad 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/ValidationConfig.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/ValidationConfig.java @@ -8,10 +8,15 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.misc.Market; import ru.clearing.classes.statics.data.misc.OrderCurrency; import ru.clearing.classes.statics.data.misc.OvernightSettings; +import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.OvernightTypeDictionary; +import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyByCompanyAndTcrAlreadyPresent; +import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyPLBLCheck; import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyValidationStored; +import ru.spcex.clearing.dflt.management.component.validation.OvernightTypeChanged; import ru.spcex.clearing.dflt.management.component.validation.QuantityLotGreaterThanZero; +import ru.spcex.clearing.dflt.management.component.validation.SpotPairPresent; import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.misc.OvernightSettingsNewRequest; @@ -23,7 +28,9 @@ import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.SpecialIdPresentRule; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.api.predicate.specific.IdEqualPredicate; +import static ru.spcex.platform.imdg.api.predicate.specific.IdEqualPredicate.byId; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.LogPrefixId; import ru.spcex.platform.imdg.validation.rule.PresentById; @@ -41,6 +48,7 @@ public class ValidationConfig { private final Imdg marketImdg; private final Imdg osTypeDictionaryImdg; private final Imdg orderCurrencyImdg; + private final Imdg rgsImdg; @Autowired public ValidationConfig(ImdgProvider imdgProvider) { @@ -50,6 +58,7 @@ public class ValidationConfig { this.osTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightTypeDictionary, OvernightTypeDictionary.class); this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); this.tcrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); } public enum OvernightSettingsValidationStorage { @@ -76,7 +85,7 @@ public class ValidationConfig { SpecialIdPresentRule.instance("market", OvernightSettingsNewRequest::getMarket, "code", IMDGDistributedNames.Map_Market, - ru.clearing.classes.statics.data.misc.Market.class, + Market.class, DefaultManagementErrors.RequiredFieldIsEmpty, DefaultManagementErrors.DictionaryNotFound, true @@ -107,7 +116,7 @@ public class ValidationConfig { SpecialIdPresentRule.instance("market", OvernightSettingsUpdateRequest::getMarket, "code", IMDGDistributedNames.Map_Market, - ru.clearing.classes.statics.data.misc.Market.class, + Market.class, DefaultManagementErrors.RequiredFieldIsEmpty, DefaultManagementErrors.DictionaryNotFound, true @@ -125,8 +134,34 @@ public class ValidationConfig { ctx.setValidatedObject(req); ctx.setLogPrefix(LogPrefixId.INSTANCE); ctx.addImdg(IMDGDistributedNames.Map_OrderCurrency, orderCurrencyImdg); + ctx.addImdg(IMDGDistributedNames.Map_Registry, rgsImdg); + ctx.addImdg(IMDGDistributedNames.Map_OvernightTypeDictionary, osTypeDictionaryImdg); + + var orderCurrencyPresentById = PresentByPredicate + .builder(byId(orderCurrencyImdg.predicateBuilder(), req)) + .mapName(IMDGDistributedNames.Map_OrderCurrency) + .errorProvider(r -> recordNotFound(r.getId())) + .store(OrderCurrencyValidationStored.OrderCurrency) + .build(); + + ImdgPredicateBuilder rgsPb = rgsImdg.predicateBuilder(); + + var registryPresent = PresentByPredicate + .builder(r -> { + OrderCurrency order = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency); + return rgsPb.equals("id", order.getRegistryId()); + }) + .mapName(IMDGDistributedNames.Map_Registry) + .errorProvider(r -> { + OrderCurrency order = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency); + return recordNotFound("registry.id=" + order.getRegistryId()); + }) + .store(OrderCurrencyValidationStored.Registry) + .build(); + return new ValidatorImpl<>(ctx, - new PresentById(IMDGDistributedNames.Map_OrderCurrency, DefaultManagementErrors.DictionaryNotFound, true), + orderCurrencyPresentById, + OvernightTypeChanged.INSTANCE, DictionaryPresentRule.instance( "overnightType", OvernightSettingsNewRequest::getOvernightType, @@ -134,7 +169,9 @@ public class ValidationConfig { OvernightTypeDictionary.class, DefaultManagementErrors.RequiredFieldIsEmpty, DefaultManagementErrors.DictionaryNotFound, - true) + true), + SpotPairPresent.INSTANCE, + registryPresent ); }; } @@ -194,7 +231,9 @@ public class ValidationConfig { orderCurrencyPresent, companyPresentRule, tcrPresent, - QuantityLotGreaterThanZero.INSTANCE); + QuantityLotGreaterThanZero.INSTANCE, + OrderCurrencyByCompanyAndTcrAlreadyPresent.INSTANCE, + OrderCurrencyPLBLCheck.INSTANCE); }; } diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/error/DefaultManagementErrors.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/error/DefaultManagementErrors.java index 556adfeac..eb9777438 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/error/DefaultManagementErrors.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/error/DefaultManagementErrors.java @@ -10,6 +10,8 @@ public enum DefaultManagementErrors implements IErrorEnumId { RequiredFieldIsEmpty(3002L), DictionaryNotFound(3003L), RecordNotFound(3006L), + RecordAlreadyPresent(11002L), + OnlyBalancingOrdersAllowed(11003L), ; private final Long id; diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/OrderCurrencyListener.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/OrderCurrencyListener.java index 564c3d533..dc956c1c2 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/OrderCurrencyListener.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/OrderCurrencyListener.java @@ -1,6 +1,8 @@ package ru.spcex.clearing.dflt.management.listener; import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; import java.util.Optional; import java.util.function.Function; import org.apache.kafka.clients.consumer.Consumer; @@ -10,11 +12,15 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.misc.Listing; +import ru.clearing.classes.statics.data.misc.Market; import ru.clearing.classes.statics.data.misc.OrderCurrency; import ru.clearing.classes.statics.data.misc.OvernightSettings; import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.security.Rates; +import ru.clearing.platform.dictionary.CurrencyPairDictionary; import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyValidationStored; -import ru.spcex.clearing.dflt.management.service.OrderCurrencyService; +import ru.spcex.clearing.dflt.management.service.ImdgQueryService; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -24,11 +30,17 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.platform.enumeration.MarketType; +import ru.spcex.platform.enumeration.OvernightType; +import ru.spcex.platform.enumeration.SettleCode; +import ru.spcex.platform.enumeration.Side; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; -import ru.spcex.platform.imdg.validation.Stored; +import ru.spcex.platform.utils.collection.Pair; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.number.BigDecimalUtil; +import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD; import ru.spcex.platform.utils.validation.IValidator; @Service @@ -39,6 +51,7 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing private final Imdg orderCurrencyImdg; private final Function overnightTypeUpdateValidator; private final Function orderCompanyNewValidator; + private final ImdgQueryService imdgQueryService; private final IMessageResolver msgResolver; @Autowired @@ -46,15 +59,15 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing Producer kafkaProducer, ImdgProvider imdgProvider, UserRoleVerification userRoleVerification, - OrderCurrencyService orderCurrencyService, Function overnightTypeUpdateValidator, - Function orderCompanyNewValidator, + Function orderCompanyNewValidator, ImdgQueryService imdgQueryService, IMessageResolver msgResolver) { super(kafkaQueue, kafkaProducer); this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class); this.overnightTypeUpdateValidator = overnightTypeUpdateValidator; this.orderCompanyNewValidator = orderCompanyNewValidator; + this.imdgQueryService = imdgQueryService; this.msgResolver = msgResolver; this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); } @@ -77,15 +90,122 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing if (error.isPresent()) { return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(error.get())); } - OrderCurrency orderCurrency = validator.getStored(Stored.PresentById); - orderCurrency.setOvernightType(payload.getOvernightType()); - log.info("Updating overnight type for orderCurrency.id={} to {}", - orderCurrency.getId(), - orderCurrency.getOvernightType()); - orderCurrencyImdg.update(orderCurrency); + OrderCurrency order = validator.getStored(OrderCurrencyValidationStored.OrderCurrency); + Registry rgs = validator.getStored(OrderCurrencyValidationStored.Registry); + if (OvernightType.SWAP.equalsByKey(order.getOvernightType())) { + Pair newSpotPair = swapToSpotSplit(order, rgs); + log.info("deleting old OrderCurrency.id={}", order.getId()); + orderCurrencyImdg.delete(order); + orderCurrencyImdg.insert(newSpotPair.getFirst()); + orderCurrencyImdg.insert(newSpotPair.getSecond()); + log.info("created OrderCurrency[{}, {}]", + newSpotPair.getFirst().getId(), newSpotPair.getSecond().getId()); + } else if (OvernightType.SPOT.equalsByKey(order.getOvernightType())) { + OrderCurrency pairOrder = validator.getStored(OrderCurrencyValidationStored.OrderCurrencySpotPair); + OrderCurrency newSwapOrder = spotToSwap(order, pairOrder, rgs); + log.info("deleting old records OrderCurrency[{}, {}]", order.getId(), pairOrder.getId()); + orderCurrencyImdg.delete(order); + orderCurrencyImdg.delete(pairOrder); + orderCurrencyImdg.insert(newSwapOrder); + log.info("created OrderCurrency.id={}", newSwapOrder.getId()); + } return null; } + private Pair swapToSpotSplit(OrderCurrency swap, Registry rgs) { + OrderCurrency orderT0 = new OrderCurrency(); + OrderCurrency orderT1 = new OrderCurrency(); + + orderT0.setSettleCode(SettleCode.T0.getKey()); + orderT1.setSettleCode(SettleCode.T1.getKey()); + + if (Side.SELL.equalsByKey(swap.getSide())) { + orderT0.setSide(Side.BUY.getKey()); + orderT1.setSide(Side.SELL.getKey()); + } else { + orderT0.setSide(Side.SELL.getKey()); + orderT1.setSide(Side.BUY.getKey()); + } + + Market market = imdgQueryService.getSpotMarket(); + Listing listing = imdgQueryService.findListing(rgs, market.getCode()); + //мб возвращать вместе с листингом? + CurrencyPairDictionary currPair = imdgQueryService.getCurrencyPairDictionaryByListing(listing); + Rates rate = imdgQueryService.getRate(currPair.getBaseCurrency(), LocalDate.now()); + + var pair = new Pair<>(orderT0, orderT1); + Pair.forEach(pair, o -> { + o.setSecurityId(listing.getSecurityId()); + o.setSecuritySymbol(listing.getSymbolCode()); + o.setAccount(swap.getAccount()); + o.setTradingClearingRegistryId(swap.getTradingClearingRegistryId()); + o.setCompanyId(swap.getCompanyId()); + o.setTradingCode(swap.getTradingCode()); + o.setCounterPartyId(swap.getCounterPartyId()); + o.setCounterTradingCode(swap.getCounterTradingCode()); + o.setType(swap.getType()); + o.setOvernightType(OvernightType.SPOT.getKey()); + o.setListingId(listing.getId()); + o.setMarket(MarketType.SCSP.getKey()); + o.setRate(swap.getRate()); + o.setQuantityLot(swap.getQuantityLot()); + o.setLotSize(swap.getLotSize()); + o.setStatus(swap.getStatus()); + o.setComment(swap.getComment()); + o.setRegistryId(swap.getRegistryId()); + o.setCreated(Instant.now()); + }); + orderT0.setPrice(rate.getValue()); + orderT1.setPrice(BigDecimalUtil.safeSumBD(swap.getPrice(), rate.getValue())); + return pair; + } + + private OrderCurrency spotToSwap(OrderCurrency order1, OrderCurrency order2, Registry rgs) { + OrderCurrency spotT0; + OrderCurrency spotT1; + + if (SettleCode.T0.getKey().equals(order1.getSettleCode())) { + spotT0 = order1; + spotT1 = order2; + } else { + spotT0 = order2; + spotT1 = order1; + } + + OrderCurrency swap = new OrderCurrency(); + swap.setSettleCode(SettleCode.T1.getKey()); + if (Side.SELL.equalsByKey(spotT0.getSide())) { + swap.setSide(Side.BUY.getKey()); + } else { + swap.setSide(Side.SELL.getKey()); + } + + Market market = imdgQueryService.getSwapMarket(); + Listing listing = imdgQueryService.findListing(rgs, market.getCode()); + + swap.setSecurityId(listing.getSecurityId()); + swap.setSecuritySymbol(listing.getSymbolCode()); + swap.setAccount(order1.getAccount()); + swap.setTradingClearingRegistryId(order1.getTradingClearingRegistryId()); + swap.setCompanyId(order1.getCompanyId()); + swap.setTradingCode(order1.getTradingCode()); + swap.setCounterPartyId(order1.getCounterPartyId()); + swap.setCounterTradingCode(order1.getCounterTradingCode()); + swap.setType(order1.getType()); + swap.setOvernightType(OvernightType.SWAP.getKey()); + swap.setListingId(listing.getId()); + swap.setMarket(MarketType.SCSW.getKey()); + swap.setPrice(safeBD(spotT1.getPrice()).subtract(safeBD(spotT0.getPrice()))); + swap.setRate(order1.getRate()); + swap.setQuantityLot(order1.getQuantityLot()); + swap.setLotSize(order1.getLotSize()); + swap.setStatus(order1.getStatus()); + swap.setComment(order1.getComment()); + swap.setRegistryId(order1.getRegistryId()); + swap.setCreated(Instant.now()); + return swap; + } + private RequestInfoUpdate updateCompany(BaseRequest req) { OrderCompanyNewRequest payload = req.getRequestPayload(); IValidator validator = orderCompanyNewValidator.apply(payload); diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/ImdgQueryService.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/ImdgQueryService.java index b161170bb..150dcbc2d 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/ImdgQueryService.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/ImdgQueryService.java @@ -129,7 +129,12 @@ public class ImdgQueryService { return marketImdg.getSingleObjectByPredicate(pb.equals("marketType", MarketType.SCSW)); } - public Listing findSwapListing(Registry registry, String marketCode) { + public Market getSpotMarket() { + ImdgPredicateBuilder pb = marketImdg.predicateBuilder(); + return marketImdg.getSingleObjectByPredicate(pb.equals("marketType", MarketType.SCSP)); + } + + public Listing findListing(Registry registry, String marketCode) { return "RUB".equals(registry.getSecuritySymbol()) ? findListingForRub(registry, marketCode) : findListingForOtherCurrency(registry, marketCode); diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SpotOvernightOrderService.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SpotOvernightOrderService.java index 7dfdc7f33..5d31a4f1b 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SpotOvernightOrderService.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SpotOvernightOrderService.java @@ -37,8 +37,8 @@ public class SpotOvernightOrderService { public void process(Registry registry) { String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId()); - Market market = imdgQueryService.getSwapMarket(); - Listing listing = imdgQueryService.findSwapListing(registry, market.getCode()); + Market market = imdgQueryService.getSpotMarket(); + Listing listing = imdgQueryService.findListing(registry, market.getCode()); RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry); CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P"); CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC); diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SwapOvernightOrderService.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SwapOvernightOrderService.java index 381a84774..6925f318b 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SwapOvernightOrderService.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/service/SwapOvernightOrderService.java @@ -38,7 +38,7 @@ public class SwapOvernightOrderService { String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId()); Market market = imdgQueryService.getSwapMarket(); - Listing listing = imdgQueryService.findSwapListing(registry, market.getCode()); + Listing listing = imdgQueryService.findListing(registry, market.getCode()); RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry); CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P"); CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC); diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/OrderAffil.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/OrderAffil.java new file mode 100644 index 000000000..ed5f7db36 --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/OrderAffil.java @@ -0,0 +1,20 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum OrderAffil implements IEnumKey { + PLBL("PLBL"), + + ; + + private final String key; + + OrderAffil(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SettleCode.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SettleCode.java new file mode 100644 index 000000000..0a201c835 --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SettleCode.java @@ -0,0 +1,20 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum SettleCode implements IEnumKey { + T0("T0"), + T1("T1") + ; + + private final String key; + + SettleCode(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +}