some refactoring
This commit is contained in:
parent
c16bf5ea3b
commit
3e2c1cf629
10 changed files with 966 additions and 612 deletions
|
|
@ -1,10 +1,5 @@
|
||||||
package ru.spcex.clearing.dflt.management.listener;
|
package ru.spcex.clearing.dflt.management.listener;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.MathContext;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.time.DayOfWeek;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.apache.kafka.clients.consumer.Consumer;
|
import org.apache.kafka.clients.consumer.Consumer;
|
||||||
|
|
@ -14,83 +9,41 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
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.misc.OvernightSettings;
|
||||||
import ru.clearing.classes.statics.data.registry.Registry;
|
import ru.clearing.classes.statics.data.registry.Registry;
|
||||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
import ru.spcex.clearing.dflt.management.service.ImdgQueryService;
|
||||||
import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
|
import ru.spcex.clearing.dflt.management.service.SpotOvernightOrderService;
|
||||||
import ru.clearing.classes.statics.data.security.CurrencyPairSecurity;
|
import ru.spcex.clearing.dflt.management.service.SwapOvernightOrderService;
|
||||||
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.imdg.IMDGDistributedNames;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.misc.OvernightSettingsNewRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.misc.OvernightSettingsNewRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
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.DayStatus;
|
|
||||||
import ru.spcex.platform.enumeration.MarketType;
|
|
||||||
import ru.spcex.platform.enumeration.OvernightType;
|
import ru.spcex.platform.enumeration.OvernightType;
|
||||||
import ru.spcex.platform.enumeration.Side;
|
|
||||||
import ru.spcex.platform.enumeration.Task;
|
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.Imdg;
|
||||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
|
||||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TaskListener extends QueueConsumer implements InitializingBean {
|
public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
private final OrderCurrencyService orderCurrencyService;
|
private final ImdgQueryService imdgQueryService;
|
||||||
private final ImdgProvider imdgProvider;
|
|
||||||
private final Imdg<Registry> registryImdg;
|
private final Imdg<Registry> registryImdg;
|
||||||
private final Imdg<ClearingMemberCategory> categoryImdg;
|
private final SwapOvernightOrderService swapOvernightOrderService;
|
||||||
private final Imdg<OvernightSettings> overnightSettingsImdg;
|
private final SpotOvernightOrderService spotOvernightOrderService;
|
||||||
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 Imdg<ClearingCalendar> clearingCalendarImdg;
|
|
||||||
private final DefaultManagementSettings settings;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public TaskListener(Consumer<String, Object> kafkaQueue,
|
public TaskListener(Consumer<String, Object> kafkaQueue,
|
||||||
Producer<String, Object> kafkaProducer,
|
Producer<String, Object> kafkaProducer,
|
||||||
|
ImdgQueryService imdgQueryService,
|
||||||
ImdgProvider imdgProvider,
|
ImdgProvider imdgProvider,
|
||||||
UserRoleVerification userRoleVerification,
|
SwapOvernightOrderService swapOvernightOrderService,
|
||||||
OrderCurrencyService orderCurrencyService,
|
SpotOvernightOrderService spotOvernightOrderService) {
|
||||||
DefaultManagementSettings settings) {
|
|
||||||
super(kafkaQueue, kafkaProducer);
|
super(kafkaQueue, kafkaProducer);
|
||||||
this.imdgProvider = imdgProvider;
|
this.imdgQueryService = imdgQueryService;
|
||||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||||
this.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class);
|
this.swapOvernightOrderService = swapOvernightOrderService;
|
||||||
this.categoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
this.spotOvernightOrderService = spotOvernightOrderService;
|
||||||
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.clearingCalendarImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingCalendar, ClearingCalendar.class);
|
|
||||||
this.orderCurrencyService = orderCurrencyService;
|
|
||||||
this.settings = settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -104,7 +57,7 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
private void createOrder(BaseRequest<OvernightSettingsNewRequest> newReq) {
|
private void createOrder(BaseRequest<OvernightSettingsNewRequest> newReq) {
|
||||||
log.info("CROR createOrder started, request={}", newReq);
|
log.info("CROR createOrder started, request={}", newReq);
|
||||||
|
|
||||||
Collection<Long> registryIds = orderCurrencyService.getCurrencyRegistry();
|
Collection<Long> registryIds = imdgQueryService.getCurrencyRegistry();
|
||||||
if (registryIds == null || registryIds.isEmpty()) {
|
if (registryIds == null || registryIds.isEmpty()) {
|
||||||
log.info("No registries found for CROR processing");
|
log.info("No registries found for CROR processing");
|
||||||
return;
|
return;
|
||||||
|
|
@ -119,13 +72,12 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
OvernightType overnightType = resolveOvernightType(registry);
|
OvernightType overnightType = resolveOvernightType(registry);
|
||||||
|
|
||||||
log.info("Processing registry id={}, companyId={}, overnightType={}",
|
log.info("Processing registry id={}, companyId={}, overnightType={}",
|
||||||
registry.getId(), registry.getCompanyId(), overnightType);
|
registry.getId(), registry.getCompanyId(), overnightType);
|
||||||
|
|
||||||
switch (overnightType) {
|
switch (overnightType) {
|
||||||
case SWAP -> createSwapOrders(registry);
|
case SWAP -> swapOvernightOrderService.process(registry);
|
||||||
case SPOT -> createSpotOrders(registry);
|
case SPOT -> spotOvernightOrderService.process(registry);
|
||||||
default ->
|
default ->
|
||||||
log.warn("Unsupported overnightType={} for registry id={}", overnightType, registry.getId());
|
log.warn("Unsupported overnightType={} for registry id={}", overnightType, registry.getId());
|
||||||
}
|
}
|
||||||
|
|
@ -139,558 +91,10 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
|
|
||||||
private OvernightType resolveOvernightType(Registry registry) {
|
private OvernightType resolveOvernightType(Registry registry) {
|
||||||
Optional<OvernightSettings> settingsOpt =
|
Optional<OvernightSettings> settingsOpt =
|
||||||
orderCurrencyService.findOvernightSettingsByCompany(registry.getCompanyId());
|
imdgQueryService.findOvernightSettingsByCompany(registry.getCompanyId());
|
||||||
|
|
||||||
return settingsOpt
|
return settingsOpt
|
||||||
.map(settings -> IEnumKey.getEnumByKey(OvernightType.class, settings.getOvernightType()))
|
.map(settings -> IEnumKey.getEnumByKey(OvernightType.class, settings.getOvernightType()))
|
||||||
.orElse(OvernightType.SWAP);
|
.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) {
|
|
||||||
CurrencyPairSecurity currencyPairSecurity = currencyPairSecurityImdg.getSingleObjectByID(listing.getSecurityId());
|
|
||||||
CurrencyPairDictionary currencyPairDictionary = currencyPairDictionaryImdg
|
|
||||||
.getSingleObjectByID(currencyPairSecurity.getCurrencyPairId());
|
|
||||||
|
|
||||||
BigDecimal s = defineTransferRate(currencyPairDictionary.getId(), registry.getSecuritySymbol());
|
|
||||||
BigDecimal n = numberOfDaysOfTransfer();
|
|
||||||
CalculationResultHolder resultHolder = calculationSwapSums(registry, listing.getLotSize().intValue(), s, n);
|
|
||||||
BigDecimal quantityLot = resultHolder.getSum3().abs();
|
|
||||||
BigDecimal price = swapPriceCalc(currencyPairDictionary.getBaseCurrency(), s, n);
|
|
||||||
|
|
||||||
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());
|
|
||||||
orderCurrency.setPrice(price);
|
|
||||||
orderCurrency.setQuantityLot(quantityLot);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.getSecuritySymbol());
|
|
||||||
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.getSecuritySymbol());
|
|
||||||
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(String securitySymbol) {
|
|
||||||
ImdgPredicateBuilder predicateBuilder = registryImdg.predicateBuilder();
|
|
||||||
return ratesImdg.getSingleObjectByPredicate(
|
|
||||||
predicateBuilder.and(
|
|
||||||
predicateBuilder.equals("currency", securitySymbol),
|
|
||||||
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())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal swapPriceCalc(String baseCurrency, BigDecimal s, BigDecimal n) {
|
|
||||||
LocalDate now = LocalDate.now();
|
|
||||||
ImdgPredicateBuilder predicateBuilder = ratesImdg.predicateBuilder();
|
|
||||||
BigDecimal daysInYear = BigDecimal.valueOf(365);
|
|
||||||
|
|
||||||
Rates rates = ratesImdg.getSingleObjectByPredicate(
|
|
||||||
predicateBuilder.and(
|
|
||||||
predicateBuilder.equals("currency", baseCurrency),
|
|
||||||
predicateBuilder.equals("valueDate", now),
|
|
||||||
predicateBuilder.equals("workflowStatus", WorkflowStatus.Active.getKey())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
BigDecimal rateValue = rates.getValue();
|
|
||||||
return rateValue.multiply(s, MC).multiply(n, MC).divide(daysInYear, MC);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal defineTransferRate(Long currencyPairDictionaryId, String securitySymbol) {
|
|
||||||
ImdgPredicateBuilder predicateBuilder = riskParameterImdg.predicateBuilder();
|
|
||||||
String securitySymbolCondition = securitySymbol.equals("RUB") ? "CNY" : securitySymbol;
|
|
||||||
RiskParameter riskParameter = riskParameterImdg.getSingleObjectByPredicate(
|
|
||||||
predicateBuilder.and(
|
|
||||||
predicateBuilder.equals("settlementType", "T0"),
|
|
||||||
predicateBuilder.equals("currencyPairId", currencyPairDictionaryId),
|
|
||||||
predicateBuilder.equals("baseCurrency", securitySymbolCondition)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return riskParameter.getQuoteValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal numberOfDaysOfTransfer() {
|
|
||||||
LocalDate nextWorkingDay = findNextWorkingDate();
|
|
||||||
return BigDecimal.valueOf(nextWorkingDay.compareTo(LocalDate.now()));
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LocalDate findNextWorkingDate() {
|
|
||||||
LocalDate checkingDate = LocalDate.now().plusDays(1);
|
|
||||||
|
|
||||||
ImdgPredicateBuilder predicateBuilder = clearingCalendarImdg.predicateBuilder();
|
|
||||||
while (true) {
|
|
||||||
ClearingCalendar clearingCalendar = clearingCalendarImdg.getFirstObjectByPredicate(
|
|
||||||
predicateBuilder.equals("clearingDate", checkingDate)
|
|
||||||
);
|
|
||||||
DayOfWeek dayOfWeek = checkingDate.getDayOfWeek();
|
|
||||||
if (isWeekday(dayOfWeek)) {
|
|
||||||
if (clearingCalendar != null && DayStatus.Workday.equalsByKey(clearingCalendar.getDayStatus())) {
|
|
||||||
return checkingDate;
|
|
||||||
}
|
|
||||||
checkingDate = checkingDate.plusDays(1);
|
|
||||||
} else {
|
|
||||||
if (clearingCalendar != null && DayStatus.DayOff.equalsByKey(clearingCalendar.getDayStatus())) {
|
|
||||||
checkingDate = checkingDate.plusDays(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return checkingDate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isWeekday(DayOfWeek dayOfWeek) {
|
|
||||||
return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.model;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
public record CalculationResult(
|
||||||
|
BigDecimal sum1,
|
||||||
|
BigDecimal sum2,
|
||||||
|
BigDecimal sum3,
|
||||||
|
BigDecimal sum4,
|
||||||
|
BigDecimal sum5,
|
||||||
|
BigDecimal sum6
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.model;
|
||||||
|
|
||||||
|
public record CounterpartyInfo(
|
||||||
|
Long companyId,
|
||||||
|
String tradingCode,
|
||||||
|
Long registryId,
|
||||||
|
String registryCode
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.model;
|
||||||
|
|
||||||
|
import ru.clearing.classes.statics.data.misc.Listing;
|
||||||
|
import ru.clearing.classes.statics.data.misc.Market;
|
||||||
|
import ru.clearing.classes.statics.data.registry.Registry;
|
||||||
|
import ru.clearing.classes.statics.data.security.RiskParameter;
|
||||||
|
|
||||||
|
public class SwapContext {
|
||||||
|
private final Registry registry;
|
||||||
|
private final String orderCategory;
|
||||||
|
private final Market market;
|
||||||
|
private final Listing listing;
|
||||||
|
private final RiskParameter riskParameter;
|
||||||
|
private final CounterpartyInfo categoryP;
|
||||||
|
private final CounterpartyInfo clcc;
|
||||||
|
private final CounterpartyInfo rgcm;
|
||||||
|
|
||||||
|
private SwapContext(Builder builder) {
|
||||||
|
this.registry = builder.registry;
|
||||||
|
this.orderCategory = builder.orderCategory;
|
||||||
|
this.market = builder.market;
|
||||||
|
this.listing = builder.listing;
|
||||||
|
this.riskParameter = builder.riskParameter;
|
||||||
|
this.categoryP = builder.categoryP;
|
||||||
|
this.clcc = builder.clcc;
|
||||||
|
this.rgcm = builder.rgcm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registry getRegistry() {
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderCategory() {
|
||||||
|
return orderCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Market getMarket() {
|
||||||
|
return market;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Listing getListing() {
|
||||||
|
return listing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RiskParameter getRiskParameter() {
|
||||||
|
return riskParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CounterpartyInfo getCategoryP() {
|
||||||
|
return categoryP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CounterpartyInfo getClcc() {
|
||||||
|
return clcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CounterpartyInfo getRgcm() {
|
||||||
|
return rgcm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private Registry registry;
|
||||||
|
private String orderCategory;
|
||||||
|
private Market market;
|
||||||
|
private Listing listing;
|
||||||
|
private RiskParameter riskParameter;
|
||||||
|
private CounterpartyInfo categoryP;
|
||||||
|
private CounterpartyInfo clcc;
|
||||||
|
private CounterpartyInfo rgcm;
|
||||||
|
|
||||||
|
public Builder registry(Registry registry) {
|
||||||
|
this.registry = registry;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder orderCategory(String orderCategory) {
|
||||||
|
this.orderCategory = orderCategory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder market(Market market) {
|
||||||
|
this.market = market;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder listing(Listing listing) {
|
||||||
|
this.listing = listing;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder riskParameter(RiskParameter riskParameter) {
|
||||||
|
this.riskParameter = riskParameter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder categoryP(CounterpartyInfo categoryP) {
|
||||||
|
this.categoryP = categoryP;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder clcc(CounterpartyInfo clcc) {
|
||||||
|
this.clcc = clcc;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder rgcm(CounterpartyInfo rgcm) {
|
||||||
|
this.rgcm = rgcm;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SwapContext build() {
|
||||||
|
return new SwapContext(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,261 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Optional;
|
||||||
|
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.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.model.CounterpartyInfo;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.enumeration.CompanyRole;
|
||||||
|
import ru.spcex.platform.enumeration.MarketType;
|
||||||
|
import ru.spcex.platform.enumeration.RegistryStatus;
|
||||||
|
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.ImdgPredicate;
|
||||||
|
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ImdgQueryService {
|
||||||
|
private final Imdg<ClearingMemberCategory> categoryImdg;
|
||||||
|
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 Imdg<Registry> registryImdg;
|
||||||
|
private final Imdg<OvernightSettings> overnightSettingsImdg;
|
||||||
|
|
||||||
|
|
||||||
|
public ImdgQueryService(ImdgProvider imdgProvider) {
|
||||||
|
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.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||||
|
this.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class);
|
||||||
|
}
|
||||||
|
public Collection<Long> getCurrencyRegistry() {
|
||||||
|
ImdgPredicateBuilder builder = registryImdg.predicateBuilder();
|
||||||
|
ImdgPredicate registryPredicate = builder.and(
|
||||||
|
builder.regex("registryCode", "^PM.*T"),
|
||||||
|
builder.not(builder.equals("registryStatus", RegistryStatus.OK.getKey()))
|
||||||
|
);
|
||||||
|
|
||||||
|
return registryImdg.getCollectionIdsByPredicate(registryPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<OvernightSettings> findOvernightSettingsByCompany(Long companyId) {
|
||||||
|
ImdgPredicateBuilder builder = overnightSettingsImdg.predicateBuilder();
|
||||||
|
ImdgPredicate predicate = builder.and(
|
||||||
|
builder.equals("market", ru.spcex.platform.enumeration.Market.curr),
|
||||||
|
builder.equals("companyId", companyId)
|
||||||
|
);
|
||||||
|
OvernightSettings overnightSettings = overnightSettingsImdg.getFirstObjectByPredicate(predicate);
|
||||||
|
return Optional.ofNullable(overnightSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String resolveOrderCategory(Long companyId) {
|
||||||
|
ImdgPredicateBuilder pb = categoryImdg.predicateBuilder();
|
||||||
|
ClearingMemberCategory category = categoryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.equals("companyId", companyId)
|
||||||
|
);
|
||||||
|
return "P".equals(category.getClearingMemberCategory()) ? "PL" : "UK";
|
||||||
|
}
|
||||||
|
|
||||||
|
public CounterpartyInfo getCompanyByRole(CompanyRole role) {
|
||||||
|
ImdgPredicateBuilder pb = companyRoleSetImdg.predicateBuilder();
|
||||||
|
CompanyRoleSet roleSet = companyRoleSetImdg.getSingleObjectByPredicate(
|
||||||
|
pb.equals("companyRole", role)
|
||||||
|
);
|
||||||
|
|
||||||
|
Company company = companyImdg.getSingleObjectByID(roleSet.getCompanyId());
|
||||||
|
TradingClearingRegistry registry = tradingClearingRegistryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.equals("companyId", company.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
return new CounterpartyInfo(
|
||||||
|
company.getId(),
|
||||||
|
company.getTradingCode(),
|
||||||
|
registry != null ? registry.getId() : null,
|
||||||
|
registry != null ? registry.getCode() : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CounterpartyInfo getCompanyByClearingCategory(String clearingCategory) {
|
||||||
|
ImdgPredicateBuilder pb = categoryImdg.predicateBuilder();
|
||||||
|
ClearingMemberCategory category = categoryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.equals("clearingMemberCategory", clearingCategory)
|
||||||
|
);
|
||||||
|
|
||||||
|
Company company = companyImdg.getSingleObjectByID(category.getCompanyId());
|
||||||
|
TradingClearingRegistry registry = tradingClearingRegistryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.equals("companyId", company.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
return new CounterpartyInfo(
|
||||||
|
company.getId(),
|
||||||
|
company.getTradingCode(),
|
||||||
|
registry != null ? registry.getId() : null,
|
||||||
|
registry != null ? registry.getCode() : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Market getSwapMarket() {
|
||||||
|
ImdgPredicateBuilder pb = marketImdg.predicateBuilder();
|
||||||
|
return marketImdg.getSingleObjectByPredicate(pb.equals("marketType", MarketType.SCSW));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Listing findSwapListing(Registry registry, String marketCode) {
|
||||||
|
return "RUB".equals(registry.getSecuritySymbol())
|
||||||
|
? findListingForRub(registry, marketCode)
|
||||||
|
: findListingForOtherCurrency(registry, marketCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RiskParameter findRiskParameter(Registry registry) {
|
||||||
|
return "RUB".equals(registry.getSecuritySymbol())
|
||||||
|
? findRiskParameterForRub()
|
||||||
|
: findRiskParameterForOtherCurrency(registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rates getRate(String currency, LocalDate valueDate) {
|
||||||
|
ImdgPredicateBuilder pb = ratesImdg.predicateBuilder();
|
||||||
|
return ratesImdg.getSingleObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.equals("currency", currency),
|
||||||
|
pb.equals("valueDate", valueDate),
|
||||||
|
pb.equals("workflowStatus", WorkflowStatus.Active.getKey())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal defineTransferRate(Long currencyPairDictionaryId, String securitySymbol) {
|
||||||
|
ImdgPredicateBuilder pb = riskParameterImdg.predicateBuilder();
|
||||||
|
String baseCurrency = "RUB".equals(securitySymbol) ? "CNY" : securitySymbol;
|
||||||
|
|
||||||
|
RiskParameter riskParameter = riskParameterImdg.getSingleObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.equals("settlementType", "T0"),
|
||||||
|
pb.equals("currencyPairId", currencyPairDictionaryId),
|
||||||
|
pb.equals("baseCurrency", baseCurrency)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return riskParameter.getQuoteValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurrencyPairDictionary getCurrencyPairDictionaryByListing(Listing listing) {
|
||||||
|
CurrencyPairSecurity security = currencyPairSecurityImdg.getSingleObjectByID(listing.getSecurityId());
|
||||||
|
return currencyPairDictionaryImdg.getSingleObjectByID(security.getCurrencyPairId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Listing findListingForRub(Registry registry, String marketCode) {
|
||||||
|
ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder();
|
||||||
|
|
||||||
|
CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.equals("baseCurrency", "CNY"),
|
||||||
|
pb.equals("quoteCurrency", registry.getSecuritySymbol())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Collection<Long> securityIds = currencyPairSecurityImdg.getCollectionIdsByPredicate(
|
||||||
|
pb.equals("currencyPairId", pair.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
return listingImdg.getSingleObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.in("securityId", securityIds.toArray(new Long[0])),
|
||||||
|
pb.equals("market", marketCode)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Listing findListingForOtherCurrency(Registry registry, String marketCode) {
|
||||||
|
ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder();
|
||||||
|
|
||||||
|
CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.equals("baseCurrency", registry.getSecuritySymbol()),
|
||||||
|
pb.equals("quoteCurrency", "RUB")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Collection<Long> securityIds = currencyPairSecurityImdg.getCollectionIdsByPredicate(
|
||||||
|
pb.equals("currencyPairId", pair.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
return listingImdg.getSingleObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.in("securityId", securityIds.toArray(new Long[0])),
|
||||||
|
pb.equals("market", marketCode)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RiskParameter findRiskParameterForRub() {
|
||||||
|
ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder();
|
||||||
|
CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.equals("baseCurrency", "CNY")
|
||||||
|
);
|
||||||
|
|
||||||
|
return riskParameterImdg.getSingleObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.equals("currencyPairId", pair.getId()),
|
||||||
|
pb.equals("settlementType", "T0")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RiskParameter findRiskParameterForOtherCurrency(Registry registry) {
|
||||||
|
ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder();
|
||||||
|
CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate(
|
||||||
|
pb.equals("baseCurrency", registry.getSecuritySymbol())
|
||||||
|
);
|
||||||
|
|
||||||
|
return riskParameterImdg.getSingleObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.equals("currencyPairId", pair.getId()),
|
||||||
|
pb.equals("settlementType", "T0")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registry getRegistryById(Long id) {
|
||||||
|
return registryImdg.getSingleObjectByID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registry findAmtRegistry(Registry registry, String securitySymbol) {
|
||||||
|
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
|
||||||
|
return registryImdg.getSingleObjectByPredicate(
|
||||||
|
pb.and(
|
||||||
|
pb.regex("registryCode", "^PM.*T"),
|
||||||
|
pb.equals("securitySymbol", securitySymbol),
|
||||||
|
pb.equals("tradingClearingRegistryId", registry.getId()),
|
||||||
|
pb.equals("companyId", registry.getCompanyId())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.service;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
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.registry.Registry;
|
||||||
|
import ru.clearing.classes.statics.data.security.RiskParameter;
|
||||||
|
import ru.spcex.clearing.dflt.management.model.CounterpartyInfo;
|
||||||
|
import ru.spcex.clearing.dflt.management.model.SwapContext;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.enumeration.CompanyRole;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SpotOvernightOrderService {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final ImdgQueryService imdgQueryService;
|
||||||
|
private final Imdg<OrderCurrency> orderCurrencyImdg;
|
||||||
|
private final SwapOrderTemplateBuilder templateBuilder;
|
||||||
|
private final SwapCalculationService swapCalculationService;
|
||||||
|
|
||||||
|
public SpotOvernightOrderService(ImdgProvider imdgProvider,
|
||||||
|
ImdgQueryService imdgQueryService,
|
||||||
|
SwapOrderTemplateBuilder templateBuilder,
|
||||||
|
SwapCalculationService swapCalculationService) {
|
||||||
|
this.imdgQueryService = imdgQueryService;
|
||||||
|
this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
|
||||||
|
this.templateBuilder = templateBuilder;
|
||||||
|
this.swapCalculationService = swapCalculationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(Registry registry) {
|
||||||
|
String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId());
|
||||||
|
|
||||||
|
Market market = imdgQueryService.getSwapMarket();
|
||||||
|
Listing listing = imdgQueryService.findSwapListing(registry, market.getCode());
|
||||||
|
RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry);
|
||||||
|
CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P");
|
||||||
|
CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC);
|
||||||
|
CounterpartyInfo rgcm = imdgQueryService.getCompanyByRole(CompanyRole.RGCM);
|
||||||
|
|
||||||
|
SwapContext context = SwapContext.builder()
|
||||||
|
.registry(registry)
|
||||||
|
.orderCategory(orderCategory)
|
||||||
|
.market(market)
|
||||||
|
.listing(listing)
|
||||||
|
.riskParameter(riskParameter)
|
||||||
|
.categoryP(categoryP)
|
||||||
|
.clcc(clcc)
|
||||||
|
.rgcm(rgcm)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// OrderCurrency primaryTransfer = templateBuilder.buildPrimaryTransfer(context);
|
||||||
|
// OrderCurrency counterTransfer = templateBuilder.buildCounterTransfer(context);
|
||||||
|
// OrderCurrency primaryBalancing = templateBuilder.buildPrimaryBalancing(context);
|
||||||
|
// OrderCurrency counterBalancing = templateBuilder.buildCounterBalancing(context);
|
||||||
|
//
|
||||||
|
// swapCalculationService.calcAndEnrich(primaryTransfer, context);
|
||||||
|
// swapCalculationService.calcAndEnrich(counterTransfer, context);
|
||||||
|
// swapCalculationService.calcAndEnrich(primaryBalancing, context);
|
||||||
|
// swapCalculationService.calcAndEnrich(counterBalancing, context);
|
||||||
|
//
|
||||||
|
// orderCurrencyImdg.insert(primaryTransfer);
|
||||||
|
// orderCurrencyImdg.insert(counterTransfer);
|
||||||
|
// orderCurrencyImdg.insert(primaryBalancing);
|
||||||
|
// orderCurrencyImdg.insert(counterBalancing);
|
||||||
|
|
||||||
|
log.info("Spot orders created for registryId={}", registry.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.clearing.classes.statics.data.misc.Listing;
|
||||||
|
import ru.clearing.classes.statics.data.misc.OrderCurrency;
|
||||||
|
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.model.CalculationResult;
|
||||||
|
import ru.spcex.clearing.dflt.management.model.SwapContext;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SwapCalculationService {
|
||||||
|
private static final MathContext MC = new MathContext(20, RoundingMode.HALF_UP);
|
||||||
|
|
||||||
|
private final ImdgQueryService imdgQueryService;
|
||||||
|
private final TransferDateService transferDateService;
|
||||||
|
|
||||||
|
public SwapCalculationService(ImdgQueryService imdgQueryService,
|
||||||
|
TransferDateService transferDateService) {
|
||||||
|
this.imdgQueryService = imdgQueryService;
|
||||||
|
this.transferDateService = transferDateService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calcAndEnrich(OrderCurrency order,
|
||||||
|
SwapContext context) {
|
||||||
|
Registry registry = context.getRegistry();
|
||||||
|
Listing listing = context.getListing();
|
||||||
|
|
||||||
|
CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryByListing(listing);
|
||||||
|
BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol());
|
||||||
|
BigDecimal n = transferDateService.numberOfDaysOfTransfer();
|
||||||
|
|
||||||
|
CalculationResult result = isRub(registry)
|
||||||
|
? calculationSwapRubSums(registry, listing.getLotSize().intValue(), s, n)
|
||||||
|
: calculationSwapSums(registry, listing.getLotSize().intValue(), s, n);
|
||||||
|
|
||||||
|
BigDecimal quantityLot = result.sum3().abs();
|
||||||
|
BigDecimal price = swapPriceCalc(pair.getBaseCurrency(), s, n);
|
||||||
|
|
||||||
|
order.setPrice(price);
|
||||||
|
order.setQuantityLot(quantityLot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CalculationResult calculationSwapSums(Registry registry, Integer lotSize, BigDecimal s, BigDecimal n) {
|
||||||
|
BigDecimal planPosition = registry.getBalance();
|
||||||
|
BigDecimal sum1 = planPosition.abs();
|
||||||
|
|
||||||
|
Registry rubRegistry = imdgQueryService.findAmtRegistry(registry, "RUB");
|
||||||
|
BigDecimal planPositionRub = rubRegistry.getBalance();
|
||||||
|
|
||||||
|
Rates rates = imdgQueryService.getRate(registry.getSecuritySymbol(), LocalDate.now());
|
||||||
|
BigDecimal rateValue = rates.getValue();
|
||||||
|
|
||||||
|
BigDecimal sum2 = planPositionRub.divide(rateValue, lotSize, RoundingMode.HALF_DOWN);
|
||||||
|
BigDecimal sum3 = sum1.setScale(0, RoundingMode.CEILING).min(sum2);
|
||||||
|
BigDecimal sum4 = sum3.multiply(rateValue, MC).negate();
|
||||||
|
BigDecimal sum5 = sum3.negate();
|
||||||
|
|
||||||
|
BigDecimal multiplier = BigDecimal.ONE.add(
|
||||||
|
s.divide(BigDecimal.valueOf(365), MC).multiply(n, MC),
|
||||||
|
MC
|
||||||
|
);
|
||||||
|
|
||||||
|
BigDecimal sum6 = sum3.multiply(rateValue, MC).multiply(multiplier, MC);
|
||||||
|
|
||||||
|
return new CalculationResult(sum1, sum2, sum3, sum4, sum5, sum6);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CalculationResult calculationSwapRubSums(Registry registry, Integer lotSize, BigDecimal s, BigDecimal n) {
|
||||||
|
BigDecimal planPosition = registry.getBalance();
|
||||||
|
Rates cnyRate = imdgQueryService.getRate(registry.getSecuritySymbol(), LocalDate.now());
|
||||||
|
BigDecimal rateValue = cnyRate.getValue();
|
||||||
|
|
||||||
|
BigDecimal sum1 = planPosition.divide(rateValue, MC);
|
||||||
|
|
||||||
|
Registry cnyRegistry = imdgQueryService.findAmtRegistry(registry, "CNY");
|
||||||
|
BigDecimal planPositionCny = cnyRegistry.getBalance();
|
||||||
|
|
||||||
|
BigDecimal sum2 = planPositionCny.divide(rateValue, lotSize, RoundingMode.HALF_DOWN);
|
||||||
|
BigDecimal sum3 = sum1.setScale(0, RoundingMode.CEILING).min(sum2).negate();
|
||||||
|
BigDecimal sum4 = sum3.multiply(rateValue, MC).negate();
|
||||||
|
BigDecimal sum5 = sum3.negate();
|
||||||
|
|
||||||
|
BigDecimal multiplier = BigDecimal.ONE.add(
|
||||||
|
s.divide(BigDecimal.valueOf(365), MC).multiply(n, MC),
|
||||||
|
MC
|
||||||
|
);
|
||||||
|
|
||||||
|
BigDecimal sum6 = sum3.multiply(rateValue, MC).multiply(multiplier, MC);
|
||||||
|
|
||||||
|
return new CalculationResult(sum1, sum2, sum3, sum4, sum5, sum6);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal swapPriceCalc(String baseCurrency, BigDecimal s, BigDecimal n) {
|
||||||
|
Rates rate = imdgQueryService.getRate(baseCurrency, LocalDate.now());
|
||||||
|
return rate.getValue()
|
||||||
|
.multiply(s, MC)
|
||||||
|
.multiply(n, MC)
|
||||||
|
.divide(BigDecimal.valueOf(365), MC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRub(Registry registry) {
|
||||||
|
return "RUB".equals(registry.getSecuritySymbol());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,231 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.service;
|
||||||
|
|
||||||
|
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.registry.Registry;
|
||||||
|
import ru.clearing.classes.statics.data.security.RiskParameter;
|
||||||
|
import ru.spcex.clearing.dflt.management.model.CounterpartyInfo;
|
||||||
|
import ru.spcex.clearing.dflt.management.model.SwapContext;
|
||||||
|
import ru.spcex.platform.enumeration.Side;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SwapOrderTemplateBuilder {
|
||||||
|
private final ImdgQueryService imdgQueryService;
|
||||||
|
|
||||||
|
public SwapOrderTemplateBuilder(ImdgQueryService imdgQueryService) {
|
||||||
|
this.imdgQueryService = imdgQueryService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderCurrency buildPrimaryTransfer(SwapContext context) {
|
||||||
|
OrderCurrency orderCurrency;
|
||||||
|
switch (context.getOrderCategory()) {
|
||||||
|
case "PL" -> orderCurrency = buildPrimaryTransferPl(context);
|
||||||
|
case "UK" -> orderCurrency = buildPrimaryTransferUk(context);
|
||||||
|
default -> throw new IllegalArgumentException("Unsupported order category: " + context.getOrderCategory());
|
||||||
|
}
|
||||||
|
Side side = resolvePrimaryTransferSide(context.getRegistry());
|
||||||
|
enrichOrder(orderCurrency, context, side, "overnight");
|
||||||
|
return orderCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderCurrency buildCounterTransfer(SwapContext context) {
|
||||||
|
OrderCurrency orderCurrency;
|
||||||
|
switch (context.getOrderCategory()) {
|
||||||
|
case "PL" -> orderCurrency = buildCounterTransferPl(context);
|
||||||
|
case "UK" -> orderCurrency = buildCounterTransferUk(context);
|
||||||
|
default -> throw new IllegalArgumentException("Unsupported order category: " + context.getOrderCategory());
|
||||||
|
};
|
||||||
|
Side side = resolveCounterTransferSide(context.getRegistry());
|
||||||
|
enrichOrder(orderCurrency, context, side, "overnight");
|
||||||
|
return orderCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderCurrency buildPrimaryBalancing(SwapContext context) {
|
||||||
|
OrderCurrency orderCurrency;
|
||||||
|
switch (context.getOrderCategory()) {
|
||||||
|
case "PL" -> orderCurrency = buildPrimaryBalancingPl(context);
|
||||||
|
case "UK" -> orderCurrency = buildPrimaryBalancingUk(context);
|
||||||
|
default -> throw new IllegalArgumentException("Unsupported order category: " + context.getOrderCategory());
|
||||||
|
};
|
||||||
|
Side side = resolvePrimaryBalancingSide(context.getRegistry());
|
||||||
|
enrichOrder(orderCurrency, context, side, "balance");
|
||||||
|
return orderCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderCurrency buildCounterBalancing(SwapContext context) {
|
||||||
|
OrderCurrency orderCurrency;
|
||||||
|
switch (context.getOrderCategory()) {
|
||||||
|
case "PL" -> orderCurrency = buildCounterBalancingPl(context);
|
||||||
|
case "UK" -> orderCurrency = buildCounterBalancingUk(context);
|
||||||
|
default -> throw new IllegalArgumentException("Unsupported order category: " + context.getOrderCategory());
|
||||||
|
};
|
||||||
|
Side side = resolveCounterBalancingSide(context.getRegistry());
|
||||||
|
enrichOrder(orderCurrency, context, side, "balance");
|
||||||
|
return orderCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildPrimaryTransferUk(SwapContext context) {
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
Registry registry = context.getRegistry();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(registry.getTradingClearingRegistry());
|
||||||
|
order.setTradingClearingRegistryId(registry.getTradingClearingRegistryId());
|
||||||
|
order.setCompanyId(registry.getCompanyId());
|
||||||
|
order.setTradingCode(registry.getTradingCode());
|
||||||
|
order.setCounterPartyId(clcc.companyId());
|
||||||
|
order.setCounterTradingCode(clcc.tradingCode());
|
||||||
|
order.setType("CMOV");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildCounterTransferUk(SwapContext context) {
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
Registry registry = context.getRegistry();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(clcc.registryCode());
|
||||||
|
order.setTradingClearingRegistryId(clcc.registryId());
|
||||||
|
order.setCompanyId(clcc.companyId());
|
||||||
|
order.setTradingCode(clcc.tradingCode());
|
||||||
|
order.setCounterPartyId(registry.getCompanyId());
|
||||||
|
order.setCounterTradingCode(registry.getTradingCode());
|
||||||
|
order.setType("CMOV");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildPrimaryBalancingUk(SwapContext context) {
|
||||||
|
CounterpartyInfo categoryP = context.getCategoryP();
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(categoryP.registryCode());
|
||||||
|
order.setTradingClearingRegistryId(categoryP.registryId());
|
||||||
|
order.setCompanyId(categoryP.companyId());
|
||||||
|
order.setTradingCode(categoryP.tradingCode());
|
||||||
|
order.setCounterPartyId(clcc.companyId());
|
||||||
|
order.setCounterTradingCode(clcc.tradingCode());
|
||||||
|
order.setType("CMBL");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildCounterBalancingUk(SwapContext context) {
|
||||||
|
CounterpartyInfo categoryP = context.getCategoryP();
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(clcc.registryCode());
|
||||||
|
order.setTradingClearingRegistryId(clcc.registryId());
|
||||||
|
order.setCompanyId(clcc.companyId());
|
||||||
|
order.setTradingCode(clcc.tradingCode());
|
||||||
|
order.setCounterPartyId(categoryP.companyId());
|
||||||
|
order.setCounterTradingCode(categoryP.tradingCode());
|
||||||
|
order.setType("CMBL");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildPrimaryTransferPl(SwapContext context) {
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
Registry registry = context.getRegistry();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(registry.getTradingClearingRegistry());
|
||||||
|
order.setTradingClearingRegistryId(registry.getTradingClearingRegistryId());
|
||||||
|
order.setCompanyId(registry.getCompanyId());
|
||||||
|
order.setTradingCode(registry.getTradingCode());
|
||||||
|
order.setCounterPartyId(clcc.companyId());
|
||||||
|
order.setCounterTradingCode(clcc.tradingCode());
|
||||||
|
order.setType("PLOV");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildCounterTransferPl(SwapContext context) {
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
Registry registry = context.getRegistry();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(clcc.registryCode());
|
||||||
|
order.setTradingClearingRegistryId(clcc.registryId());
|
||||||
|
order.setCompanyId(clcc.companyId());
|
||||||
|
order.setTradingCode(clcc.tradingCode());
|
||||||
|
order.setCounterPartyId(registry.getCompanyId());
|
||||||
|
order.setCounterTradingCode(registry.getTradingCode());
|
||||||
|
order.setType("PLOV");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildPrimaryBalancingPl(SwapContext context) {
|
||||||
|
CounterpartyInfo rgcm = context.getRgcm();
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(rgcm.registryCode());
|
||||||
|
order.setTradingClearingRegistryId(rgcm.registryId());
|
||||||
|
order.setCompanyId(rgcm.companyId());
|
||||||
|
order.setTradingCode(rgcm.tradingCode());
|
||||||
|
order.setCounterPartyId(clcc.companyId());
|
||||||
|
order.setCounterTradingCode(clcc.tradingCode());
|
||||||
|
order.setType("PLBL");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderCurrency buildCounterBalancingPl(SwapContext context) {
|
||||||
|
CounterpartyInfo clcc = context.getClcc();
|
||||||
|
CounterpartyInfo rgcm = context.getRgcm();
|
||||||
|
|
||||||
|
OrderCurrency order = new OrderCurrency();
|
||||||
|
order.setAccount(clcc.registryCode());
|
||||||
|
order.setTradingClearingRegistryId(clcc.registryId());
|
||||||
|
order.setCompanyId(clcc.companyId());
|
||||||
|
order.setTradingCode(clcc.tradingCode());
|
||||||
|
order.setCounterPartyId(rgcm.companyId());
|
||||||
|
order.setCounterTradingCode(rgcm.tradingCode());
|
||||||
|
order.setType("PLBL");
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enrichOrder(OrderCurrency order,
|
||||||
|
SwapContext context,
|
||||||
|
Side side,
|
||||||
|
String comment) {
|
||||||
|
Registry registry = context.getRegistry();
|
||||||
|
Listing listing = context.getListing();
|
||||||
|
Market market = context.getMarket();
|
||||||
|
RiskParameter riskParameter = context.getRiskParameter();
|
||||||
|
|
||||||
|
order.setOvernightType("SWAP");
|
||||||
|
order.setMarket(market.getCode());
|
||||||
|
order.setListingId(listing.getId());
|
||||||
|
order.setSecuritySymbol(listing.getSymbolCode());
|
||||||
|
order.setSecurityId(listing.getSecurityId());
|
||||||
|
order.setLotSize(listing.getLotSize());
|
||||||
|
order.setRate(riskParameter.getQuoteValue());
|
||||||
|
order.setSide(side.getKey());
|
||||||
|
order.setSettleCode("T1");
|
||||||
|
order.setStatus("CRET");
|
||||||
|
order.setComment(comment);
|
||||||
|
order.setRegistryId(registry.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Side resolvePrimaryTransferSide(Registry registry) {
|
||||||
|
return isRub(registry) ? Side.BUY : Side.SELL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Side resolveCounterTransferSide(Registry registry) {
|
||||||
|
return isRub(registry) ? Side.SELL : Side.BUY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Side resolvePrimaryBalancingSide(Registry registry) {
|
||||||
|
return isRub(registry) ? Side.SELL : Side.BUY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Side resolveCounterBalancingSide(Registry registry) {
|
||||||
|
return isRub(registry) ? Side.BUY : Side.SELL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRub(Registry registry) {
|
||||||
|
return "RUB".equals(registry.getSecuritySymbol());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.service;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
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.registry.Registry;
|
||||||
|
import ru.clearing.classes.statics.data.security.RiskParameter;
|
||||||
|
import ru.spcex.clearing.dflt.management.model.CounterpartyInfo;
|
||||||
|
import ru.spcex.clearing.dflt.management.model.SwapContext;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.enumeration.CompanyRole;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SwapOvernightOrderService {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final ImdgQueryService imdgQueryService;
|
||||||
|
private final Imdg<OrderCurrency> orderCurrencyImdg;
|
||||||
|
private final SwapOrderTemplateBuilder templateBuilder;
|
||||||
|
private final SwapCalculationService swapCalculationService;
|
||||||
|
|
||||||
|
public SwapOvernightOrderService(ImdgProvider imdgProvider,
|
||||||
|
ImdgQueryService imdgQueryService,
|
||||||
|
SwapOrderTemplateBuilder templateBuilder,
|
||||||
|
SwapCalculationService swapCalculationService) {
|
||||||
|
this.imdgQueryService = imdgQueryService;
|
||||||
|
this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
|
||||||
|
this.templateBuilder = templateBuilder;
|
||||||
|
this.swapCalculationService = swapCalculationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(Registry registry) {
|
||||||
|
String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId());
|
||||||
|
|
||||||
|
Market market = imdgQueryService.getSwapMarket();
|
||||||
|
Listing listing = imdgQueryService.findSwapListing(registry, market.getCode());
|
||||||
|
RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry);
|
||||||
|
CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P");
|
||||||
|
CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC);
|
||||||
|
CounterpartyInfo rgcm = imdgQueryService.getCompanyByRole(CompanyRole.RGCM);
|
||||||
|
|
||||||
|
SwapContext context = SwapContext.builder()
|
||||||
|
.registry(registry)
|
||||||
|
.orderCategory(orderCategory)
|
||||||
|
.market(market)
|
||||||
|
.listing(listing)
|
||||||
|
.riskParameter(riskParameter)
|
||||||
|
.categoryP(categoryP)
|
||||||
|
.clcc(clcc)
|
||||||
|
.rgcm(rgcm)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OrderCurrency primaryTransfer = templateBuilder.buildPrimaryTransfer(context);
|
||||||
|
OrderCurrency counterTransfer = templateBuilder.buildCounterTransfer(context);
|
||||||
|
OrderCurrency primaryBalancing = templateBuilder.buildPrimaryBalancing(context);
|
||||||
|
OrderCurrency counterBalancing = templateBuilder.buildCounterBalancing(context);
|
||||||
|
|
||||||
|
swapCalculationService.calcAndEnrich(primaryTransfer, context);
|
||||||
|
swapCalculationService.calcAndEnrich(counterTransfer, context);
|
||||||
|
swapCalculationService.calcAndEnrich(primaryBalancing, context);
|
||||||
|
swapCalculationService.calcAndEnrich(counterBalancing, context);
|
||||||
|
|
||||||
|
orderCurrencyImdg.insert(primaryTransfer);
|
||||||
|
orderCurrencyImdg.insert(counterTransfer);
|
||||||
|
orderCurrencyImdg.insert(primaryBalancing);
|
||||||
|
orderCurrencyImdg.insert(counterBalancing);
|
||||||
|
|
||||||
|
log.info("Swap orders created for registryId={}", registry.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.enumeration.DayStatus;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TransferDateService {
|
||||||
|
private final Imdg<ClearingCalendar> clearingCalendarImdg;
|
||||||
|
|
||||||
|
public TransferDateService(ImdgProvider imdgProvider) {
|
||||||
|
this.clearingCalendarImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingCalendar, ClearingCalendar.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate findNextWorkingDate() {
|
||||||
|
LocalDate checkingDate = LocalDate.now().plusDays(1);
|
||||||
|
ImdgPredicateBuilder pb = clearingCalendarImdg.predicateBuilder();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
ClearingCalendar calendarDay = clearingCalendarImdg.getFirstObjectByPredicate(
|
||||||
|
pb.equals("clearingDate", checkingDate)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isWeekday(checkingDate.getDayOfWeek())) {
|
||||||
|
// Будний день рабочий, если НЕТ явной записи DOFF
|
||||||
|
if (calendarDay == null || !DayStatus.DayOff.equalsByKey(calendarDay.getDayStatus())) {
|
||||||
|
return checkingDate;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Выходной рабочий, только если ЕСТЬ явная запись BDAY
|
||||||
|
if (calendarDay != null && DayStatus.Workday.equalsByKey(calendarDay.getDayStatus())) {
|
||||||
|
return checkingDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkingDate = checkingDate.plusDays(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal numberOfDaysOfTransfer() {
|
||||||
|
long days = ChronoUnit.DAYS.between(LocalDate.now(), findNextWorkingDate());
|
||||||
|
return BigDecimal.valueOf(days);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWeekday(DayOfWeek dayOfWeek) {
|
||||||
|
return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue