From 0aa4c1aff95d481949bc28a6d0b133448c3330fa Mon Sep 17 00:00:00 2001 From: mianyang <784310601@qq.com> Date: Thu, 7 May 2026 00:24:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/download-second-board-profit-csv.md | 3 +++ internal/api/limit_second_profit_csv_handler.go | 10 +++++++--- internal/service/limit_board_service.go | 10 +++++----- internal/service/stock_service.go | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/download-second-board-profit-csv.md b/docs/download-second-board-profit-csv.md index ce86189..9ddd1a2 100644 --- a/docs/download-second-board-profit-csv.md +++ b/docs/download-second-board-profit-csv.md @@ -95,6 +95,7 @@ GET /api/v1/download/limit-board/second-board-profit-csv?tradeStartDate=2026-04- | `name` | `string` | `股票简称` | 股票简称 | | `market` | `string` | `市场` | 市场信息 | | `industry` | `string` | `行业` | 所属行业 | +| `open_pct_chg` | `number \| null` | `T日开盘涨跌幅%` | T 日开盘价相对 T-1 收盘价的涨跌幅百分比 | | `next_open_profitable` | `string` | `T+1开盘是否盈利` | T+1 开盘收益大于 0 时为 `是`,否则为 `否`;无次日数据时为 `无次日数据` | | `next_close_profitable` | `string` | `T+1收盘是否盈利` | T+1 收盘收益大于 0 时为 `是`,否则为 `否`;无次日数据时为 `无次日数据` | | `next_intraday_profitable` | `string` | `T+1盘中是否可盈利` | T+1 最高收益大于 0 时为 `是`,否则为 `否`;无次日数据时为 `无次日数据` | @@ -131,6 +132,7 @@ GET /api/v1/download/limit-board/second-board-profit-csv?tradeStartDate=2026-04- "name": "示例股份", "market": "主板", "industry": "软件开发", + "open_pct_chg": 1.36, "next_open_profitable": "是", "next_close_profitable": "否", "next_intraday_profitable": "是", @@ -162,6 +164,7 @@ CSV 字段顺序: | `股票简称` | 股票简称 | | `市场` | 市场信息 | | `行业` | 所属行业 | +| `T日开盘涨跌幅%` | T 日开盘价相对 T-1 收盘价的涨跌幅百分比 | | `T+1开盘是否盈利` | T+1 开盘收益大于 0 时为 `是`,否则为 `否`;无次日数据时为 `无次日数据` | | `T+1收盘是否盈利` | T+1 收盘收益大于 0 时为 `是`,否则为 `否`;无次日数据时为 `无次日数据` | | `T+1盘中是否可盈利` | T+1 最高收益大于 0 时为 `是`,否则为 `否`;无次日数据时为 `无次日数据` | diff --git a/internal/api/limit_second_profit_csv_handler.go b/internal/api/limit_second_profit_csv_handler.go index 666a8c8..99bb796 100644 --- a/internal/api/limit_second_profit_csv_handler.go +++ b/internal/api/limit_second_profit_csv_handler.go @@ -86,6 +86,7 @@ type secondProfitListItem struct { Name string `json:"name"` Market string `json:"market"` Industry string `json:"industry"` + OpenPctChg *float64 `json:"open_pct_chg"` NextOpenProfitable string `json:"next_open_profitable"` NextCloseProfitable string `json:"next_close_profitable"` NextIntradayProfitable string `json:"next_intraday_profitable"` @@ -344,11 +345,11 @@ INNER JOIN stock_limit_combined_data pl LEFT JOIN stock_limit_combined_data ppl ON ppl.ts_code = l.ts_code AND ppl.trade_date = c.previous_two_trade_date AND ppl.final_status = 1 LEFT JOIN stock_daily d - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = d.ts_code AND d.trade_date = l.trade_date + ON l.ts_code = d.ts_code AND d.trade_date = l.trade_date LEFT JOIN stock_daily pd - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = pd.ts_code AND pd.trade_date = c.previous_trade_date + ON l.ts_code = pd.ts_code AND pd.trade_date = c.previous_trade_date LEFT JOIN stock_daily nd - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = nd.ts_code AND nd.trade_date = c.next_trade_date + ON l.ts_code = nd.ts_code AND nd.trade_date = c.next_trade_date WHERE c.trade_date BETWEEN ? AND ? AND c.previous_trade_date IS NOT NULL AND c.previous_two_trade_date IS NOT NULL @@ -397,6 +398,7 @@ ORDER BY c.trade_date ASC, l.ts_code ASC` func secondProfitCSVHeaders() []string { return []string{ "交易日", "股票代码", "股票简称", "市场", "行业", + "T日开盘涨跌幅%", "T+1开盘是否盈利", "T+1收盘是否盈利", "T+1盘中是否可盈利", "T+1最高盈利%", "T+1最低盈利%", "开板次数", "换手率%", "首次涨停时间", "封单额", "成交额", @@ -410,6 +412,7 @@ func secondProfitCSVRecord(row secondProfitCSVRow) []string { row.Name, row.Market, row.Industry, + secondProfitFormatNullFloat(row.OpenPctChg), row.NextOpenProfitable, row.NextCloseProfitable, row.NextIntradayProfitable, @@ -430,6 +433,7 @@ func secondProfitBuildItem(row secondProfitCSVRow) secondProfitListItem { Name: row.Name, Market: row.Market, Industry: row.Industry, + OpenPctChg: secondProfitNullFloatPtr(row.OpenPctChg), NextOpenProfitable: row.NextOpenProfitable, NextCloseProfitable: row.NextCloseProfitable, NextIntradayProfitable: row.NextIntradayProfitable, diff --git a/internal/service/limit_board_service.go b/internal/service/limit_board_service.go index 18a7447..a83e483 100644 --- a/internal/service/limit_board_service.go +++ b/internal/service/limit_board_service.go @@ -358,7 +358,7 @@ func (s *LimitBoardService) loadCurrentLimitStocks(tradeDate string) ([]model.Li l.calc_vol AS vol FROM stock_limit_combined_data l LEFT JOIN stock_daily d - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = d.ts_code AND d.trade_date = l.trade_date + ON l.ts_code = d.ts_code AND d.trade_date = l.trade_date WHERE l.trade_date = ? AND l.final_status = 1 ORDER BY d.pct_chg DESC, l.ts_code ASC` @@ -402,9 +402,9 @@ func (s *LimitBoardService) loadLimitOpenCompareStocks(tradeDate, previousTradeD l.calc_vol AS vol FROM stock_limit_combined_data l LEFT JOIN stock_daily d - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = d.ts_code AND d.trade_date = l.trade_date + ON l.ts_code = d.ts_code AND d.trade_date = l.trade_date LEFT JOIN stock_daily pd - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = pd.ts_code AND pd.trade_date = ? + ON l.ts_code = pd.ts_code AND pd.trade_date = ? INNER JOIN stock_limit_combined_data pl ON pl.ts_code = l.ts_code AND pl.trade_date = ? AND pl.final_status = 1 WHERE l.trade_date = ? AND l.final_status = 1 @@ -448,9 +448,9 @@ func (s *LimitBoardService) loadLimitOpenThresholdStocks(tradeDate, previousTrad l.calc_vol AS vol FROM stock_limit_combined_data l LEFT JOIN stock_daily d - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = d.ts_code AND d.trade_date = l.trade_date + ON l.ts_code = d.ts_code AND d.trade_date = l.trade_date LEFT JOIN stock_daily pd - ON l.ts_code COLLATE utf8mb4_0900_ai_ci = pd.ts_code AND pd.trade_date = ? + ON l.ts_code = pd.ts_code AND pd.trade_date = ? INNER JOIN stock_limit_combined_data pl ON pl.ts_code = l.ts_code AND pl.trade_date = ? AND pl.final_status = 1 WHERE l.trade_date = ? AND l.final_status = 1 diff --git a/internal/service/stock_service.go b/internal/service/stock_service.go index 3ad54c9..6bd93ae 100644 --- a/internal/service/stock_service.go +++ b/internal/service/stock_service.go @@ -39,7 +39,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An // 查询涨停股 query := `SELECT l.ts_code, l.name, d.open, COALESCE(l.calc_high, d.high, 0) AS high FROM stock_limit_combined_data l - LEFT JOIN stock_daily d ON l.ts_code COLLATE utf8mb4_0900_ai_ci = d.ts_code AND l.trade_date = d.trade_date + LEFT JOIN stock_daily d ON l.ts_code = d.ts_code AND l.trade_date = d.trade_date WHERE l.trade_date = ? AND l.final_status = 1` if err := s.DB.Raw(query, startDate).Scan(&limits).Error; err != nil { -- 2.43.0