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) {
T validatedObject = ctx.getValidatedObject();
Imdg<OrderCurrency> imdg = ctx.obtainMap(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
OrderCurrency existOrder = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
ImdgPredicateBuilder pb = imdg.predicateBuilder();
Collection<OrderCurrency> orders = imdg.getCollectionObjectsByPredicate(
pb.and(
pb.equals("tradingClearingRegistryId", validatedObject.getTradingClearingRegistryId()),
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()) {

View file

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