diff --git a/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/entity/FinanceIndicator.java b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/entity/FinanceIndicator.java new file mode 100644 index 0000000..2a3f445 --- /dev/null +++ b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/entity/FinanceIndicator.java @@ -0,0 +1,150 @@ +package com.lanyuanxiaoyao.leopard.core.entity; + +import com.lanyuanxiaoyao.leopard.core.Constants; +import com.lanyuanxiaoyao.service.template.entity.SimpleEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.FieldNameConstants; +import org.hibernate.annotations.Comment; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@Setter +@Getter +@ToString(callSuper = true) +@FieldNameConstants +@Entity +@DynamicUpdate +@DynamicInsert +@EntityListeners(AuditingEntityListener.class) +@Table(name = Constants.DATABASE_PREFIX + "finance_indicator") +public class FinanceIndicator extends SimpleEntity { + @ManyToOne + private Stock stock; + @Comment("年报年度") + private Integer year; + @Comment("总股本") + private Double totalShareCapital; + @Comment("资本公积金") + private Double capitalSurplus; + @Comment("盈余公积金") + private Double surplusReserve; + @Comment("未分配利润") + private Double undistributedProfit; + @Comment("现金及现金等价物") + private Double cashAndCashEquivalents; + @Comment("现金及现金等价物占总资产比率") + private Double cashAndCashEquivalentsToTotalAssetsRatio; + @Comment("应收账款") + private Double accountsReceivable; + @Comment("应收账款占总资产比率") + private Double accountsReceivableToTotalAssetsRatio; + @Comment("应付账款") + private Double accountsPayable; + @Comment("应付账款占总资产比率") + private Double accountsPayableToTotalAssetsRatio; + @Comment("存货") + private Double inventory; + @Comment("存货占总资产比率") + private Double inventoryToTotalAssetsRatio; + @Comment("商誉") + private Double goodwill; + @Comment("商誉占总资产比率") + private Double goodwillToTotalAssetsRatio; + @Comment("流动资产") + private Double currentAssets; + @Comment("流动资产占总资产比率") + private Double currentAssetsToTotalAssetsRatio; + @Comment("固定资产") + private Double fixedAssets; + @Comment("固定资产占总资产比率") + private Double fixedAssetsToTotalAssetsRatio; + @Comment("流动负债") + private Double currentLiabilities; + @Comment("流动负债占总资产比率") + private Double currentLiabilitiesToTotalAssetsRatio; + @Comment("流动负债占总负债比率") + private Double currentLiabilitiesToTotalLiabilitiesRatio; + @Comment("长期负债") + private Double longTermLiabilities; + @Comment("长期负债占总资产比率") + private Double longTermLiabilitiesToTotalAssetsRatio; + @Comment("长期负债占总负债比率") + private Double longTermLiabilitiesToTotalLiabilitiesRatio; + @Comment("总负债") + private Double totalLiabilities; + @Comment("负债占总资产比率") + private Double liabilitiesToTotalAssetsRatio; + @Comment("股东权益") + private Double shareholdersEquity; + @Comment("股东权益占总资产比率") + private Double shareholdersEquityToTotalAssetsRatio; + @Comment("总资产") + private Double totalAssets; + @Comment("营业收入") + private Double operatingRevenue; + @Comment("营业成本") + private Double operatingCost; + @Comment("营业利润") + private Double operatingProfit; + @Comment("营业支出") + private Double operatingExpenses; + @Comment("净利润") + private Double netProfit; + @Comment("经营活动现金流净额") + private Double netCashFlowFromOperatingActivities; + @Comment("营业活动现金流量") + private Double cashFlowFromOperatingActivities; + @Comment("投资活动现金流量") + private Double cashFlowFromInvestingActivities; + @Comment("筹资活动现金流量") + private Double cashFlowFromFinancingActivities; + @Comment("流动比率") + private Double currentRatio; + @Comment("速动比率") + private Double quickRatio; + @Comment("长期资金占固定资产比率") + private Double longTermFundsToFixedAssetsRatio; + @Comment("应收账款周转率") + private Double accountsReceivableTurnover; + @Comment("应收账款周转天数(平均收现天数)") + private Double daysAccountsReceivableTurnover; + @Comment("存货周转率") + private Double inventoryTurnover; + @Comment("存货周转天数(平均销货天数)") + private Double daysInventoryTurnover; + @Comment("固定资产周转率") + private Double fixedAssetsTurnover; + @Comment("固定资产周转天数") + private Double daysFixedAssetsTurnover; + @Comment("总资产周转率") + private Double totalAssetsTurnover; + @Comment("总资产周转天数") + private Double daysTotalAssetsTurnover; + @Comment("ROE") + private Double returnOnEquity; + @Comment("ROA") + private Double returnOnAssets; + @Comment("营业毛利率") + private Double operatingGrossProfitMargin; + @Comment("营业利益率") + private Double operatingProfitMargin; + @Comment("经营安全边际率") + private Double operatingSafetyMarginRatio; + @Comment("净利率") + private Double netProfitMargin; + @Comment("每股盈余") + private Double earningsPerShare; + @Comment("现金流量比率") + private Double cashFlowRatio; + @Comment("现金流量允当比率") + private Double cashFlowAdequacyRatio; + @Comment("现金再投资比率") + private Double cashReinvestmentRatio; +} diff --git a/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/entity/Stock.java b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/entity/Stock.java index 183c74b..29357aa 100644 --- a/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/entity/Stock.java +++ b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/entity/Stock.java @@ -73,6 +73,10 @@ public class Stock extends SimpleEntity { @ToString.Exclude private Set cashFlows; + @OneToMany(mappedBy = "stock", cascade = CascadeType.REMOVE) + @ToString.Exclude + private Set indicators; + @Getter @AllArgsConstructor public enum Market implements SimpleEnum { diff --git a/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/repository/FinanceIndicatorRepository.java b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/repository/FinanceIndicatorRepository.java new file mode 100644 index 0000000..dad687d --- /dev/null +++ b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/repository/FinanceIndicatorRepository.java @@ -0,0 +1,9 @@ +package com.lanyuanxiaoyao.leopard.core.repository; + +import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator; +import com.lanyuanxiaoyao.service.template.repository.SimpleRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FinanceIndicatorRepository extends SimpleRepository { +} diff --git a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/helper/NumberHelper.java b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/helper/NumberHelper.java index 87cb837..4adfca4 100644 --- a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/helper/NumberHelper.java +++ b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/helper/NumberHelper.java @@ -30,4 +30,25 @@ public class NumberHelper { var result = parseDouble(value); return ObjectUtil.isNull(result) ? null : ifSuccess.apply(result); } + + public static Double safePlus(Double a, Double b) { + if (ObjectUtil.isNull(a) || ObjectUtil.isNull(b)) { + return null; + } + return a + b; + } + + public static Double safeMinus(Double a, Double b) { + if (ObjectUtil.isNull(a) || ObjectUtil.isNull(b)) { + return null; + } + return a - b; + } + + public static Double safeDiv(Double a, Double b) { + if (ObjectUtil.isNull(a) || ObjectUtil.isNull(b) || b == 0) { + return null; + } + return NumberUtil.div(a, b, 4); + } } diff --git a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TuShareService.java b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TuShareService.java index 2bce51e..18307c0 100644 --- a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TuShareService.java +++ b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TuShareService.java @@ -3,9 +3,11 @@ package com.lanyuanxiaoyao.leopard.server.service; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -224,6 +226,24 @@ public class TuShareService { return tuShareResponse; } + public List> request(String api, Map params, List fields) throws JsonProcessingException { + var response = HttpUtil.post(API_URL, buildRequest(api, params, fields)); + var tuShareResponse = mapper.readValue(response, TuShareResponse.class); + if (tuShareResponse.code != 0) { + throw new RuntimeException(tuShareResponse.message); + } + var data = tuShareResponse.data; + var result = new ArrayList>(); + for (var item : data.items) { + var map = new HashMap(); + for (int i = 0; i < data.fields.size(); i++) { + map.put(data.fields.get(i), item.get(i)); + } + result.add(map); + } + return result; + } + public record TuShareResponse( Integer code, @JsonProperty("msg") diff --git a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/task/UpdateFinanceIndicatorNode.java b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/task/UpdateFinanceIndicatorNode.java new file mode 100644 index 0000000..02456b0 --- /dev/null +++ b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/task/UpdateFinanceIndicatorNode.java @@ -0,0 +1,174 @@ +package com.lanyuanxiaoyao.leopard.server.service.task; + +import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator; +import com.lanyuanxiaoyao.leopard.core.entity.Stock; +import com.lanyuanxiaoyao.leopard.core.repository.FinanceIndicatorRepository; +import com.lanyuanxiaoyao.leopard.core.repository.StockRepository; +import com.lanyuanxiaoyao.leopard.server.helper.NumberHelper; +import com.lanyuanxiaoyao.leopard.server.service.TaskService; +import com.lanyuanxiaoyao.leopard.server.service.TuShareService; +import com.yomahub.liteflow.annotation.LiteflowComponent; +import java.time.LocalDate; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@LiteflowComponent("update_finance_indicators") +public class UpdateFinanceIndicatorNode extends TaskNodeComponent { + private final FinanceIndicatorRepository financeIndicatorRepository; + private final StockRepository stockRepository; + + private final TuShareService tuShareService; + + protected UpdateFinanceIndicatorNode(TaskService taskService, FinanceIndicatorRepository financeIndicatorRepository, StockRepository stockRepository, TuShareService tuShareService) { + super(taskService); + this.financeIndicatorRepository = financeIndicatorRepository; + this.stockRepository = stockRepository; + this.tuShareService = tuShareService; + } + + @Override + public void process() throws Exception { + var stocks = stockRepository.findAll(); + var currentYear = LocalDate.now().getYear(); + for (int year = 1990; year < currentYear; year++) { + var balances = tuShareService.request( + "balancesheet_vip", + Map.of("period", LocalDate.of(year, 12, 31).format(TuShareService.TRADE_FORMAT)), + List.of( + "ts_code", + "total_share", + "cap_rese", + "surplus_rese", + "undistr_porfit", + "cash_reser_cb", + "accounts_receiv_bill", + "accounts_pay", + "inventories", + "goodwill", + "total_cur_assets", + "total_nca", + "total_cur_liab", + "total_ncl", + "total_liab", + "total_hldr_eqy_inc_min_int", + "total_assets" + ) + ); + var balancesMap = balances.stream().collect(Collectors.toMap(balance -> balance.get("ts_code"), balance -> balance)); + var incomes = tuShareService.request( + "income_vip", + Map.of("period", LocalDate.of(year, 12, 31).format(TuShareService.TRADE_FORMAT)), + List.of( + "ts_code", + "total_revenue", + "total_cogs", + "operate_profit", + "oper_exp", + "n_income" + ) + ); + var incomesMap = incomes.stream().collect(Collectors.toMap(income -> income.get("ts_code"), income -> income)); + var cashFlows = tuShareService.request( + "cashflow_vip", + Map.of("period", LocalDate.of(year, 12, 31).format(TuShareService.TRADE_FORMAT)), + List.of( + "n_cashflow_act", + "n_cashflow_inv_act", + "n_cash_flows_fnc_act" + ) + ); + var cashFlowsMap = cashFlows.stream().collect(Collectors.toMap(cashFlow -> cashFlow.get("ts_code"), cashFlow -> cashFlow)); + var finaIndicators = tuShareService.request( + "fina_indicator_vip", + Map.of("period", LocalDate.of(year, 12, 31).format(TuShareService.TRADE_FORMAT)), + List.of( + "ca_to_assets", + "nca_to_assets", + "currentdebt_to_debt", + "longdeb_to_debt", + "current_ratio", + "quick_ratio", + "ar_turn", + "arturn_days", + "inv_turn", + "invturn_days", + "fa_turn", + "assets_turn", + "roe_dt", + "roa", + "roa_dp", + "total_revenue_ps" + ) + ); + var finaIndicatorsMap = finaIndicators.stream().collect(Collectors.toMap(finaIndicator -> finaIndicator.get("ts_code"), finaIndicator -> finaIndicator)); + + for (Stock stock : stocks) { + var balance = balancesMap.get(stock.getCode()); + var income = incomesMap.get(stock.getCode()); + var cashFlow = cashFlowsMap.get(stock.getCode()); + var finaIndicator = finaIndicatorsMap.get(stock.getCode()); + var indicator = new FinanceIndicator(); + indicator.setStock(stock); + indicator.setYear(year); + indicator.setTotalAssets(NumberHelper.parseDouble(balance.get("total_assets"))); + indicator.setTotalShareCapital(NumberHelper.parseDouble(balance.get("total_share"))); + indicator.setCapitalSurplus(NumberHelper.parseDouble(balance.get("cap_rese"))); + indicator.setSurplusReserve(NumberHelper.parseDouble(balance.get("surplus_rese"))); + indicator.setUndistributedProfit(NumberHelper.parseDouble(balance.get("undistr_porfit"))); + indicator.setCashAndCashEquivalents(NumberHelper.parseDouble(balance.get("cash_reser_cb"))); + indicator.setCashAndCashEquivalentsToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getCashAndCashEquivalents(), indicator.getTotalAssets())); + indicator.setAccountsReceivable(NumberHelper.parseDouble(balance.get("accounts_receiv_bill"))); + indicator.setAccountsReceivableToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getAccountsReceivable(), indicator.getTotalAssets())); + indicator.setAccountsPayable(NumberHelper.parseDouble(balance.get("accounts_pay"))); + indicator.setAccountsPayableToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getAccountsPayable(), indicator.getTotalAssets())); + indicator.setInventory(NumberHelper.parseDouble(balance.get("inventories"))); + indicator.setInventoryToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getInventory(), indicator.getTotalAssets())); + indicator.setGoodwill(NumberHelper.parseDouble(balance.get("goodwill"))); + indicator.setGoodwillToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getGoodwill(), indicator.getTotalAssets())); + indicator.setCurrentAssets(NumberHelper.parseDouble(balance.get("total_cur_assets"))); + indicator.setCurrentAssetsToTotalAssetsRatio(NumberHelper.parseDouble(finaIndicator.get("ca_to_assets"))); + indicator.setFixedAssets(NumberHelper.parseDouble(balance.get("total_nca"))); + indicator.setFixedAssetsToTotalAssetsRatio(NumberHelper.parseDouble(finaIndicator.get("nca_to_assets"))); + indicator.setTotalLiabilities(NumberHelper.parseDouble(balance.get("total_liab"))); + indicator.setCurrentLiabilities(NumberHelper.parseDouble(balance.get("total_cur_liab"))); + indicator.setCurrentLiabilitiesToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getCurrentLiabilities(), indicator.getTotalAssets())); + indicator.setCurrentLiabilitiesToTotalLiabilitiesRatio(NumberHelper.parseDouble(finaIndicator.get("currentdebt_to_debt"))); + indicator.setLongTermLiabilities(NumberHelper.parseDouble(balance.get("total_ncl"))); + indicator.setLongTermLiabilitiesToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getLongTermLiabilities(), indicator.getTotalAssets())); + indicator.setLongTermLiabilitiesToTotalLiabilitiesRatio(NumberHelper.parseDouble(finaIndicator.get("longdeb_to_debt"))); + indicator.setLiabilitiesToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getTotalLiabilities(), indicator.getTotalAssets())); + indicator.setShareholdersEquity(NumberHelper.parseDouble(balance.get("total_hldr_eqy_inc_min_int"))); + indicator.setShareholdersEquityToTotalAssetsRatio(NumberHelper.safeDiv(indicator.getShareholdersEquity(), indicator.getTotalAssets())); + indicator.setOperatingRevenue(NumberHelper.parseDouble(income.get("total_revenue"))); + indicator.setOperatingCost(NumberHelper.parseDouble(income.get("total_cogs"))); + indicator.setOperatingProfit(NumberHelper.parseDouble(income.get("operate_profit"))); + indicator.setOperatingExpenses(NumberHelper.parseDouble(income.get("oper_exp"))); + indicator.setNetProfit(NumberHelper.parseDouble(income.get("n_income"))); + indicator.setCashFlowFromOperatingActivities(NumberHelper.parseDouble(cashFlow.get("n_cashflow_act"))); + indicator.setCashFlowFromInvestingActivities(NumberHelper.parseDouble(cashFlow.get("n_cashflow_inv_act"))); + indicator.setCashFlowFromFinancingActivities(NumberHelper.parseDouble(cashFlow.get("n_cash_flows_fnc_act"))); + indicator.setCurrentRatio(NumberHelper.parseDouble(finaIndicator.get("current_ratio"))); + indicator.setQuickRatio(NumberHelper.parseDouble(finaIndicator.get("quick_ratio"))); + indicator.setAccountsReceivableTurnover(NumberHelper.parseDouble(finaIndicator.get("ar_turn"))); + indicator.setDaysAccountsReceivableTurnover(NumberHelper.parseDouble(finaIndicator.get("arturn_days"))); + indicator.setInventoryTurnover(NumberHelper.parseDouble(finaIndicator.get("inv_turn"))); + indicator.setDaysInventoryTurnover(NumberHelper.parseDouble(finaIndicator.get("invturn_days"))); + indicator.setFixedAssetsTurnover(NumberHelper.parseDouble(finaIndicator.get("fa_turn"))); + indicator.setDaysFixedAssetsTurnover(NumberHelper.safeDiv(360.0, indicator.getFixedAssetsTurnover())); + indicator.setTotalAssetsTurnover(NumberHelper.parseDouble(finaIndicator.get("assets_turn"))); + indicator.setDaysTotalAssetsTurnover(NumberHelper.safeDiv(360.0, indicator.getTotalAssetsTurnover())); + indicator.setReturnOnEquity(NumberHelper.parseDouble(finaIndicator.get("roe_dt"))); + indicator.setReturnOnAssets(NumberHelper.parseDouble(finaIndicator.get("roa"))); + indicator.setOperatingGrossProfitMargin(NumberHelper.safeDiv(NumberHelper.safeMinus(indicator.getOperatingRevenue(), indicator.getOperatingCost()), indicator.getOperatingRevenue())); + indicator.setOperatingProfitMargin(NumberHelper.safeDiv(indicator.getOperatingProfit(), indicator.getOperatingRevenue())); + indicator.setOperatingSafetyMarginRatio(NumberHelper.safeDiv(indicator.getOperatingProfitMargin(), indicator.getOperatingGrossProfitMargin())); + indicator.setNetProfitMargin(NumberHelper.parseDouble(finaIndicator.get("roa_dp"))); + indicator.setEarningsPerShare(NumberHelper.parseDouble(finaIndicator.get("total_revenue_ps"))); + financeIndicatorRepository.save(indicator); + } + } + } +} diff --git a/leopard-server/src/test/resources/tushare.http b/leopard-server/src/test/resources/tushare.http index 19eabf8..5e01413 100644 --- a/leopard-server/src/test/resources/tushare.http +++ b/leopard-server/src/test/resources/tushare.http @@ -197,10 +197,8 @@ Content-Type: application/json "period": "20191231" }, "fields": [ - "accounts_receiv", - "accounts_receiv_bill", - "oth_rcv_total", - "acc_receivable" + "total_liab_hldr_eqy", + "total_assets" ] } @@ -212,13 +210,15 @@ Content-Type: application/json "api_name": "fina_indicator", "token": "{{api_key}}", "params": { - "ts_code": "000002.SZ", - "period": "20231231" + "ts_code": "600132.SH", + "period": "20191231" }, "fields": [ - "ann_date", - "ocf_to_shortdebt", - "currentdebt_to_debt" + "current_ratio", + "quick_ratio", + "invturn_days", + "arturn_days", + "ar_turn" ] } diff --git a/leopard-strategy/src/main/java/com/lanyuanxiaoyao/leopard/strategy/StrategyApplication.java b/leopard-strategy/src/main/java/com/lanyuanxiaoyao/leopard/strategy/StrategyApplication.java index 4c74b3d..989908d 100644 --- a/leopard-strategy/src/main/java/com/lanyuanxiaoyao/leopard/strategy/StrategyApplication.java +++ b/leopard-strategy/src/main/java/com/lanyuanxiaoyao/leopard/strategy/StrategyApplication.java @@ -44,7 +44,7 @@ public class StrategyApplication { @Transactional(rollbackOn = Throwable.class) @EventListener(ApplicationReadyEvent.class) public void test() { - var code = "000799.SZ"; + var code = "600132.SH"; for (int year = 2019; year <= 2019; year++) { var balance = balanceSheetRepository.findOne( QBalanceSheet.balanceSheet.stock.code.eq(code) @@ -70,7 +70,10 @@ public class StrategyApplication { safeDiv(safeMinus(balance.getTotalCurrentAssets(), balance.getInventories()), balance.getTotalCurrentLiabilities()), safeDiv(income.getOperatingRevenue(), balance.getNotesAndAccountsReceivable()), safeDiv(360.0, safeDiv(income.getOperatingRevenue(), balance.getNotesAndAccountsReceivable())), - safeDiv(income.getTotalOperatingCost(), balance.getInventories()) + safeDiv(income.getTotalOperatingCost(), balance.getInventories()), + safeDiv(360.0, safeDiv(income.getTotalOperatingCost(), balance.getInventories())), + safeDiv(income.getOperatingRevenue(), balance.getTotalAssets()), + safeDiv(income.getNetProfitIncludingMinorityInterest(), balance.getTotalShareholdersEquityExcludingMinorityInterest()) ); } @@ -102,7 +105,10 @@ public class StrategyApplication { Double quickRatio, Double accountsReceivableTurnoverRate, Double averageCashCollectionDays, - Double inventoryTurnoverRate + Double inventoryTurnoverRate, + Double averageSalesDays, + Double totalAssetTurnover, + Double roe ) { @Override public String toString() { @@ -113,6 +119,9 @@ public class StrategyApplication { ", 应收账款周转率=" + accountsReceivableTurnoverRate + ", 平均现金回收天数=" + averageCashCollectionDays + ", 库存周转率=" + inventoryTurnoverRate + + ", 平均销货天数=" + averageSalesDays + + ", 总资产周转率=" + totalAssetTurnover + + ", 股东权益报酬率(ROE)=" + roe + ';'; } }