diff --git a/leopard-server/src/main/resources/application.yml b/leopard-server/src/main/resources/application.yml index a51f1e7..3a7fb88 100644 --- a/leopard-server/src/main/resources/application.yml +++ b/leopard-server/src/main/resources/application.yml @@ -22,7 +22,6 @@ spring: startup-delay: 30s job-store-type: jdbc jdbc: - # platform: mysql platform: postgres # initialize-schema: always properties: diff --git a/leopard-server/src/main/resources/logback-spring.xml b/leopard-server/src/main/resources/logback-spring.xml index 0bb27ac..a857bbe 100644 --- a/leopard-server/src/main/resources/logback-spring.xml +++ b/leopard-server/src/main/resources/logback-spring.xml @@ -30,12 +30,8 @@ - - - - - + \ No newline at end of file diff --git a/leopard-server/src/test/resources/tushare.http b/leopard-server/src/test/resources/tushare.http index 2aaa3be..19eabf8 100644 --- a/leopard-server/src/test/resources/tushare.http +++ b/leopard-server/src/test/resources/tushare.http @@ -144,18 +144,15 @@ POST {{api_url}} Content-Type: application/json { - "api_name": "income", + "api_name": "income_vip", "token": "{{api_key}}", "params": { - "ts_code": "000001.SZ", - "period": "20241231" + "ts_code": "000799.SZ", + "period": "20191231" }, "fields": [ - "ts_code", - "ann_date", - "total_revenue", - "total_cogs", - "n_income" + "revenue", + "total_revenue" ] } @@ -196,41 +193,14 @@ Content-Type: application/json "api_name": "balancesheet_vip", "token": "{{api_key}}", "params": { - "ts_code": "000001.SZ", - "period": "20241231" + "ts_code": "000799.SZ", + "period": "20191231" }, "fields": [ - "ts_code", - "total_share", - "cap_rese", - "undistr_porfit", - "money_cap", "accounts_receiv", - "inventories", - "total_cur_assets", - "lt_eqt_invest", - "lt_rec", - "fix_assets", - "r_and_d", - "goodwill", - "total_nca", - "total_assets", - "lt_borr", - "st_borr", - "acct_payable", - "adv_receipts", - "total_cur_liab", - "total_ncl", - "total_liab", - "total_hldr_eqy_exc_min_int", - "total_hldr_eqy_inc_min_int", - "total_liab_hldr_eqy", - "acc_receivable", - "payables", "accounts_receiv_bill", - "accounts_pay", "oth_rcv_total", - "fix_assets_total" + "acc_receivable" ] } 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 9d88845..4c74b3d 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 @@ -1,26 +1,26 @@ package com.lanyuanxiaoyao.leopard.strategy; -import com.lanyuanxiaoyao.leopard.core.entity.Daily; -import com.lanyuanxiaoyao.leopard.core.entity.Daily_; -import com.lanyuanxiaoyao.leopard.core.entity.QDaily; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import com.lanyuanxiaoyao.leopard.core.entity.BalanceSheet; +import com.lanyuanxiaoyao.leopard.core.entity.CashFlow; +import com.lanyuanxiaoyao.leopard.core.entity.Income; +import com.lanyuanxiaoyao.leopard.core.entity.QBalanceSheet; +import com.lanyuanxiaoyao.leopard.core.entity.QCashFlow; +import com.lanyuanxiaoyao.leopard.core.entity.QIncome; +import com.lanyuanxiaoyao.leopard.core.repository.BalanceSheetRepository; +import com.lanyuanxiaoyao.leopard.core.repository.CashFlowRepository; import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository; +import com.lanyuanxiaoyao.leopard.core.repository.IncomeRepository; import com.lanyuanxiaoyao.leopard.core.repository.StockRepository; import jakarta.annotation.Resource; import jakarta.transaction.Transactional; -import java.time.Duration; -import java.time.ZoneId; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; -import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.ta4j.core.BaseBar; -import org.ta4j.core.BaseBarSeriesBuilder; -import org.ta4j.core.indicators.EMAIndicator; -import org.ta4j.core.indicators.helpers.ClosePriceIndicator; -import org.ta4j.core.num.DoubleNum; @Slf4j @SpringBootApplication(scanBasePackages = "com.lanyuanxiaoyao.leopard") @@ -30,6 +30,12 @@ public class StrategyApplication { private StockRepository stockRepository; @Resource private DailyRepository dailyRepository; + @Resource + private BalanceSheetRepository balanceSheetRepository; + @Resource + private IncomeRepository incomeRepository; + @Resource + private CashFlowRepository cashFlowRepository; public static void main(String[] args) { SpringApplication.run(StrategyApplication.class, args); @@ -38,32 +44,76 @@ public class StrategyApplication { @Transactional(rollbackOn = Throwable.class) @EventListener(ApplicationReadyEvent.class) public void test() { - var dailies = dailyRepository.findAll(QDaily.daily.stock.code.eq("000001.SZ"), Sort.by(Daily_.TRADE_DATE)); - var series = new BaseBarSeriesBuilder() - .withNumTypeOf(DoubleNum.class) - .build(); - log.info("{}", dailies.size()); - for (Daily daily : dailies) { - series.addBar(new BaseBar( - Duration.ofDays(1), - daily.getTradeDate().plusDays(1).atStartOfDay(ZoneId.systemDefault()), - DoubleNum.valueOf(daily.getOpen() * daily.getFactor()), - DoubleNum.valueOf(daily.getHigh() * daily.getFactor()), - DoubleNum.valueOf(daily.getLow() * daily.getFactor()), - DoubleNum.valueOf(daily.getClose() * daily.getFactor()), - DoubleNum.valueOf(daily.getVolume()), - DoubleNum.valueOf(daily.getPriceChangeAmount()), - daily.getTurnover().longValue() - )); + var code = "000799.SZ"; + for (int year = 2019; year <= 2019; year++) { + var balance = balanceSheetRepository.findOne( + QBalanceSheet.balanceSheet.stock.code.eq(code) + .and(QBalanceSheet.balanceSheet.year.eq(year)) + ).orElseThrow(); + var income = incomeRepository.findOne( + QIncome.income.stock.code.eq(code) + .and(QIncome.income.year.eq(year)) + ).orElseThrow(); + var cashflow = cashFlowRepository.findOne( + QCashFlow.cashFlow.stock.code.eq(code) + .and(QCashFlow.cashFlow.year.eq(year)) + ).orElseThrow(); + log.info("{} {}", year, calculateFinanceIndicator(balance, income, cashflow)); } - var ema = new EMAIndicator(new ClosePriceIndicator(series), 5); - var emaValues = ema.stream().toList(); - log.info("{}", emaValues.size()); + } - for (int index = 0; index < dailies.size(); index++) { - var daily = dailies.get(index); - var emaValue = emaValues.get(index); - log.info("{} {} {} {} {}", daily.getTradeDate().toString(), daily.getClose(), daily.getFactor(), daily.getClose() * daily.getFactor(), emaValue.doubleValue()); + private FinanceIndicator calculateFinanceIndicator(BalanceSheet balance, Income income, CashFlow cashflow) { + return new FinanceIndicator( + safeDiv(balance.getTotalLiabilities(), balance.getTotalAssets()), + safeDiv(balance.getTotalAssets(), balance.getTotalNonCurrentAssets()), + safeDiv(balance.getTotalCurrentAssets(), balance.getTotalCurrentLiabilities()), + 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()) + ); + } + + private Double safePlus(Double a, Double b) { + if (ObjectUtil.isNull(a) || ObjectUtil.isNull(b)) { + return null; + } + return a + b; + } + + private Double safeMinus(Double a, Double b) { + if (ObjectUtil.isNull(a) || ObjectUtil.isNull(b)) { + return null; + } + return a - b; + } + + private Double safeDiv(Double a, Double b) { + if (ObjectUtil.isNull(a) || ObjectUtil.isNull(b) || b == 0) { + return null; + } + return NumberUtil.div(a, b, 4); + } + + public record FinanceIndicator( + Double debtToAssetRatio, + Double longTermFundsToRealEstateRatio, + Double currentRatio, + Double quickRatio, + Double accountsReceivableTurnoverRate, + Double averageCashCollectionDays, + Double inventoryTurnoverRate + ) { + @Override + public String toString() { + return "负债占资产比率=" + debtToAssetRatio + + ", 长期资金占固定资产比率=" + longTermFundsToRealEstateRatio + + ", 流动比率=" + currentRatio + + ", 速动比率=" + quickRatio + + ", 应收账款周转率=" + accountsReceivableTurnoverRate + + ", 平均现金回收天数=" + averageCashCollectionDays + + ", 库存周转率=" + inventoryTurnoverRate + + ';'; } } } diff --git a/leopard-strategy/src/main/resources/application.yml b/leopard-strategy/src/main/resources/application.yml index d6c0fe5..6fcbf15 100644 --- a/leopard-strategy/src/main/resources/application.yml +++ b/leopard-strategy/src/main/resources/application.yml @@ -2,9 +2,13 @@ spring: application: name: leopard-strategy datasource: - url: jdbc:postgresql://192.168.31.127:6785/leopard + url: jdbc:postgresql://81.71.3.24:6785/leopard_dev username: leopard password: '9NEzFzovnddf@PyEP?e*AYAWnCyd7UhYwQK$pJf>7?ccFiN^x4$eKEZ5~E<7<+~X' driver-class-name: org.postgresql.Driver + jpa: + generate-ddl: false + main: + banner-mode: off fenix: print-banner: false diff --git a/leopard-strategy/src/main/resources/logback-spring.xml b/leopard-strategy/src/main/resources/logback-spring.xml index 732f71d..8587748 100644 --- a/leopard-strategy/src/main/resources/logback-spring.xml +++ b/leopard-strategy/src/main/resources/logback-spring.xml @@ -14,10 +14,10 @@ - + - + \ No newline at end of file diff --git a/leopard-web/src/pages/stock/StockDetail.tsx b/leopard-web/src/pages/stock/StockDetail.tsx index a7a4948..ad96d36 100644 --- a/leopard-web/src/pages/stock/StockDetail.tsx +++ b/leopard-web/src/pages/stock/StockDetail.tsx @@ -49,7 +49,7 @@ const financePropertyLabel = (id: string | undefined, label: string, type: strin actionType: 'dialog', dialog: { title: `${label}五年趋势`, - size: 'md', + size: 'lg', bodyClassName: 'p-0', ...readOnlyDialogOptions(), body: {