etreschenkov 2026-04-08 21:32:29 +03:00
parent 00c2ab02c9
commit c8716d1c08
5 changed files with 577 additions and 11 deletions

View file

@ -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;
}
}

View file

@ -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<Registry> registryImdg;
private final Imdg<ClearingMemberCategory> categoryImdg;
private final Imdg<OvernightSettings> overnightSettingsImdg;
private final Imdg<CompanyRoleSet> companyRoleSetImdg;
private final Imdg<Company> companyImdg;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<CurrencyPairDictionary> currencyPairDictionaryImdg;
private final Imdg<CurrencyPairSecurity> currencyPairSecurityImdg;
private final Imdg<Listing> listingImdg;
private final Imdg<Market> marketImdg;
private final Imdg<RiskParameter> riskParameterImdg;
private final Imdg<Rates> ratesImdg;
private final DefaultManagementSettings settings;
@Autowired
public TaskListener(Consumer<String, Object> kafkaQueue,
Producer<String, Object> 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<OvernightSettingsNewRequest> newReq) {
Collection<Long> registries = orderCurrencyService.getCurrencyRegistry();
for (Long registryId : registries) {
Registry registry = registryImdg.getSingleObjectByID(registryId);
Optional<OvernightSettings> overnightSettings = orderCurrencyService.findOvernightSettingsByCompany(registry.getCompanyId());
Optional<OvernightType> 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<Long> 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<OvernightSettings> 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<Long> 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<Long> 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;
}
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}
}