This commit is contained in:
parent
c8716d1c08
commit
d686200604
1 changed files with 83 additions and 5 deletions
|
|
@ -3,6 +3,7 @@ package ru.spcex.clearing.dflt.management.listener;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.time.DayOfWeek;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
@ -22,6 +23,7 @@ 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;
|
||||||
|
import ru.clearing.classes.statics.data.scheduler.ClearingCalendar;
|
||||||
import ru.clearing.classes.statics.data.security.CurrencyPairSecurity;
|
import ru.clearing.classes.statics.data.security.CurrencyPairSecurity;
|
||||||
import ru.clearing.classes.statics.data.security.Rates;
|
import ru.clearing.classes.statics.data.security.Rates;
|
||||||
import ru.clearing.classes.statics.data.security.RiskParameter;
|
import ru.clearing.classes.statics.data.security.RiskParameter;
|
||||||
|
|
@ -34,6 +36,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.misc.OvernightSettingsNew
|
||||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||||
import ru.spcex.clearing.util.security.UserRoleVerification;
|
import ru.spcex.clearing.util.security.UserRoleVerification;
|
||||||
import ru.spcex.platform.enumeration.CompanyRole;
|
import ru.spcex.platform.enumeration.CompanyRole;
|
||||||
|
import ru.spcex.platform.enumeration.DayStatus;
|
||||||
import ru.spcex.platform.enumeration.MarketType;
|
import ru.spcex.platform.enumeration.MarketType;
|
||||||
import ru.spcex.platform.enumeration.OvernightType;
|
import ru.spcex.platform.enumeration.OvernightType;
|
||||||
import ru.spcex.platform.enumeration.Side;
|
import ru.spcex.platform.enumeration.Side;
|
||||||
|
|
@ -61,6 +64,7 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
private final Imdg<Market> marketImdg;
|
private final Imdg<Market> marketImdg;
|
||||||
private final Imdg<RiskParameter> riskParameterImdg;
|
private final Imdg<RiskParameter> riskParameterImdg;
|
||||||
private final Imdg<Rates> ratesImdg;
|
private final Imdg<Rates> ratesImdg;
|
||||||
|
private final Imdg<ClearingCalendar> clearingCalendarImdg;
|
||||||
private final DefaultManagementSettings settings;
|
private final DefaultManagementSettings settings;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
@ -84,6 +88,7 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class);
|
this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class);
|
||||||
this.riskParameterImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
|
this.riskParameterImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
|
||||||
this.ratesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Rates, Rates.class);
|
this.ratesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Rates, Rates.class);
|
||||||
|
this.clearingCalendarImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingCalendar, ClearingCalendar.class);
|
||||||
this.orderCurrencyService = orderCurrencyService;
|
this.orderCurrencyService = orderCurrencyService;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
@ -378,6 +383,16 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
RiskParameter riskParameter,
|
RiskParameter riskParameter,
|
||||||
Side side,
|
Side side,
|
||||||
String comment) {
|
String comment) {
|
||||||
|
CurrencyPairSecurity currencyPairSecurity = currencyPairSecurityImdg.getSingleObjectByID(listing.getSecurityId());
|
||||||
|
CurrencyPairDictionary currencyPairDictionary = currencyPairDictionaryImdg
|
||||||
|
.getSingleObjectByID(currencyPairSecurity.getCurrencyPairId());
|
||||||
|
|
||||||
|
BigDecimal s = defineTransferRate(currencyPairDictionary.getId(), registry.getSecuritySymbol());
|
||||||
|
BigDecimal n = numberOfDaysOfTransfer();
|
||||||
|
CalculationResultHolder resultHolder = calculationSwapSums(registry, listing.getLotSize().intValue(), s, n);
|
||||||
|
BigDecimal quantityLot = resultHolder.getSum3().abs();
|
||||||
|
BigDecimal price = swapPriceCalc(currencyPairDictionary.getBaseCurrency(), s, n);
|
||||||
|
|
||||||
orderCurrency.setOvernightType("SWAP");
|
orderCurrency.setOvernightType("SWAP");
|
||||||
orderCurrency.setMarket(market.getCode());
|
orderCurrency.setMarket(market.getCode());
|
||||||
orderCurrency.setListingId(listing.getId());
|
orderCurrency.setListingId(listing.getId());
|
||||||
|
|
@ -390,6 +405,8 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
orderCurrency.setStatus("CRET");
|
orderCurrency.setStatus("CRET");
|
||||||
orderCurrency.setComment(comment);
|
orderCurrency.setComment(comment);
|
||||||
orderCurrency.setRegistryId(registry.getId());
|
orderCurrency.setRegistryId(registry.getId());
|
||||||
|
orderCurrency.setPrice(price);
|
||||||
|
orderCurrency.setQuantityLot(quantityLot);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Listing findListingForRub(Registry registry, String market) {
|
private Listing findListingForRub(Registry registry, String market) {
|
||||||
|
|
@ -468,7 +485,7 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
Registry amtRubRegistry = findAmtRegistry(registry, "RUB");
|
Registry amtRubRegistry = findAmtRegistry(registry, "RUB");
|
||||||
BigDecimal planPositionRub = amtRubRegistry.getBalance();
|
BigDecimal planPositionRub = amtRubRegistry.getBalance();
|
||||||
|
|
||||||
Rates rates = findRates(registry);
|
Rates rates = findRates(registry.getSecuritySymbol());
|
||||||
BigDecimal ratesValue = rates.getValue();
|
BigDecimal ratesValue = rates.getValue();
|
||||||
|
|
||||||
BigDecimal sum2 = planPositionRub.divide(ratesValue, lotSize, RoundingMode.HALF_DOWN);
|
BigDecimal sum2 = planPositionRub.divide(ratesValue, lotSize, RoundingMode.HALF_DOWN);
|
||||||
|
|
@ -495,7 +512,7 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
//registry.securitySymbol == 'RUB'
|
//registry.securitySymbol == 'RUB'
|
||||||
private CalculationResultHolder calculationSwapRubSums(Registry registry, Integer lotSize, BigDecimal s, BigDecimal n) {
|
private CalculationResultHolder calculationSwapRubSums(Registry registry, Integer lotSize, BigDecimal s, BigDecimal n) {
|
||||||
BigDecimal planPosition = registry.getBalance();
|
BigDecimal planPosition = registry.getBalance();
|
||||||
Rates cnyRates = findRates(registry);
|
Rates cnyRates = findRates(registry.getSecuritySymbol());
|
||||||
BigDecimal ratesValue = cnyRates.getValue();
|
BigDecimal ratesValue = cnyRates.getValue();
|
||||||
BigDecimal sum1 = planPosition.divide(ratesValue, MC);
|
BigDecimal sum1 = planPosition.divide(ratesValue, MC);
|
||||||
|
|
||||||
|
|
@ -535,11 +552,11 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Rates findRates(Registry registry) {
|
private Rates findRates(String securitySymbol) {
|
||||||
ImdgPredicateBuilder predicateBuilder = registryImdg.predicateBuilder();
|
ImdgPredicateBuilder predicateBuilder = registryImdg.predicateBuilder();
|
||||||
return ratesImdg.getSingleObjectByPredicate(
|
return ratesImdg.getSingleObjectByPredicate(
|
||||||
predicateBuilder.and(
|
predicateBuilder.and(
|
||||||
predicateBuilder.equals("currency", registry.getSecuritySymbol()),
|
predicateBuilder.equals("currency", securitySymbol),
|
||||||
predicateBuilder.equals("valueDate", LocalDate.now()),
|
predicateBuilder.equals("valueDate", LocalDate.now()),
|
||||||
predicateBuilder.equals("workflowStatus", WorkflowStatus.Active.getKey())
|
predicateBuilder.equals("workflowStatus", WorkflowStatus.Active.getKey())
|
||||||
)
|
)
|
||||||
|
|
@ -557,6 +574,39 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BigDecimal swapPriceCalc(String baseCurrency, BigDecimal s, BigDecimal n) {
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
ImdgPredicateBuilder predicateBuilder = ratesImdg.predicateBuilder();
|
||||||
|
BigDecimal daysInYear = BigDecimal.valueOf(365);
|
||||||
|
|
||||||
|
Rates rates = ratesImdg.getSingleObjectByPredicate(
|
||||||
|
predicateBuilder.and(
|
||||||
|
predicateBuilder.equals("currency", baseCurrency),
|
||||||
|
predicateBuilder.equals("valueDate", now),
|
||||||
|
predicateBuilder.equals("workflowStatus", WorkflowStatus.Active.getKey())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
BigDecimal rateValue = rates.getValue();
|
||||||
|
return rateValue.multiply(s, MC).multiply(n, MC).divide(daysInYear, MC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal defineTransferRate(Long currencyPairDictionaryId, String securitySymbol) {
|
||||||
|
ImdgPredicateBuilder predicateBuilder = riskParameterImdg.predicateBuilder();
|
||||||
|
String securitySymbolCondition = securitySymbol.equals("RUB") ? "CNY" : securitySymbol;
|
||||||
|
RiskParameter riskParameter = riskParameterImdg.getSingleObjectByPredicate(
|
||||||
|
predicateBuilder.and(
|
||||||
|
predicateBuilder.equals("settlementType", "T0"),
|
||||||
|
predicateBuilder.equals("currencyPairId", currencyPairDictionaryId),
|
||||||
|
predicateBuilder.equals("baseCurrency", securitySymbolCondition)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return riskParameter.getQuoteValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal numberOfDaysOfTransfer() {
|
||||||
|
LocalDate nextWorkingDay = findNextWorkingDate();
|
||||||
|
return BigDecimal.valueOf(nextWorkingDay.compareTo(LocalDate.now()));
|
||||||
|
}
|
||||||
public static BigDecimal ceilMath(BigDecimal value, BigDecimal significance) {
|
public static BigDecimal ceilMath(BigDecimal value, BigDecimal significance) {
|
||||||
if (significance == null || significance.compareTo(BigDecimal.ZERO) <= 0) {
|
if (significance == null || significance.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
throw new IllegalArgumentException("significance must be > 0");
|
throw new IllegalArgumentException("significance must be > 0");
|
||||||
|
|
@ -569,6 +619,34 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
|
||||||
return divided.multiply(significance);
|
return divided.multiply(significance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LocalDate findNextWorkingDate() {
|
||||||
|
LocalDate checkingDate = LocalDate.now().plusDays(1);
|
||||||
|
|
||||||
|
ImdgPredicateBuilder predicateBuilder = clearingCalendarImdg.predicateBuilder();
|
||||||
|
while (true) {
|
||||||
|
ClearingCalendar clearingCalendar = clearingCalendarImdg.getFirstObjectByPredicate(
|
||||||
|
predicateBuilder.equals("clearingDate", checkingDate)
|
||||||
|
);
|
||||||
|
DayOfWeek dayOfWeek = checkingDate.getDayOfWeek();
|
||||||
|
if (isWeekday(dayOfWeek)) {
|
||||||
|
if (clearingCalendar != null && DayStatus.Workday.equalsByKey(clearingCalendar.getDayStatus())) {
|
||||||
|
return checkingDate;
|
||||||
|
}
|
||||||
|
checkingDate = checkingDate.plusDays(1);
|
||||||
|
} else {
|
||||||
|
if (clearingCalendar != null && DayStatus.DayOff.equalsByKey(clearingCalendar.getDayStatus())) {
|
||||||
|
checkingDate = checkingDate.plusDays(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return checkingDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWeekday(DayOfWeek dayOfWeek) {
|
||||||
|
return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
|
||||||
|
}
|
||||||
|
|
||||||
public static class CalculationResultHolder {
|
public static class CalculationResultHolder {
|
||||||
private BigDecimal sum1;
|
private BigDecimal sum1;
|
||||||
private BigDecimal sum2;
|
private BigDecimal sum2;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue