This commit is contained in:
parent
5b6eb04345
commit
2b33c99f87
11 changed files with 276 additions and 14 deletions
|
|
@ -14,7 +14,7 @@ public class DefaultManagementSettings {
|
||||||
private HazelcastClientParams hazelcast;
|
private HazelcastClientParams hazelcast;
|
||||||
private KafkaConsumerSettings kafkaConsumer;
|
private KafkaConsumerSettings kafkaConsumer;
|
||||||
private KafkaProducerSettings kafkaProducer;
|
private KafkaProducerSettings kafkaProducer;
|
||||||
private String clearingSystem;
|
private String fileStoragePath;
|
||||||
|
|
||||||
public HazelcastClientParams getHazelcast() {
|
public HazelcastClientParams getHazelcast() {
|
||||||
return hazelcast;
|
return hazelcast;
|
||||||
|
|
@ -40,11 +40,11 @@ public class DefaultManagementSettings {
|
||||||
this.kafkaProducer = kafkaProducer;
|
this.kafkaProducer = kafkaProducer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClearingSystem() {
|
public String getFileStoragePath() {
|
||||||
return clearingSystem;
|
return fileStoragePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClearingSystem(String clearingSystem) {
|
public void setFileStoragePath(String fileStoragePath) {
|
||||||
this.clearingSystem = clearingSystem;
|
this.fileStoragePath = fileStoragePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package ru.spcex.clearing.dflt.management.listener;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import org.apache.kafka.clients.consumer.Consumer;
|
import org.apache.kafka.clients.consumer.Consumer;
|
||||||
|
|
@ -18,6 +19,7 @@ import ru.clearing.classes.statics.data.misc.Listing;
|
||||||
import ru.clearing.classes.statics.data.misc.Market;
|
import ru.clearing.classes.statics.data.misc.Market;
|
||||||
import ru.clearing.classes.statics.data.misc.OrderCurrency;
|
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.misc.SOrders;
|
||||||
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.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||||
import ru.clearing.classes.statics.data.security.Rates;
|
import ru.clearing.classes.statics.data.security.Rates;
|
||||||
|
|
@ -31,12 +33,14 @@ import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyNewRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyNewRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyUpdateRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyUpdateRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCurrencyStatusUpdateRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCurrencyUpdateRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCurrencyUpdateRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||||
import ru.spcex.clearing.platform.messaging.service.Status;
|
import ru.spcex.clearing.platform.messaging.service.Status;
|
||||||
import ru.spcex.clearing.util.security.UserRoleVerification;
|
import ru.spcex.clearing.util.security.UserRoleVerification;
|
||||||
import ru.spcex.platform.enumeration.MarketType;
|
import ru.spcex.platform.enumeration.MarketType;
|
||||||
|
import ru.spcex.platform.enumeration.OrderStatus;
|
||||||
import ru.spcex.platform.enumeration.OvernightType;
|
import ru.spcex.platform.enumeration.OvernightType;
|
||||||
import ru.spcex.platform.enumeration.SettleCode;
|
import ru.spcex.platform.enumeration.SettleCode;
|
||||||
import ru.spcex.platform.enumeration.Side;
|
import ru.spcex.platform.enumeration.Side;
|
||||||
|
|
@ -55,6 +59,7 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
private final Imdg<Registry> registryImdg;
|
private final Imdg<Registry> registryImdg;
|
||||||
private final Imdg<OvernightSettings> overnightSettingsImdg;
|
private final Imdg<OvernightSettings> overnightSettingsImdg;
|
||||||
private final Imdg<OrderCurrency> orderCurrencyImdg;
|
private final Imdg<OrderCurrency> orderCurrencyImdg;
|
||||||
|
private final Imdg<SOrders> sOrdersImdg;
|
||||||
private final Function<OrderCurrencyUpdateRequest, IValidator> orderCurrencyUpdateValidator;
|
private final Function<OrderCurrencyUpdateRequest, IValidator> orderCurrencyUpdateValidator;
|
||||||
private final Function<OrderCurrencyUpdateRequest, IValidator> overnightTypeUpdateValidator;
|
private final Function<OrderCurrencyUpdateRequest, IValidator> overnightTypeUpdateValidator;
|
||||||
private final Function<OrderCompanyNewRequest, IValidator> orderCompanyNewValidator;
|
private final Function<OrderCompanyNewRequest, IValidator> orderCompanyNewValidator;
|
||||||
|
|
@ -81,6 +86,7 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
super(kafkaQueue, kafkaProducer);
|
super(kafkaQueue, kafkaProducer);
|
||||||
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.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class);
|
||||||
|
this.sOrdersImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SOrders, SOrders.class);;
|
||||||
this.orderCurrencyUpdateValidator = orderCurrencyUpdateValidator;
|
this.orderCurrencyUpdateValidator = orderCurrencyUpdateValidator;
|
||||||
this.overnightTypeUpdateValidator = overnightTypeUpdateValidator;
|
this.overnightTypeUpdateValidator = overnightTypeUpdateValidator;
|
||||||
this.orderCompanyNewValidator = orderCompanyNewValidator;
|
this.orderCompanyNewValidator = orderCompanyNewValidator;
|
||||||
|
|
@ -110,6 +116,12 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
callback(CommonDeleteRequest.class)
|
callback(CommonDeleteRequest.class)
|
||||||
.setFunction(this::deleteCompany)
|
.setFunction(this::deleteCompany)
|
||||||
.forDestination(Consts.ORDER_CURRENCY_COMPANY_DELETE, callbacks::put);
|
.forDestination(Consts.ORDER_CURRENCY_COMPANY_DELETE, callbacks::put);
|
||||||
|
callback(OrderCurrencyStatusUpdateRequest.class)
|
||||||
|
.setConsumer(this::updateByImporter)
|
||||||
|
.forDestination(Consts.ORDER_CURRENCY_STATUS_UPDATE_IMPORTER, callbacks::put);
|
||||||
|
callback(OrderCurrencyStatusUpdateRequest.class)
|
||||||
|
.setConsumer(this::updateByFix)
|
||||||
|
.forDestination(Consts.ORDER_CURRENCY_STATUS_UPDATE_FIX, callbacks::put);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +191,7 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
Market market = imdgQueryService.getSpotMarket();
|
Market market = imdgQueryService.getSpotMarket();
|
||||||
Listing listing = imdgQueryService.findListing(rgs, market.getCode());
|
Listing listing = imdgQueryService.findListing(rgs, market.getCode());
|
||||||
//мб возвращать вместе с листингом?
|
//мб возвращать вместе с листингом?
|
||||||
CurrencyPairDictionary currPair = imdgQueryService.getCurrencyPairDictionaryByListing(listing);
|
CurrencyPairDictionary currPair = imdgQueryService.getCurrencyPairDictionaryBySecurityId(listing.getSecurityId());
|
||||||
Rates rate = imdgQueryService.getRate(currPair.getBaseCurrency(), LocalDate.now());
|
Rates rate = imdgQueryService.getRate(currPair.getBaseCurrency(), LocalDate.now());
|
||||||
|
|
||||||
var pair = new Pair<>(orderT0, orderT1);
|
var pair = new Pair<>(orderT0, orderT1);
|
||||||
|
|
@ -335,4 +347,54 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
|
||||||
orderCurrencyImdg.delete(counterOrder);
|
orderCurrencyImdg.delete(counterOrder);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateByImporter(BaseRequest<OrderCurrencyStatusUpdateRequest> req) {
|
||||||
|
OrderCurrencyStatusUpdateRequest payload = req.getRequestPayload();
|
||||||
|
for (Long orderId : payload.getIds()) {
|
||||||
|
SOrders sOrder = sOrdersImdg.getSingleObjectByID(orderId);
|
||||||
|
OrderCurrency orderCurrency = orderCurrencyImdg.getSingleObjectByID(orderId);
|
||||||
|
OrderStatus status = resolveStatusByImportState(sOrder.getState());
|
||||||
|
if (status == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
orderCurrency.setStatus(status.getKey());
|
||||||
|
orderCurrencyImdg.update(orderCurrency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void updateByFix(BaseRequest<OrderCurrencyStatusUpdateRequest> req) {
|
||||||
|
OrderCurrencyStatusUpdateRequest payload = req.getRequestPayload();
|
||||||
|
for (Long orderId : payload.getIds()) {
|
||||||
|
SOrders sOrder = sOrdersImdg.getSingleObjectByID(orderId);
|
||||||
|
OrderCurrency orderCurrency = orderCurrencyImdg.getSingleObjectByID(orderId);
|
||||||
|
OrderStatus status = resolveStatusByFixState(sOrder.getState());
|
||||||
|
if (status == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
orderCurrency.setStatus(status.getKey());
|
||||||
|
orderCurrencyImdg.update(orderCurrency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderStatus resolveStatusByImportState(String state) {
|
||||||
|
if (Arrays.asList("0", "1", "15").contains(state)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (state.equals("3")) {
|
||||||
|
return OrderStatus.NEW;
|
||||||
|
} else {
|
||||||
|
return OrderStatus.REJECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderStatus resolveStatusByFixState(String state) {
|
||||||
|
return switch (state) {
|
||||||
|
case "0" -> OrderStatus.NEW;
|
||||||
|
case "1" -> OrderStatus.PTFL;
|
||||||
|
case "2" -> OrderStatus.FILL;
|
||||||
|
case "4" -> OrderStatus.CNCL;
|
||||||
|
case "5" -> OrderStatus.REPL;
|
||||||
|
case "8" -> OrderStatus.REJECTED;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
package ru.spcex.clearing.dflt.management.listener;
|
package ru.spcex.clearing.dflt.management.listener;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
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;
|
||||||
|
|
@ -9,20 +15,26 @@ 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.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.spcex.clearing.dflt.management.config.settings.DefaultManagementSettings;
|
||||||
import ru.spcex.clearing.dflt.management.service.ImdgQueryService;
|
import ru.spcex.clearing.dflt.management.service.ImdgQueryService;
|
||||||
|
import ru.spcex.clearing.dflt.management.service.OrderCurrencyTriExportService;
|
||||||
import ru.spcex.clearing.dflt.management.service.SpotOvernightOrderService;
|
import ru.spcex.clearing.dflt.management.service.SpotOvernightOrderService;
|
||||||
import ru.spcex.clearing.dflt.management.service.SwapOvernightOrderService;
|
import ru.spcex.clearing.dflt.management.service.SwapOvernightOrderService;
|
||||||
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.Consts;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||||
import ru.spcex.platform.enumeration.OvernightType;
|
import ru.spcex.platform.enumeration.OvernightType;
|
||||||
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;
|
||||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||||
|
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TaskListener extends QueueConsumer implements InitializingBean {
|
public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
|
|
@ -31,6 +43,10 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
private final Imdg<Registry> registryImdg;
|
private final Imdg<Registry> registryImdg;
|
||||||
private final SwapOvernightOrderService swapOvernightOrderService;
|
private final SwapOvernightOrderService swapOvernightOrderService;
|
||||||
private final SpotOvernightOrderService spotOvernightOrderService;
|
private final SpotOvernightOrderService spotOvernightOrderService;
|
||||||
|
private final OrderCurrencyTriExportService orderCurrencyTriExportService;
|
||||||
|
private final KafkaSender kafkaSender;
|
||||||
|
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyymmddHHmmssSSS");
|
||||||
|
private final Path storagePath;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public TaskListener(Consumer<String, Object> kafkaQueue,
|
public TaskListener(Consumer<String, Object> kafkaQueue,
|
||||||
|
|
@ -38,12 +54,18 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
ImdgQueryService imdgQueryService,
|
ImdgQueryService imdgQueryService,
|
||||||
ImdgProvider imdgProvider,
|
ImdgProvider imdgProvider,
|
||||||
SwapOvernightOrderService swapOvernightOrderService,
|
SwapOvernightOrderService swapOvernightOrderService,
|
||||||
SpotOvernightOrderService spotOvernightOrderService) {
|
SpotOvernightOrderService spotOvernightOrderService,
|
||||||
|
OrderCurrencyTriExportService orderCurrencyTriExportService,
|
||||||
|
KafkaSender kafkaSender,
|
||||||
|
DefaultManagementSettings defaultManagementSettings) {
|
||||||
super(kafkaQueue, kafkaProducer);
|
super(kafkaQueue, kafkaProducer);
|
||||||
this.imdgQueryService = imdgQueryService;
|
this.imdgQueryService = imdgQueryService;
|
||||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||||
this.swapOvernightOrderService = swapOvernightOrderService;
|
this.swapOvernightOrderService = swapOvernightOrderService;
|
||||||
this.spotOvernightOrderService = spotOvernightOrderService;
|
this.spotOvernightOrderService = spotOvernightOrderService;
|
||||||
|
this.orderCurrencyTriExportService = orderCurrencyTriExportService;
|
||||||
|
this.kafkaSender = kafkaSender;
|
||||||
|
this.storagePath = Path.of(defaultManagementSettings.getFileStoragePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -51,6 +73,9 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
callback(LauncherCommandRequest.class)
|
callback(LauncherCommandRequest.class)
|
||||||
.setConsumer(this::createOrder)
|
.setConsumer(this::createOrder)
|
||||||
.forDestination(Task.CROR.topic(), callbacks::put);
|
.forDestination(Task.CROR.topic(), callbacks::put);
|
||||||
|
callback(LauncherCommandRequest.class)
|
||||||
|
.setConsumer(this::exportToTriAndSendToFix)
|
||||||
|
.forDestination(Task.SDOR.topic(), callbacks::put);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,6 +113,19 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
log.info("CROR createOrder finished");
|
log.info("CROR createOrder finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void exportToTriAndSendToFix(BaseRequest<LauncherCommandRequest> req) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Collection<OrderCurrency> orders = imdgQueryService.getClccOrderCurrencyIds();
|
||||||
|
String content = orderCurrencyTriExportService.exportToTri(orders);
|
||||||
|
Path fileName = storagePath.resolve(String.format("KS_TS_ORDERS_%s.tri",
|
||||||
|
LocalTime.now().format(formatter)));
|
||||||
|
Files.writeString(fileName, content, StandardCharsets.UTF_8);
|
||||||
|
kafkaSender.sendRequestToQueue(Consts.SDOR_FIX_TASK, req.getRequestPayload());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error while import order currency to tri file: {}", ExceptionUtils.getStackTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private OvernightType resolveOvernightType(Registry registry) {
|
private OvernightType resolveOvernightType(Registry registry) {
|
||||||
Optional<OvernightSettings> settingsOpt =
|
Optional<OvernightSettings> settingsOpt =
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import ru.clearing.classes.statics.data.company.Company;
|
||||||
import ru.clearing.classes.statics.data.company.CompanyRoleSet;
|
import ru.clearing.classes.statics.data.company.CompanyRoleSet;
|
||||||
import ru.clearing.classes.statics.data.misc.Listing;
|
import ru.clearing.classes.statics.data.misc.Listing;
|
||||||
import ru.clearing.classes.statics.data.misc.Market;
|
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.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||||
|
|
@ -42,6 +43,7 @@ public class ImdgQueryService {
|
||||||
private final Imdg<Rates> ratesImdg;
|
private final Imdg<Rates> ratesImdg;
|
||||||
private final Imdg<Registry> registryImdg;
|
private final Imdg<Registry> registryImdg;
|
||||||
private final Imdg<OvernightSettings> overnightSettingsImdg;
|
private final Imdg<OvernightSettings> overnightSettingsImdg;
|
||||||
|
private final Imdg<OrderCurrency> orderCurrencyImdg;
|
||||||
|
|
||||||
|
|
||||||
public ImdgQueryService(ImdgProvider imdgProvider) {
|
public ImdgQueryService(ImdgProvider imdgProvider) {
|
||||||
|
|
@ -57,6 +59,7 @@ public class ImdgQueryService {
|
||||||
this.ratesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Rates, Rates.class);
|
this.ratesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Rates, Rates.class);
|
||||||
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.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class);
|
||||||
|
this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
|
||||||
}
|
}
|
||||||
public Collection<Long> getCurrencyRegistry() {
|
public Collection<Long> getCurrencyRegistry() {
|
||||||
ImdgPredicateBuilder builder = registryImdg.predicateBuilder();
|
ImdgPredicateBuilder builder = registryImdg.predicateBuilder();
|
||||||
|
|
@ -68,6 +71,23 @@ public class ImdgQueryService {
|
||||||
return registryImdg.getCollectionIdsByPredicate(registryPredicate);
|
return registryImdg.getCollectionIdsByPredicate(registryPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<OrderCurrency> getClccOrderCurrencyIds() {
|
||||||
|
ImdgPredicateBuilder builder = orderCurrencyImdg.predicateBuilder();
|
||||||
|
CompanyRoleSet companyRoleSet = companyRoleSetImdg.getFirstObjectByPredicate(
|
||||||
|
builder.equals("companyRole", CompanyRole.CLCC.getKey())
|
||||||
|
);
|
||||||
|
|
||||||
|
ImdgPredicate clccOrderPredicate = builder.and(
|
||||||
|
builder.equals("status", "CRET"),
|
||||||
|
builder.or(
|
||||||
|
builder.equals("companyId", companyRoleSet.getCompanyId()),
|
||||||
|
builder.equals("counterPartyId", companyRoleSet.getCompanyId())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return orderCurrencyImdg.getCollectionObjectsByPredicate(clccOrderPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<OvernightSettings> findOvernightSettingsByCompany(Long companyId) {
|
public Optional<OvernightSettings> findOvernightSettingsByCompany(Long companyId) {
|
||||||
ImdgPredicateBuilder builder = overnightSettingsImdg.predicateBuilder();
|
ImdgPredicateBuilder builder = overnightSettingsImdg.predicateBuilder();
|
||||||
ImdgPredicate predicate = builder.and(
|
ImdgPredicate predicate = builder.and(
|
||||||
|
|
@ -170,8 +190,8 @@ public class ImdgQueryService {
|
||||||
return riskParameter.getQuoteValue();
|
return riskParameter.getQuoteValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CurrencyPairDictionary getCurrencyPairDictionaryByListing(Listing listing) {
|
public CurrencyPairDictionary getCurrencyPairDictionaryBySecurityId(Long securityId) {
|
||||||
CurrencyPairSecurity security = currencyPairSecurityImdg.getSingleObjectByID(listing.getSecurityId());
|
CurrencyPairSecurity security = currencyPairSecurityImdg.getSingleObjectByID(securityId);
|
||||||
return currencyPairDictionaryImdg.getSingleObjectByID(security.getCurrencyPairId());
|
return currencyPairDictionaryImdg.getSingleObjectByID(security.getCurrencyPairId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class OrderCalculationService {
|
||||||
Registry registry = context.getRegistry();
|
Registry registry = context.getRegistry();
|
||||||
Listing listing = context.getListing();
|
Listing listing = context.getListing();
|
||||||
|
|
||||||
CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryByListing(listing);
|
CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryBySecurityId(listing.getSecurityId());
|
||||||
BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol());
|
BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol());
|
||||||
BigDecimal n = transferDateService.numberOfDaysOfTransfer();
|
BigDecimal n = transferDateService.numberOfDaysOfTransfer();
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ public class OrderCalculationService {
|
||||||
Registry registry = context.getRegistry();
|
Registry registry = context.getRegistry();
|
||||||
Listing listing = context.getListing();
|
Listing listing = context.getListing();
|
||||||
|
|
||||||
CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryByListing(listing);
|
CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryBySecurityId(listing.getSecurityId());
|
||||||
BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol());
|
BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol());
|
||||||
BigDecimal n = transferDateService.numberOfDaysOfTransfer();
|
BigDecimal n = transferDateService.numberOfDaysOfTransfer();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
package ru.spcex.clearing.dflt.management.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.clearing.classes.statics.data.misc.OrderCurrency;
|
||||||
|
import ru.clearing.classes.statics.data.security.Rates;
|
||||||
|
import ru.clearing.platform.dictionary.CurrencyPairDictionary;
|
||||||
|
import ru.spcex.platform.enumeration.OvernightType;
|
||||||
|
import ru.spcex.platform.enumeration.Side;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class OrderCurrencyTriExportService {
|
||||||
|
private final ImdgQueryService imdgQueryService;
|
||||||
|
private static final String ACTION = "Ввод внебиржевой заявки";
|
||||||
|
|
||||||
|
public OrderCurrencyTriExportService(
|
||||||
|
ImdgQueryService imdgQueryService) {
|
||||||
|
this.imdgQueryService = imdgQueryService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает содержимое tri-файла в виде строки.
|
||||||
|
*/
|
||||||
|
public String exportToTri(Collection<OrderCurrency> orders) {
|
||||||
|
return orders.stream()
|
||||||
|
.map(this::toTriLine)
|
||||||
|
.reduce((a, b) -> a + System.lineSeparator() + b)
|
||||||
|
.orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает содержимое tri-файла в байтах, чтобы можно было отдать как файл.
|
||||||
|
*/
|
||||||
|
public byte[] exportToTriBytes(List<OrderCurrency> orders) {
|
||||||
|
return exportToTri(orders).getBytes(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toTriLine(OrderCurrency orderCurrency) {
|
||||||
|
StringJoiner joiner = new StringJoiner(";", "", ";");
|
||||||
|
joiner.add("TRANS_ID=" + nullSafe(orderCurrency.getId()));
|
||||||
|
joiner.add("CLASSCODE=" + nullSafe(orderCurrency.getMarket()));
|
||||||
|
joiner.add("ACTION=" + ACTION);
|
||||||
|
joiner.add("Торговый счет=" + nullSafe(orderCurrency.getAccount()));
|
||||||
|
joiner.add("К/П=" + mapSide(orderCurrency.getSide()));
|
||||||
|
joiner.add("Класс=" + nullSafe(orderCurrency.getMarket()));
|
||||||
|
joiner.add("Инструмент=" + nullSafe(orderCurrency.getSecuritySymbol()));
|
||||||
|
joiner.add("Контрагент=" + nullSafe(orderCurrency.getCounterTradingCode()));
|
||||||
|
joiner.add("Цена=" + formatDecimal(orderCurrency.getPrice()));
|
||||||
|
joiner.add("Количество=" + formatDecimal(orderCurrency.getQuantityLot()));
|
||||||
|
joiner.add("Примечание=" + nullSafe(orderCurrency.getAccount()));
|
||||||
|
joiner.add("Ссылка=");
|
||||||
|
joiner.add("Код расчетов=" + nullSafe(orderCurrency.getSettleCode()));
|
||||||
|
joiner.add("На заявку №=");
|
||||||
|
joiner.add("Базовый курс=" + resolveBaseRate(orderCurrency));
|
||||||
|
|
||||||
|
return joiner.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String mapSide(String side) {
|
||||||
|
if (Side.BUY.equalsByKey(side)) {
|
||||||
|
return "Покупка";
|
||||||
|
}
|
||||||
|
if (Side.SELL.equalsByKey(side)) {
|
||||||
|
return "Продажа";
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Неизвестное значение side: " + side);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveBaseRate(OrderCurrency orderCurrency) {
|
||||||
|
if (OvernightType.SPOT.equalsByKey(orderCurrency.getOvernightType())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrencyPairDictionary currencyPairDictionary = imdgQueryService.getCurrencyPairDictionaryBySecurityId(orderCurrency.getSecurityId());
|
||||||
|
String baseCurrency = currencyPairDictionary.getBaseCurrency();
|
||||||
|
Rates rates = imdgQueryService.getRate(currencyPairDictionary.getBaseCurrency(), LocalDate.now());
|
||||||
|
|
||||||
|
if (rates == null || rates.getValue() == null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Не найден активный курс для валюты " + baseCurrency + " на дату " + LocalDate.now()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatDecimal(rates.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatDecimal(BigDecimal value) {
|
||||||
|
return value == null ? "" : value.toPlainString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String nullSafe(Object value) {
|
||||||
|
return value == null ? "" : String.valueOf(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
spring.main.web-application-type=none
|
spring.main.web-application-type=none
|
||||||
|
default-management.file-storage-path=/opt/storage/csv-impoter/
|
||||||
|
|
||||||
default-management.hazelcast.cluster-members=127.0.0.1:5701
|
default-management.hazelcast.cluster-members=127.0.0.1:5701
|
||||||
default-management.hazelcast.login=dev
|
default-management.hazelcast.login=dev
|
||||||
default-management.hazelcast.password=dev-pass
|
default-management.hazelcast.password=dev-pass
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ru.spcex.platform.enumeration;
|
||||||
|
|
||||||
|
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||||
|
|
||||||
|
public enum OrderStatus implements IEnumKey {
|
||||||
|
NEW("NEW"), PTFL("PTFL"), FILL("FILL"), CNCL("CNCL"), REPL("REPL"), REJECTED("RJCT");
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
OrderStatus(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -62,8 +62,9 @@ public enum Task implements IEnumKey {
|
||||||
makeFiles_MTCR("MTCR"), // Формирование файлов с МТКР
|
makeFiles_MTCR("MTCR"), // Формирование файлов с МТКР
|
||||||
CX84("CX84"), // Формирование отчета CCX84
|
CX84("CX84"), // Формирование отчета CCX84
|
||||||
GVTF("GVTF"), // Проведение сверки по регистрам AMAT и AMAF
|
GVTF("GVTF"), // Проведение сверки по регистрам AMAT и AMAF
|
||||||
LORT("LORT"), // Загрузка курсов валют
|
LORT("LORT"),
|
||||||
CROR("CROR"), // Загрузка курсов валют
|
CROR("CROR"),
|
||||||
|
SDOR("SDOR"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String key;
|
private final String key;
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,9 @@ public interface Consts {
|
||||||
String ORDER_CURRENCY_COMPANY_NEW = "order-currency-company-new";
|
String ORDER_CURRENCY_COMPANY_NEW = "order-currency-company-new";
|
||||||
String ORDER_CURRENCY_COMPANY_UPDATE = "order-currency-company-update";
|
String ORDER_CURRENCY_COMPANY_UPDATE = "order-currency-company-update";
|
||||||
String ORDER_CURRENCY_COMPANY_DELETE = "order-currency-company-delete";
|
String ORDER_CURRENCY_COMPANY_DELETE = "order-currency-company-delete";
|
||||||
|
String ORDER_CURRENCY_STATUS_UPDATE_IMPORTER = "order-currency-status-update-importer";
|
||||||
|
String ORDER_CURRENCY_STATUS_UPDATE_FIX = "order-currency-status-update-fix";
|
||||||
|
String SDOR_FIX_TASK = "sdor-fix-task";
|
||||||
String DESTINATION_SDF08_NEW = "s-df-08-new";
|
String DESTINATION_SDF08_NEW = "s-df-08-new";
|
||||||
String DESTINATION_SDF02_NEW = "s-df-02-new";
|
String DESTINATION_SDF02_NEW = "s-df-02-new";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.spcex.clearing.platform.messaging.domain.cud.order;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OrderCurrencyStatusUpdateRequest {
|
||||||
|
@JsonProperty
|
||||||
|
private List<Long> ids = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<Long> getIds() {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addId(Long id) {
|
||||||
|
if (id != null) {
|
||||||
|
ids.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue