feat: 补全金字塔选股
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.lanyuanxiaoyao.leopard.strategy;
|
package com.lanyuanxiaoyao.leopard.strategy;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator;
|
import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator;
|
||||||
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
||||||
@@ -32,7 +33,7 @@ public class StrategyApplication {
|
|||||||
@Transactional(rollbackOn = Throwable.class)
|
@Transactional(rollbackOn = Throwable.class)
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
public void test() {
|
public void test() {
|
||||||
var stocks = stockRepository.findAllByIndicatorsSizeGreaterThanEqual(6);
|
var stocks = stockRepository.findAllByIndicatorsSizeGreaterThanEqual(5);
|
||||||
var stocksMap = stocks.stream().collect(Collectors.toMap(Stock::getCode, stock -> stock));
|
var stocksMap = stocks.stream().collect(Collectors.toMap(Stock::getCode, stock -> stock));
|
||||||
var scores = stocks.stream().map(Stock::getCode).collect(Collectors.toMap(code -> code, code -> 0));
|
var scores = stocks.stream().map(Stock::getCode).collect(Collectors.toMap(code -> code, code -> 0));
|
||||||
for (Stock stock : stocks) {
|
for (Stock stock : stocks) {
|
||||||
@@ -41,9 +42,9 @@ public class StrategyApplication {
|
|||||||
.sorted((a, b) -> b.getYear() - a.getYear())
|
.sorted((a, b) -> b.getYear() - a.getYear())
|
||||||
.limit(5)
|
.limit(5)
|
||||||
.toList();
|
.toList();
|
||||||
var latestIndicator = recentIndicators.get(0);
|
var latestIndicator = recentIndicators.getFirst();
|
||||||
|
|
||||||
int roeScore = 0;
|
var roeScore = 0;
|
||||||
if (recentIndicators.stream().noneMatch(indicator -> indicator.getReturnOnEquity() == null || indicator.getReturnOnEquity() < 0)) {
|
if (recentIndicators.stream().noneMatch(indicator -> indicator.getReturnOnEquity() == null || indicator.getReturnOnEquity() < 0)) {
|
||||||
var averageRoe = recentIndicators.stream()
|
var averageRoe = recentIndicators.stream()
|
||||||
.map(FinanceIndicator::getReturnOnEquity)
|
.map(FinanceIndicator::getReturnOnEquity)
|
||||||
@@ -67,11 +68,10 @@ public class StrategyApplication {
|
|||||||
}
|
}
|
||||||
scores.put(stock.getCode(), scores.get(stock.getCode()) + roeScore);
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + roeScore);
|
||||||
|
|
||||||
int roaScore = 0;
|
var roaScore = 0;
|
||||||
if (recentIndicators.stream().noneMatch(indicator -> indicator.getReturnOnAssets() == null)) {
|
if (recentIndicators.stream().noneMatch(indicator -> indicator.getReturnOnAssets() == null)) {
|
||||||
var averageRoa = recentIndicators.stream()
|
var averageRoa = recentIndicators.stream()
|
||||||
.map(FinanceIndicator::getReturnOnAssets)
|
.map(FinanceIndicator::getReturnOnAssets)
|
||||||
.map(item -> ObjectUtil.defaultIfNull(item, 0.0))
|
|
||||||
.mapToDouble(Double::doubleValue)
|
.mapToDouble(Double::doubleValue)
|
||||||
.average()
|
.average()
|
||||||
.orElse(0.0);
|
.orElse(0.0);
|
||||||
@@ -85,11 +85,10 @@ public class StrategyApplication {
|
|||||||
}
|
}
|
||||||
scores.put(stock.getCode(), scores.get(stock.getCode()) + roaScore);
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + roaScore);
|
||||||
|
|
||||||
int netProfitScore = 0;
|
var netProfitScore = 0;
|
||||||
if (recentIndicators.stream().noneMatch(indicator -> indicator.getNetProfit() == null)) {
|
if (recentIndicators.stream().noneMatch(indicator -> indicator.getNetProfit() == null)) {
|
||||||
var averageNetProfit = recentIndicators.stream()
|
var averageNetProfit = recentIndicators.stream()
|
||||||
.map(FinanceIndicator::getNetProfit)
|
.map(FinanceIndicator::getNetProfit)
|
||||||
.map(item -> ObjectUtil.defaultIfNull(item, 0.0))
|
|
||||||
.mapToDouble(Double::doubleValue)
|
.mapToDouble(Double::doubleValue)
|
||||||
.average()
|
.average()
|
||||||
.orElse(0.0);
|
.orElse(0.0);
|
||||||
@@ -101,8 +100,14 @@ public class StrategyApplication {
|
|||||||
}
|
}
|
||||||
scores.put(stock.getCode(), scores.get(stock.getCode()) + netProfitScore);
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + netProfitScore);
|
||||||
|
|
||||||
int cashScore = 0;
|
var cashScore = 0;
|
||||||
if (ObjectUtil.isNotNull(latestIndicator.getTotalAssetsTurnover()) && ObjectUtil.isNotNull(latestIndicator.getCashAndCashEquivalentsToTotalAssetsRatio()) && (latestIndicator.getTotalAssetsTurnover() > 0.8 && latestIndicator.getCashAndCashEquivalentsToTotalAssetsRatio() >= 0.1 || latestIndicator.getTotalAssetsTurnover() <= 0.8 && latestIndicator.getCashAndCashEquivalentsToTotalAssetsRatio() >= 0.2)) {
|
if (
|
||||||
|
ArrayUtil.isAllNotNull(latestIndicator.getTotalAssetsTurnover(), latestIndicator.getCashAndCashEquivalentsToTotalAssetsRatio())
|
||||||
|
&& (
|
||||||
|
latestIndicator.getTotalAssetsTurnover() > 0.8 && latestIndicator.getCashAndCashEquivalentsToTotalAssetsRatio() >= 0.1
|
||||||
|
|| latestIndicator.getTotalAssetsTurnover() <= 0.8 && latestIndicator.getCashAndCashEquivalentsToTotalAssetsRatio() >= 0.2
|
||||||
|
)
|
||||||
|
) {
|
||||||
cashScore = 50;
|
cashScore = 50;
|
||||||
}
|
}
|
||||||
scores.put(stock.getCode(), scores.get(stock.getCode()) + cashScore);
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + cashScore);
|
||||||
@@ -113,7 +118,7 @@ public class StrategyApplication {
|
|||||||
if (ObjectUtil.isNotNull(latestIndicator.getDaysInventoryTurnover()) && latestIndicator.getDaysInventoryTurnover() <= 30) {
|
if (ObjectUtil.isNotNull(latestIndicator.getDaysInventoryTurnover()) && latestIndicator.getDaysInventoryTurnover() <= 30) {
|
||||||
scores.put(stock.getCode(), scores.get(stock.getCode()) + 20);
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + 20);
|
||||||
}
|
}
|
||||||
if (ObjectUtil.isNotNull(latestIndicator.getDaysAccountsReceivableTurnover()) && ObjectUtil.isNotNull(latestIndicator.getDaysInventoryTurnover())) {
|
if (ArrayUtil.isAllNotNull(latestIndicator.getDaysAccountsReceivableTurnover(), latestIndicator.getDaysInventoryTurnover())) {
|
||||||
if (latestIndicator.getDaysAccountsReceivableTurnover() + latestIndicator.getDaysInventoryTurnover() <= 40) {
|
if (latestIndicator.getDaysAccountsReceivableTurnover() + latestIndicator.getDaysInventoryTurnover() <= 40) {
|
||||||
scores.put(stock.getCode(), scores.get(stock.getCode()) + 20);
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + 20);
|
||||||
} else if (latestIndicator.getDaysAccountsReceivableTurnover() + latestIndicator.getDaysInventoryTurnover() <= 60) {
|
} else if (latestIndicator.getDaysAccountsReceivableTurnover() + latestIndicator.getDaysInventoryTurnover() <= 60) {
|
||||||
@@ -131,6 +136,73 @@ public class StrategyApplication {
|
|||||||
scores.put(stock.getCode(), scores.get(stock.getCode()) + 50);
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var operatingSafeMarginScore = 0;
|
||||||
|
if (ObjectUtil.isNotNull(latestIndicator.getOperatingSafetyMarginRatio())) {
|
||||||
|
if (latestIndicator.getOperatingSafetyMarginRatio() >= 70) {
|
||||||
|
operatingSafeMarginScore = 50;
|
||||||
|
} else if (latestIndicator.getOperatingSafetyMarginRatio() >= 50) {
|
||||||
|
operatingSafeMarginScore = 30;
|
||||||
|
} else if (latestIndicator.getOperatingSafetyMarginRatio() >= 30) {
|
||||||
|
operatingSafeMarginScore = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + operatingSafeMarginScore);
|
||||||
|
|
||||||
|
var netProfitAscendingScore = 0;
|
||||||
|
if (recentIndicators.stream().noneMatch(indicator -> indicator.getNetProfit() == null)) {
|
||||||
|
if (recentIndicators.get(0).getNetProfit() > recentIndicators.get(1).getNetProfit()) {
|
||||||
|
netProfitAscendingScore += 30;
|
||||||
|
} else {
|
||||||
|
netProfitAscendingScore -= 30;
|
||||||
|
}
|
||||||
|
if (recentIndicators.get(1).getNetProfit() > recentIndicators.get(2).getNetProfit()) {
|
||||||
|
netProfitAscendingScore += 25;
|
||||||
|
} else {
|
||||||
|
netProfitAscendingScore -= 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recentIndicators.get(2).getNetProfit() > recentIndicators.get(3).getNetProfit()) {
|
||||||
|
netProfitAscendingScore += 20;
|
||||||
|
} else {
|
||||||
|
netProfitAscendingScore -= 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recentIndicators.get(3).getNetProfit() > recentIndicators.get(4).getNetProfit()) {
|
||||||
|
netProfitAscendingScore += 15;
|
||||||
|
} else {
|
||||||
|
netProfitAscendingScore -= 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + netProfitAscendingScore);
|
||||||
|
|
||||||
|
var cashAscendingScore = 0;
|
||||||
|
if (recentIndicators.stream().noneMatch(indicator -> indicator.getCashAndCashEquivalents() == null)) {
|
||||||
|
if (recentIndicators.get(0).getCashAndCashEquivalents() > recentIndicators.get(1).getCashAndCashEquivalents()) {
|
||||||
|
cashAscendingScore += 30;
|
||||||
|
} else {
|
||||||
|
cashAscendingScore -= 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recentIndicators.get(1).getCashAndCashEquivalents() > recentIndicators.get(2).getCashAndCashEquivalents()) {
|
||||||
|
cashAscendingScore += 25;
|
||||||
|
} else {
|
||||||
|
cashAscendingScore -= 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recentIndicators.get(2).getCashAndCashEquivalents() > recentIndicators.get(3).getCashAndCashEquivalents()) {
|
||||||
|
cashAscendingScore += 20;
|
||||||
|
} else {
|
||||||
|
cashAscendingScore -= 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recentIndicators.get(3).getCashAndCashEquivalents() > recentIndicators.get(4).getCashAndCashEquivalents()) {
|
||||||
|
cashAscendingScore += 15;
|
||||||
|
} else {
|
||||||
|
cashAscendingScore -= 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scores.put(stock.getCode(), scores.get(stock.getCode()) + cashAscendingScore);
|
||||||
}
|
}
|
||||||
scores.entrySet()
|
scores.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
|
|||||||
Reference in New Issue
Block a user