fix rounding and validation

This commit is contained in:
etreschenkov 2026-06-03 16:26:57 +03:00
parent f46e699d68
commit 7a622f8a70
3 changed files with 35 additions and 18 deletions

View file

@ -26,12 +26,14 @@ public class OrderCurrencyByCompanyAndTcrAlreadyPresent<T extends WithTcrId & Wi
public Optional<EnumMessage> validate(ImdgValidationContext<T> ctx) { public Optional<EnumMessage> validate(ImdgValidationContext<T> ctx) {
T validatedObject = ctx.getValidatedObject(); T validatedObject = ctx.getValidatedObject();
Imdg<OrderCurrency> imdg = ctx.obtainMap(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); Imdg<OrderCurrency> imdg = ctx.obtainMap(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
OrderCurrency existOrder = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
ImdgPredicateBuilder pb = imdg.predicateBuilder(); ImdgPredicateBuilder pb = imdg.predicateBuilder();
Collection<OrderCurrency> orders = imdg.getCollectionObjectsByPredicate( Collection<OrderCurrency> orders = imdg.getCollectionObjectsByPredicate(
pb.and( pb.and(
pb.equals("tradingClearingRegistryId", validatedObject.getTradingClearingRegistryId()), pb.equals("tradingClearingRegistryId", validatedObject.getTradingClearingRegistryId()),
pb.equals("companyId", validatedObject.getCompanyId()), pb.equals("companyId", validatedObject.getCompanyId()),
pb.equals("status", OrderStatus.CREATED.getKey()) pb.equals("status", OrderStatus.CREATED.getKey()),
pb.equals("registryId", existOrder.getRegistryId())
) )
); );
if (!orders.isEmpty()) { if (!orders.isEmpty()) {

View file

@ -9,11 +9,13 @@ import java.nio.file.Path;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -44,6 +46,7 @@ import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.enumeration.OrderStatus; import ru.spcex.platform.enumeration.OrderStatus;
import ru.spcex.platform.enumeration.OvernightType; import ru.spcex.platform.enumeration.OvernightType;
import ru.spcex.platform.enumeration.Priority; import ru.spcex.platform.enumeration.Priority;
import ru.spcex.platform.enumeration.Side;
import ru.spcex.platform.enumeration.Task; import ru.spcex.platform.enumeration.Task;
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;
@ -155,13 +158,13 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
private void exportToTriAndSendToFix(BaseRequest<LauncherCommandRequest> req) { private void exportToTriAndSendToFix(BaseRequest<LauncherCommandRequest> req) {
log.info("SDOR check balance and send notification, request={}", req); log.info("SDOR check balance and send notification, request={}", req);
Collection<OrderCurrency> cretOrderCurrencies = imdgQueryService.getCRETOrderCurrencies(); Collection<OrderCurrency> cretOrderCurrencies = imdgQueryService.getCRETOrderCurrencies();
HashSet<Long> seen = new HashSet<>(); Map<Long, List<OrderCurrency>> cretOrderCurrenciesByRegistryId = cretOrderCurrencies.stream()
Collection<OrderCurrency> withRegistryIdUnique = cretOrderCurrencies.stream() .filter(orderCurrency -> IEnumKey.getEnumByKey(Side.class, orderCurrency.getSide()) == Side.SELL &&
.filter(orderCurrency -> seen.add(orderCurrency.getRegistryId())) (Arrays.asList("CMOV", "PLOV").contains(orderCurrency.getType())))
.toList(); .collect(Collectors.groupingBy(OrderCurrency::getRegistryId));
List<String> messages = withRegistryIdUnique.stream() List<String> messages = cretOrderCurrenciesByRegistryId.entrySet().stream()
.map(this::checkBalance) .map(entry -> checkBalance(entry.getKey(), entry.getValue()))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.toList(); .toList();
@ -187,8 +190,10 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
} }
} }
private String checkBalance(OrderCurrency orderCurrency) { private String checkBalance(Long registryId, List<OrderCurrency> orderCurrencies) {
Registry pmtRegistry = imdgQueryService.getRegistryById(orderCurrency.getRegistryId()); log.debug("Check balance for registryId={}; order ids: {}", registryId,
orderCurrencies.stream().map(OrderCurrency::getId).collect(Collectors.toList()));
Registry pmtRegistry = imdgQueryService.getRegistryById(registryId);
Registry amfRegistry = null; Registry amfRegistry = null;
boolean isRubPmt = pmtRegistry.getSecuritySymbol().equals(CurrencyCode.RUB.getKey()); boolean isRubPmt = pmtRegistry.getSecuritySymbol().equals(CurrencyCode.RUB.getKey());
if (!isRubPmt) { if (!isRubPmt) {
@ -198,13 +203,23 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
String currency = isRubPmt ? CurrencyCode.CNY.getKey() : pmtRegistry.getSecuritySymbol(); String currency = isRubPmt ? CurrencyCode.CNY.getKey() : pmtRegistry.getSecuritySymbol();
Rates rates = imdgQueryService.getRateOnNextWorkingDay(currency); Rates rates = imdgQueryService.getRateOnNextWorkingDay(currency);
BigDecimal val = orderCurrency.getQuantityLot() BigDecimal summaryValByCurrencies = BigDecimal.ZERO;
.multiply(orderCurrency.getLotSize()) for (OrderCurrency orderCurrency : orderCurrencies) {
.multiply(rates.getValue()); summaryValByCurrencies = summaryValByCurrencies.add(orderCurrency.getQuantityLot()
.multiply(orderCurrency.getLotSize())
BigDecimal diff = isRubPmt ? .multiply(rates.getValue()));
pmtRegistry.getBalance().add(val) : }
amfRegistry.getBalance().subtract(val); BigDecimal registryBalance;
BigDecimal diff;
if (isRubPmt) {
registryBalance = pmtRegistry.getBalance();
diff = registryBalance.add(summaryValByCurrencies);
} else {
registryBalance = amfRegistry.getBalance();
diff = registryBalance.subtract(summaryValByCurrencies);
}
log.debug("Registry balance: {}; Summary balance by orders: {}; diff: {}", registryBalance,
summaryValByCurrencies, diff);
if (diff.compareTo(BigDecimal.ZERO) < 0) { if (diff.compareTo(BigDecimal.ZERO) < 0) {
return String.format("Для ТКР %s компании %s: баланс %s RUB;", return String.format("Для ТКР %s компании %s: баланс %s RUB;",
pmtRegistry.getTradingClearingRegistry(), pmtRegistry.getShortName(), pmtRegistry.getTradingClearingRegistry(), pmtRegistry.getShortName(),

View file

@ -94,7 +94,7 @@ public class OrderCalculationService {
throw new IllegalStateException(String.format("Not fond rate by security symbol: %s", CurrencyCode.CNY.getKey())); throw new IllegalStateException(String.format("Not fond rate by security symbol: %s", CurrencyCode.CNY.getKey()));
} }
BigDecimal rateValue = rates.getValue(); BigDecimal rateValue = rates.getValue();
BigDecimal sum3 = sum1.divide(BigDecimal.valueOf(lotSize), 0, RoundingMode.DOWN); BigDecimal sum3 = sum1.divide(BigDecimal.valueOf(lotSize), 0, RoundingMode.UP);
BigDecimal sum4 = sum3.multiply(rateValue, MC).negate(); BigDecimal sum4 = sum3.multiply(rateValue, MC).negate();
BigDecimal sum5 = sum3.negate(); BigDecimal sum5 = sum3.negate();