This commit is contained in:
parent
b0b4f294ec
commit
5a829620bf
6 changed files with 135 additions and 7 deletions
|
|
@ -0,0 +1,24 @@
|
|||
package ru.spcex.clearing.component.predicate.cash;
|
||||
|
||||
import ru.clearing.classes.statics.data.security.UtilitarianDigitalRight;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2;
|
||||
|
||||
public class UtilitarianDigitalRightPredicate {
|
||||
|
||||
public static UtilitarianDigitalRightPredicate getPredicate(Long secId) {
|
||||
return new UtilitarianDigitalRightPredicate(secId);
|
||||
}
|
||||
|
||||
private final Long secId;
|
||||
|
||||
private UtilitarianDigitalRightPredicate(Long secId) {
|
||||
this.secId = secId;
|
||||
}
|
||||
|
||||
public ImdgPredicate cashed(ImdgPredicateBuilder pb, CashV2<Long, UtilitarianDigitalRight> cash) {
|
||||
ImdgPredicate prdct = pb.equals("securityId", secId);
|
||||
return pb.cashed(prdct, cash, secId);
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@ public enum ClearingError implements IErrorEnumId {
|
|||
MarketIsNotMkr(5217L),
|
||||
BalanceInsufficient(5222L),
|
||||
Sdf57UnexpectedBalance(5435L),
|
||||
UtilitarianDigitalRightNotFound(5436L),
|
||||
TCRegistryNotFound(3022L),
|
||||
WrongField(5004L),
|
||||
GatewayTimeout(6003L),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package ru.spcex.clearing.service.execution;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Instant;
|
||||
|
|
@ -10,6 +9,7 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import static java.lang.String.format;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.event.Level;
|
||||
|
|
@ -33,6 +33,7 @@ import ru.clearing.classes.statics.data.security.CurrencyPairSecurity;
|
|||
import ru.clearing.classes.statics.data.security.DigitalCertificateSecurity;
|
||||
import ru.clearing.classes.statics.data.security.MoneyMarketSecurity;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.clearing.classes.statics.data.security.UtilitarianDigitalRight;
|
||||
import ru.spcex.clearing.config.element.ClearingServiceSettings;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.error.ClearingException;
|
||||
|
|
@ -44,10 +45,12 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.ExecutionType;
|
|||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
import ru.spcex.clearing.service.validation.strades.CompanyByTradingCodeCashingValidationRule;
|
||||
import ru.spcex.clearing.service.validation.strades.STradesSecurityDGCTValidationRule;
|
||||
import ru.spcex.clearing.service.validation.strades.STradesSecurityPresentValidationRule;
|
||||
import ru.spcex.clearing.service.validation.strades.TcrByCodeAndCmpIsActiveCashingValidationRule;
|
||||
import ru.spcex.platform.enumeration.CurrencyCode;
|
||||
import ru.spcex.platform.enumeration.InstrumentType;
|
||||
import ru.spcex.platform.enumeration.NominalTypeCode;
|
||||
import ru.spcex.platform.enumeration.ObjectType;
|
||||
import ru.spcex.platform.enumeration.Priority;
|
||||
import ru.spcex.platform.enumeration.Section;
|
||||
|
|
@ -58,6 +61,7 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
|
|||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashCloser;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2ByIdAndString;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2ByString;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
|
|
@ -67,6 +71,7 @@ import ru.spcex.platform.utils.enumeration.IEnumId;
|
|||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
import static ru.spcex.platform.utils.number.BigDecimalUtil.parse;
|
||||
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
|
||||
import ru.spcex.platform.utils.text.TextUtil;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
|
@ -92,6 +97,7 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
private final Imdg<Company> imdgCompany;
|
||||
private final Imdg<TradingClearingRegistry> imdgTradingClearingRegistry;
|
||||
private final Imdg<DigitalCertificateSecurity> imdgDigitCertSecurity;
|
||||
private final Imdg<UtilitarianDigitalRight> udrImdg;
|
||||
private final ImdgId idGen;
|
||||
|
||||
//fixme ждать ТЗ
|
||||
|
|
@ -126,6 +132,7 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
this.equitySecurityImdg = imdgProvider.getCashingImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class, null);
|
||||
this.imdgCompany = imdgProvider.getCashingImdg(IMDGDistributedNames.Map_Company, Company.class, null);
|
||||
this.imdgTradingClearingRegistry = imdgProvider.getCashingImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class, null);
|
||||
this.udrImdg = imdgProvider.getCashingImdg(IMDGDistributedNames.Map_UtilitarianDigitalRight, UtilitarianDigitalRight.class, null);
|
||||
this.idGen = imdgProvider.getImdgIdGenerator();
|
||||
this.valuation = settings.getTrade().getValuation(); //fixme
|
||||
this.kafkaSender = kafkaSender;
|
||||
|
|
@ -278,6 +285,7 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
Company company = validator.getStored(ValidationStored.STradesCompany);
|
||||
Company counterCompany = validator.getStored(ValidationStored.STradesCounterCompany);
|
||||
TradingClearingRegistry rgstr = validator.getStored(ValidationStored.STradesTradingClearingRegistry);
|
||||
UtilitarianDigitalRight udr = validator.getStored(ValidationStored.STradesUtilitarianDigitalRight);
|
||||
ClientCode clientCode = clientCodeImdg.getFirstObjectByFieldValues(Map.of("code", sTrades.getClientCode()));
|
||||
|
||||
ExecutionFond eFond = new ExecutionFond();
|
||||
|
|
@ -293,7 +301,21 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
Market market = marketImdg.getFirstObjectBySQL("code = '%s'".formatted(sTrades.getClassCode()));
|
||||
eFond.setMarket(sTrades.getClassCode());
|
||||
|
||||
eFond.setPrice(sTrades.getPrice());
|
||||
BigDecimal price = sTrades.getPrice();
|
||||
if (udr != null) {
|
||||
DigitalCertificateSecurity dcs = (DigitalCertificateSecurity) security;
|
||||
BigDecimal baseUnitSize = BigDecimal.valueOf(Optional.ofNullable(dcs.getBaseUnitSize()).orElse(0L));
|
||||
if (NominalTypeCode.INDX.equalsByKey(dcs.getNominalTypeCode())) {
|
||||
price = safeBD(sTrades.getPrice())
|
||||
.multiply(safeBD(dcs.getNominalValue()))
|
||||
.multiply(baseUnitSize);
|
||||
} else if (NominalTypeCode.INDX.equalsByKey(dcs.getNominalTypeCode())) {
|
||||
price = safeBD(sTrades.getPrice())
|
||||
.multiply(safeBD(parse(udr.getRightUnit())))
|
||||
.multiply(baseUnitSize);
|
||||
}
|
||||
}
|
||||
eFond.setPrice(price);
|
||||
eFond.setLots(sTrades.getQty());
|
||||
eFond.setQuantity(sTrades.getQtyPcs());
|
||||
{
|
||||
|
|
@ -327,9 +349,10 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
BigDecimal lotSize = listing != null ? safeBD(listing.getLotSize()) : BigDecimal.ONE;
|
||||
BigDecimal qty = safeBD(eFond.getLots()).multiply(lotSize);
|
||||
eFond.setQuantity(qty);
|
||||
BigDecimal price = safeBD(sTrades.getPrice());// eFond.setPrice
|
||||
BigDecimal settlementAmount = BigDecimal.ZERO;
|
||||
if (InstrumentType.BOND.equalsByKey(security.getInstrumentType())) {
|
||||
if (udr != null) {
|
||||
settlementAmount = qty.multiply(eFond.getPrice());
|
||||
} else if (InstrumentType.BOND.equalsByKey(security.getInstrumentType())) {
|
||||
FixedIncomeSecurity fixedIncome = (FixedIncomeSecurity) security;
|
||||
BigDecimal nominalValue;
|
||||
ImdgPredicateBuilder pb = fixedIncomeCashFlowImdg.predicateBuilder();
|
||||
|
|
@ -450,6 +473,8 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany);
|
||||
context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
|
||||
context.addImdg(IMDGDistributedNames.Map_DigitalCertificateSecurity, imdgDigitCertSecurity);
|
||||
context.addImdg(IMDGDistributedNames.Map_UtilitarianDigitalRight, udrImdg);
|
||||
//fixme add map utilitarian
|
||||
context.setLogPrefix(LogPrefixId.INSTANCE);
|
||||
return new ValidatorImpl<>(context,
|
||||
new STradesSecurityPresentValidationRule(valCash.fixIncSecCash,
|
||||
|
|
@ -463,7 +488,8 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
new CompanyByTradingCodeCashingValidationRule<>(
|
||||
STrades::getCpFirmId, valCash.cmpCash, ValidationStored.STradesCounterCompany
|
||||
),
|
||||
new TcrByCodeAndCmpIsActiveCashingValidationRule(valCash.tcrCash)
|
||||
new TcrByCodeAndCmpIsActiveCashingValidationRule(valCash.tcrCash),
|
||||
new STradesSecurityDGCTValidationRule(valCash.udrCash)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -474,6 +500,7 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
private final CashV2ByString<Security> currPairSecCash;
|
||||
private final CashV2ByString<Security> digitCertSecCash;
|
||||
private final CashV2ByString<Company> cmpCash;
|
||||
private final CashV2<Long, UtilitarianDigitalRight> udrCash;
|
||||
private final CashV2ByIdAndString<TradingClearingRegistry> tcrCash;
|
||||
|
||||
public ExecFondCompCash() {
|
||||
|
|
@ -485,6 +512,12 @@ public class ExecutionFondComponent implements IExecutionUploadComponent {
|
|||
this.cmpCash = add(new CashV2ByString<>("cmpCash", Company::getTradingCode));
|
||||
this.tcrCash = add(new CashV2ByIdAndString<>("tcrCash", tcr -> new CashV2ByIdAndString.CustomKey(tcr.getCompanyId(), tcr.getCode())));
|
||||
this.digitCertSecCash = add(new CashV2ByString<>("digitCertSecCash", Security::getSecuritySymbol));
|
||||
this.udrCash = add(new CashV2<Long, UtilitarianDigitalRight>("udrCash") {
|
||||
@Override
|
||||
protected Long extractKey(UtilitarianDigitalRight obj) {
|
||||
return obj.getSecurityId();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package ru.spcex.clearing.service.validation;
|
|||
|
||||
public enum ValidationStored {
|
||||
STradesCompany, STradesCounterCompany, STradesSecurity, STradesTradingClearingRegistry,
|
||||
Account, Company,
|
||||
Account, Company, STradesUtilitarianDigitalRight,
|
||||
|
||||
Sdf57CompanyDeb, Sdf57CompanyCred, Sdf57AccountDeb, Sdf57AccountCred,
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package ru.spcex.clearing.service.validation.strades;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import ru.clearing.classes.statics.data.misc.STrades;
|
||||
import ru.clearing.classes.statics.data.security.DigitalCertificateSecurity;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.clearing.classes.statics.data.security.UtilitarianDigitalRight;
|
||||
import ru.spcex.clearing.component.predicate.cash.UtilitarianDigitalRightPredicate;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
import ru.spcex.platform.enumeration.InstrumentType;
|
||||
import ru.spcex.platform.enumeration.NominalTypeCode;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.CashV2;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.text.TextUtil;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
public class STradesSecurityDGCTValidationRule implements IValidationRule<ImdgValidationContext<STrades>> {
|
||||
private final CashV2<Long, UtilitarianDigitalRight> udrCash;
|
||||
|
||||
public STradesSecurityDGCTValidationRule(CashV2<Long, UtilitarianDigitalRight> udrCash) {
|
||||
this.udrCash = udrCash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String ruleName() {
|
||||
return "STradesSecurityDGCTValidationRule";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<STrades> ctx) {
|
||||
STrades validatedObject = ctx.getValidatedObject();
|
||||
Security security = ctx.getStoredObject(ValidationStored.STradesSecurity);
|
||||
if (security == null || !InstrumentType.DGCT.equalsByKey(security.getInstrumentType())) {
|
||||
return empty();
|
||||
}
|
||||
DigitalCertificateSecurity dcs = (DigitalCertificateSecurity) security;
|
||||
Imdg<UtilitarianDigitalRight> udrImdg = ctx.obtainMap(
|
||||
IMDGDistributedNames.Map_UtilitarianDigitalRight, UtilitarianDigitalRight.class
|
||||
);
|
||||
ImdgPredicateBuilder pb = udrImdg.predicateBuilder();
|
||||
ImdgPredicate cashingPredicate = UtilitarianDigitalRightPredicate
|
||||
.getPredicate(security.getId())
|
||||
.cashed(pb, udrCash);
|
||||
UtilitarianDigitalRight udr = udrImdg.getFirstObjectByPredicate(cashingPredicate);
|
||||
if (udr == null) {
|
||||
return of(ClearingError.UtilitarianDigitalRightNotFound, security.getSecuritySymbol());
|
||||
}
|
||||
if (NominalTypeCode.INDX.equalsByKey(dcs.getNominalTypeCode())) {
|
||||
if (!Objects.equals(dcs.getNominalIndexationDate(), validatedObject.getTradeDate())) {
|
||||
return of(ClearingError.UtilitarianDigitalRightNotFound, security.getSecuritySymbol());
|
||||
}
|
||||
if (dcs.getNominalValue() == null) {
|
||||
return of(ClearingError.UtilitarianDigitalRightNotFound, security.getSecuritySymbol());
|
||||
}
|
||||
} else if (NominalTypeCode.FIXD.equalsByKey(dcs.getNominalTypeCode())) {
|
||||
if (TextUtil.isEmpty(udr.getRightUnit())) {
|
||||
return of(ClearingError.UtilitarianDigitalRightNotFound, security.getSecuritySymbol());
|
||||
}
|
||||
}
|
||||
ctx.storeObject(ValidationStored.STradesUtilitarianDigitalRight, udr);
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ public class BigDecimalUtil {
|
|||
// private final Pattern numberPattern = Pattern.compile("\\d+([.,]\\d+)?");
|
||||
|
||||
public static BigDecimal parse(String number) {
|
||||
if (number == null) {
|
||||
if (TextUtil.isEmpty(number)) {
|
||||
return null;
|
||||
}
|
||||
number = number.trim().replace(",", ".");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue