From bfb6cb7380d48dad525f4b6d47f72717e68bfdd5 Mon Sep 17 00:00:00 2001 From: ialbert Date: Tue, 1 Oct 2024 13:09:20 +0300 Subject: [PATCH] PREP session --- .../clearing/session/stage/PrepSession.java | 131 +++++++++ .../session/stage/SessionManager.java | 5 +- .../session/stage/impl/IRegistryBuilder.java | 1 + .../session/stage/impl/RegistryCkBuilder.java | 275 ++++++++++++++++++ .../RequirementsAndObligationCreation.java | 68 ++++- 5 files changed, 477 insertions(+), 3 deletions(-) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrepSession.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryCkBuilder.java diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrepSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrepSession.java new file mode 100644 index 000000000..dc406a056 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrepSession.java @@ -0,0 +1,131 @@ +package ru.spcex.clearing.session.stage; + +import java.time.Instant; +import java.time.LocalDate; +import java.util.List; +import java.util.function.Supplier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.execution.ExecutionCurrency; +import ru.clearing.classes.statics.data.misc.Session; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.session.stage.impl.BalanceRevise; +import ru.spcex.clearing.session.stage.impl.DealsPrepare; +import ru.spcex.clearing.session.stage.impl.ObligationAdmission; +import ru.spcex.clearing.session.stage.impl.RequirementsAndObligationCreation; +import ru.spcex.clearing.session.stage.task.DealsPreparePayload; +import ru.spcex.clearing.session.stage.task.RequirementsAndObligationCreationPayload; +import ru.spcex.platform.classes.base.interfaces.ExecutionType; +import ru.spcex.platform.enumeration.Section; +import ru.spcex.platform.enumeration.SessionStatus; +import ru.spcex.platform.enumeration.SessionType; +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.IMessageResolver; + +@Service +public class PrepSession extends AbstractSession implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final DealsPrepare dealsPrepare; + private final RequirementsAndObligationCreation requirementsAndObligationCreation; + private final ObligationAdmission obligationsAdmission; + private final Imdg executionCurrencyImdg; + private final Supplier> marketCodes; + + public PrepSession( + ImdgProvider imdgProvider, + BalanceRevise balanceRevise, + DealsPrepare dealsPrepare, + RequirementsAndObligationCreation requirementsAndObligationCreation, + IMessageResolver messageResolver, ObligationAdmission obligationsAdmission, + @Qualifier("marketCodesForCurr") Supplier> marketCodes) { + super(imdgProvider, messageResolver); + this.dealsPrepare = dealsPrepare; + this.requirementsAndObligationCreation = requirementsAndObligationCreation; + this.obligationsAdmission = obligationsAdmission; + this.executionCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionCurrency, ExecutionCurrency.class); + this.marketCodes = marketCodes; + } + + @Override + public void afterPropertiesSet() throws Exception { + dealsPrepare.searchForExecutions(ExecutionType.ExecutionCurrency); + ImdgPredicateBuilder execFondPb = executionCurrencyImdg.predicateBuilder(); + dealsPrepare.addExecutionCurrencyCondition(execFondPb.regex("settlementCode", "^T0.*$")); + dealsPrepare.addExecutionCurrencyCondition(execFondPb.in("market", marketCodes.get().toArray(new String[0]))); + requirementsAndObligationCreation.setSessionType(sessionType()); + imdgProvider.waitAvailable(); + initSessionIfPresent(); + } + + @Override + public void runSession(BaseRequest req) { + if (!startSession()) { + return; + } + log.info("session is running, stage {}", currStage.get()); + try { + //stage 1 + StageResult> dealsPreparationResult; + { + DealsPreparePayload payload = new DealsPreparePayload(); + payload.setSessionId(currSession.getId()); + dealsPreparationResult = runStage(TaskType.DealsPrepare, payload, dealsPrepare); + } + { + //stage 2 + RequirementsAndObligationCreationPayload payload = new RequirementsAndObligationCreationPayload( + dealsPreparationResult.getStageResult(), currSession.getId() + ); + runStage(TaskType.RequirementsAndObligationsCreate, payload, requirementsAndObligationCreation); + } + //stage 3 + runStage(TaskType.ObligationsAdmission, currSession.getId(), obligationsAdmission); + endSession(); + } catch (StageException e) { + //already logged + } + + } + + private boolean startSession() { + synchronized (this.currStage) { + if (this.currStage.get() != null) { + log.info("already running session.id={}", this.currSession.getId()); + return false; + } else { + TaskType startStatus = TaskType.StartRevise; + Session newSession = new Session(); + newSession.setSection(section().getKey()); + newSession.setSessionType(sessionType().getKey()); + newSession.setSessionStatus(startStatus.getKey()); + newSession.setWorkflowStatus(SessionStatus.ACTV.getKey()); + newSession.setClearingDate(LocalDate.now()); + newSession.setCreated(Instant.now()); + + //todo companyId/securityId/userId передается из сообщения очереди + sessionImdg.insert(newSession); + currSession = newSession; + log.info("started new session.id={}", this.currSession.getId()); + currStage.set(TaskType.StartRevise); + return true; + } + } + } + + @Override + protected Section section() { + return Section.CURR; + } + + @Override + protected SessionType sessionType() { + return SessionType.PREP; + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SessionManager.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SessionManager.java index d18415d74..d00d76d88 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SessionManager.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SessionManager.java @@ -37,6 +37,7 @@ public class SessionManager { private final CurrencySession currencySession; private final IntermediateMkrSession intermediateMkrSession; private final FinalMkrSession finalMkrSession; + private final PrepSession prepSession; private final ReturnDepositSession returnDepositSession; private final UnitedSession unitedSession; private final TradingTimeService time; @@ -46,7 +47,7 @@ public class SessionManager { PrimaryAuctionBnSession primaryAuctionBnSession, PrimaryAuctionB0Session primaryAuctionB0Session, SecondaryAuctionT0Session secondaryAuctionT0Session, CurrencySession currencySession, - IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, UnitedSession unitedSession, TradingTimeService time) { + IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, PrepSession prepSession, ReturnDepositSession returnDepositSession, UnitedSession unitedSession, TradingTimeService time) { this.notification = notification; this.msgs = msgs; this.primaryAuctionT0Session = primaryAuctionT0Session; @@ -56,6 +57,7 @@ public class SessionManager { this.currencySession = currencySession; this.intermediateMkrSession = intermediateMkrSession; this.finalMkrSession = finalMkrSession; + this.prepSession = prepSession; this.returnDepositSession = returnDepositSession; sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class); @@ -119,6 +121,7 @@ public class SessionManager { case CURR -> session = currencySession; case MEDM -> session = intermediateMkrSession; case FINL -> session = finalMkrSession; + case PREP -> session = prepSession; case XDEP -> session = returnDepositSession; case UNIT -> session = unitedSession; } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/IRegistryBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/IRegistryBuilder.java index 551788bd8..b9bc000dc 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/IRegistryBuilder.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/IRegistryBuilder.java @@ -41,4 +41,5 @@ public interface IRegistryBuilder { default IRegistryBuilder dpAccCash(CashV2 dpAccCash) {return this;}//CashV2 dpAccCash; default IRegistryBuilder currCash(CashV2 currCash) {return this;}//CashV2 currCash; default IRegistryBuilder clrAccCash(CashV2 clrAccCash) {return this;}//CashV2 clrAccCash; + default IRegistryBuilder ckTcr(TradingClearingRegistry ckTcr) {return this;} } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryCkBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryCkBuilder.java new file mode 100644 index 000000000..294bded7f --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryCkBuilder.java @@ -0,0 +1,275 @@ +package ru.spcex.clearing.session.stage.impl; + +import java.time.Instant; +import java.time.LocalDate; +import java.util.Optional; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.ClearingAccount; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.execution.ExecutionCurrency; +import ru.clearing.classes.statics.data.misc.Currency; +import ru.clearing.classes.statics.data.misc.Session; +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.platform.dictionary.CurrencyPairDictionary; +import ru.spcex.clearing.component.predicate.cash.account.AccountIdCashingPredicate; +import ru.spcex.clearing.component.predicate.cash.currency.CurrencyCodePredicate; +import ru.spcex.clearing.service.TcrSearcher; +import ru.spcex.clearing.session.stage.util.RegistryUtil; +import ru.spcex.platform.classes.base.interfaces.ExecutionType; +import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.BalanceDimension; +import ru.spcex.platform.enumeration.CurrencyCode; +import ru.spcex.platform.enumeration.ISide; +import ru.spcex.platform.enumeration.MoneyFlowSide; +import ru.spcex.platform.enumeration.RegistryCapacity; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryInstrumentType; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.enumeration.Section; +import ru.spcex.platform.enumeration.Sender; +import ru.spcex.platform.enumeration.Side; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2; + +public class RegistryCkBuilder implements IRegistryBuilder { + private CashV2 currCash; + private CashV2 clrAccCash; + + private Imdg companyImdg; + private Imdg tradingClearingRegistryImdg; + private Imdg sessionImdg; + private Imdg clearingAccountImdg; + private Imdg currencyImdg; + private Imdg currPairSecImdg; + private Imdg currPairDictImdg; + private TcrSearcher tcrSearcher; + private ExecutionCommon exec; + private RegistryDesignation regDsgn; + private TradingClearingRegistry ckTcr; + + + private RegistryCkBuilder() { + } + + public static RegistryCkBuilder builder() { + return new RegistryCkBuilder(); + } + + public IRegistryBuilder cmpImdg(Imdg cmpImdg) { + this.companyImdg = cmpImdg; + return this; + } + + public IRegistryBuilder tcrImdg(Imdg tcrImdg) { + this.tradingClearingRegistryImdg = tcrImdg; + return this; + } + + public IRegistryBuilder ssnImdg(Imdg ssnImdg) { + this.sessionImdg = ssnImdg; + return this; + } + + public IRegistryBuilder clAccImdg(Imdg clAccImdg) { + this.clearingAccountImdg = clAccImdg; + return this; + } + + public IRegistryBuilder currPairSecImdg(Imdg currPairSecImdg) { + this.currPairSecImdg = currPairSecImdg; + return this; + } + + public IRegistryBuilder currPairDictImdg(Imdg currPairDictImdg) { + this.currPairDictImdg = currPairDictImdg; + return this; + } + + public IRegistryBuilder currImdg(Imdg currImdg) { + this.currencyImdg = currImdg; + return this; + } + + public IRegistryBuilder tcrSearcher(TcrSearcher tcrSearcher) { + this.tcrSearcher = tcrSearcher; + return this; + } + + @Override + public RegistryCkBuilder exec(ExecutionCommon exec) { + this.exec = exec; + return this; + } + + @Override + public RegistryCkBuilder registryDesignation(RegistryDesignation registryDesignation) { + this.regDsgn = registryDesignation; + return this; + } + + @Override + public IRegistryBuilder returnDeposit(boolean returnDep) { + if (returnDep) { + throw new IllegalStateException("cannot create second leg registry for ExecutionFond"); + } + return this; + } + + @Override + public IRegistryBuilder ckTcr(TradingClearingRegistry ckTcr) { + this.ckTcr = ckTcr; + return this; + } + + @Override + public Registry build() { + ISide side = getSide(exec); + Registry reg = new Registry(); + reg.setCompanyId(Sender.CK.getId()); + reg.setCounterPartyId(exec.getCompanyId()); + + reg.setCreated(Instant.now()); + Company company = searchCompany(); + reg.setTradingCode(company.getTradingCode()); + reg.setClearingCode(company.getClearingCode()); + reg.setShortName(company.getShortName()); + reg.setFullName(company.getFullName()); + TradingClearingRegistry tcr = ckTcr; + String capacityByAccount = null; + + //In: execution_currency (SECURITY_SYMBOL: CNYRUB_TOM_C, securityId-->registry.contract) + // C securityId идем в currency_pair_security, чтобы найти currency_pair_id + // C currency_pair_id идем currency_pair_dictionary для базовой base_currency_id [CNY], и обменная в чем торги quote_currency_id [RUB] + //3.1 Для side=Buy + //OM_T = RUB [quote_currency_id] balance=settlement_ammount + //TM_T = CNY [base_currency_id] balance=quantity + //3.2 для side=Sell + //OM_T = CNY [base_currency_id] balance=quantity + //TM_T = RUB [quote_currency_id] balance=settlement_ammount + reg.setContract(String.valueOf(exec.getSecurityId())); + CurrencyPairSecurity curPairSec = currPairSecImdg.getSingleObjectByID(exec.getSecurityId()); + CurrencyPairDictionary curPairDict = null; + if (curPairSec != null) { + curPairDict = currPairDictImdg.getSingleObjectByID(curPairSec.getCurrencyPairId()); + } + assert curPairSec != null && curPairDict != null; + ExecutionCurrency execCurr = (ExecutionCurrency) this.exec; + //что покупают + String baseCurrency = curPairDict.getBaseCurrency(); + //за что покупают + String quoteCurrency = curPairDict.getQuoteCurrency(); + reg.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + reg.setBalanceDimension(BalanceDimension.MONY.getKey()); + String curr; + + Currency currency; + if ((regDsgn.equals(RegistryDesignation.O) && !side.isBuy()) || (regDsgn.equals(RegistryDesignation.T) && !side.isSell())) { + curr = quoteCurrency; + reg.setBalance(execCurr.getSettlementAmount()); + } else if ((regDsgn.equals(RegistryDesignation.T) && !side.isBuy()) || (regDsgn.equals(RegistryDesignation.O) && !side.isSell())) { + curr = baseCurrency; + reg.setBalance(execCurr.getQuantity()); + } else curr = CurrencyCode.RUB.getKey(); + ImdgPredicate currPrdct = CurrencyCodePredicate + .getPredicate(curr) + .cashed(currencyImdg.predicateBuilder(), currCash); + + currency = currencyImdg.getFirstObjectByPredicate(currPrdct); + reg.setSecurityId(currency.getId()); + reg.setSecuritySymbol(currency.getCurrencyCode()); + Optional acc = tcrSearcher.searchByTcr(tcr.getId(), curr); + if (acc.isPresent()) { + reg.setAccountId(acc.get().getId()); + reg.setAccount(acc.get().getAccount()); + reg.setAccountType(acc.get().getAccountType()); + capacityByAccount = defineCapacityByAccountType(acc.get().getAccountType(), acc.get().getId()); + } + + reg.setRegistryDesignation(regDsgn.getKey()); + if (capacityByAccount != null) { + reg.setRegistryCapacity(capacityByAccount); + } + reg.setRegistryUnit(RegistryUnit.T.getKey()); + reg.setRegistryCode(RegistryUtil.clearingCode(reg)); + reg.setTradingClearingRegistryId(tcr.getId()); + reg.setTradingClearingRegistry(tcr.getCode()); + reg.setRegistryStatus(RegistryStatus.PROC.getKey()); + reg.setSettlementDate(execCurr.getSettlementDate()); + reg.setValueDate(execCurr.getSettlementDate()); + reg.setSettlementCode(execCurr.getSettlementCode()); + reg.setTradingDate(exec.getTradingDate()); + reg.setClearingDate(LocalDate.now()); + reg.setPrice(exec.getPrice()); + reg.setCounterPartyId(exec.getCompanyId()); + reg.setGroupId(groupId()); + reg.setSessionId(exec.getSessionId()); + reg.setSessionType(sessionType()); + reg.setSection(Section.CURR.getKey()); + return reg; + } + + private Long groupId() { +// Market market = marketImdg.getFirstObjectBySQL("code = '" + exec.getMarket() + "'"); + return exec.getExchangeExecutionId(); + } + + //можно передать из стейджа + private String sessionType() { + Session session = sessionImdg.getSingleObjectByID(exec.getSessionId()); + return session.getSessionType(); + } + + private Company searchCompany() { + return companyImdg.getSingleObjectByID(Sender.CK.getId()); + } + + private TradingClearingRegistry searchTradingClearingRegistry() { + + return tradingClearingRegistryImdg.getSingleObjectByID(exec.getTradingClearingRegistryId()); + } + + private static ISide getSide(ExecutionCommon exec) { + if (exec.type().equals(ExecutionType.ExecutionDeposit)) { + return ISide.parse(MoneyFlowSide.class, exec.getSide()); + } else if (exec.type().equals(ExecutionType.ExecutionFond)) { + return ISide.parse(Side.class, exec.getSide()); + } else if (exec.type().equals(ExecutionType.ExecutionCurrency)) { + return ISide.parse(Side.class, exec.getSide()); + } else { + throw new RuntimeException("Unknown Execution type: " + exec.type()); + } + } + + private String defineCapacityByAccountType(String accountType, Long moneyAccountId) { + String capacityByAccount = null; + if (AccountType.Clrn.equalsByKey(accountType)) { + ImdgPredicate prdct = AccountIdCashingPredicate + .getPredicate(moneyAccountId) + .cashed(clearingAccountImdg.predicateBuilder(), clrAccCash); + ClearingAccount clearingAccount = clearingAccountImdg.getFirstObjectByPredicate(prdct); + if (clearingAccount != null) { + capacityByAccount = clearingAccount.getClearingAccountType(); + } + } else if (AccountType.Info.equalsByKey(accountType)) { + capacityByAccount = RegistryCapacity.A.getKey(); + } + return capacityByAccount; + } + + @Override + public IRegistryBuilder currCash(CashV2 currCash) { + this.currCash = currCash; + return this; + } + + @Override + public IRegistryBuilder clrAccCash(CashV2 clrAccCash) { + this.clrAccCash = clrAccCash; + return this; + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirementsAndObligationCreation.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirementsAndObligationCreation.java index e59eff5f5..6c8661729 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirementsAndObligationCreation.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirementsAndObligationCreation.java @@ -51,6 +51,8 @@ import ru.spcex.platform.enumeration.RegistryDesignation; import ru.spcex.platform.enumeration.RegistryInstrumentType; import ru.spcex.platform.enumeration.RegistryTradingParams; import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.enumeration.Sender; +import ru.spcex.platform.enumeration.SessionType; import ru.spcex.platform.enumeration.Side; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; @@ -65,6 +67,7 @@ import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2ById; import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2ByIdAndString; import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2ByString; import ru.spcex.platform.utils.collection.Pair; +import ru.spcex.platform.utils.enumeration.IEnumKey; /** * LiabilitiesAndClaims @@ -92,7 +95,12 @@ public class RequirementsAndObligationCreation implements ISessionStage { private final Imdg currImdg; private final TcrSearcher tcrSearcher; private final SecuritySelector secSelector; + private SessionType sessionType; + private TradingClearingRegistry ckTcr; + public void setSessionType(SessionType sessionType) { + this.sessionType = sessionType; + } @Autowired public RequirementsAndObligationCreation(ImdgProvider imdgProvider) { @@ -193,6 +201,7 @@ public class RequirementsAndObligationCreation implements ISessionStage { } protected StageResult createRegisters(List data, Long sessionId, Map rgsStorage) { + this.ckTcr = null; data.sort(tradeTimeComparator.thenComparing(execIdComparator)); Map newRgss = rgsStorage != null ? rgsStorage : storageMap(data); //см. описание к #matchExecutions @@ -266,6 +275,12 @@ public class RequirementsAndObligationCreation implements ISessionStage { findAndUpdateOrCreate.accept(counterExec, RegistryDesignation.T, true); findAndUpdateOrCreate.accept(counterExec, RegistryDesignation.O, true); } + if (isCk()) { + createRegistryForCK(partyExec, RegistryDesignation.O, newRgss); + createRegistryForCK(partyExec, RegistryDesignation.T, newRgss); + createRegistryForCK(counterExec, RegistryDesignation.O, newRgss); + createRegistryForCK(counterExec, RegistryDesignation.T, newRgss); + } } if (rgsStorage == null) { log.info("batch insert {} registries into map", newRgss.size()); @@ -274,6 +289,48 @@ public class RequirementsAndObligationCreation implements ISessionStage { return new StageResult<>(null, true); } + private boolean isCk() { + return IEnumKey.contains(sessionType, SessionType.PREP, SessionType.PAYM); + } + + private void createRegistryForCK( + ExecutionCommon exec, + RegistryDesignation rgsDsgn, + Map newRgss + ) { + if (this.ckTcr == null) { + this.ckTcr = tcrImdg.getSingleObjectByPredicate( + tcrImdg.predicateBuilder().equals("companyId", Sender.CK.getId()) + ); + } + IRegistryBuilder registryBuilder = RegistryCkBuilder.builder(); + Registry newRegister = registryBuilder + //cashes + .dpAccCash(cash.dpAccCash) + .currCash(cash.currCash) + .clrAccCash(cash.clrAccCash) + //imdg + .cmpImdg(cmpImdg) + .tcrImdg(tcrImdg) + .accImdg(accImdg) + .ssnImdg(ssnImdg) + .clAccImdg(clAccImdg) + .dpAccImdg(dpAccImdg) + .currPairSecImdg(currPairSecImdg) + .currPairDictImdg(currPairDictImdg) + .currImdg(currImdg) + .tcrSearcher(tcrSearcher) + .secSelector(secSelector) + .imdg(imdgProvider) + .ckTcr(ckTcr) + .exec(exec) + .registryDesignation(rgsDsgn) + .returnDeposit(false) + .build(); + newRegister.setId(idGen.nextId()); + newRgss.put(newRegister.getId(), newRegister); + log.debug("execution id {}: created rgs.id={}", exec, newRegister.getId()); + } private Optional findReg(ExecutionCommon exec, RegistryDesignation des) { ISide side = getSide(exec); @@ -390,9 +447,16 @@ public class RequirementsAndObligationCreation implements ISessionStage { invalid = String.format("exchangeExecutionId %d and %d not equal", exec1.getExchangeExecutionId(), exec2.getExchangeExecutionId()); } else if (Objects.equals(getSide(exec1), getSide(exec2))) { invalid = String.format("side %s and %s equal, must be opposite", getSide(exec1), getSide(exec1)); - } else if (!Objects.equals(exec1.getCompanyId(), exec2.getCounterPartyId()) || !Objects.equals(exec1.getCounterPartyId(), exec2.getCompanyId())) { + } else if (!isCk() + && (!Objects.equals(exec1.getCompanyId(), exec2.getCounterPartyId()) + || !Objects.equals(exec1.getCounterPartyId(), exec2.getCompanyId()))) { invalid = String.format("Execution#id(%d)#companyId(%d)#counterPartyId(%d), Execution#id(%d)#companyId(%d)#counterPartyId(%d)", - exec1.getId(), exec1.getCompanyId(), exec1.getCounterPartyId(), exec2.getId(), exec2.getCompanyId(), exec2.getCounterPartyId()); + exec1.getId(), exec1.getCompanyId(), exec1.getCounterPartyId(), exec2.getId(), exec2.getCompanyId(), exec2.getCounterPartyId()); + } else if (isCk() + && !Objects.equals(exec1.getTradingDate(), exec2.getTradingDate())) { + invalid = String.format("[Execution#id(%d)#tradingDate=%s, Execution#id(%d)#tradingDate=%s] exchangeExecutionId=%d; tradingDate must be equal", + exec1.getId(), exec1.getTradingDate(), + exec2.getId(), exec2.getTradingDate(), exec2.getExchangeExecutionId()); } if (invalid != null) { log.error("FATAL couldn't match Execution#id({}) with Execution#id({}) error: {}", exec1.getId(), exec2.getId(), invalid);