etreschenkov 2026-04-21 15:59:14 +03:00
parent 5ea4fff504
commit 2968cfb3d8
6 changed files with 41 additions and 31 deletions

View file

@ -1,6 +1,5 @@
package ru.spcex.clearing.dflt.management.model; package ru.spcex.clearing.dflt.management.model;
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.registry.Registry; import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.security.RiskParameter; import ru.clearing.classes.statics.data.security.RiskParameter;
@ -9,7 +8,6 @@ public class SwapContext {
private final Registry registry; private final Registry registry;
private final String orderCategory; private final String orderCategory;
private final Market market; private final Market market;
private final Listing listing;
private final RiskParameter riskParameter; private final RiskParameter riskParameter;
private final CounterpartyInfo categoryP; private final CounterpartyInfo categoryP;
private final CounterpartyInfo clcc; private final CounterpartyInfo clcc;
@ -19,7 +17,6 @@ public class SwapContext {
this.registry = builder.registry; this.registry = builder.registry;
this.orderCategory = builder.orderCategory; this.orderCategory = builder.orderCategory;
this.market = builder.market; this.market = builder.market;
this.listing = builder.listing;
this.riskParameter = builder.riskParameter; this.riskParameter = builder.riskParameter;
this.categoryP = builder.categoryP; this.categoryP = builder.categoryP;
this.clcc = builder.clcc; this.clcc = builder.clcc;
@ -38,10 +35,6 @@ public class SwapContext {
return market; return market;
} }
public Listing getListing() {
return listing;
}
public RiskParameter getRiskParameter() { public RiskParameter getRiskParameter() {
return riskParameter; return riskParameter;
} }
@ -66,7 +59,6 @@ public class SwapContext {
private Registry registry; private Registry registry;
private String orderCategory; private String orderCategory;
private Market market; private Market market;
private Listing listing;
private RiskParameter riskParameter; private RiskParameter riskParameter;
private CounterpartyInfo categoryP; private CounterpartyInfo categoryP;
private CounterpartyInfo clcc; private CounterpartyInfo clcc;
@ -87,11 +79,6 @@ public class SwapContext {
return this; return this;
} }
public Builder listing(Listing listing) {
this.listing = listing;
return this;
}
public Builder riskParameter(RiskParameter riskParameter) { public Builder riskParameter(RiskParameter riskParameter) {
this.riskParameter = riskParameter; this.riskParameter = riskParameter;
return this; return this;

View file

@ -4,6 +4,7 @@ import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.Company;
@ -68,7 +69,8 @@ public class ImdgQueryService {
ImdgPredicateBuilder builder = registryImdg.predicateBuilder(); ImdgPredicateBuilder builder = registryImdg.predicateBuilder();
ImdgPredicate registryPredicate = builder.and( ImdgPredicate registryPredicate = builder.and(
builder.regex("registryCode", "^PM.*T"), builder.regex("registryCode", "^PM.*T"),
builder.not(builder.equals("registryStatus", RegistryStatus.OK.getKey())) builder.not(builder.equals("registryStatus", RegistryStatus.OK.getKey())),
builder.equals("clearingDate", LocalDate.now())
); );
return registryImdg.getCollectionIdsByPredicate(registryPredicate); return registryImdg.getCollectionIdsByPredicate(registryPredicate);
@ -159,8 +161,14 @@ public class ImdgQueryService {
public Listing findListing(Registry registry, String marketCode) { public Listing findListing(Registry registry, String marketCode) {
return "RUB".equals(registry.getSecuritySymbol()) return "RUB".equals(registry.getSecuritySymbol())
? findListingForRub(registry, marketCode) ? findListingForRub(registry, marketCode, null)
: findListingForOtherCurrency(registry, marketCode); : findListingForOtherCurrency(registry, marketCode, null);
}
public Listing findListing(Registry registry, String marketCode, String settleCode) {
return "RUB".equals(registry.getSecuritySymbol())
? findListingForRub(registry, marketCode, settleCode)
: findListingForOtherCurrency(registry, marketCode, settleCode);
} }
public RiskParameter findRiskParameter(Registry registry) { public RiskParameter findRiskParameter(Registry registry) {
@ -208,9 +216,8 @@ public class ImdgQueryService {
return currencyPairDictionaryImdg.getSingleObjectByID(security.getCurrencyPairId()); return currencyPairDictionaryImdg.getSingleObjectByID(security.getCurrencyPairId());
} }
private Listing findListingForRub(Registry registry, String marketCode) { private Listing findListingForRub(Registry registry, String marketCode, String settleCode) {
ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder(); ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder();
CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate( CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate(
pb.and( pb.and(
pb.equals("baseCurrency", "CNY"), pb.equals("baseCurrency", "CNY"),
@ -218,8 +225,13 @@ public class ImdgQueryService {
) )
); );
ImdgPredicate settlementTypeCondition =
StringUtils.isNotEmpty(settleCode) ? pb.equals("settlementType", settleCode) : pb.alwaysTrue();
Collection<Long> securityIds = currencyPairSecurityImdg.getCollectionIdsByPredicate( Collection<Long> securityIds = currencyPairSecurityImdg.getCollectionIdsByPredicate(
pb.equals("currencyPairId", pair.getId()) pb.and(
pb.equals("currencyPairId", pair.getId()),
settlementTypeCondition
)
); );
return listingImdg.getSingleObjectByPredicate( return listingImdg.getSingleObjectByPredicate(
@ -230,7 +242,7 @@ public class ImdgQueryService {
); );
} }
private Listing findListingForOtherCurrency(Registry registry, String marketCode) { private Listing findListingForOtherCurrency(Registry registry, String marketCode, String settleCode) {
ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder(); ImdgPredicateBuilder pb = currencyPairDictionaryImdg.predicateBuilder();
CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate( CurrencyPairDictionary pair = currencyPairDictionaryImdg.getFirstObjectByPredicate(
@ -240,8 +252,13 @@ public class ImdgQueryService {
) )
); );
ImdgPredicate settlementTypeCondition =
StringUtils.isNotEmpty(settleCode) ? pb.equals("settlementType", settleCode) : pb.alwaysTrue();
Collection<Long> securityIds = currencyPairSecurityImdg.getCollectionIdsByPredicate( Collection<Long> securityIds = currencyPairSecurityImdg.getCollectionIdsByPredicate(
pb.equals("currencyPairId", pair.getId()) pb.and(
pb.equals("currencyPairId", pair.getId()),
settlementTypeCondition
)
); );
return listingImdg.getSingleObjectByPredicate( return listingImdg.getSingleObjectByPredicate(

View file

@ -31,7 +31,7 @@ public class OrderCalculationService {
public void calcAndEnrichSwap(OrderCurrency order, public void calcAndEnrichSwap(OrderCurrency order,
SwapContext context) { SwapContext context) {
Registry registry = context.getRegistry(); Registry registry = context.getRegistry();
Listing listing = context.getListing(); Listing listing = imdgQueryService.findListing(registry, context.getMarket().getCode(), order.getSettleCode());
CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryBySecurityId(listing.getSecurityId()); CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryBySecurityId(listing.getSecurityId());
BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol()); BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol());
@ -51,7 +51,7 @@ public class OrderCalculationService {
public void calcAndEnrichSpot(OrderCurrency order, public void calcAndEnrichSpot(OrderCurrency order,
SwapContext context) { SwapContext context) {
Registry registry = context.getRegistry(); Registry registry = context.getRegistry();
Listing listing = context.getListing(); Listing listing = imdgQueryService.findListing(registry, context.getMarket().getCode(), order.getSettleCode());
CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryBySecurityId(listing.getSecurityId()); CurrencyPairDictionary pair = imdgQueryService.getCurrencyPairDictionaryBySecurityId(listing.getSecurityId());
BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol()); BigDecimal s = imdgQueryService.defineTransferRate(pair.getId(), registry.getSecuritySymbol());
@ -88,7 +88,7 @@ public class OrderCalculationService {
BigDecimal rateValue = rates.getValue(); BigDecimal rateValue = rates.getValue();
BigDecimal sum2 = planPositionRub.divide(rateValue, lotSize, RoundingMode.HALF_DOWN); BigDecimal sum2 = planPositionRub.divide(rateValue, lotSize, RoundingMode.HALF_DOWN);
BigDecimal sum3 = sum1.setScale(0, RoundingMode.CEILING).min(sum2); BigDecimal sum3 = sum1.setScale(lotSize, RoundingMode.CEILING);
BigDecimal sum4 = sum3.multiply(rateValue, MC).negate(); BigDecimal sum4 = sum3.multiply(rateValue, MC).negate();
BigDecimal sum5 = sum3.negate(); BigDecimal sum5 = sum3.negate();
@ -113,7 +113,7 @@ public class OrderCalculationService {
BigDecimal planPositionCny = cnyRegistry.getBalance(); BigDecimal planPositionCny = cnyRegistry.getBalance();
BigDecimal sum2 = planPositionCny.divide(rateValue, lotSize, RoundingMode.HALF_DOWN); BigDecimal sum2 = planPositionCny.divide(rateValue, lotSize, RoundingMode.HALF_DOWN);
BigDecimal sum3 = sum1.setScale(0, RoundingMode.CEILING).min(sum2).negate(); BigDecimal sum3 = sum1.setScale(lotSize, RoundingMode.CEILING).min(sum2).negate();
BigDecimal sum4 = sum3.multiply(rateValue, MC).negate(); BigDecimal sum4 = sum3.multiply(rateValue, MC).negate();
BigDecimal sum5 = sum3.negate(); BigDecimal sum5 = sum3.negate();

View file

@ -1,5 +1,6 @@
package ru.spcex.clearing.dflt.management.service; package ru.spcex.clearing.dflt.management.service;
import java.time.Instant;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
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;
@ -208,6 +209,7 @@ public class OrderTemplateBuilder {
order.setStatus("CRET"); order.setStatus("CRET");
order.setComment(comment); order.setComment(comment);
order.setRegistryId(registry.getId()); order.setRegistryId(registry.getId());
order.setCreated(Instant.now());
} }
private Side resolvePrimaryTransferSide(Registry registry, SettleCode settleCode) { private Side resolvePrimaryTransferSide(Registry registry, SettleCode settleCode) {

View file

@ -3,7 +3,6 @@ package ru.spcex.clearing.dflt.management.service;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
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.registry.Registry; import ru.clearing.classes.statics.data.registry.Registry;
@ -12,6 +11,7 @@ import ru.spcex.clearing.dflt.management.model.CounterpartyInfo;
import ru.spcex.clearing.dflt.management.model.SwapContext; import ru.spcex.clearing.dflt.management.model.SwapContext;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.CompanyRole; import ru.spcex.platform.enumeration.CompanyRole;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.SettleCode; import ru.spcex.platform.enumeration.SettleCode;
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;
@ -22,6 +22,7 @@ public class SpotOvernightOrderService {
private final ImdgQueryService imdgQueryService; private final ImdgQueryService imdgQueryService;
private final Imdg<OrderCurrency> orderCurrencyImdg; private final Imdg<OrderCurrency> orderCurrencyImdg;
private final Imdg<Registry> registryImdg;
private final OrderTemplateBuilder templateBuilder; private final OrderTemplateBuilder templateBuilder;
private final OrderCalculationService swapCalculationService; private final OrderCalculationService swapCalculationService;
@ -31,6 +32,7 @@ public class SpotOvernightOrderService {
OrderCalculationService swapCalculationService) { OrderCalculationService swapCalculationService) {
this.imdgQueryService = imdgQueryService; this.imdgQueryService = imdgQueryService;
this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.templateBuilder = templateBuilder; this.templateBuilder = templateBuilder;
this.swapCalculationService = swapCalculationService; this.swapCalculationService = swapCalculationService;
} }
@ -39,7 +41,6 @@ public class SpotOvernightOrderService {
String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId()); String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId());
Market market = imdgQueryService.getSpotMarket(); Market market = imdgQueryService.getSpotMarket();
Listing listing = imdgQueryService.findListing(registry, market.getCode());
RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry); RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry);
CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P"); CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P");
CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC); CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC);
@ -49,7 +50,6 @@ public class SpotOvernightOrderService {
.registry(registry) .registry(registry)
.orderCategory(orderCategory) .orderCategory(orderCategory)
.market(market) .market(market)
.listing(listing)
.riskParameter(riskParameter) .riskParameter(riskParameter)
.categoryP(categoryP) .categoryP(categoryP)
.clcc(clcc) .clcc(clcc)
@ -86,6 +86,8 @@ public class SpotOvernightOrderService {
orderCurrencyImdg.insert(primaryBalancingT1); orderCurrencyImdg.insert(primaryBalancingT1);
orderCurrencyImdg.insert(counterBalancingT1); orderCurrencyImdg.insert(counterBalancingT1);
registry.setRegistryStatus(RegistryStatus.OK.getKey());
registryImdg.update(registry);
log.info("Spot orders created for registryId={}", registry.getId()); log.info("Spot orders created for registryId={}", registry.getId());
} }

View file

@ -3,7 +3,6 @@ package ru.spcex.clearing.dflt.management.service;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
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.registry.Registry; import ru.clearing.classes.statics.data.registry.Registry;
@ -12,6 +11,7 @@ import ru.spcex.clearing.dflt.management.model.CounterpartyInfo;
import ru.spcex.clearing.dflt.management.model.SwapContext; import ru.spcex.clearing.dflt.management.model.SwapContext;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.CompanyRole; import ru.spcex.platform.enumeration.CompanyRole;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.SettleCode; import ru.spcex.platform.enumeration.SettleCode;
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;
@ -22,6 +22,7 @@ public class SwapOvernightOrderService {
private final ImdgQueryService imdgQueryService; private final ImdgQueryService imdgQueryService;
private final Imdg<OrderCurrency> orderCurrencyImdg; private final Imdg<OrderCurrency> orderCurrencyImdg;
private final Imdg<Registry> registryImdg;
private final OrderTemplateBuilder templateBuilder; private final OrderTemplateBuilder templateBuilder;
private final OrderCalculationService swapCalculationService; private final OrderCalculationService swapCalculationService;
@ -31,6 +32,7 @@ public class SwapOvernightOrderService {
OrderCalculationService swapCalculationService) { OrderCalculationService swapCalculationService) {
this.imdgQueryService = imdgQueryService; this.imdgQueryService = imdgQueryService;
this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.templateBuilder = templateBuilder; this.templateBuilder = templateBuilder;
this.swapCalculationService = swapCalculationService; this.swapCalculationService = swapCalculationService;
} }
@ -39,7 +41,6 @@ public class SwapOvernightOrderService {
String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId()); String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId());
Market market = imdgQueryService.getSwapMarket(); Market market = imdgQueryService.getSwapMarket();
Listing listing = imdgQueryService.findListing(registry, market.getCode());
RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry); RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry);
CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P"); CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P");
CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC); CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC);
@ -49,7 +50,6 @@ public class SwapOvernightOrderService {
.registry(registry) .registry(registry)
.orderCategory(orderCategory) .orderCategory(orderCategory)
.market(market) .market(market)
.listing(listing)
.riskParameter(riskParameter) .riskParameter(riskParameter)
.categoryP(categoryP) .categoryP(categoryP)
.clcc(clcc) .clcc(clcc)
@ -71,6 +71,8 @@ public class SwapOvernightOrderService {
orderCurrencyImdg.insert(primaryBalancing); orderCurrencyImdg.insert(primaryBalancing);
orderCurrencyImdg.insert(counterBalancing); orderCurrencyImdg.insert(counterBalancing);
registry.setRegistryStatus(RegistryStatus.OK.getKey());
registryImdg.update(registry);
log.info("Swap orders created for registryId={}", registry.getId()); log.info("Swap orders created for registryId={}", registry.getId());
} }