From c8716d1c0834043d330d459e82bf020576ae1477 Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Wed, 8 Apr 2026 21:32:29 +0300 Subject: [PATCH] http://jira.mfd.msk:8088/browse/CLS-943 --- .../settings/DefaultManagementSettings.java | 9 + .../management/listener/TaskListener.java | 565 +++++++++++++++++- .../platform/enumeration/CompanyRole.java | 4 +- .../platform/enumeration/MarketType.java | 2 +- .../ru/spcex/platform/enumeration/Side.java | 8 + 5 files changed, 577 insertions(+), 11 deletions(-) diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/settings/DefaultManagementSettings.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/settings/DefaultManagementSettings.java index c01590b6b..e9d57d19d 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/settings/DefaultManagementSettings.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/config/settings/DefaultManagementSettings.java @@ -14,6 +14,7 @@ public class DefaultManagementSettings { private HazelcastClientParams hazelcast; private KafkaConsumerSettings kafkaConsumer; private KafkaProducerSettings kafkaProducer; + private String clearingSystem; public HazelcastClientParams getHazelcast() { return hazelcast; @@ -38,4 +39,12 @@ public class DefaultManagementSettings { public void setKafkaProducer(KafkaProducerSettings kafkaProducer) { this.kafkaProducer = kafkaProducer; } + + public String getClearingSystem() { + return clearingSystem; + } + + public void setClearingSystem(String clearingSystem) { + this.clearingSystem = clearingSystem; + } } diff --git a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/TaskListener.java b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/TaskListener.java index 3993b7878..764b9786c 100644 --- a/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/TaskListener.java +++ b/clearing-parent/default-management/src/main/java/ru/spcex/clearing/dflt/management/listener/TaskListener.java @@ -1,5 +1,9 @@ package ru.spcex.clearing.dflt.management.listener; +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; +import java.time.LocalDate; import java.util.Collection; import java.util.Optional; import org.apache.kafka.clients.consumer.Consumer; @@ -9,18 +13,35 @@ 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.company.ClearingMemberCategory; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanyRoleSet; +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.registry.TradingClearingRegistry; +import ru.clearing.classes.statics.data.security.CurrencyPairSecurity; +import ru.clearing.classes.statics.data.security.Rates; +import ru.clearing.classes.statics.data.security.RiskParameter; +import ru.clearing.platform.dictionary.CurrencyPairDictionary; +import ru.spcex.clearing.dflt.management.config.settings.DefaultManagementSettings; import ru.spcex.clearing.dflt.management.service.OrderCurrencyService; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.cud.misc.OvernightSettingsNewRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.platform.enumeration.CompanyRole; +import ru.spcex.platform.enumeration.MarketType; import ru.spcex.platform.enumeration.OvernightType; +import ru.spcex.platform.enumeration.Side; import ru.spcex.platform.enumeration.Task; +import ru.spcex.platform.enumeration.WorkflowStatus; 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.utils.enumeration.IEnumKey; @Service @@ -29,19 +50,42 @@ public class TaskListener extends QueueConsumer implements InitializingBean { private final OrderCurrencyService orderCurrencyService; private final ImdgProvider imdgProvider; private final Imdg registryImdg; + private final Imdg categoryImdg; private final Imdg overnightSettingsImdg; + private final Imdg companyRoleSetImdg; + private final Imdg companyImdg; + private final Imdg tradingClearingRegistryImdg; + private final Imdg currencyPairDictionaryImdg; + private final Imdg currencyPairSecurityImdg; + private final Imdg listingImdg; + private final Imdg marketImdg; + private final Imdg riskParameterImdg; + private final Imdg ratesImdg; + private final DefaultManagementSettings settings; @Autowired public TaskListener(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, UserRoleVerification userRoleVerification, - OrderCurrencyService orderCurrencyService) { + OrderCurrencyService orderCurrencyService, + DefaultManagementSettings settings) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class); + this.categoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + this.companyRoleSetImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + this.currencyPairDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyPairDictionary, CurrencyPairDictionary.class); + this.currencyPairSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyPairSecurity, CurrencyPairSecurity.class); + this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class); + this.riskParameterImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class); + this.ratesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Rates, Rates.class); this.orderCurrencyService = orderCurrencyService; + this.settings = settings; } @Override @@ -53,19 +97,522 @@ public class TaskListener extends QueueConsumer implements InitializingBean { } private void createOrder(BaseRequest newReq) { - Collection registries = orderCurrencyService.getCurrencyRegistry(); - for (Long registryId : registries) { - Registry registry = registryImdg.getSingleObjectByID(registryId); - Optional overnightSettings = orderCurrencyService.findOvernightSettingsByCompany(registry.getCompanyId()); - Optional overnightType = overnightSettings - .map(settings -> IEnumKey.getEnumByKey(OvernightType.class, settings.getOvernightType())); + log.info("CROR createOrder started, request={}", newReq); - if (overnightType.isPresent() && overnightType.get() == OvernightType.SPOT) { + Collection registryIds = orderCurrencyService.getCurrencyRegistry(); + if (registryIds == null || registryIds.isEmpty()) { + log.info("No registries found for CROR processing"); + return; + } - } else if (overnightType.isEmpty() || overnightType.get() == OvernightType.SWAP) { + for (Long registryId : registryIds) { + try { + Registry registry = registryImdg.getSingleObjectByID(registryId); + if (registry == null) { + log.warn("Registry not found by id={}", registryId); + continue; + } + OvernightType overnightType = resolveOvernightType(registry); + + log.info("Processing registry id={}, companyId={}, overnightType={}", + registry.getId(), registry.getCompanyId(), overnightType); + + switch (overnightType) { + case SWAP -> createSwapOrders(registry); + case SPOT -> createSpotOrders(registry); + default -> + log.warn("Unsupported overnightType={} for registry id={}", overnightType, registry.getId()); + } + } catch (Exception e) { + log.error("Error while processing registryId={}", registryId, e); } } + log.info("CROR createOrder finished"); } + + private OvernightType resolveOvernightType(Registry registry) { + Optional settingsOpt = + orderCurrencyService.findOvernightSettingsByCompany(registry.getCompanyId()); + + return settingsOpt + .map(settings -> IEnumKey.getEnumByKey(OvernightType.class, settings.getOvernightType())) + .orElse(OvernightType.SWAP); + } + + private void createSpotOrders(Registry registry) { + + } + + private void createSwapOrders(Registry registry) { + OrderCurrency primaryTransferOrder = new OrderCurrency(); + OrderCurrency counterTransferOrder = new OrderCurrency(); + OrderCurrency primaryBalancingOrder = new OrderCurrency(); + OrderCurrency counterBalancingOrder = new OrderCurrency(); + + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + ClearingMemberCategory category = categoryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("companyId", registry.getCompanyId()) + ); + String orderCategory = category.getClearingMemberCategory().equals("P") ? "PL" : "UK"; + Side primaryTransferSide = Side.SELL; + Side counterTransferSide = Side.BUY; + + Side primaryBalancingSide = Side.BUY; + Side counterBalancingSide = Side.SELL; + + if (registry.getSecuritySymbol().equals("RUB")) { + primaryTransferSide = primaryTransferSide.revers(); + counterTransferSide = counterTransferSide.revers(); + primaryBalancingSide = primaryBalancingSide.revers(); + counterBalancingSide = counterBalancingSide.revers(); + } + + Market market = marketImdg.getSingleObjectByPredicate(predicateBuilder.equals("marketType", MarketType.SCSW)); + Listing listing; + RiskParameter riskParameter; + if (registry.getSecuritySymbol().equals("RUB")) { + listing = findListingForRub(registry, market.getCode()); + riskParameter = findRiskParameterForRub(); + } else { + listing = findListingForOtherCurrency(registry, market.getCode()); + riskParameter = findRiskParameterForOtherCurrency(registry); + } + + if (orderCategory.equals("PL")) { + fillPrimaryTransferP(primaryTransferOrder, registry); + fillCounterTransferP(counterTransferOrder, registry); + fillPrimaryBalancingP(primaryBalancingOrder, registry); + fillCounterBalancingP(counterBalancingOrder, registry); + } else if (orderCategory.equals("UK")) { + fillPrimaryTransferUK(primaryTransferOrder, registry); + fillCounterTransferUK(counterTransferOrder, registry); + fillPrimaryBalancingUK(primaryBalancingOrder, registry); + fillCounterBalancingUK(counterBalancingOrder, registry); + } + + fillSwapOrder(primaryTransferOrder, registry, listing, market, riskParameter, primaryTransferSide, "overnight"); + fillSwapOrder(counterTransferOrder, registry, listing, market, riskParameter, counterTransferSide, "overnight"); + fillSwapOrder(primaryBalancingOrder, registry, listing, market, riskParameter, primaryBalancingSide, "balance"); + fillSwapOrder(counterBalancingOrder, registry, listing, market, riskParameter, counterBalancingSide, "balance"); + } + + private void fillPrimaryTransferUK(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + CompanyRoleSet companyRoleSet = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company company = companyImdg.getSingleObjectByID(companyRoleSet.getCompanyId()); + + orderCurrency.setAccount(registry.getTradingClearingRegistry()); + orderCurrency.setTradingClearingRegistryId(registry.getTradingClearingRegistryId()); + orderCurrency.setCompanyId(registry.getCompanyId()); + orderCurrency.setTradingCode(registry.getTradingCode()); + orderCurrency.setCounterPartyId(companyRoleSet.getCompanyId()); + orderCurrency.setCounterTradingCode(company.getTradingCode()); + orderCurrency.setType("CMOV"); + } + + private void fillCounterTransferUK(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + CompanyRoleSet companyRoleSet = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company company = companyImdg.getSingleObjectByID(companyRoleSet.getCompanyId()); + + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("companyId", company.getId()) + ); + + orderCurrency.setAccount(tradingClearingRegistry.getCode()); + orderCurrency.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + orderCurrency.setCompanyId(company.getId()); + orderCurrency.setTradingCode(company.getTradingCode()); + orderCurrency.setCounterPartyId(registry.getCompanyId()); + orderCurrency.setCounterTradingCode(registry.getTradingCode()); + orderCurrency.setType("CMOV"); + } + + private void fillPrimaryBalancingUK(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + ClearingMemberCategory category = categoryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("clearingMemberCategory", "P") + ); + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("companyId", category.getCompanyId()) + ); + Company company = companyImdg.getSingleObjectByID(category.getCompanyId()); + + CompanyRoleSet clccCompanyRole = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company clssCompany = companyImdg.getSingleObjectByID(category.getCompanyId()); + + orderCurrency.setAccount(tradingClearingRegistry.getCode()); + orderCurrency.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + orderCurrency.setCompanyId(company.getId()); + orderCurrency.setTradingCode(company.getTradingCode()); + orderCurrency.setCounterPartyId(clccCompanyRole.getCompanyId()); + orderCurrency.setCounterTradingCode(clssCompany.getTradingCode()); + orderCurrency.setType("CMBL"); + } + + private void fillCounterBalancingUK(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + CompanyRoleSet companyRoleSet = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company company = companyImdg.getSingleObjectByID(companyRoleSet.getCompanyId()); + + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("companyId", company.getId()) + ); + + ClearingMemberCategory categoryP = categoryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("clearingMemberCategory", "P") + ); + Company companyP = companyImdg.getSingleObjectByID(categoryP.getCompanyId()); + + orderCurrency.setAccount(tradingClearingRegistry.getCode()); + orderCurrency.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + orderCurrency.setCompanyId(company.getId()); + orderCurrency.setTradingCode(company.getTradingCode()); + orderCurrency.setCounterPartyId(categoryP.getCompanyId()); + orderCurrency.setCounterTradingCode(companyP.getTradingCode()); + orderCurrency.setType("CMBL"); + } + + + private void fillPrimaryTransferP(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + CompanyRoleSet companyRoleSet = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company company = companyImdg.getSingleObjectByID(companyRoleSet.getCompanyId()); + + orderCurrency.setAccount(registry.getTradingClearingRegistry()); + orderCurrency.setTradingClearingRegistryId(registry.getTradingClearingRegistryId()); + orderCurrency.setCompanyId(registry.getCompanyId()); + orderCurrency.setTradingCode(registry.getTradingCode()); + orderCurrency.setCounterPartyId(companyRoleSet.getCompanyId()); + orderCurrency.setCounterTradingCode(company.getTradingCode()); + orderCurrency.setType("PLOV"); + } + + private void fillCounterTransferP(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + CompanyRoleSet companyRoleSet = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company company = companyImdg.getSingleObjectByID(companyRoleSet.getCompanyId()); + + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("companyId", company.getId()) + ); + + orderCurrency.setAccount(tradingClearingRegistry.getCode()); + orderCurrency.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + orderCurrency.setCompanyId(company.getId()); + orderCurrency.setTradingCode(company.getTradingCode()); + orderCurrency.setCounterPartyId(registry.getCompanyId()); + orderCurrency.setCounterTradingCode(registry.getTradingCode()); + orderCurrency.setType("PLOV"); + } + + private void fillPrimaryBalancingP(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + CompanyRoleSet companyRoleSet = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.RGCM) + ); + Company company = companyImdg.getSingleObjectByID(companyRoleSet.getCompanyId()); + + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("companyId", company.getId()) + ); + + CompanyRoleSet clccCompanyRole = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company clssCompany = companyImdg.getSingleObjectByID(clccCompanyRole.getCompanyId()); + + orderCurrency.setAccount(tradingClearingRegistry.getCode()); + orderCurrency.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + orderCurrency.setCompanyId(company.getId()); + orderCurrency.setTradingCode(company.getTradingCode()); + orderCurrency.setCounterPartyId(clccCompanyRole.getCompanyId()); + orderCurrency.setCounterTradingCode(clssCompany.getTradingCode()); + orderCurrency.setType("PLBL"); + } + + private void fillCounterBalancingP(OrderCurrency orderCurrency, Registry registry) { + ImdgPredicateBuilder predicateBuilder = categoryImdg.predicateBuilder(); + CompanyRoleSet companyRoleSet = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.CLCC) + ); + Company company = companyImdg.getSingleObjectByID(companyRoleSet.getCompanyId()); + + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getFirstObjectByPredicate( + predicateBuilder.equals("companyId", company.getId()) + ); + + CompanyRoleSet rgcmCompanyRole = companyRoleSetImdg.getSingleObjectByPredicate( + predicateBuilder.equals("companyRole", CompanyRole.RGCM) + ); + Company rgcmCompany = companyImdg.getSingleObjectByID(rgcmCompanyRole.getCompanyId()); + + orderCurrency.setAccount(tradingClearingRegistry.getCode()); + orderCurrency.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + orderCurrency.setCompanyId(company.getId()); + orderCurrency.setTradingCode(company.getTradingCode()); + orderCurrency.setCounterPartyId(rgcmCompanyRole.getCompanyId()); + orderCurrency.setCounterTradingCode(rgcmCompany.getTradingCode()); + orderCurrency.setType("PLBL"); + + } + + private void fillSwapOrder(OrderCurrency orderCurrency, + Registry registry, + Listing listing, + Market market, + RiskParameter riskParameter, + Side side, + String comment) { + orderCurrency.setOvernightType("SWAP"); + orderCurrency.setMarket(market.getCode()); + orderCurrency.setListingId(listing.getId()); + orderCurrency.setSecuritySymbol(listing.getSymbolCode()); + orderCurrency.setSecurityId(listing.getSecurityId()); + orderCurrency.setLotSize(listing.getLotSize()); + orderCurrency.setRate(riskParameter.getQuoteValue()); + orderCurrency.setSide(side.getKey()); + orderCurrency.setSettleCode("T1"); + orderCurrency.setStatus("CRET"); + orderCurrency.setComment(comment); + orderCurrency.setRegistryId(registry.getId()); + } + + private Listing findListingForRub(Registry registry, String market) { + ImdgPredicateBuilder predicateBuilder = currencyPairDictionaryImdg.predicateBuilder(); + CurrencyPairDictionary currencyPairDictionary = currencyPairDictionaryImdg.getFirstObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("baseCurrency", "CNY"), + predicateBuilder.equals("quoteCurrency", registry.getSecuritySymbol()) + )); + Collection securitiesIds = currencyPairSecurityImdg.getCollectionIdsByPredicate( + predicateBuilder.equals("currencyPairId", currencyPairDictionary.getId()) + ); + Listing listing = listingImdg.getSingleObjectByPredicate( + predicateBuilder.and( + predicateBuilder.in("securityId", securitiesIds.toArray(new Long[0])), + predicateBuilder.equals("market", market) + ) + ); + return listing; + } + + private Listing findListingForOtherCurrency(Registry registry, String market) { + ImdgPredicateBuilder predicateBuilder = currencyPairDictionaryImdg.predicateBuilder(); + CurrencyPairDictionary currencyPairDictionary = currencyPairDictionaryImdg.getFirstObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("baseCurrency", registry.getSecuritySymbol()), + predicateBuilder.equals("quoteCurrency", "RUB") + )); + Collection securitiesIds = currencyPairSecurityImdg.getCollectionIdsByPredicate( + predicateBuilder.equals("currencyPairId", currencyPairDictionary.getId()) + ); + Listing listing = listingImdg.getSingleObjectByPredicate( + predicateBuilder.and( + predicateBuilder.in("securityId", securitiesIds.toArray(new Long[0])), + predicateBuilder.equals("market", market) + ) + ); + return listing; + } + + private RiskParameter findRiskParameterForRub() { + ImdgPredicateBuilder predicateBuilder = currencyPairDictionaryImdg.predicateBuilder(); + CurrencyPairDictionary currencyPairDictionary = currencyPairDictionaryImdg.getFirstObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("baseCurrency", "CNY") + )); + return riskParameterImdg.getSingleObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("currencyPairId", currencyPairDictionary.getId()), + predicateBuilder.equals("settlementType", "T0") + ) + ); + } + + private RiskParameter findRiskParameterForOtherCurrency(Registry registry) { + ImdgPredicateBuilder predicateBuilder = currencyPairDictionaryImdg.predicateBuilder(); + CurrencyPairDictionary currencyPairDictionary = currencyPairDictionaryImdg.getFirstObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("baseCurrency", registry.getSecuritySymbol()) + )); + return riskParameterImdg.getSingleObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("currencyPairId", currencyPairDictionary.getId()), + predicateBuilder.equals("settlementType", "T0") + ) + ); + } + + private static final MathContext MC = new MathContext(20, RoundingMode.HALF_UP); + + //registry.securitySymbol != 'RUB' + private CalculationResultHolder calculationSwapSums(Registry registry, Integer lotSize, BigDecimal s, BigDecimal n) { + BigDecimal planPosition = registry.getBalance(); + BigDecimal sum1 = planPosition.abs(); + + Registry amtRubRegistry = findAmtRegistry(registry, "RUB"); + BigDecimal planPositionRub = amtRubRegistry.getBalance(); + + Rates rates = findRates(registry); + BigDecimal ratesValue = rates.getValue(); + + BigDecimal sum2 = planPositionRub.divide(ratesValue, lotSize, RoundingMode.HALF_DOWN); + + BigDecimal ceilSum1 = sum1.setScale(0, RoundingMode.CEILING); + BigDecimal sum3 = ceilSum1.min(sum2); + BigDecimal sum4 = sum3 + .multiply(ratesValue, MC) + .negate(); + BigDecimal sum5 = sum3.negate(); + + BigDecimal daysInYear = BigDecimal.valueOf(365); + // (S / 365) * n + BigDecimal carryPart = s.divide(daysInYear, MC).multiply(n, MC); + // 1 + S / 365 * n + BigDecimal multiplier = BigDecimal.ONE.add(carryPart, MC); + + BigDecimal sum6 = sum3 + .multiply(ratesValue, MC) + .multiply(multiplier, MC); + return new CalculationResultHolder(sum1, sum2, sum3, sum4, sum5, sum6); + } + + //registry.securitySymbol == 'RUB' + private CalculationResultHolder calculationSwapRubSums(Registry registry, Integer lotSize, BigDecimal s, BigDecimal n) { + BigDecimal planPosition = registry.getBalance(); + Rates cnyRates = findRates(registry); + BigDecimal ratesValue = cnyRates.getValue(); + BigDecimal sum1 = planPosition.divide(ratesValue, MC); + + Registry amtRubRegistry = findAmtRegistry(registry, "CNY"); + BigDecimal planPositionCny = amtRubRegistry.getBalance(); + + BigDecimal sum2 = planPositionCny.divide(ratesValue, lotSize, RoundingMode.HALF_DOWN); + + BigDecimal ceilSum1 = sum1.setScale(0, RoundingMode.CEILING); + BigDecimal sum3 = ceilSum1.min(sum2).negate(); + BigDecimal sum4 = sum3 + .multiply(ratesValue, MC) + .negate(); + BigDecimal sum5 = sum3.negate(); + + BigDecimal daysInYear = BigDecimal.valueOf(365); + // (S / 365) * n + BigDecimal carryPart = s.divide(daysInYear, MC).multiply(n, MC); + // 1 + S / 365 * n + BigDecimal multiplier = BigDecimal.ONE.add(carryPart, MC); + + BigDecimal sum6 = sum3 + .multiply(ratesValue, MC) + .multiply(multiplier, MC); + return new CalculationResultHolder(sum1, sum2, sum3, sum4, sum5, sum6); + } + + private Registry findAmtRegistry(Registry registry, String securitySymbol) { + ImdgPredicateBuilder predicateBuilder = registryImdg.predicateBuilder(); + return registryImdg.getSingleObjectByPredicate( + predicateBuilder.and( + predicateBuilder.regex("registryCode", "^PM.*T"), + predicateBuilder.equals("securitySymbol", securitySymbol), + predicateBuilder.equals("tradingClearingRegistryId", registry.getId()), + predicateBuilder.equals("companyId", registry.getCompanyId()) + ) + ); + } + + private Rates findRates(Registry registry) { + ImdgPredicateBuilder predicateBuilder = registryImdg.predicateBuilder(); + return ratesImdg.getSingleObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("currency", registry.getSecuritySymbol()), + predicateBuilder.equals("valueDate", LocalDate.now()), + predicateBuilder.equals("workflowStatus", WorkflowStatus.Active.getKey()) + ) + ); + } + + private Rates findCnyRates(Registry registry) { + ImdgPredicateBuilder predicateBuilder = registryImdg.predicateBuilder(); + return ratesImdg.getSingleObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("currency", "CNY"), + predicateBuilder.equals("valueDate", LocalDate.now()), + predicateBuilder.equals("workflowStatus", WorkflowStatus.Active.getKey()) + ) + ); + } + + public static BigDecimal ceilMath(BigDecimal value, BigDecimal significance) { + if (significance == null || significance.compareTo(BigDecimal.ZERO) <= 0) { + throw new IllegalArgumentException("significance must be > 0"); + } + if (value == null) { + throw new IllegalArgumentException("value must not be null"); + } + + BigDecimal divided = value.divide(significance, 0, RoundingMode.CEILING); + return divided.multiply(significance); + } + + public static class CalculationResultHolder { + private BigDecimal sum1; + private BigDecimal sum2; + private BigDecimal sum3; + private BigDecimal sum4; + private BigDecimal sum5; + private BigDecimal sum6; + + public CalculationResultHolder(BigDecimal sum1, + BigDecimal sum2, + BigDecimal sum3, + BigDecimal sum4, + BigDecimal sum5, + BigDecimal sum6) { + this.sum1 = sum1; + this.sum2 = sum2; + this.sum3 = sum3; + this.sum4 = sum4; + this.sum5 = sum5; + this.sum6 = sum6; + } + + public BigDecimal getSum1() { + return sum1; + } + + public BigDecimal getSum2() { + return sum2; + } + + public BigDecimal getSum3() { + return sum3; + } + + public BigDecimal getSum4() { + return sum4; + } + + public BigDecimal getSum5() { + return sum5; + } + + public BigDecimal getSum6() { + return sum6; + } + } } diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanyRole.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanyRole.java index dd573885b..383b6ee37 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanyRole.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanyRole.java @@ -4,7 +4,9 @@ import ru.spcex.platform.utils.enumeration.IEnumKey; public enum CompanyRole implements IEnumKey { ODEP("ODEP"), - SETH("SETH") + SETH("SETH"), + RGCM("RGCM"), + CLCC("CLCC") ; private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java index cc338474d..1c8786c62 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum MarketType implements IEnumKey { - PRMR("PRMR"), SCND("SCND"); + PRMR("PRMR"), SCND("SCND"), SCSW("SCSW"), SCSP("SCSP"); private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java index 2efb0196d..8ddd75924 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java @@ -28,4 +28,12 @@ public enum Side implements IEnumKey, ISide { public boolean isSell() { return equals(SELL); } + + public Side revers() { + if (isBuy()) { + return SELL; + } else { + return BUY; + } + } }