diff --git a/src/experiment/learn_to_rank.ipynb b/src/experiment/learn_to_rank.ipynb index 435e6c0..22bfea2 100644 --- a/src/experiment/learn_to_rank.ipynb +++ b/src/experiment/learn_to_rank.ipynb @@ -1,15 +1,15 @@ { "cells": [ { - "cell_type": "markdown", "metadata": {}, + "cell_type": "markdown", "source": [ "# Learn-to-Rank 排序学习训练流程\n", - "\n", + "#\n", "本 Notebook 实现基于 LightGBM LambdaRank 的排序学习训练,用于股票排序任务。\n", - "\n", + "#\n", "## 核心特点\n", - "\n", + "#\n", "1. **Label 转换**: 将 `future_return_5` 按每日进行 20 分位数划分(qcut)\n", "2. **排序学习**: 使用 LambdaRank 目标函数,学习每日股票排序\n", "3. **NDCG 评估**: 使用 NDCG@1/5/10/20 评估排序质量\n", @@ -17,20 +17,15 @@ ] }, { - "cell_type": "markdown", "metadata": {}, - "source": [ - "## 1. 导入依赖" - ] + "cell_type": "markdown", + "source": "## 1. 导入依赖" }, { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:00.454472Z", - "start_time": "2026-03-11T13:27:55.535146Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "import os\n", "from datetime import datetime\n", @@ -53,41 +48,37 @@ " StandardScaler,\n", ")\n", "from src.training.components.models import LightGBMLambdaRankModel\n", - "from src.training.config import TrainingConfig" - ], - "outputs": [], - "execution_count": 1 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2. 辅助函数" + "from src.training.config import TrainingConfig\n", + "\n" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "## 2. 辅助函数" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:00.468024Z", - "start_time": "2026-03-11T13:28:00.460009Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ - "def create_factors_with_strings(engine: FactorEngine, factor_definitions: dict, label_factor: dict) -> List[str]:\n", - " \"\"\"使用字符串表达式注册因子\"\"\"\n", + "def create_factors_with_metadata(\n", + " engine: FactorEngine, factor_definitions: dict, label_factor: dict\n", + ") -> List[str]:\n", + " \"\"\"使用 metadata 注册因子(特征因子通过名称注册,label 因子通过表达式注册)\"\"\"\n", " print(\"=\" * 80)\n", - " print(\"使用字符串表达式定义因子\")\n", + " print(\"使用 metadata 注册因子\")\n", " print(\"=\" * 80)\n", "\n", - " # 注册所有特征因子\n", - " print(\"\\n注册特征因子:\")\n", - " for name, expr in factor_definitions.items():\n", - " engine.add_factor(name, expr)\n", - " print(f\" - {name}: {expr}\")\n", + " # 注册所有特征因子(通过 metadata 名称)\n", + " print(\"\\n注册特征因子(从 metadata):\")\n", + " for name in factor_definitions.keys():\n", + " engine.add_factor_by_name(name)\n", + " print(f\" - {name}\")\n", "\n", - " # 注册 label 因子\n", - " print(\"\\n注册 Label 因子:\")\n", + " # 注册 label 因子(通过表达式,因为 label 不在 metadata 中)\n", + " print(\"\\n注册 Label 因子(表达式):\")\n", " for name, expr in label_factor.items():\n", " engine.add_factor(name, expr)\n", " print(f\" - {name}: {expr}\")\n", @@ -138,69 +129,73 @@ " n_quantiles: int = 20,\n", ") -> Tuple[pl.DataFrame, str]:\n", " \"\"\"准备排序学习数据\n", - " \n", + "\n", " 将连续 label 转换为分位数标签,用于排序学习任务。\n", - " \n", + "\n", " Args:\n", " df: 原始数据\n", " label_col: 原始标签列名\n", " date_col: 日期列名\n", " n_quantiles: 分位数数量\n", - " \n", + "\n", " Returns:\n", " (处理后的 DataFrame, 新的标签列名)\n", " \"\"\"\n", " print(\"\\n\" + \"=\" * 80)\n", " print(f\"准备排序学习数据(将 {label_col} 转换为 {n_quantiles} 分位数标签)\")\n", " print(\"=\" * 80)\n", - " \n", + "\n", " # 新的标签列名\n", " rank_col = f\"{label_col}_rank\"\n", - " \n", + "\n", " # 按日期分组进行分位数划分\n", " # 使用 rank 生成 0, 1, 2, ..., n_quantiles-1 的标签\n", " # 方法: 计算每天内的排名,然后映射到 n_quantiles 个分位数组\n", - " df_ranked = df.with_columns(\n", - " # 计算每天内的排名 (1-based)\n", - " pl.col(label_col).rank(method=\"min\").over(date_col).alias(\"_rank\")\n", - " ).with_columns(\n", - " # 将排名转换为分位数标签 (0 to n_quantiles-1)\n", - " ((pl.col(\"_rank\") - 1) / pl.len().over(date_col) * n_quantiles)\n", - " .floor()\n", - " .cast(pl.Int64)\n", - " .clip(0, n_quantiles - 1)\n", - " .alias(rank_col)\n", - " ).drop(\"_rank\")\n", - " \n", + " df_ranked = (\n", + " df.with_columns(\n", + " # 计算每天内的排名 (1-based)\n", + " pl.col(label_col).rank(method=\"min\").over(date_col).alias(\"_rank\")\n", + " )\n", + " .with_columns(\n", + " # 将排名转换为分位数标签 (0 to n_quantiles-1)\n", + " ((pl.col(\"_rank\") - 1) / pl.len().over(date_col) * n_quantiles)\n", + " .floor()\n", + " .cast(pl.Int64)\n", + " .clip(0, n_quantiles - 1)\n", + " .alias(rank_col)\n", + " )\n", + " .drop(\"_rank\")\n", + " )\n", + "\n", " # 检查转换结果\n", " print(f\"\\n原始 {label_col} 统计:\")\n", " print(df_ranked[label_col].describe())\n", - " \n", + "\n", " print(f\"\\n转换后 {rank_col} 统计:\")\n", " print(df_ranked[rank_col].describe())\n", - " \n", + "\n", " # 检查每日样本分布\n", " print(f\"\\n每日样本数统计:\")\n", " daily_counts = df_ranked.group_by(date_col).agg(pl.count().alias(\"count\"))\n", " print(daily_counts[\"count\"].describe())\n", - " \n", + "\n", " # 检查分位数分布(应该是均匀的)\n", " print(f\"\\n分位数标签分布:\")\n", " rank_dist = df_ranked[rank_col].value_counts().sort(rank_col)\n", " print(rank_dist)\n", - " \n", + "\n", " return df_ranked, rank_col\n", "\n", "\n", "def compute_group_array(df: pl.DataFrame, date_col: str = \"trade_date\") -> np.ndarray:\n", " \"\"\"计算 group 数组用于 LambdaRank\n", - " \n", + "\n", " 每个日期作为一个 query,group 数组表示每个 query 的样本数。\n", - " \n", + "\n", " Args:\n", " df: 数据框\n", " date_col: 日期列名\n", - " \n", + "\n", " Returns:\n", " group 数组\n", " \"\"\"\n", @@ -217,29 +212,29 @@ " k_list: List[int] = [1, 5, 10, 20],\n", ") -> dict:\n", " \"\"\"计算 NDCG@k 指标\n", - " \n", + "\n", " Args:\n", " y_true: 真实标签\n", " y_pred: 预测分数\n", " group: 分组数组\n", " k_list: 要计算的 k 值列表\n", - " \n", + "\n", " Returns:\n", " NDCG 指标字典\n", " \"\"\"\n", " results = {}\n", - " \n", + "\n", " # 按 group 拆分数据\n", " start_idx = 0\n", " y_true_groups = []\n", " y_pred_groups = []\n", - " \n", + "\n", " for group_size in group:\n", " end_idx = start_idx + group_size\n", " y_true_groups.append(y_true[start_idx:end_idx])\n", " y_pred_groups.append(y_pred[start_idx:end_idx])\n", " start_idx = end_idx\n", - " \n", + "\n", " # 计算每个 k 值的平均 NDCG\n", " for k in k_list:\n", " ndcg_scores = []\n", @@ -251,32 +246,27 @@ " except ValueError:\n", " # 标签都相同,无法计算\n", " pass\n", - " \n", + "\n", " results[f\"ndcg@{k}\"] = np.mean(ndcg_scores) if ndcg_scores else 0.0\n", - " \n", + "\n", " return results\n", "\n" - ], - "outputs": [], - "execution_count": 2 + ] }, { - "cell_type": "markdown", "metadata": {}, + "cell_type": "markdown", "source": [ "## 3. 配置参数\n", - "\n", + "#\n", "### 3.1 因子定义" ] }, { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:00.479401Z", - "start_time": "2026-03-11T13:28:00.472206Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "# 特征因子定义字典(复用 regression.ipynb 的因子定义)\n", "LABEL_NAME = \"future_return_5_rank\"\n", @@ -295,7 +285,6 @@ " \"mom_acceleration_10_20\": \"(close / (ts_delay(close, 10) + 1e-8) - 1) - (ts_delay(close, 10) / (ts_delay(close, 20) + 1e-8) - 1)\",\n", " \"drawdown_from_high_60\": \"close / (ts_max(high, 60) + 1e-8) - 1\",\n", " \"up_days_ratio_20\": \"ts_sum(close > ts_delay(close, 1), 20) / 20\",\n", - "\n", " # ================= 2. 波动率、风险调整与高阶矩 =================\n", " \"volatility_5\": \"ts_std(close, 5)\",\n", " \"volatility_20\": \"ts_std(close, 20)\",\n", @@ -304,13 +293,11 @@ " \"sharpe_ratio_20\": \"ts_mean(close / (ts_delay(close, 1) + 1e-8) - 1, 20) / (ts_std(close / (ts_delay(close, 1) + 1e-8) - 1, 20) + 1e-8)\",\n", " \"min_ret_20\": \"ts_min(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\",\n", " \"volatility_squeeze_5_60\": \"ts_std(close, 5) / (ts_std(close, 60) + 1e-8)\",\n", - "\n", " # ================= 3. 日内微观结构与异象 =================\n", " \"overnight_intraday_diff\": \"(open / (ts_delay(close, 1) + 1e-8) - 1) - (close / (open + 1e-8) - 1)\",\n", " \"upper_shadow_ratio\": \"(high - ((open + close + abs(open - close)) / 2)) / (high - low + 1e-8)\",\n", " \"capital_retention_20\": \"ts_sum(abs(close - open), 20) / (ts_sum(high - low, 20) + 1e-8)\",\n", " \"max_ret_20\": \"ts_max(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\",\n", - "\n", " # ================= 4. 量能、流动性与量价背离 =================\n", " \"volume_ratio_5_20\": \"ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)\",\n", " \"turnover_rate_mean_5\": \"ts_mean(turnover_rate, 5)\",\n", @@ -319,7 +306,6 @@ " \"turnover_cv_20\": \"ts_std(turnover_rate, 20) / (ts_mean(turnover_rate, 20) + 1e-8)\",\n", " \"pv_corr_20\": \"ts_corr(close / (ts_delay(close, 1) + 1e-8) - 1, vol, 20)\",\n", " \"close_vwap_deviation\": \"close / (amount / (vol * 100 + 1e-8) + 1e-8) - 1\",\n", - "\n", " # ================= 5. 基本面财务特征 =================\n", " \"roe\": \"n_income / (total_hldr_eqy_exc_min_int + 1e-8)\",\n", " \"roa\": \"n_income / (total_assets + 1e-8)\",\n", @@ -329,7 +315,6 @@ " \"net_profit_yoy\": \"(n_income / (ts_delay(n_income, 252) + 1e-8)) - 1\",\n", " \"revenue_yoy\": \"(revenue / (ts_delay(revenue, 252) + 1e-8)) - 1\",\n", " \"healthy_expansion_velocity\": \"(total_assets / (ts_delay(total_assets, 252) + 1e-8) - 1) - (total_liab / (ts_delay(total_liab, 252) + 1e-8) - 1)\",\n", - "\n", " # ================= 6. 基本面估值与截面动量共振 =================\n", " \"EP\": \"n_income / (total_mv * 10000 + 1e-8)\",\n", " \"BP\": \"total_hldr_eqy_exc_min_int / (total_mv * 10000 + 1e-8)\",\n", @@ -348,25 +333,18 @@ "LABEL_FACTOR = {\n", " LABEL_NAME: \"(ts_delay(close, -5) / ts_delay(open, -1)) - 1\",\n", "}" - ], - "outputs": [], - "execution_count": 3 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2 训练参数配置" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 3.2 训练参数配置" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:00.489508Z", - "start_time": "2026-03-11T13:28:00.483843Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "# 日期范围配置(正确的 train/val/test 三分法)\n", "TRAIN_START = \"20200101\"\n", @@ -408,10 +386,11 @@ " StandardScaler(feature_cols=FEATURE_COLS),\n", "]\n", "\n", + "\n", "# 股票池筛选函数\n", "def stock_pool_filter(df: pl.DataFrame) -> pl.Series:\n", " \"\"\"股票池筛选函数(单日数据)\n", - " \n", + "\n", " 筛选条件:\n", " 1. 排除创业板(代码以 300 开头)\n", " 2. 排除科创板(代码以 688 开头)\n", @@ -419,19 +398,20 @@ " 4. 选取当日市值最小的500只股票\n", " \"\"\"\n", " code_filter = (\n", - " ~df[\"ts_code\"].str.starts_with(\"30\") &\n", - " ~df[\"ts_code\"].str.starts_with(\"68\") &\n", - " ~df[\"ts_code\"].str.starts_with(\"8\") &\n", - " ~df[\"ts_code\"].str.starts_with(\"9\") &\n", - " ~df[\"ts_code\"].str.starts_with(\"4\")\n", + " ~df[\"ts_code\"].str.starts_with(\"30\")\n", + " & ~df[\"ts_code\"].str.starts_with(\"68\")\n", + " & ~df[\"ts_code\"].str.starts_with(\"8\")\n", + " & ~df[\"ts_code\"].str.starts_with(\"9\")\n", + " & ~df[\"ts_code\"].str.starts_with(\"4\")\n", " )\n", - " \n", + "\n", " valid_df = df.filter(code_filter)\n", " n = min(1000, len(valid_df))\n", " small_cap_codes = valid_df.sort(\"total_mv\").head(n)[\"ts_code\"]\n", - " \n", + "\n", " return df[\"ts_code\"].is_in(small_cap_codes)\n", "\n", + "\n", "STOCK_FILTER_REQUIRED_COLUMNS = [\"total_mv\"]\n", "\n", "# 输出配置\n", @@ -441,37 +421,30 @@ "\n", "# Top N 配置:每日推荐股票数量\n", "TOP_N = 5 # 可调整为 10, 20 等" - ], - "outputs": [], - "execution_count": 4 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4. 训练流程" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "## 4. 训练流程" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:24.494829Z", - "start_time": "2026-03-11T13:28:00.494691Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"LightGBM LambdaRank 排序学习训练\")\n", "print(\"=\" * 80)\n", "\n", - "# 1. 创建 FactorEngine\n", + "# 1. 创建 FactorEngine(启用 metadata 功能)\n", "print(\"\\n[1] 创建 FactorEngine\")\n", - "engine = FactorEngine()\n", + "engine = FactorEngine(metadata_path=\"data/factors.jsonl\")\n", "\n", - "# 2. 使用字符串表达式定义因子\n", - "print(\"\\n[2] 定义因子(字符串表达式)\")\n", - "feature_cols = create_factors_with_strings(engine, FACTOR_DEFINITIONS, LABEL_FACTOR)\n", + "# 2. 使用 metadata 定义因子\n", + "print(\"\\n[2] 定义因子(从 metadata 注册)\")\n", + "feature_cols = create_factors_with_metadata(engine, FACTOR_DEFINITIONS, LABEL_FACTOR)\n", "\n", "# 3. 准备数据\n", "print(\"\\n[3] 准备数据\")\n", @@ -534,238 +507,18 @@ " feature_cols=feature_cols,\n", " persist_model=PERSIST_MODEL,\n", ")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "LightGBM LambdaRank 排序学习训练\n", - "================================================================================\n", - "\n", - "[1] 创建 FactorEngine\n", - "\n", - "[2] 定义因子(字符串表达式)\n", - "================================================================================\n", - "使用字符串表达式定义因子\n", - "================================================================================\n", - "\n", - "注册特征因子:\n", - " - ma_5: ts_mean(close, 5)\n", - " - ma_20: ts_mean(close, 20)\n", - " - ma_ratio_5_20: ts_mean(close, 5) / (ts_mean(close, 20) + 1e-8) - 1\n", - " - bias_10: close / (ts_mean(close, 10) + 1e-8) - 1\n", - " - high_low_ratio: (close - ts_min(low, 20)) / (ts_max(high, 20) - ts_min(low, 20) + 1e-8)\n", - " - bbi_ratio: (ts_mean(close, 3) + ts_mean(close, 6) + ts_mean(close, 12) + ts_mean(close, 24)) / (4 * close + 1e-8)\n", - " - return_5: (close / (ts_delay(close, 5) + 1e-8)) - 1\n", - " - return_20: (close / (ts_delay(close, 20) + 1e-8)) - 1\n", - " - kaufman_ER_20: abs(close - ts_delay(close, 20)) / (ts_sum(abs(close - ts_delay(close, 1)), 20) + 1e-8)\n", - " - mom_acceleration_10_20: (close / (ts_delay(close, 10) + 1e-8) - 1) - (ts_delay(close, 10) / (ts_delay(close, 20) + 1e-8) - 1)\n", - " - drawdown_from_high_60: close / (ts_max(high, 60) + 1e-8) - 1\n", - " - up_days_ratio_20: ts_sum(close > ts_delay(close, 1), 20) / 20\n", - " - volatility_5: ts_std(close, 5)\n", - " - volatility_20: ts_std(close, 20)\n", - " - volatility_ratio: ts_std(close, 5) / (ts_std(close, 20) + 1e-8)\n", - " - std_return_20: ts_std((close / (ts_delay(close, 1) + 1e-8)) - 1, 20)\n", - " - sharpe_ratio_20: ts_mean(close / (ts_delay(close, 1) + 1e-8) - 1, 20) / (ts_std(close / (ts_delay(close, 1) + 1e-8) - 1, 20) + 1e-8)\n", - " - min_ret_20: ts_min(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\n", - " - volatility_squeeze_5_60: ts_std(close, 5) / (ts_std(close, 60) + 1e-8)\n", - " - overnight_intraday_diff: (open / (ts_delay(close, 1) + 1e-8) - 1) - (close / (open + 1e-8) - 1)\n", - " - upper_shadow_ratio: (high - ((open + close + abs(open - close)) / 2)) / (high - low + 1e-8)\n", - " - capital_retention_20: ts_sum(abs(close - open), 20) / (ts_sum(high - low, 20) + 1e-8)\n", - " - max_ret_20: ts_max(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\n", - " - volume_ratio_5_20: ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)\n", - " - turnover_rate_mean_5: ts_mean(turnover_rate, 5)\n", - " - turnover_deviation: (turnover_rate - ts_mean(turnover_rate, 10)) / (ts_std(turnover_rate, 10) + 1e-8)\n", - " - amihud_illiq_20: ts_mean(abs(close / (ts_delay(close, 1) + 1e-8) - 1) / (amount + 1e-8), 20)\n", - " - turnover_cv_20: ts_std(turnover_rate, 20) / (ts_mean(turnover_rate, 20) + 1e-8)\n", - " - pv_corr_20: ts_corr(close / (ts_delay(close, 1) + 1e-8) - 1, vol, 20)\n", - " - close_vwap_deviation: close / (amount / (vol * 100 + 1e-8) + 1e-8) - 1\n", - " - roe: n_income / (total_hldr_eqy_exc_min_int + 1e-8)\n", - " - roa: n_income / (total_assets + 1e-8)\n", - " - profit_margin: n_income / (revenue + 1e-8)\n", - " - debt_to_equity: total_liab / (total_hldr_eqy_exc_min_int + 1e-8)\n", - " - current_ratio: total_cur_assets / (total_cur_liab + 1e-8)\n", - " - net_profit_yoy: (n_income / (ts_delay(n_income, 252) + 1e-8)) - 1\n", - " - revenue_yoy: (revenue / (ts_delay(revenue, 252) + 1e-8)) - 1\n", - " - healthy_expansion_velocity: (total_assets / (ts_delay(total_assets, 252) + 1e-8) - 1) - (total_liab / (ts_delay(total_liab, 252) + 1e-8) - 1)\n", - " - EP: n_income / (total_mv * 10000 + 1e-8)\n", - " - BP: total_hldr_eqy_exc_min_int / (total_mv * 10000 + 1e-8)\n", - " - CP: n_cashflow_act / (total_mv * 10000 + 1e-8)\n", - " - market_cap_rank: cs_rank(total_mv)\n", - " - turnover_rank: cs_rank(turnover_rate)\n", - " - return_5_rank: cs_rank((close / (ts_delay(close, 5) + 1e-8)) - 1)\n", - " - EP_rank: cs_rank(n_income / (total_mv + 1e-8))\n", - " - pe_expansion_trend: (total_mv / (n_income + 1e-8)) / (ts_delay(total_mv, 60) / (ts_delay(n_income, 60) + 1e-8) + 1e-8) - 1\n", - " - value_price_divergence: cs_rank((n_income - ts_delay(n_income, 252)) / (abs(ts_delay(n_income, 252)) + 1e-8)) - cs_rank(close / (ts_delay(close, 20) + 1e-8))\n", - " - active_market_cap: total_mv * ts_mean(turnover_rate, 20)\n", - " - ebit_rank: cs_rank(ebit)\n", - "\n", - "注册 Label 因子:\n", - " - future_return_5_rank: (ts_delay(close, -5) / ts_delay(open, -1)) - 1\n", - "\n", - "特征因子数: 49\n", - "Label: future_return_5_rank\n", - "已注册因子总数: 50\n", - "\n", - "[3] 准备数据\n", - "\n", - "================================================================================\n", - "准备数据\n", - "================================================================================\n", - "\n", - "计算因子: 20200101 - 20251231\n", - "[FinancialLoader] 加载 financial_fina_indicator 失败: Binder Error: Referenced column \"f_ann_date\" not found in FROM clause!\n", - "Candidate bindings: \"ann_date\", \"end_date\", \"ocf_to_debt\", \"arturn_days\", \"nca_to_assets\"\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "D:\\PyProject\\ProStock\\src\\data\\financial_loader.py:148: UserWarning: Sortedness of columns cannot be checked when 'by' groups provided\n", - " merged = df_price.join_asof(\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "数据形状: (7044952, 70)\n", - "数据列: ['ts_code', 'trade_date', 'close', 'open', 'high', 'amount', 'low', 'vol', 'turnover_rate', 'total_assets', 'total_mv', 'f_ann_date', 'n_income', 'revenue', 'total_liab', 'total_cur_liab', 'total_cur_assets', 'total_hldr_eqy_exc_min_int', 'n_cashflow_act', 'ebit', 'ma_5', 'ma_20', 'ma_ratio_5_20', 'bias_10', 'high_low_ratio', 'bbi_ratio', 'return_5', 'return_20', 'kaufman_ER_20', 'mom_acceleration_10_20', 'drawdown_from_high_60', 'up_days_ratio_20', 'volatility_5', 'volatility_20', 'volatility_ratio', 'std_return_20', 'sharpe_ratio_20', 'min_ret_20', 'volatility_squeeze_5_60', 'overnight_intraday_diff', 'upper_shadow_ratio', 'capital_retention_20', 'max_ret_20', 'volume_ratio_5_20', 'turnover_rate_mean_5', 'turnover_deviation', 'amihud_illiq_20', 'turnover_cv_20', 'pv_corr_20', 'close_vwap_deviation', 'roe', 'roa', 'profit_margin', 'debt_to_equity', 'current_ratio', 'net_profit_yoy', 'revenue_yoy', 'healthy_expansion_velocity', 'EP', 'BP', 'CP', 'market_cap_rank', 'turnover_rank', 'return_5_rank', 'EP_rank', 'pe_expansion_trend', 'value_price_divergence', 'active_market_cap', 'ebit_rank', 'future_return_5_rank']\n", - "\n", - "前5行预览:\n", - "shape: (5, 70)\n", - "┌───────────┬────────────┬─────────┬─────────┬───┬────────────┬────────────┬───────────┬───────────┐\n", - "│ ts_code ┆ trade_date ┆ close ┆ open ┆ … ┆ value_pric ┆ active_mar ┆ ebit_rank ┆ future_re │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ e_divergen ┆ ket_cap ┆ --- ┆ turn_5_ra │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ ce ┆ --- ┆ f64 ┆ nk │\n", - "│ ┆ ┆ ┆ ┆ ┆ --- ┆ f64 ┆ ┆ --- │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ ┆ ┆ f64 │\n", - "╞═══════════╪════════════╪═════════╪═════════╪═══╪════════════╪════════════╪═══════════╪═══════════╡\n", - "│ 000001.SZ ┆ 20200102 ┆ 1841.69 ┆ 1817.67 ┆ … ┆ null ┆ null ┆ null ┆ -0.008857 │\n", - "│ 000001.SZ ┆ 20200103 ┆ 1875.53 ┆ 1849.33 ┆ … ┆ null ┆ null ┆ null ┆ -0.01881 │\n", - "│ 000001.SZ ┆ 20200106 ┆ 1863.52 ┆ 1856.97 ┆ … ┆ null ┆ null ┆ null ┆ -0.008171 │\n", - "│ 000001.SZ ┆ 20200107 ┆ 1872.26 ┆ 1870.07 ┆ … ┆ null ┆ null ┆ null ┆ -0.014117 │\n", - "│ 000001.SZ ┆ 20200108 ┆ 1818.76 ┆ 1855.88 ┆ … ┆ null ┆ null ┆ null ┆ -0.017252 │\n", - "└───────────┴────────────┴─────────┴─────────┴───┴────────────┴────────────┴───────────┴───────────┘\n", - "\n", - "[4] 转换为排序学习格式\n", - "\n", - "================================================================================\n", - "准备排序学习数据(将 future_return_5_rank 转换为 20 分位数标签)\n", - "================================================================================\n", - "\n", - "原始 future_return_5_rank 统计:\n", - "shape: (9, 2)\n", - "┌────────────┬───────────┐\n", - "│ statistic ┆ value │\n", - "│ --- ┆ --- │\n", - "│ str ┆ f64 │\n", - "╞════════════╪═══════════╡\n", - "│ count ┆ 7.01659e6 │\n", - "│ null_count ┆ 28362.0 │\n", - "│ mean ┆ 0.003779 │\n", - "│ std ┆ 0.073221 │\n", - "│ min ┆ -0.969459 │\n", - "│ 25% ┆ -0.033163 │\n", - "│ 50% ┆ -0.001483 │\n", - "│ 75% ┆ 0.032547 │\n", - "│ max ┆ 10.361925 │\n", - "└────────────┴───────────┘\n", - "\n", - "转换后 future_return_5_rank_rank 统计:\n", - "shape: (9, 2)\n", - "┌────────────┬───────────┐\n", - "│ statistic ┆ value │\n", - "│ --- ┆ --- │\n", - "│ str ┆ f64 │\n", - "╞════════════╪═══════════╡\n", - "│ count ┆ 7.01659e6 │\n", - "│ null_count ┆ 28362.0 │\n", - "│ mean ┆ 9.495412 │\n", - "│ std ┆ 5.765668 │\n", - "│ min ┆ 0.0 │\n", - "│ 25% ┆ 4.0 │\n", - "│ 50% ┆ 9.0 │\n", - "│ 75% ┆ 14.0 │\n", - "│ max ┆ 19.0 │\n", - "└────────────┴───────────┘\n", - "\n", - "每日样本数统计:\n", - "shape: (9, 2)\n", - "┌────────────┬─────────────┐\n", - "│ statistic ┆ value │\n", - "│ --- ┆ --- │\n", - "│ str ┆ f64 │\n", - "╞════════════╪═════════════╡\n", - "│ count ┆ 1455.0 │\n", - "│ null_count ┆ 0.0 │\n", - "│ mean ┆ 4841.891409 │\n", - "│ std ┆ 560.948186 │\n", - "│ min ┆ 3740.0 │\n", - "│ 25% ┆ 4369.0 │\n", - "│ 50% ┆ 5060.0 │\n", - "│ 75% ┆ 5344.0 │\n", - "│ max ┆ 5458.0 │\n", - "└────────────┴─────────────┘\n", - "\n", - "分位数标签分布:\n", - "shape: (21, 2)\n", - "┌───────────────────────────┬────────┐\n", - "│ future_return_5_rank_rank ┆ count │\n", - "│ --- ┆ --- │\n", - "│ i64 ┆ u32 │\n", - "╞═══════════════════════════╪════════╡\n", - "│ null ┆ 28362 │\n", - "│ 0 ┆ 351599 │\n", - "│ 1 ┆ 350894 │\n", - "│ 2 ┆ 350944 │\n", - "│ 3 ┆ 351077 │\n", - "│ … ┆ … │\n", - "│ 15 ┆ 350910 │\n", - "│ 16 ┆ 350835 │\n", - "│ 17 ┆ 350848 │\n", - "│ 18 ┆ 350871 │\n", - "│ 19 ┆ 349137 │\n", - "└───────────────────────────┴────────┘\n", - "\n", - "[配置] 训练期: 20200101 - 20231231\n", - "[配置] 验证期: 20240101 - 20241231\n", - "[配置] 测试期: 20250101 - 20251231\n", - "[配置] 特征数: 49\n", - "[配置] 目标变量: future_return_5_rank_rank(20分位数)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\liaozhaorun\\AppData\\Local\\Temp\\ipykernel_29336\\551043002.py:108: DeprecationWarning: `pl.count()` is deprecated. Please use `pl.len()` instead.\n", - "(Deprecated in version 0.20.5)\n", - " daily_counts = df_ranked.group_by(date_col).agg(pl.count().alias(\"count\"))\n" - ] - } - ], - "execution_count": 5 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.1 股票池筛选" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.1 股票池筛选" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:49.070709Z", - "start_time": "2026-03-11T13:28:24.501332Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"股票池筛选\")\n", @@ -788,1504 +541,18 @@ "else:\n", " filtered_data = data\n", " print(\" 未配置股票池管理器,跳过筛选\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "股票池筛选\n", - "================================================================================\n", - "\n", - "[过滤] 应用 ST 过滤器...\n", - " [20200103] 过滤 129 只 ST 股票\n", - " [20200106] 过滤 129 只 ST 股票\n", - " [20200107] 过滤 128 只 ST 股票\n", - " [20200108] 过滤 128 只 ST 股票\n", - " [20200109] 过滤 128 只 ST 股票\n", - " [20200110] 过滤 128 只 ST 股票\n", - " [20200113] 过滤 129 只 ST 股票\n", - " [20200114] 过滤 129 只 ST 股票\n", - " [20200115] 过滤 130 只 ST 股票\n", - " [20200116] 过滤 130 只 ST 股票\n", - " [20200117] 过滤 129 只 ST 股票\n", - " [20200120] 过滤 129 只 ST 股票\n", - " [20200121] 过滤 131 只 ST 股票\n", - " [20200122] 过滤 132 只 ST 股票\n", - " [20200123] 过滤 132 只 ST 股票\n", - " [20200203] 过滤 132 只 ST 股票\n", - " [20200204] 过滤 132 只 ST 股票\n", - " [20200205] 过滤 132 只 ST 股票\n", - " [20200206] 过滤 132 只 ST 股票\n", - " [20200207] 过滤 132 只 ST 股票\n", - " [20200210] 过滤 132 只 ST 股票\n", - " [20200211] 过滤 132 只 ST 股票\n", - " [20200212] 过滤 132 只 ST 股票\n", - " [20200213] 过滤 132 只 ST 股票\n", - " [20200214] 过滤 132 只 ST 股票\n", - " [20200217] 过滤 132 只 ST 股票\n", - " [20200218] 过滤 132 只 ST 股票\n", - " [20200219] 过滤 132 只 ST 股票\n", - " [20200221] 过滤 132 只 ST 股票\n", - " [20200224] 过滤 132 只 ST 股票\n", - " [20200226] 过滤 132 只 ST 股票\n", - " [20200227] 过滤 131 只 ST 股票\n", - " [20200228] 过滤 132 只 ST 股票\n", - " [20200302] 过滤 132 只 ST 股票\n", - " [20200303] 过滤 131 只 ST 股票\n", - " [20200304] 过滤 130 只 ST 股票\n", - " [20200305] 过滤 129 只 ST 股票\n", - " [20200306] 过滤 129 只 ST 股票\n", - " [20200309] 过滤 129 只 ST 股票\n", - " [20200310] 过滤 129 只 ST 股票\n", - " [20200311] 过滤 129 只 ST 股票\n", - " [20200312] 过滤 129 只 ST 股票\n", - " [20200313] 过滤 129 只 ST 股票\n", - " [20200317] 过滤 129 只 ST 股票\n", - " [20200318] 过滤 129 只 ST 股票\n", - " [20200319] 过滤 130 只 ST 股票\n", - " [20200320] 过滤 129 只 ST 股票\n", - " [20200323] 过滤 130 只 ST 股票\n", - " [20200324] 过滤 130 只 ST 股票\n", - " [20200325] 过滤 130 只 ST 股票\n", - " [20200326] 过滤 130 只 ST 股票\n", - " [20200327] 过滤 130 只 ST 股票\n", - " [20200330] 过滤 130 只 ST 股票\n", - " [20200331] 过滤 131 只 ST 股票\n", - " [20200401] 过滤 133 只 ST 股票\n", - " [20200402] 过滤 133 只 ST 股票\n", - " [20200403] 过滤 133 只 ST 股票\n", - " [20200407] 过滤 133 只 ST 股票\n", - " [20200408] 过滤 131 只 ST 股票\n", - " [20200409] 过滤 132 只 ST 股票\n", - " [20200410] 过滤 131 只 ST 股票\n", - " [20200413] 过滤 130 只 ST 股票\n", - " [20200414] 过滤 129 只 ST 股票\n", - " [20200415] 过滤 130 只 ST 股票\n", - " [20200416] 过滤 131 只 ST 股票\n", - " [20200417] 过滤 131 只 ST 股票\n", - " [20200420] 过滤 127 只 ST 股票\n", - " [20200421] 过滤 128 只 ST 股票\n", - " [20200422] 过滤 131 只 ST 股票\n", - " [20200424] 过滤 132 只 ST 股票\n", - " [20200427] 过滤 135 只 ST 股票\n", - " [20200428] 过滤 135 只 ST 股票\n", - " [20200429] 过滤 139 只 ST 股票\n", - " [20200430] 过滤 151 只 ST 股票\n", - " [20200506] 过滤 183 只 ST 股票\n", - " [20200507] 过滤 184 只 ST 股票\n", - " [20200508] 过滤 182 只 ST 股票\n", - " [20200511] 过滤 184 只 ST 股票\n", - " [20200512] 过滤 182 只 ST 股票\n", - " [20200513] 过滤 184 只 ST 股票\n", - " [20200514] 过滤 184 只 ST 股票\n", - " [20200515] 过滤 184 只 ST 股票\n", - " [20200518] 过滤 184 只 ST 股票\n", - " [20200519] 过滤 184 只 ST 股票\n", - " [20200520] 过滤 183 只 ST 股票\n", - " [20200521] 过滤 184 只 ST 股票\n", - " [20200522] 过滤 184 只 ST 股票\n", - " [20200525] 过滤 183 只 ST 股票\n", - " [20200526] 过滤 183 只 ST 股票\n", - " [20200527] 过滤 183 只 ST 股票\n", - " [20200528] 过滤 181 只 ST 股票\n", - " [20200529] 过滤 181 只 ST 股票\n", - " [20200601] 过滤 182 只 ST 股票\n", - " [20200602] 过滤 184 只 ST 股票\n", - " [20200603] 过滤 182 只 ST 股票\n", - " [20200604] 过滤 181 只 ST 股票\n", - " [20200605] 过滤 180 只 ST 股票\n", - " [20200608] 过滤 176 只 ST 股票\n", - " [20200609] 过滤 180 只 ST 股票\n", - " [20200610] 过滤 179 只 ST 股票\n", - " [20200611] 过滤 178 只 ST 股票\n", - " [20200612] 过滤 180 只 ST 股票\n", - " [20200615] 过滤 182 只 ST 股票\n", - " [20200616] 过滤 183 只 ST 股票\n", - " [20200617] 过滤 182 只 ST 股票\n", - " [20200619] 过滤 183 只 ST 股票\n", - " [20200622] 过滤 183 只 ST 股票\n", - " [20200623] 过滤 183 只 ST 股票\n", - " [20200624] 过滤 186 只 ST 股票\n", - " [20200629] 过滤 190 只 ST 股票\n", - " [20200630] 过滤 188 只 ST 股票\n", - " [20200701] 过滤 196 只 ST 股票\n", - " [20200702] 过滤 197 只 ST 股票\n", - " [20200703] 过滤 197 只 ST 股票\n", - " [20200706] 过滤 197 只 ST 股票\n", - " [20200707] 过滤 196 只 ST 股票\n", - " [20200709] 过滤 197 只 ST 股票\n", - " [20200710] 过滤 196 只 ST 股票\n", - " [20200713] 过滤 197 只 ST 股票\n", - " [20200714] 过滤 197 只 ST 股票\n", - " [20200715] 过滤 197 只 ST 股票\n", - " [20200716] 过滤 195 只 ST 股票\n", - " [20200717] 过滤 196 只 ST 股票\n", - " [20200721] 过滤 195 只 ST 股票\n", - " [20200722] 过滤 194 只 ST 股票\n", - " [20200723] 过滤 193 只 ST 股票\n", - " [20200724] 过滤 194 只 ST 股票\n", - " [20200727] 过滤 195 只 ST 股票\n", - " [20200728] 过滤 195 只 ST 股票\n", - " [20200729] 过滤 195 只 ST 股票\n", - " [20200730] 过滤 196 只 ST 股票\n", - " [20200731] 过滤 196 只 ST 股票\n", - " [20200805] 过滤 194 只 ST 股票\n", - " [20200806] 过滤 195 只 ST 股票\n", - " [20200807] 过滤 195 只 ST 股票\n", - " [20200810] 过滤 194 只 ST 股票\n", - " [20200811] 过滤 194 只 ST 股票\n", - " [20200812] 过滤 195 只 ST 股票\n", - " [20200813] 过滤 194 只 ST 股票\n", - " [20200814] 过滤 194 只 ST 股票\n", - " [20200817] 过滤 195 只 ST 股票\n", - " [20200818] 过滤 195 只 ST 股票\n", - " [20200819] 过滤 195 只 ST 股票\n", - " [20200820] 过滤 196 只 ST 股票\n", - " [20200821] 过滤 196 只 ST 股票\n", - " [20200825] 过滤 198 只 ST 股票\n", - " [20200826] 过滤 198 只 ST 股票\n", - " [20200827] 过滤 198 只 ST 股票\n", - " [20200828] 过滤 198 只 ST 股票\n", - " [20200831] 过滤 198 只 ST 股票\n", - " [20200901] 过滤 199 只 ST 股票\n", - " [20200902] 过滤 199 只 ST 股票\n", - " [20200903] 过滤 199 只 ST 股票\n", - " [20200904] 过滤 198 只 ST 股票\n", - " [20200907] 过滤 197 只 ST 股票\n", - " [20200908] 过滤 197 只 ST 股票\n", - " [20200909] 过滤 197 只 ST 股票\n", - " [20200910] 过滤 197 只 ST 股票\n", - " [20200911] 过滤 197 只 ST 股票\n", - " [20200914] 过滤 197 只 ST 股票\n", - " [20200915] 过滤 200 只 ST 股票\n", - " [20200916] 过滤 200 只 ST 股票\n", - " [20200917] 过滤 199 只 ST 股票\n", - " [20200918] 过滤 200 只 ST 股票\n", - " [20200921] 过滤 200 只 ST 股票\n", - " [20200922] 过滤 201 只 ST 股票\n", - " [20200923] 过滤 201 只 ST 股票\n", - " [20200924] 过滤 200 只 ST 股票\n", - " [20200925] 过滤 200 只 ST 股票\n", - " [20200928] 过滤 202 只 ST 股票\n", - " [20200929] 过滤 203 只 ST 股票\n", - " [20200930] 过滤 204 只 ST 股票\n", - " [20201009] 过滤 204 只 ST 股票\n", - " [20201012] 过滤 204 只 ST 股票\n", - " [20201013] 过滤 204 只 ST 股票\n", - " [20201014] 过滤 203 只 ST 股票\n", - " [20201015] 过滤 203 只 ST 股票\n", - " [20201016] 过滤 203 只 ST 股票\n", - " [20201019] 过滤 203 只 ST 股票\n", - " [20201020] 过滤 203 只 ST 股票\n", - " [20201021] 过滤 203 只 ST 股票\n", - " [20201022] 过滤 203 只 ST 股票\n", - " [20201023] 过滤 203 只 ST 股票\n", - " [20201026] 过滤 203 只 ST 股票\n", - " [20201027] 过滤 203 只 ST 股票\n", - " [20201028] 过滤 203 只 ST 股票\n", - " [20201029] 过滤 203 只 ST 股票\n", - " [20201030] 过滤 201 只 ST 股票\n", - " [20201102] 过滤 201 只 ST 股票\n", - " [20201103] 过滤 203 只 ST 股票\n", - " [20201104] 过滤 204 只 ST 股票\n", - " [20201105] 过滤 204 只 ST 股票\n", - " [20201106] 过滤 204 只 ST 股票\n", - " [20201109] 过滤 203 只 ST 股票\n", - " [20201110] 过滤 203 只 ST 股票\n", - " [20201111] 过滤 203 只 ST 股票\n", - " [20201112] 过滤 203 只 ST 股票\n", - " [20201113] 过滤 203 只 ST 股票\n", - " [20201116] 过滤 204 只 ST 股票\n", - " [20201117] 过滤 204 只 ST 股票\n", - " [20201118] 过滤 204 只 ST 股票\n", - " [20201119] 过滤 204 只 ST 股票\n", - " [20201123] 过滤 203 只 ST 股票\n", - " [20201124] 过滤 203 只 ST 股票\n", - " [20201125] 过滤 201 只 ST 股票\n", - " [20201126] 过滤 202 只 ST 股票\n", - " [20201127] 过滤 202 只 ST 股票\n", - " [20201130] 过滤 202 只 ST 股票\n", - " [20201201] 过滤 202 只 ST 股票\n", - " [20201202] 过滤 202 只 ST 股票\n", - " [20201203] 过滤 202 只 ST 股票\n", - " [20201204] 过滤 201 只 ST 股票\n", - " [20201207] 过滤 201 只 ST 股票\n", - " [20201208] 过滤 201 只 ST 股票\n", - " [20201209] 过滤 201 只 ST 股票\n", - " [20201210] 过滤 201 只 ST 股票\n", - " [20201211] 过滤 201 只 ST 股票\n", - " [20201214] 过滤 202 只 ST 股票\n", - " [20201215] 过滤 203 只 ST 股票\n", - " [20201216] 过滤 203 只 ST 股票\n", - " [20201217] 过滤 203 只 ST 股票\n", - " [20201218] 过滤 203 只 ST 股票\n", - " [20201221] 过滤 203 只 ST 股票\n", - " [20201222] 过滤 201 只 ST 股票\n", - " [20201223] 过滤 201 只 ST 股票\n", - " [20201224] 过滤 200 只 ST 股票\n", - " [20201225] 过滤 200 只 ST 股票\n", - " [20201228] 过滤 200 只 ST 股票\n", - " [20201229] 过滤 201 只 ST 股票\n", - " [20201230] 过滤 201 只 ST 股票\n", - " [20201231] 过滤 200 只 ST 股票\n", - " [20210104] 过滤 199 只 ST 股票\n", - " [20210105] 过滤 199 只 ST 股票\n", - " [20210106] 过滤 199 只 ST 股票\n", - " [20210107] 过滤 199 只 ST 股票\n", - " [20210108] 过滤 199 只 ST 股票\n", - " [20210111] 过滤 199 只 ST 股票\n", - " [20210112] 过滤 199 只 ST 股票\n", - " [20210113] 过滤 199 只 ST 股票\n", - " [20210114] 过滤 198 只 ST 股票\n", - " [20210115] 过滤 198 只 ST 股票\n", - " [20210118] 过滤 198 只 ST 股票\n", - " [20210119] 过滤 199 只 ST 股票\n", - " [20210120] 过滤 199 只 ST 股票\n", - " [20210121] 过滤 198 只 ST 股票\n", - " [20210122] 过滤 198 只 ST 股票\n", - " [20210125] 过滤 198 只 ST 股票\n", - " [20210126] 过滤 199 只 ST 股票\n", - " [20210127] 过滤 199 只 ST 股票\n", - " [20210128] 过滤 199 只 ST 股票\n", - " [20210201] 过滤 197 只 ST 股票\n", - " [20210202] 过滤 199 只 ST 股票\n", - " [20210203] 过滤 199 只 ST 股票\n", - " [20210204] 过滤 200 只 ST 股票\n", - " [20210205] 过滤 200 只 ST 股票\n", - " [20210208] 过滤 199 只 ST 股票\n", - " [20210209] 过滤 200 只 ST 股票\n", - " [20210210] 过滤 200 只 ST 股票\n", - " [20210218] 过滤 200 只 ST 股票\n", - " [20210219] 过滤 203 只 ST 股票\n", - " [20210222] 过滤 203 只 ST 股票\n", - " [20210223] 过滤 202 只 ST 股票\n", - " [20210224] 过滤 202 只 ST 股票\n", - " [20210225] 过滤 201 只 ST 股票\n", - " [20210226] 过滤 200 只 ST 股票\n", - " [20210301] 过滤 200 只 ST 股票\n", - " [20210302] 过滤 200 只 ST 股票\n", - " [20210303] 过滤 200 只 ST 股票\n", - " [20210304] 过滤 201 只 ST 股票\n", - " [20210305] 过滤 200 只 ST 股票\n", - " [20210308] 过滤 201 只 ST 股票\n", - " [20210309] 过滤 201 只 ST 股票\n", - " [20210310] 过滤 201 只 ST 股票\n", - " [20210311] 过滤 200 只 ST 股票\n", - " [20210312] 过滤 199 只 ST 股票\n", - " [20210315] 过滤 198 只 ST 股票\n", - " [20210317] 过滤 198 只 ST 股票\n", - " [20210318] 过滤 198 只 ST 股票\n", - " [20210319] 过滤 195 只 ST 股票\n", - " [20210322] 过滤 194 只 ST 股票\n", - " [20210323] 过滤 194 只 ST 股票\n", - " [20210324] 过滤 194 只 ST 股票\n", - " [20210325] 过滤 194 只 ST 股票\n", - " [20210326] 过滤 194 只 ST 股票\n", - " [20210329] 过滤 194 只 ST 股票\n", - " [20210330] 过滤 194 只 ST 股票\n", - " [20210331] 过滤 192 只 ST 股票\n", - " [20210401] 过滤 191 只 ST 股票\n", - " [20210402] 过滤 189 只 ST 股票\n", - " [20210406] 过滤 190 只 ST 股票\n", - " [20210407] 过滤 191 只 ST 股票\n", - " [20210408] 过滤 191 只 ST 股票\n", - " [20210409] 过滤 190 只 ST 股票\n", - " [20210412] 过滤 188 只 ST 股票\n", - " [20210413] 过滤 187 只 ST 股票\n", - " [20210414] 过滤 186 只 ST 股票\n", - " [20210415] 过滤 182 只 ST 股票\n", - " [20210416] 过滤 180 只 ST 股票\n", - " [20210419] 过滤 179 只 ST 股票\n", - " [20210420] 过滤 179 只 ST 股票\n", - " [20210421] 过滤 180 只 ST 股票\n", - " [20210422] 过滤 180 只 ST 股票\n", - " [20210423] 过滤 178 只 ST 股票\n", - " [20210426] 过滤 183 只 ST 股票\n", - " [20210427] 过滤 180 只 ST 股票\n", - " [20210428] 过滤 190 只 ST 股票\n", - " [20210429] 过滤 185 只 ST 股票\n", - " [20210430] 过滤 200 只 ST 股票\n", - " [20210506] 过滤 225 只 ST 股票\n", - " [20210507] 过滤 222 只 ST 股票\n", - " [20210510] 过滤 218 只 ST 股票\n", - " [20210511] 过滤 215 只 ST 股票\n", - " [20210512] 过滤 214 只 ST 股票\n", - " [20210513] 过滤 212 只 ST 股票\n", - " [20210514] 过滤 210 只 ST 股票\n", - " [20210517] 过滤 208 只 ST 股票\n", - " [20210518] 过滤 202 只 ST 股票\n", - " [20210519] 过滤 196 只 ST 股票\n", - " [20210520] 过滤 202 只 ST 股票\n", - " [20210521] 过滤 201 只 ST 股票\n", - " [20210524] 过滤 199 只 ST 股票\n", - " [20210525] 过滤 198 只 ST 股票\n", - " [20210526] 过滤 197 只 ST 股票\n", - " [20210527] 过滤 197 只 ST 股票\n", - " [20210528] 过滤 196 只 ST 股票\n", - " [20210531] 过滤 196 只 ST 股票\n", - " [20210601] 过滤 196 只 ST 股票\n", - " [20210602] 过滤 195 只 ST 股票\n", - " [20210603] 过滤 193 只 ST 股票\n", - " [20210604] 过滤 193 只 ST 股票\n", - " [20210607] 过滤 190 只 ST 股票\n", - " [20210608] 过滤 191 只 ST 股票\n", - " [20210609] 过滤 190 只 ST 股票\n", - " [20210610] 过滤 189 只 ST 股票\n", - " [20210611] 过滤 190 只 ST 股票\n", - " [20210615] 过滤 187 只 ST 股票\n", - " [20210616] 过滤 187 只 ST 股票\n", - " [20210617] 过滤 186 只 ST 股票\n", - " [20210618] 过滤 185 只 ST 股票\n", - " [20210621] 过滤 183 只 ST 股票\n", - " [20210622] 过滤 183 只 ST 股票\n", - " [20210623] 过滤 181 只 ST 股票\n", - " [20210624] 过滤 183 只 ST 股票\n", - " [20210625] 过滤 181 只 ST 股票\n", - " [20210628] 过滤 181 只 ST 股票\n", - " [20210629] 过滤 181 只 ST 股票\n", - " [20210630] 过滤 180 只 ST 股票\n", - " [20210701] 过滤 180 只 ST 股票\n", - " [20210702] 过滤 182 只 ST 股票\n", - " [20210705] 过滤 182 只 ST 股票\n", - " [20210706] 过滤 182 只 ST 股票\n", - " [20210707] 过滤 184 只 ST 股票\n", - " [20210708] 过滤 184 只 ST 股票\n", - " [20210709] 过滤 182 只 ST 股票\n", - " [20210712] 过滤 182 只 ST 股票\n", - " [20210713] 过滤 183 只 ST 股票\n", - " [20210714] 过滤 182 只 ST 股票\n", - " [20210715] 过滤 181 只 ST 股票\n", - " [20210716] 过滤 181 只 ST 股票\n", - " [20210719] 过滤 180 只 ST 股票\n", - " [20210720] 过滤 179 只 ST 股票\n", - " [20210721] 过滤 178 只 ST 股票\n", - " [20210722] 过滤 180 只 ST 股票\n", - " [20210723] 过滤 181 只 ST 股票\n", - " [20210726] 过滤 182 只 ST 股票\n", - " [20210727] 过滤 181 只 ST 股票\n", - " [20210728] 过滤 181 只 ST 股票\n", - " [20210729] 过滤 180 只 ST 股票\n", - " [20210730] 过滤 180 只 ST 股票\n", - " [20210802] 过滤 180 只 ST 股票\n", - " [20210803] 过滤 180 只 ST 股票\n", - " [20210804] 过滤 180 只 ST 股票\n", - " [20210805] 过滤 181 只 ST 股票\n", - " [20210806] 过滤 181 只 ST 股票\n", - " [20210809] 过滤 179 只 ST 股票\n", - " [20210810] 过滤 179 只 ST 股票\n", - " [20210811] 过滤 179 只 ST 股票\n", - " [20210812] 过滤 179 只 ST 股票\n", - " [20210813] 过滤 179 只 ST 股票\n", - " [20210816] 过滤 179 只 ST 股票\n", - " [20210817] 过滤 180 只 ST 股票\n", - " [20210818] 过滤 180 只 ST 股票\n", - " [20210819] 过滤 180 只 ST 股票\n", - " [20210820] 过滤 180 只 ST 股票\n", - " [20210823] 过滤 179 只 ST 股票\n", - " [20210824] 过滤 181 只 ST 股票\n", - " [20210825] 过滤 181 只 ST 股票\n", - " [20210826] 过滤 180 只 ST 股票\n", - " [20210827] 过滤 181 只 ST 股票\n", - " [20210830] 过滤 180 只 ST 股票\n", - " [20210831] 过滤 180 只 ST 股票\n", - " [20210901] 过滤 180 只 ST 股票\n", - " [20210902] 过滤 180 只 ST 股票\n", - " [20210903] 过滤 180 只 ST 股票\n", - " [20210906] 过滤 180 只 ST 股票\n", - " [20210907] 过滤 181 只 ST 股票\n", - " [20210908] 过滤 181 只 ST 股票\n", - " [20210909] 过滤 181 只 ST 股票\n", - " [20210910] 过滤 181 只 ST 股票\n", - " [20210913] 过滤 181 只 ST 股票\n", - " [20210914] 过滤 181 只 ST 股票\n", - " [20210915] 过滤 182 只 ST 股票\n", - " [20210916] 过滤 182 只 ST 股票\n", - " [20210917] 过滤 182 只 ST 股票\n", - " [20210922] 过滤 180 只 ST 股票\n", - " [20210923] 过滤 179 只 ST 股票\n", - " [20210924] 过滤 180 只 ST 股票\n", - " [20210927] 过滤 178 只 ST 股票\n", - " [20210928] 过滤 178 只 ST 股票\n", - " [20210929] 过滤 180 只 ST 股票\n", - " [20210930] 过滤 180 只 ST 股票\n", - " [20211008] 过滤 181 只 ST 股票\n", - " [20211011] 过滤 181 只 ST 股票\n", - " [20211012] 过滤 182 只 ST 股票\n", - " [20211013] 过滤 182 只 ST 股票\n", - " [20211014] 过滤 182 只 ST 股票\n", - " [20211015] 过滤 182 只 ST 股票\n", - " [20211018] 过滤 182 只 ST 股票\n", - " [20211019] 过滤 182 只 ST 股票\n", - " [20211020] 过滤 182 只 ST 股票\n", - " [20211021] 过滤 182 只 ST 股票\n", - " [20211022] 过滤 182 只 ST 股票\n", - " [20211025] 过滤 182 只 ST 股票\n", - " [20211026] 过滤 182 只 ST 股票\n", - " [20211027] 过滤 182 只 ST 股票\n", - " [20211028] 过滤 182 只 ST 股票\n", - " [20211029] 过滤 182 只 ST 股票\n", - " [20211101] 过滤 182 只 ST 股票\n", - " [20211102] 过滤 182 只 ST 股票\n", - " [20211103] 过滤 182 只 ST 股票\n", - " [20211104] 过滤 182 只 ST 股票\n", - " [20211105] 过滤 182 只 ST 股票\n", - " [20211108] 过滤 182 只 ST 股票\n", - " [20211109] 过滤 180 只 ST 股票\n", - " [20211110] 过滤 181 只 ST 股票\n", - " [20211111] 过滤 181 只 ST 股票\n", - " [20211112] 过滤 182 只 ST 股票\n", - " [20211115] 过滤 182 只 ST 股票\n", - " [20211116] 过滤 182 只 ST 股票\n", - " [20211117] 过滤 180 只 ST 股票\n", - " [20211118] 过滤 182 只 ST 股票\n", - " [20211119] 过滤 182 只 ST 股票\n", - " [20211122] 过滤 182 只 ST 股票\n", - " [20211123] 过滤 182 只 ST 股票\n", - " [20211124] 过滤 182 只 ST 股票\n", - " [20211125] 过滤 182 只 ST 股票\n", - " [20211126] 过滤 182 只 ST 股票\n", - " [20211129] 过滤 182 只 ST 股票\n", - " [20211130] 过滤 182 只 ST 股票\n", - " [20211201] 过滤 181 只 ST 股票\n", - " [20211202] 过滤 180 只 ST 股票\n", - " [20211203] 过滤 179 只 ST 股票\n", - " [20211206] 过滤 180 只 ST 股票\n", - " [20211207] 过滤 180 只 ST 股票\n", - " [20211208] 过滤 180 只 ST 股票\n", - " [20211209] 过滤 181 只 ST 股票\n", - " [20211210] 过滤 181 只 ST 股票\n", - " [20211213] 过滤 181 只 ST 股票\n", - " [20211214] 过滤 180 只 ST 股票\n", - " [20211215] 过滤 181 只 ST 股票\n", - " [20211216] 过滤 180 只 ST 股票\n", - " [20211217] 过滤 178 只 ST 股票\n", - " [20211220] 过滤 178 只 ST 股票\n", - " [20211221] 过滤 177 只 ST 股票\n", - " [20211222] 过滤 178 只 ST 股票\n", - " [20211223] 过滤 178 只 ST 股票\n", - " [20211224] 过滤 177 只 ST 股票\n", - " [20211227] 过滤 177 只 ST 股票\n", - " [20211228] 过滤 177 只 ST 股票\n", - " [20211229] 过滤 177 只 ST 股票\n", - " [20211230] 过滤 175 只 ST 股票\n", - " [20211231] 过滤 174 只 ST 股票\n", - " [20220104] 过滤 177 只 ST 股票\n", - " [20220105] 过滤 177 只 ST 股票\n", - " [20220106] 过滤 178 只 ST 股票\n", - " [20220107] 过滤 178 只 ST 股票\n", - " [20220110] 过滤 178 只 ST 股票\n", - " [20220111] 过滤 178 只 ST 股票\n", - " [20220112] 过滤 178 只 ST 股票\n", - " [20220113] 过滤 177 只 ST 股票\n", - " [20220114] 过滤 178 只 ST 股票\n", - " [20220117] 过滤 179 只 ST 股票\n", - " [20220118] 过滤 179 只 ST 股票\n", - " [20220119] 过滤 179 只 ST 股票\n", - " [20220120] 过滤 179 只 ST 股票\n", - " [20220121] 过滤 179 只 ST 股票\n", - " [20220124] 过滤 179 只 ST 股票\n", - " [20220125] 过滤 179 只 ST 股票\n", - " [20220126] 过滤 179 只 ST 股票\n", - " [20220127] 过滤 179 只 ST 股票\n", - " [20220128] 过滤 179 只 ST 股票\n", - " [20220207] 过滤 178 只 ST 股票\n", - " [20220208] 过滤 178 只 ST 股票\n", - " [20220209] 过滤 179 只 ST 股票\n", - " [20220210] 过滤 179 只 ST 股票\n", - " [20220211] 过滤 179 只 ST 股票\n", - " [20220214] 过滤 178 只 ST 股票\n", - " [20220215] 过滤 179 只 ST 股票\n", - " [20220216] 过滤 179 只 ST 股票\n", - " [20220217] 过滤 179 只 ST 股票\n", - " [20220218] 过滤 179 只 ST 股票\n", - " [20220221] 过滤 179 只 ST 股票\n", - " [20220222] 过滤 179 只 ST 股票\n", - " [20220223] 过滤 179 只 ST 股票\n", - " [20220224] 过滤 179 只 ST 股票\n", - " [20220225] 过滤 179 只 ST 股票\n", - " [20220228] 过滤 179 只 ST 股票\n", - " [20220301] 过滤 179 只 ST 股票\n", - " [20220302] 过滤 179 只 ST 股票\n", - " [20220303] 过滤 178 只 ST 股票\n", - " [20220304] 过滤 179 只 ST 股票\n", - " [20220307] 过滤 178 只 ST 股票\n", - " [20220308] 过滤 177 只 ST 股票\n", - " [20220309] 过滤 177 只 ST 股票\n", - " [20220310] 过滤 178 只 ST 股票\n", - " [20220311] 过滤 178 只 ST 股票\n", - " [20220314] 过滤 178 只 ST 股票\n", - " [20220315] 过滤 179 只 ST 股票\n", - " [20220316] 过滤 179 只 ST 股票\n", - " [20220317] 过滤 179 只 ST 股票\n", - " [20220318] 过滤 178 只 ST 股票\n", - " [20220321] 过滤 178 只 ST 股票\n", - " [20220322] 过滤 178 只 ST 股票\n", - " [20220323] 过滤 178 只 ST 股票\n", - " [20220324] 过滤 177 只 ST 股票\n", - " [20220325] 过滤 176 只 ST 股票\n", - " [20220328] 过滤 176 只 ST 股票\n", - " [20220329] 过滤 176 只 ST 股票\n", - " [20220330] 过滤 176 只 ST 股票\n", - " [20220331] 过滤 173 只 ST 股票\n", - " [20220401] 过滤 171 只 ST 股票\n", - " [20220406] 过滤 171 只 ST 股票\n", - " [20220407] 过滤 170 只 ST 股票\n", - " [20220408] 过滤 170 只 ST 股票\n", - " [20220411] 过滤 168 只 ST 股票\n", - " [20220412] 过滤 167 只 ST 股票\n", - " [20220413] 过滤 167 只 ST 股票\n", - " [20220414] 过滤 167 只 ST 股票\n", - " [20220415] 过滤 165 只 ST 股票\n", - " [20220418] 过滤 163 只 ST 股票\n", - " [20220419] 过滤 165 只 ST 股票\n", - " [20220420] 过滤 165 只 ST 股票\n", - " [20220421] 过滤 167 只 ST 股票\n", - " [20220422] 过滤 165 只 ST 股票\n", - " [20220425] 过滤 167 只 ST 股票\n", - " [20220426] 过滤 166 只 ST 股票\n", - " [20220427] 过滤 164 只 ST 股票\n", - " [20220428] 过滤 162 只 ST 股票\n", - " [20220429] 过滤 162 只 ST 股票\n", - " [20220505] 过滤 135 只 ST 股票\n", - " [20220506] 过滤 168 只 ST 股票\n", - " [20220509] 过滤 166 只 ST 股票\n", - " [20220510] 过滤 164 只 ST 股票\n", - " [20220511] 过滤 163 只 ST 股票\n", - " [20220512] 过滤 161 只 ST 股票\n", - " [20220513] 过滤 162 只 ST 股票\n", - " [20220516] 过滤 162 只 ST 股票\n", - " [20220517] 过滤 161 只 ST 股票\n", - " [20220518] 过滤 159 只 ST 股票\n", - " [20220519] 过滤 155 只 ST 股票\n", - " [20220520] 过滤 155 只 ST 股票\n", - " [20220523] 过滤 155 只 ST 股票\n", - " [20220524] 过滤 154 只 ST 股票\n", - " [20220525] 过滤 151 只 ST 股票\n", - " [20220526] 过滤 149 只 ST 股票\n", - " [20220527] 过滤 149 只 ST 股票\n", - " [20220530] 过滤 148 只 ST 股票\n", - " [20220531] 过滤 149 只 ST 股票\n", - " [20220601] 过滤 149 只 ST 股票\n", - " [20220602] 过滤 148 只 ST 股票\n", - " [20220606] 过滤 149 只 ST 股票\n", - " [20220607] 过滤 149 只 ST 股票\n", - " [20220608] 过滤 149 只 ST 股票\n", - " [20220609] 过滤 148 只 ST 股票\n", - " [20220610] 过滤 147 只 ST 股票\n", - " [20220613] 过滤 148 只 ST 股票\n", - " [20220614] 过滤 146 只 ST 股票\n", - " [20220615] 过滤 147 只 ST 股票\n", - " [20220616] 过滤 147 只 ST 股票\n", - " [20220617] 过滤 147 只 ST 股票\n", - " [20220620] 过滤 147 只 ST 股票\n", - " [20220621] 过滤 147 只 ST 股票\n", - " [20220622] 过滤 144 只 ST 股票\n", - " [20220623] 过滤 145 只 ST 股票\n", - " [20220624] 过滤 143 只 ST 股票\n", - " [20220627] 过滤 144 只 ST 股票\n", - " [20220628] 过滤 144 只 ST 股票\n", - " [20220629] 过滤 144 只 ST 股票\n", - " [20220630] 过滤 142 只 ST 股票\n", - " [20220701] 过滤 144 只 ST 股票\n", - " [20220704] 过滤 144 只 ST 股票\n", - " [20220705] 过滤 144 只 ST 股票\n", - " [20220706] 过滤 144 只 ST 股票\n", - " [20220707] 过滤 144 只 ST 股票\n", - " [20220708] 过滤 144 只 ST 股票\n", - " [20220711] 过滤 143 只 ST 股票\n", - " [20220712] 过滤 143 只 ST 股票\n", - " [20220713] 过滤 144 只 ST 股票\n", - " [20220714] 过滤 145 只 ST 股票\n", - " [20220715] 过滤 145 只 ST 股票\n", - " [20220718] 过滤 145 只 ST 股票\n", - " [20220719] 过滤 145 只 ST 股票\n", - " [20220720] 过滤 145 只 ST 股票\n", - " [20220721] 过滤 145 只 ST 股票\n", - " [20220722] 过滤 145 只 ST 股票\n", - " [20220725] 过滤 143 只 ST 股票\n", - " [20220726] 过滤 144 只 ST 股票\n", - " [20220727] 过滤 144 只 ST 股票\n", - " [20220728] 过滤 144 只 ST 股票\n", - " [20220729] 过滤 144 只 ST 股票\n", - " [20220801] 过滤 145 只 ST 股票\n", - " [20220802] 过滤 145 只 ST 股票\n", - " [20220803] 过滤 145 只 ST 股票\n", - " [20220804] 过滤 145 只 ST 股票\n", - " [20220805] 过滤 145 只 ST 股票\n", - " [20220808] 过滤 146 只 ST 股票\n", - " [20220809] 过滤 146 只 ST 股票\n", - " [20220810] 过滤 145 只 ST 股票\n", - " [20220811] 过滤 144 只 ST 股票\n", - " [20220812] 过滤 144 只 ST 股票\n", - " [20220815] 过滤 141 只 ST 股票\n", - " [20220816] 过滤 143 只 ST 股票\n", - " [20220817] 过滤 142 只 ST 股票\n", - " [20220818] 过滤 142 只 ST 股票\n", - " [20220819] 过滤 142 只 ST 股票\n", - " [20220822] 过滤 142 只 ST 股票\n", - " [20220823] 过滤 142 只 ST 股票\n", - " [20220824] 过滤 142 只 ST 股票\n", - " [20220825] 过滤 142 只 ST 股票\n", - " [20220826] 过滤 142 只 ST 股票\n", - " [20220829] 过滤 142 只 ST 股票\n", - " [20220830] 过滤 141 只 ST 股票\n", - " [20220831] 过滤 142 只 ST 股票\n", - " [20220901] 过滤 141 只 ST 股票\n", - " [20220902] 过滤 141 只 ST 股票\n", - " [20220905] 过滤 141 只 ST 股票\n", - " [20220906] 过滤 141 只 ST 股票\n", - " [20220907] 过滤 141 只 ST 股票\n", - " [20220908] 过滤 141 只 ST 股票\n", - " [20220909] 过滤 141 只 ST 股票\n", - " [20220913] 过滤 140 只 ST 股票\n", - " [20220914] 过滤 140 只 ST 股票\n", - " [20220915] 过滤 139 只 ST 股票\n", - " [20220916] 过滤 139 只 ST 股票\n", - " [20220919] 过滤 139 只 ST 股票\n", - " [20220920] 过滤 139 只 ST 股票\n", - " [20220921] 过滤 140 只 ST 股票\n", - " [20220922] 过滤 138 只 ST 股票\n", - " [20220923] 过滤 138 只 ST 股票\n", - " [20220926] 过滤 138 只 ST 股票\n", - " [20220927] 过滤 139 只 ST 股票\n", - " [20220928] 过滤 140 只 ST 股票\n", - " [20220929] 过滤 138 只 ST 股票\n", - " [20220930] 过滤 137 只 ST 股票\n", - " [20221010] 过滤 137 只 ST 股票\n", - " [20221011] 过滤 137 只 ST 股票\n", - " [20221012] 过滤 137 只 ST 股票\n", - " [20221013] 过滤 137 只 ST 股票\n", - " [20221014] 过滤 137 只 ST 股票\n", - " [20221017] 过滤 137 只 ST 股票\n", - " [20221018] 过滤 137 只 ST 股票\n", - " [20221019] 过滤 137 只 ST 股票\n", - " [20221020] 过滤 137 只 ST 股票\n", - " [20221021] 过滤 137 只 ST 股票\n", - " [20221024] 过滤 137 只 ST 股票\n", - " [20221025] 过滤 137 只 ST 股票\n", - " [20221026] 过滤 137 只 ST 股票\n", - " [20221027] 过滤 137 只 ST 股票\n", - " [20221028] 过滤 137 只 ST 股票\n", - " [20221031] 过滤 137 只 ST 股票\n", - " [20221101] 过滤 136 只 ST 股票\n", - " [20221102] 过滤 137 只 ST 股票\n", - " [20221103] 过滤 137 只 ST 股票\n", - " [20221104] 过滤 137 只 ST 股票\n", - " [20221107] 过滤 137 只 ST 股票\n", - " [20221108] 过滤 136 只 ST 股票\n", - " [20221109] 过滤 136 只 ST 股票\n", - " [20221110] 过滤 136 只 ST 股票\n", - " [20221111] 过滤 136 只 ST 股票\n", - " [20221114] 过滤 136 只 ST 股票\n", - " [20221115] 过滤 136 只 ST 股票\n", - " [20221116] 过滤 135 只 ST 股票\n", - " [20221117] 过滤 134 只 ST 股票\n", - " [20221118] 过滤 133 只 ST 股票\n", - " [20221121] 过滤 133 只 ST 股票\n", - " [20221122] 过滤 135 只 ST 股票\n", - " [20221123] 过滤 135 只 ST 股票\n", - " [20221124] 过滤 135 只 ST 股票\n", - " [20221125] 过滤 135 只 ST 股票\n", - " [20221128] 过滤 134 只 ST 股票\n", - " [20221129] 过滤 135 只 ST 股票\n", - " [20221130] 过滤 135 只 ST 股票\n", - " [20221201] 过滤 134 只 ST 股票\n", - " [20221202] 过滤 134 只 ST 股票\n", - " [20221205] 过滤 134 只 ST 股票\n", - " [20221206] 过滤 134 只 ST 股票\n", - " [20221207] 过滤 134 只 ST 股票\n", - " [20221208] 过滤 135 只 ST 股票\n", - " [20221209] 过滤 133 只 ST 股票\n", - " [20221212] 过滤 134 只 ST 股票\n", - " [20221213] 过滤 134 只 ST 股票\n", - " [20221214] 过滤 134 只 ST 股票\n", - " [20221215] 过滤 134 只 ST 股票\n", - " [20221216] 过滤 134 只 ST 股票\n", - " [20221219] 过滤 133 只 ST 股票\n", - " [20221220] 过滤 133 只 ST 股票\n", - " [20221221] 过滤 132 只 ST 股票\n", - " [20221222] 过滤 132 只 ST 股票\n", - " [20221223] 过滤 134 只 ST 股票\n", - " [20221226] 过滤 134 只 ST 股票\n", - " [20221227] 过滤 134 只 ST 股票\n", - " [20221228] 过滤 134 只 ST 股票\n", - " [20221229] 过滤 134 只 ST 股票\n", - " [20221230] 过滤 133 只 ST 股票\n", - " [20230103] 过滤 133 只 ST 股票\n", - " [20230104] 过滤 133 只 ST 股票\n", - " [20230105] 过滤 133 只 ST 股票\n", - " [20230106] 过滤 133 只 ST 股票\n", - " [20230109] 过滤 132 只 ST 股票\n", - " [20230110] 过滤 133 只 ST 股票\n", - " [20230111] 过滤 133 只 ST 股票\n", - " [20230112] 过滤 133 只 ST 股票\n", - " [20230113] 过滤 133 只 ST 股票\n", - " [20230116] 过滤 133 只 ST 股票\n", - " [20230117] 过滤 132 只 ST 股票\n", - " [20230118] 过滤 133 只 ST 股票\n", - " [20230119] 过滤 133 只 ST 股票\n", - " [20230120] 过滤 133 只 ST 股票\n", - " [20230130] 过滤 133 只 ST 股票\n", - " [20230131] 过滤 133 只 ST 股票\n", - " [20230201] 过滤 134 只 ST 股票\n", - " [20230202] 过滤 134 只 ST 股票\n", - " [20230203] 过滤 131 只 ST 股票\n", - " [20230206] 过滤 131 只 ST 股票\n", - " [20230207] 过滤 131 只 ST 股票\n", - " [20230208] 过滤 131 只 ST 股票\n", - " [20230209] 过滤 131 只 ST 股票\n", - " [20230210] 过滤 131 只 ST 股票\n", - " [20230213] 过滤 131 只 ST 股票\n", - " [20230214] 过滤 131 只 ST 股票\n", - " [20230215] 过滤 131 只 ST 股票\n", - " [20230216] 过滤 131 只 ST 股票\n", - " [20230217] 过滤 130 只 ST 股票\n", - " [20230220] 过滤 131 只 ST 股票\n", - " [20230221] 过滤 131 只 ST 股票\n", - " [20230222] 过滤 131 只 ST 股票\n", - " [20230223] 过滤 131 只 ST 股票\n", - " [20230224] 过滤 131 只 ST 股票\n", - " [20230227] 过滤 130 只 ST 股票\n", - " [20230228] 过滤 129 只 ST 股票\n", - " [20230301] 过滤 129 只 ST 股票\n", - " [20230302] 过滤 129 只 ST 股票\n", - " [20230303] 过滤 128 只 ST 股票\n", - " [20230306] 过滤 128 只 ST 股票\n", - " [20230307] 过滤 128 只 ST 股票\n", - " [20230308] 过滤 127 只 ST 股票\n", - " [20230309] 过滤 126 只 ST 股票\n", - " [20230310] 过滤 126 只 ST 股票\n", - " [20230313] 过滤 127 只 ST 股票\n", - " [20230314] 过滤 128 只 ST 股票\n", - " [20230315] 过滤 128 只 ST 股票\n", - " [20230316] 过滤 128 只 ST 股票\n", - " [20230317] 过滤 128 只 ST 股票\n", - " [20230320] 过滤 127 只 ST 股票\n", - " [20230321] 过滤 127 只 ST 股票\n", - " [20230322] 过滤 127 只 ST 股票\n", - " [20230323] 过滤 128 只 ST 股票\n", - " [20230324] 过滤 128 只 ST 股票\n", - " [20230327] 过滤 128 只 ST 股票\n", - " [20230328] 过滤 128 只 ST 股票\n", - " [20230329] 过滤 127 只 ST 股票\n", - " [20230330] 过滤 126 只 ST 股票\n", - " [20230331] 过滤 125 只 ST 股票\n", - " [20230403] 过滤 124 只 ST 股票\n", - " [20230404] 过滤 124 只 ST 股票\n", - " [20230406] 过滤 124 只 ST 股票\n", - " [20230407] 过滤 124 只 ST 股票\n", - " [20230410] 过滤 125 只 ST 股票\n", - " [20230411] 过滤 125 只 ST 股票\n", - " [20230412] 过滤 124 只 ST 股票\n", - " [20230413] 过滤 124 只 ST 股票\n", - " [20230414] 过滤 122 只 ST 股票\n", - " [20230417] 过滤 122 只 ST 股票\n", - " [20230418] 过滤 122 只 ST 股票\n", - " [20230419] 过滤 120 只 ST 股票\n", - " [20230420] 过滤 121 只 ST 股票\n", - " [20230421] 过滤 121 只 ST 股票\n", - " [20230424] 过滤 120 只 ST 股票\n", - " [20230425] 过滤 120 只 ST 股票\n", - " [20230426] 过滤 118 只 ST 股票\n", - " [20230427] 过滤 122 只 ST 股票\n", - " [20230428] 过滤 121 只 ST 股票\n", - " [20230504] 过滤 116 只 ST 股票\n", - " [20230505] 过滤 153 只 ST 股票\n", - " [20230508] 过滤 153 只 ST 股票\n", - " [20230509] 过滤 150 只 ST 股票\n", - " [20230510] 过滤 148 只 ST 股票\n", - " [20230511] 过滤 148 只 ST 股票\n", - " [20230512] 过滤 148 只 ST 股票\n", - " [20230515] 过滤 148 只 ST 股票\n", - " [20230516] 过滤 148 只 ST 股票\n", - " [20230517] 过滤 148 只 ST 股票\n", - " [20230518] 过滤 147 只 ST 股票\n", - " [20230519] 过滤 146 只 ST 股票\n", - " [20230522] 过滤 145 只 ST 股票\n", - " [20230523] 过滤 144 只 ST 股票\n", - " [20230524] 过滤 144 只 ST 股票\n", - " [20230525] 过滤 143 只 ST 股票\n", - " [20230526] 过滤 142 只 ST 股票\n", - " [20230529] 过滤 140 只 ST 股票\n", - " [20230530] 过滤 139 只 ST 股票\n", - " [20230531] 过滤 138 只 ST 股票\n", - " [20230601] 过滤 140 只 ST 股票\n", - " [20230602] 过滤 135 只 ST 股票\n", - " [20230605] 过滤 134 只 ST 股票\n", - " [20230606] 过滤 133 只 ST 股票\n", - " [20230607] 过滤 133 只 ST 股票\n", - " [20230608] 过滤 132 只 ST 股票\n", - " [20230609] 过滤 132 只 ST 股票\n", - " [20230612] 过滤 130 只 ST 股票\n", - " [20230613] 过滤 127 只 ST 股票\n", - " [20230614] 过滤 123 只 ST 股票\n", - " [20230615] 过滤 124 只 ST 股票\n", - " [20230616] 过滤 122 只 ST 股票\n", - " [20230619] 过滤 122 只 ST 股票\n", - " [20230620] 过滤 121 只 ST 股票\n", - " [20230621] 过滤 121 只 ST 股票\n", - " [20230626] 过滤 121 只 ST 股票\n", - " [20230627] 过滤 119 只 ST 股票\n", - " [20230628] 过滤 119 只 ST 股票\n", - " [20230629] 过滤 119 只 ST 股票\n", - " [20230630] 过滤 121 只 ST 股票\n", - " [20230703] 过滤 122 只 ST 股票\n", - " [20230704] 过滤 122 只 ST 股票\n", - " [20230705] 过滤 123 只 ST 股票\n", - " [20230706] 过滤 123 只 ST 股票\n", - " [20230707] 过滤 123 只 ST 股票\n", - " [20230710] 过滤 123 只 ST 股票\n", - " [20230711] 过滤 123 只 ST 股票\n", - " [20230712] 过滤 123 只 ST 股票\n", - " [20230713] 过滤 123 只 ST 股票\n", - " [20230714] 过滤 122 只 ST 股票\n", - " [20230717] 过滤 122 只 ST 股票\n", - " [20230718] 过滤 122 只 ST 股票\n", - " [20230719] 过滤 123 只 ST 股票\n", - " [20230720] 过滤 123 只 ST 股票\n", - " [20230721] 过滤 122 只 ST 股票\n", - " [20230724] 过滤 122 只 ST 股票\n", - " [20230725] 过滤 122 只 ST 股票\n", - " [20230726] 过滤 122 只 ST 股票\n", - " [20230727] 过滤 121 只 ST 股票\n", - " [20230728] 过滤 121 只 ST 股票\n", - " [20230731] 过滤 121 只 ST 股票\n", - " [20230801] 过滤 121 只 ST 股票\n", - " [20230802] 过滤 121 只 ST 股票\n", - " [20230803] 过滤 121 只 ST 股票\n", - " [20230804] 过滤 121 只 ST 股票\n", - " [20230807] 过滤 121 只 ST 股票\n", - " [20230808] 过滤 121 只 ST 股票\n", - " [20230809] 过滤 121 只 ST 股票\n", - " [20230810] 过滤 121 只 ST 股票\n", - " [20230811] 过滤 121 只 ST 股票\n", - " [20230814] 过滤 121 只 ST 股票\n", - " [20230815] 过滤 121 只 ST 股票\n", - " [20230816] 过滤 121 只 ST 股票\n", - " [20230817] 过滤 120 只 ST 股票\n", - " [20230818] 过滤 120 只 ST 股票\n", - " [20230821] 过滤 120 只 ST 股票\n", - " [20230822] 过滤 120 只 ST 股票\n", - " [20230823] 过滤 120 只 ST 股票\n", - " [20230824] 过滤 120 只 ST 股票\n", - " [20230825] 过滤 120 只 ST 股票\n", - " [20230828] 过滤 120 只 ST 股票\n", - " [20230829] 过滤 120 只 ST 股票\n", - " [20230830] 过滤 120 只 ST 股票\n", - " [20230831] 过滤 120 只 ST 股票\n", - " [20230901] 过滤 120 只 ST 股票\n", - " [20230904] 过滤 118 只 ST 股票\n", - " [20230905] 过滤 118 只 ST 股票\n", - " [20230906] 过滤 118 只 ST 股票\n", - " [20230907] 过滤 118 只 ST 股票\n", - " [20230908] 过滤 118 只 ST 股票\n", - " [20230911] 过滤 118 只 ST 股票\n", - " [20230912] 过滤 118 只 ST 股票\n", - " [20230913] 过滤 118 只 ST 股票\n", - " [20230914] 过滤 118 只 ST 股票\n", - " [20230915] 过滤 118 只 ST 股票\n", - " [20230918] 过滤 118 只 ST 股票\n", - " [20230919] 过滤 118 只 ST 股票\n", - " [20230920] 过滤 118 只 ST 股票\n", - " [20230921] 过滤 117 只 ST 股票\n", - " [20230922] 过滤 118 只 ST 股票\n", - " [20230925] 过滤 117 只 ST 股票\n", - " [20230926] 过滤 117 只 ST 股票\n", - " [20230927] 过滤 118 只 ST 股票\n", - " [20230928] 过滤 116 只 ST 股票\n", - " [20231009] 过滤 117 只 ST 股票\n", - " [20231010] 过滤 118 只 ST 股票\n", - " [20231011] 过滤 118 只 ST 股票\n", - " [20231012] 过滤 119 只 ST 股票\n", - " [20231013] 过滤 119 只 ST 股票\n", - " [20231016] 过滤 119 只 ST 股票\n", - " [20231017] 过滤 119 只 ST 股票\n", - " [20231018] 过滤 118 只 ST 股票\n", - " [20231019] 过滤 118 只 ST 股票\n", - " [20231020] 过滤 118 只 ST 股票\n", - " [20231023] 过滤 118 只 ST 股票\n", - " [20231024] 过滤 117 只 ST 股票\n", - " [20231025] 过滤 118 只 ST 股票\n", - " [20231026] 过滤 118 只 ST 股票\n", - " [20231027] 过滤 118 只 ST 股票\n", - " [20231030] 过滤 118 只 ST 股票\n", - " [20231031] 过滤 119 只 ST 股票\n", - " [20231101] 过滤 119 只 ST 股票\n", - " [20231102] 过滤 118 只 ST 股票\n", - " [20231103] 过滤 118 只 ST 股票\n", - " [20231106] 过滤 116 只 ST 股票\n", - " [20231107] 过滤 116 只 ST 股票\n", - " [20231108] 过滤 116 只 ST 股票\n", - " [20231109] 过滤 116 只 ST 股票\n", - " [20231110] 过滤 116 只 ST 股票\n", - " [20231113] 过滤 116 只 ST 股票\n", - " [20231114] 过滤 116 只 ST 股票\n", - " [20231115] 过滤 116 只 ST 股票\n", - " [20231116] 过滤 115 只 ST 股票\n", - " [20231117] 过滤 115 只 ST 股票\n", - " [20231120] 过滤 115 只 ST 股票\n", - " [20231121] 过滤 116 只 ST 股票\n", - " [20231122] 过滤 115 只 ST 股票\n", - " [20231123] 过滤 115 只 ST 股票\n", - " [20231124] 过滤 114 只 ST 股票\n", - " [20231127] 过滤 116 只 ST 股票\n", - " [20231128] 过滤 116 只 ST 股票\n", - " [20231129] 过滤 116 只 ST 股票\n", - " [20231130] 过滤 116 只 ST 股票\n", - " [20231201] 过滤 116 只 ST 股票\n", - " [20231204] 过滤 116 只 ST 股票\n", - " [20231205] 过滤 116 只 ST 股票\n", - " [20231206] 过滤 116 只 ST 股票\n", - " [20231207] 过滤 114 只 ST 股票\n", - " [20231208] 过滤 115 只 ST 股票\n", - " [20231211] 过滤 115 只 ST 股票\n", - " [20231212] 过滤 115 只 ST 股票\n", - " [20231213] 过滤 115 只 ST 股票\n", - " [20231214] 过滤 116 只 ST 股票\n", - " [20231215] 过滤 115 只 ST 股票\n", - " [20231218] 过滤 116 只 ST 股票\n", - " [20231219] 过滤 114 只 ST 股票\n", - " [20231220] 过滤 116 只 ST 股票\n", - " [20231221] 过滤 116 只 ST 股票\n", - " [20231222] 过滤 115 只 ST 股票\n", - " [20231225] 过滤 113 只 ST 股票\n", - " [20231226] 过滤 114 只 ST 股票\n", - " [20231227] 过滤 114 只 ST 股票\n", - " [20231228] 过滤 110 只 ST 股票\n", - " [20231229] 过滤 113 只 ST 股票\n", - " [20240102] 过滤 114 只 ST 股票\n", - " [20240103] 过滤 114 只 ST 股票\n", - " [20240104] 过滤 114 只 ST 股票\n", - " [20240105] 过滤 114 只 ST 股票\n", - " [20240108] 过滤 114 只 ST 股票\n", - " [20240109] 过滤 113 只 ST 股票\n", - " [20240110] 过滤 113 只 ST 股票\n", - " [20240111] 过滤 113 只 ST 股票\n", - " [20240112] 过滤 111 只 ST 股票\n", - " [20240115] 过滤 112 只 ST 股票\n", - " [20240116] 过滤 112 只 ST 股票\n", - " [20240117] 过滤 112 只 ST 股票\n", - " [20240118] 过滤 112 只 ST 股票\n", - " [20240119] 过滤 111 只 ST 股票\n", - " [20240122] 过滤 111 只 ST 股票\n", - " [20240123] 过滤 111 只 ST 股票\n", - " [20240124] 过滤 110 只 ST 股票\n", - " [20240125] 过滤 110 只 ST 股票\n", - " [20240126] 过滤 111 只 ST 股票\n", - " [20240129] 过滤 112 只 ST 股票\n", - " [20240130] 过滤 112 只 ST 股票\n", - " [20240131] 过滤 113 只 ST 股票\n", - " [20240201] 过滤 113 只 ST 股票\n", - " [20240202] 过滤 113 只 ST 股票\n", - " [20240205] 过滤 112 只 ST 股票\n", - " [20240206] 过滤 111 只 ST 股票\n", - " [20240207] 过滤 111 只 ST 股票\n", - " [20240208] 过滤 111 只 ST 股票\n", - " [20240219] 过滤 111 只 ST 股票\n", - " [20240220] 过滤 111 只 ST 股票\n", - " [20240221] 过滤 111 只 ST 股票\n", - " [20240222] 过滤 111 只 ST 股票\n", - " [20240223] 过滤 111 只 ST 股票\n", - " [20240226] 过滤 111 只 ST 股票\n", - " [20240227] 过滤 112 只 ST 股票\n", - " [20240228] 过滤 112 只 ST 股票\n", - " [20240229] 过滤 112 只 ST 股票\n", - " [20240301] 过滤 112 只 ST 股票\n", - " [20240304] 过滤 112 只 ST 股票\n", - " [20240305] 过滤 112 只 ST 股票\n", - " [20240306] 过滤 111 只 ST 股票\n", - " [20240307] 过滤 111 只 ST 股票\n", - " [20240308] 过滤 110 只 ST 股票\n", - " [20240311] 过滤 110 只 ST 股票\n", - " [20240312] 过滤 110 只 ST 股票\n", - " [20240313] 过滤 110 只 ST 股票\n", - " [20240314] 过滤 110 只 ST 股票\n", - " [20240315] 过滤 110 只 ST 股票\n", - " [20240318] 过滤 110 只 ST 股票\n", - " [20240319] 过滤 110 只 ST 股票\n", - " [20240320] 过滤 110 只 ST 股票\n", - " [20240321] 过滤 110 只 ST 股票\n", - " [20240322] 过滤 110 只 ST 股票\n", - " [20240325] 过滤 110 只 ST 股票\n", - " [20240326] 过滤 110 只 ST 股票\n", - " [20240327] 过滤 110 只 ST 股票\n", - " [20240328] 过滤 109 只 ST 股票\n", - " [20240329] 过滤 110 只 ST 股票\n", - " [20240401] 过滤 112 只 ST 股票\n", - " [20240402] 过滤 112 只 ST 股票\n", - " [20240403] 过滤 112 只 ST 股票\n", - " [20240408] 过滤 113 只 ST 股票\n", - " [20240409] 过滤 113 只 ST 股票\n", - " [20240410] 过滤 113 只 ST 股票\n", - " [20240411] 过滤 113 只 ST 股票\n", - " [20240412] 过滤 113 只 ST 股票\n", - " [20240415] 过滤 113 只 ST 股票\n", - " [20240416] 过滤 113 只 ST 股票\n", - " [20240417] 过滤 113 只 ST 股票\n", - " [20240418] 过滤 113 只 ST 股票\n", - " [20240419] 过滤 113 只 ST 股票\n", - " [20240422] 过滤 112 只 ST 股票\n", - " [20240423] 过滤 114 只 ST 股票\n", - " [20240424] 过滤 115 只 ST 股票\n", - " [20240425] 过滤 114 只 ST 股票\n", - " [20240426] 过滤 115 只 ST 股票\n", - " [20240429] 过滤 117 只 ST 股票\n", - " [20240430] 过滤 118 只 ST 股票\n", - " [20240506] 过滤 163 只 ST 股票\n", - " [20240507] 过滤 163 只 ST 股票\n", - " [20240508] 过滤 161 只 ST 股票\n", - " [20240509] 过滤 161 只 ST 股票\n", - " [20240510] 过滤 161 只 ST 股票\n", - " [20240513] 过滤 161 只 ST 股票\n", - " [20240514] 过滤 163 只 ST 股票\n", - " [20240515] 过滤 163 只 ST 股票\n", - " [20240516] 过滤 162 只 ST 股票\n", - " [20240517] 过滤 162 只 ST 股票\n", - " [20240520] 过滤 161 只 ST 股票\n", - " [20240521] 过滤 163 只 ST 股票\n", - " [20240522] 过滤 163 只 ST 股票\n", - " [20240523] 过滤 163 只 ST 股票\n", - " [20240524] 过滤 163 只 ST 股票\n", - " [20240527] 过滤 162 只 ST 股票\n", - " [20240528] 过滤 162 只 ST 股票\n", - " [20240529] 过滤 161 只 ST 股票\n", - " [20240530] 过滤 160 只 ST 股票\n", - " [20240531] 过滤 159 只 ST 股票\n", - " [20240603] 过滤 159 只 ST 股票\n", - " [20240604] 过滤 158 只 ST 股票\n", - " [20240605] 过滤 157 只 ST 股票\n", - " [20240606] 过滤 157 只 ST 股票\n", - " [20240607] 过滤 153 只 ST 股票\n", - " [20240611] 过滤 148 只 ST 股票\n", - " [20240612] 过滤 147 只 ST 股票\n", - " [20240613] 过滤 145 只 ST 股票\n", - " [20240614] 过滤 144 只 ST 股票\n", - " [20240617] 过滤 143 只 ST 股票\n", - " [20240618] 过滤 140 只 ST 股票\n", - " [20240619] 过滤 139 只 ST 股票\n", - " [20240620] 过滤 138 只 ST 股票\n", - " [20240621] 过滤 137 只 ST 股票\n", - " [20240624] 过滤 135 只 ST 股票\n", - " [20240625] 过滤 130 只 ST 股票\n", - " [20240626] 过滤 131 只 ST 股票\n", - " [20240627] 过滤 128 只 ST 股票\n", - " [20240628] 过滤 128 只 ST 股票\n", - " [20240701] 过滤 126 只 ST 股票\n", - " [20240702] 过滤 125 只 ST 股票\n", - " [20240703] 过滤 123 只 ST 股票\n", - " [20240704] 过滤 123 只 ST 股票\n", - " [20240705] 过滤 122 只 ST 股票\n", - " [20240708] 过滤 122 只 ST 股票\n", - " [20240709] 过滤 128 只 ST 股票\n", - " [20240710] 过滤 128 只 ST 股票\n", - " [20240711] 过滤 128 只 ST 股票\n", - " [20240712] 过滤 128 只 ST 股票\n", - " [20240715] 过滤 128 只 ST 股票\n", - " [20240716] 过滤 128 只 ST 股票\n", - " [20240717] 过滤 126 只 ST 股票\n", - " [20240718] 过滤 125 只 ST 股票\n", - " [20240719] 过滤 126 只 ST 股票\n", - " [20240722] 过滤 125 只 ST 股票\n", - " [20240723] 过滤 125 只 ST 股票\n", - " [20240724] 过滤 125 只 ST 股票\n", - " [20240725] 过滤 124 只 ST 股票\n", - " [20240726] 过滤 123 只 ST 股票\n", - " [20240729] 过滤 122 只 ST 股票\n", - " [20240730] 过滤 122 只 ST 股票\n", - " [20240731] 过滤 122 只 ST 股票\n", - " [20240801] 过滤 122 只 ST 股票\n", - " [20240802] 过滤 123 只 ST 股票\n", - " [20240805] 过滤 121 只 ST 股票\n", - " [20240806] 过滤 122 只 ST 股票\n", - " [20240807] 过滤 123 只 ST 股票\n", - " [20240808] 过滤 123 只 ST 股票\n", - " [20240809] 过滤 123 只 ST 股票\n", - " [20240812] 过滤 124 只 ST 股票\n", - " [20240813] 过滤 124 只 ST 股票\n", - " [20240814] 过滤 124 只 ST 股票\n", - " [20240815] 过滤 123 只 ST 股票\n", - " [20240816] 过滤 122 只 ST 股票\n", - " [20240819] 过滤 121 只 ST 股票\n", - " [20240820] 过滤 121 只 ST 股票\n", - " [20240821] 过滤 121 只 ST 股票\n", - " [20240822] 过滤 121 只 ST 股票\n", - " [20240823] 过滤 119 只 ST 股票\n", - " [20240826] 过滤 120 只 ST 股票\n", - " [20240827] 过滤 120 只 ST 股票\n", - " [20240828] 过滤 120 只 ST 股票\n", - " [20240829] 过滤 119 只 ST 股票\n", - " [20240830] 过滤 119 只 ST 股票\n", - " [20240902] 过滤 119 只 ST 股票\n", - " [20240903] 过滤 120 只 ST 股票\n", - " [20240904] 过滤 119 只 ST 股票\n", - " [20240905] 过滤 119 只 ST 股票\n", - " [20240906] 过滤 119 只 ST 股票\n", - " [20240909] 过滤 119 只 ST 股票\n", - " [20240910] 过滤 118 只 ST 股票\n", - " [20240911] 过滤 119 只 ST 股票\n", - " [20240912] 过滤 119 只 ST 股票\n", - " [20240913] 过滤 119 只 ST 股票\n", - " [20240918] 过滤 118 只 ST 股票\n", - " [20240919] 过滤 121 只 ST 股票\n", - " [20240920] 过滤 121 只 ST 股票\n", - " [20240923] 过滤 121 只 ST 股票\n", - " [20240924] 过滤 121 只 ST 股票\n", - " [20240925] 过滤 121 只 ST 股票\n", - " [20240926] 过滤 121 只 ST 股票\n", - " [20240927] 过滤 121 只 ST 股票\n", - " [20240930] 过滤 121 只 ST 股票\n", - " [20241008] 过滤 119 只 ST 股票\n", - " [20241009] 过滤 119 只 ST 股票\n", - " [20241010] 过滤 119 只 ST 股票\n", - " [20241011] 过滤 119 只 ST 股票\n", - " [20241014] 过滤 119 只 ST 股票\n", - " [20241015] 过滤 119 只 ST 股票\n", - " [20241016] 过滤 120 只 ST 股票\n", - " [20241017] 过滤 120 只 ST 股票\n", - " [20241018] 过滤 120 只 ST 股票\n", - " [20241021] 过滤 120 只 ST 股票\n", - " [20241022] 过滤 120 只 ST 股票\n", - " [20241023] 过滤 120 只 ST 股票\n", - " [20241024] 过滤 120 只 ST 股票\n", - " [20241025] 过滤 120 只 ST 股票\n", - " [20241028] 过滤 119 只 ST 股票\n", - " [20241029] 过滤 120 只 ST 股票\n", - " [20241030] 过滤 120 只 ST 股票\n", - " [20241031] 过滤 120 只 ST 股票\n", - " [20241101] 过滤 122 只 ST 股票\n", - " [20241104] 过滤 123 只 ST 股票\n", - " [20241105] 过滤 123 只 ST 股票\n", - " [20241106] 过滤 123 只 ST 股票\n", - " [20241107] 过滤 123 只 ST 股票\n", - " [20241108] 过滤 124 只 ST 股票\n", - " [20241111] 过滤 120 只 ST 股票\n", - " [20241112] 过滤 121 只 ST 股票\n", - " [20241113] 过滤 122 只 ST 股票\n", - " [20241114] 过滤 122 只 ST 股票\n", - " [20241115] 过滤 121 只 ST 股票\n", - " [20241118] 过滤 120 只 ST 股票\n", - " [20241119] 过滤 120 只 ST 股票\n", - " [20241120] 过滤 121 只 ST 股票\n", - " [20241121] 过滤 122 只 ST 股票\n", - " [20241122] 过滤 122 只 ST 股票\n", - " [20241125] 过滤 122 只 ST 股票\n", - " [20241126] 过滤 122 只 ST 股票\n", - " [20241127] 过滤 122 只 ST 股票\n", - " [20241128] 过滤 122 只 ST 股票\n", - " [20241129] 过滤 122 只 ST 股票\n", - " [20241202] 过滤 122 只 ST 股票\n", - " [20241203] 过滤 122 只 ST 股票\n", - " [20241204] 过滤 122 只 ST 股票\n", - " [20241205] 过滤 122 只 ST 股票\n", - " [20241206] 过滤 122 只 ST 股票\n", - " [20241209] 过滤 122 只 ST 股票\n", - " [20241210] 过滤 123 只 ST 股票\n", - " [20241211] 过滤 123 只 ST 股票\n", - " [20241212] 过滤 124 只 ST 股票\n", - " [20241213] 过滤 123 只 ST 股票\n", - " [20241216] 过滤 124 只 ST 股票\n", - " [20241217] 过滤 123 只 ST 股票\n", - " [20241218] 过滤 124 只 ST 股票\n", - " [20241219] 过滤 123 只 ST 股票\n", - " [20241220] 过滤 125 只 ST 股票\n", - " [20241223] 过滤 125 只 ST 股票\n", - " [20241224] 过滤 125 只 ST 股票\n", - " [20241225] 过滤 122 只 ST 股票\n", - " [20241226] 过滤 124 只 ST 股票\n", - " [20241227] 过滤 123 只 ST 股票\n", - " [20241230] 过滤 123 只 ST 股票\n", - " [20241231] 过滤 124 只 ST 股票\n", - " [20250102] 过滤 124 只 ST 股票\n", - " [20250103] 过滤 125 只 ST 股票\n", - " [20250106] 过滤 124 只 ST 股票\n", - " [20250107] 过滤 125 只 ST 股票\n", - " [20250108] 过滤 125 只 ST 股票\n", - " [20250109] 过滤 126 只 ST 股票\n", - " [20250110] 过滤 126 只 ST 股票\n", - " [20250113] 过滤 124 只 ST 股票\n", - " [20250114] 过滤 127 只 ST 股票\n", - " [20250115] 过滤 127 只 ST 股票\n", - " [20250116] 过滤 127 只 ST 股票\n", - " [20250117] 过滤 126 只 ST 股票\n", - " [20250120] 过滤 126 只 ST 股票\n", - " [20250121] 过滤 126 只 ST 股票\n", - " [20250122] 过滤 126 只 ST 股票\n", - " [20250123] 过滤 126 只 ST 股票\n", - " [20250124] 过滤 126 只 ST 股票\n", - " [20250127] 过滤 126 只 ST 股票\n", - " [20250205] 过滤 126 只 ST 股票\n", - " [20250206] 过滤 126 只 ST 股票\n", - " [20250207] 过滤 126 只 ST 股票\n", - " [20250210] 过滤 125 只 ST 股票\n", - " [20250211] 过滤 125 只 ST 股票\n", - " [20250212] 过滤 125 只 ST 股票\n", - " [20250213] 过滤 125 只 ST 股票\n", - " [20250214] 过滤 125 只 ST 股票\n", - " [20250217] 过滤 125 只 ST 股票\n", - " [20250218] 过滤 124 只 ST 股票\n", - " [20250219] 过滤 124 只 ST 股票\n", - " [20250220] 过滤 124 只 ST 股票\n", - " [20250221] 过滤 126 只 ST 股票\n", - " [20250224] 过滤 126 只 ST 股票\n", - " [20250225] 过滤 126 只 ST 股票\n", - " [20250226] 过滤 126 只 ST 股票\n", - " [20250227] 过滤 126 只 ST 股票\n", - " [20250228] 过滤 126 只 ST 股票\n", - " [20250303] 过滤 126 只 ST 股票\n", - " [20250304] 过滤 126 只 ST 股票\n", - " [20250305] 过滤 126 只 ST 股票\n", - " [20250306] 过滤 126 只 ST 股票\n", - " [20250307] 过滤 126 只 ST 股票\n", - " [20250310] 过滤 127 只 ST 股票\n", - " [20250311] 过滤 127 只 ST 股票\n", - " [20250312] 过滤 126 只 ST 股票\n", - " [20250313] 过滤 126 只 ST 股票\n", - " [20250314] 过滤 127 只 ST 股票\n", - " [20250317] 过滤 127 只 ST 股票\n", - " [20250318] 过滤 131 只 ST 股票\n", - " [20250319] 过滤 131 只 ST 股票\n", - " [20250320] 过滤 132 只 ST 股票\n", - " [20250321] 过滤 131 只 ST 股票\n", - " [20250324] 过滤 130 只 ST 股票\n", - " [20250325] 过滤 133 只 ST 股票\n", - " [20250326] 过滤 134 只 ST 股票\n", - " [20250327] 过滤 134 只 ST 股票\n", - " [20250328] 过滤 134 只 ST 股票\n", - " [20250331] 过滤 134 只 ST 股票\n", - " [20250401] 过滤 133 只 ST 股票\n", - " [20250402] 过滤 133 只 ST 股票\n", - " [20250403] 过滤 133 只 ST 股票\n", - " [20250407] 过滤 133 只 ST 股票\n", - " [20250408] 过滤 133 只 ST 股票\n", - " [20250409] 过滤 133 只 ST 股票\n", - " [20250410] 过滤 133 只 ST 股票\n", - " [20250411] 过滤 132 只 ST 股票\n", - " [20250414] 过滤 131 只 ST 股票\n", - " [20250415] 过滤 130 只 ST 股票\n", - " [20250416] 过滤 132 只 ST 股票\n", - " [20250417] 过滤 131 只 ST 股票\n", - " [20250418] 过滤 130 只 ST 股票\n", - " [20250421] 过滤 130 只 ST 股票\n", - " [20250422] 过滤 133 只 ST 股票\n", - " [20250423] 过滤 138 只 ST 股票\n", - " [20250424] 过滤 137 只 ST 股票\n", - " [20250425] 过滤 139 只 ST 股票\n", - " [20250428] 过滤 142 只 ST 股票\n", - " [20250429] 过滤 148 只 ST 股票\n", - " [20250430] 过滤 169 只 ST 股票\n", - " [20250506] 过滤 190 只 ST 股票\n", - " [20250507] 过滤 190 只 ST 股票\n", - " [20250508] 过滤 190 只 ST 股票\n", - " [20250509] 过滤 190 只 ST 股票\n", - " [20250512] 过滤 189 只 ST 股票\n", - " [20250513] 过滤 189 只 ST 股票\n", - " [20250514] 过滤 189 只 ST 股票\n", - " [20250515] 过滤 188 只 ST 股票\n", - " [20250516] 过滤 188 只 ST 股票\n", - " [20250519] 过滤 182 只 ST 股票\n", - " [20250520] 过滤 183 只 ST 股票\n", - " [20250521] 过滤 181 只 ST 股票\n", - " [20250522] 过滤 179 只 ST 股票\n", - " [20250523] 过滤 178 只 ST 股票\n", - " [20250526] 过滤 178 只 ST 股票\n", - " [20250527] 过滤 179 只 ST 股票\n", - " [20250528] 过滤 177 只 ST 股票\n", - " [20250529] 过滤 178 只 ST 股票\n", - " [20250530] 过滤 175 只 ST 股票\n", - " [20250603] 过滤 172 只 ST 股票\n", - " [20250604] 过滤 172 只 ST 股票\n", - " [20250605] 过滤 172 只 ST 股票\n", - " [20250606] 过滤 172 只 ST 股票\n", - " [20250609] 过滤 171 只 ST 股票\n", - " [20250610] 过滤 171 只 ST 股票\n", - " [20250611] 过滤 172 只 ST 股票\n", - " [20250612] 过滤 171 只 ST 股票\n", - " [20250613] 过滤 169 只 ST 股票\n", - " [20250616] 过滤 168 只 ST 股票\n", - " [20250617] 过滤 170 只 ST 股票\n", - " [20250618] 过滤 170 只 ST 股票\n", - " [20250619] 过滤 169 只 ST 股票\n", - " [20250620] 过滤 168 只 ST 股票\n", - " [20250623] 过滤 167 只 ST 股票\n", - " [20250624] 过滤 168 只 ST 股票\n", - " [20250625] 过滤 168 只 ST 股票\n", - " [20250626] 过滤 169 只 ST 股票\n", - " [20250627] 过滤 166 只 ST 股票\n", - " [20250630] 过滤 166 只 ST 股票\n", - " [20250701] 过滤 166 只 ST 股票\n", - " [20250702] 过滤 166 只 ST 股票\n", - " [20250703] 过滤 166 只 ST 股票\n", - " [20250704] 过滤 168 只 ST 股票\n", - " [20250707] 过滤 169 只 ST 股票\n", - " [20250708] 过滤 170 只 ST 股票\n", - " [20250709] 过滤 171 只 ST 股票\n", - " [20250710] 过滤 170 只 ST 股票\n", - " [20250711] 过滤 172 只 ST 股票\n", - " [20250714] 过滤 171 只 ST 股票\n", - " [20250715] 过滤 170 只 ST 股票\n", - " [20250716] 过滤 169 只 ST 股票\n", - " [20250717] 过滤 169 只 ST 股票\n", - " [20250718] 过滤 169 只 ST 股票\n", - " [20250721] 过滤 169 只 ST 股票\n", - " [20250722] 过滤 170 只 ST 股票\n", - " [20250723] 过滤 170 只 ST 股票\n", - " [20250724] 过滤 170 只 ST 股票\n", - " [20250725] 过滤 170 只 ST 股票\n", - " [20250728] 过滤 170 只 ST 股票\n", - " [20250729] 过滤 170 只 ST 股票\n", - " [20250730] 过滤 170 只 ST 股票\n", - " [20250731] 过滤 170 只 ST 股票\n", - " [20250801] 过滤 171 只 ST 股票\n", - " [20250804] 过滤 171 只 ST 股票\n", - " [20250805] 过滤 170 只 ST 股票\n", - " [20250806] 过滤 170 只 ST 股票\n", - " [20250807] 过滤 168 只 ST 股票\n", - " [20250808] 过滤 168 只 ST 股票\n", - " [20250811] 过滤 169 只 ST 股票\n", - " [20250812] 过滤 170 只 ST 股票\n", - " [20250813] 过滤 167 只 ST 股票\n", - " [20250814] 过滤 166 只 ST 股票\n", - " [20250815] 过滤 166 只 ST 股票\n", - " [20250818] 过滤 165 只 ST 股票\n", - " [20250819] 过滤 167 只 ST 股票\n", - " [20250820] 过滤 166 只 ST 股票\n", - " [20250821] 过滤 169 只 ST 股票\n", - " [20250822] 过滤 169 只 ST 股票\n", - " [20250825] 过滤 169 只 ST 股票\n", - " [20250826] 过滤 169 只 ST 股票\n", - " [20250827] 过滤 169 只 ST 股票\n", - " [20250828] 过滤 169 只 ST 股票\n", - " [20250829] 过滤 169 只 ST 股票\n", - " [20250901] 过滤 169 只 ST 股票\n", - " [20250902] 过滤 169 只 ST 股票\n", - " [20250903] 过滤 169 只 ST 股票\n", - " [20250904] 过滤 169 只 ST 股票\n", - " [20250905] 过滤 168 只 ST 股票\n", - " [20250908] 过滤 169 只 ST 股票\n", - " [20250909] 过滤 168 只 ST 股票\n", - " [20250910] 过滤 168 只 ST 股票\n", - " [20250911] 过滤 168 只 ST 股票\n", - " [20250912] 过滤 169 只 ST 股票\n", - " [20250915] 过滤 169 只 ST 股票\n", - " [20250916] 过滤 169 只 ST 股票\n", - " [20250917] 过滤 169 只 ST 股票\n", - " [20250918] 过滤 168 只 ST 股票\n", - " [20250919] 过滤 169 只 ST 股票\n", - " [20250922] 过滤 169 只 ST 股票\n", - " [20250923] 过滤 173 只 ST 股票\n", - " [20250924] 过滤 172 只 ST 股票\n", - " [20250925] 过滤 173 只 ST 股票\n", - " [20250926] 过滤 173 只 ST 股票\n", - " [20250929] 过滤 172 只 ST 股票\n", - " [20250930] 过滤 173 只 ST 股票\n", - " [20251009] 过滤 174 只 ST 股票\n", - " [20251010] 过滤 175 只 ST 股票\n", - " [20251013] 过滤 174 只 ST 股票\n", - " [20251014] 过滤 174 只 ST 股票\n", - " [20251015] 过滤 174 只 ST 股票\n", - " [20251016] 过滤 175 只 ST 股票\n", - " [20251017] 过滤 175 只 ST 股票\n", - " [20251020] 过滤 175 只 ST 股票\n", - " [20251021] 过滤 175 只 ST 股票\n", - " [20251022] 过滤 174 只 ST 股票\n", - " [20251023] 过滤 175 只 ST 股票\n", - " [20251024] 过滤 175 只 ST 股票\n", - " [20251027] 过滤 176 只 ST 股票\n", - " [20251028] 过滤 175 只 ST 股票\n", - " [20251029] 过滤 174 只 ST 股票\n", - " [20251030] 过滤 174 只 ST 股票\n", - " [20251031] 过滤 176 只 ST 股票\n", - " [20251103] 过滤 176 只 ST 股票\n", - " [20251104] 过滤 176 只 ST 股票\n", - " [20251105] 过滤 177 只 ST 股票\n", - " [20251106] 过滤 177 只 ST 股票\n", - " [20251107] 过滤 176 只 ST 股票\n", - " [20251110] 过滤 176 只 ST 股票\n", - " [20251111] 过滤 174 只 ST 股票\n", - " [20251112] 过滤 175 只 ST 股票\n", - " [20251113] 过滤 174 只 ST 股票\n", - " [20251114] 过滤 173 只 ST 股票\n", - " [20251117] 过滤 173 只 ST 股票\n", - " [20251118] 过滤 174 只 ST 股票\n", - " [20251119] 过滤 173 只 ST 股票\n", - " [20251120] 过滤 174 只 ST 股票\n", - " [20251121] 过滤 174 只 ST 股票\n", - " [20251124] 过滤 174 只 ST 股票\n", - " [20251125] 过滤 174 只 ST 股票\n", - " [20251126] 过滤 172 只 ST 股票\n", - " [20251127] 过滤 171 只 ST 股票\n", - " [20251128] 过滤 172 只 ST 股票\n", - " [20251201] 过滤 170 只 ST 股票\n", - " [20251202] 过滤 172 只 ST 股票\n", - " [20251203] 过滤 173 只 ST 股票\n", - " [20251204] 过滤 173 只 ST 股票\n", - " [20251205] 过滤 172 只 ST 股票\n", - " [20251208] 过滤 173 只 ST 股票\n", - " [20251209] 过滤 172 只 ST 股票\n", - " [20251210] 过滤 171 只 ST 股票\n", - " [20251211] 过滤 173 只 ST 股票\n", - " [20251212] 过滤 174 只 ST 股票\n", - " [20251215] 过滤 174 只 ST 股票\n", - " [20251216] 过滤 175 只 ST 股票\n", - " [20251217] 过滤 175 只 ST 股票\n", - " [20251218] 过滤 175 只 ST 股票\n", - " [20251219] 过滤 174 只 ST 股票\n", - " [20251222] 过滤 174 只 ST 股票\n", - " [20251223] 过滤 175 只 ST 股票\n", - " [20251224] 过滤 175 只 ST 股票\n", - " [20251225] 过滤 176 只 ST 股票\n", - " [20251226] 过滤 173 只 ST 股票\n", - " [20251229] 过滤 174 只 ST 股票\n", - " [20251230] 过滤 176 只 ST 股票\n", - " [20251231] 过滤 175 只 ST 股票\n", - " ST 过滤后数据规模: (6823808, 71)\n", - "\n", - "执行每日独立筛选股票池...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\liaozhaorun\\AppData\\Local\\Temp\\ipykernel_29336\\174861970.py:63: DeprecationWarning: `is_in` with a collection of the same datatype is ambiguous and deprecated.\n", - "Please use `implode` to return to previous behavior.\n", - "\n", - "See https://github.com/pola-rs/polars/issues/22149 for more information.\n", - " return df[\"ts_code\"].is_in(small_cap_codes)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 筛选前数据规模: (6823808, 71)\n", - " 筛选后数据规模: (1455000, 71)\n", - " 筛选前股票数: 5678\n", - " 筛选后股票数: 1934\n", - " 删除记录数: 5368808\n" - ] - } - ], - "execution_count": 6 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2 数据划分" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.2 数据划分" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:49.140684Z", - "start_time": "2026-03-11T13:28:49.078377Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"数据划分\")\n", @@ -2296,12 +563,12 @@ " print(f\"\\n训练集数据规模: {train_data.shape}\")\n", " print(f\"验证集数据规模: {val_data.shape}\")\n", " print(f\"测试集数据规模: {test_data.shape}\")\n", - " \n", + "\n", " # 计算各集的 group 数组\n", " train_group = compute_group_array(train_data)\n", " val_group = compute_group_array(val_data)\n", " test_group = compute_group_array(test_data)\n", - " \n", + "\n", " print(f\"\\n训练集 group 数量: {len(train_group)}\")\n", " print(f\"验证集 group 数量: {len(val_group)}\")\n", " print(f\"测试集 group 数量: {len(test_group)}\")\n", @@ -2310,56 +577,18 @@ " print(f\"测试集日均样本数: {np.mean(test_group):.1f}\")\n", "else:\n", " raise ValueError(\"必须配置数据划分器\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "数据划分\n", - "================================================================================\n", - "\n", - "训练集数据规模: (970000, 71)\n", - "验证集数据规模: (242000, 71)\n", - "测试集数据规模: (243000, 71)\n", - "\n", - "训练集 group 数量: 970\n", - "验证集 group 数量: 242\n", - "测试集 group 数量: 243\n", - "训练集日均样本数: 1000.0\n", - "验证集日均样本数: 1000.0\n", - "测试集日均样本数: 1000.0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\liaozhaorun\\AppData\\Local\\Temp\\ipykernel_29336\\551043002.py:132: DeprecationWarning: `pl.count()` is deprecated. Please use `pl.len()` instead.\n", - "(Deprecated in version 0.20.5)\n", - " pl.count().alias(\"count\")\n" - ] - } - ], - "execution_count": 7 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3 数据预处理" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.3 数据预处理" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:49.680671Z", - "start_time": "2026-03-11T13:28:49.150412Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"数据预处理\")\n", @@ -2372,11 +601,11 @@ " print(f\" [{i}/{len(processors)}] {processor.__class__.__name__}\")\n", " train_data = processor.fit_transform(train_data)\n", " fitted_processors.append(processor)\n", - " \n", + "\n", " print(\"\\n验证集处理...\")\n", " for processor in fitted_processors:\n", " val_data = processor.transform(val_data)\n", - " \n", + "\n", " print(\"\\n测试集处理...\")\n", " for processor in fitted_processors:\n", " test_data = processor.transform(test_data)\n", @@ -2384,49 +613,18 @@ "print(f\"\\n处理后训练集形状: {train_data.shape}\")\n", "print(f\"处理后验证集形状: {val_data.shape}\")\n", "print(f\"处理后测试集形状: {test_data.shape}\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "数据预处理\n", - "================================================================================\n", - "\n", - "训练集处理...\n", - " [1/3] NullFiller\n", - " [2/3] Winsorizer\n", - " [3/3] StandardScaler\n", - "\n", - "验证集处理...\n", - "\n", - "测试集处理...\n", - "\n", - "处理后训练集形状: (970000, 71)\n", - "处理后验证集形状: (242000, 71)\n", - "处理后测试集形状: (243000, 71)\n" - ] - } - ], - "execution_count": 8 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4 训练 LambdaRank 模型" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.4 训练 LambdaRank 模型" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:52.285645Z", - "start_time": "2026-03-11T13:28:49.685562Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"训练 LambdaRank 模型\")\n", @@ -2455,65 +653,18 @@ " eval_set=(X_val, y_val, val_group),\n", ")\n", "print(\"训练完成!\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "训练 LambdaRank 模型\n", - "================================================================================\n", - "\n", - "训练样本数: 970000\n", - "验证样本数: 242000\n", - "特征数: 49\n", - "目标变量: future_return_5_rank_rank\n", - "\n", - "目标变量统计(训练集):\n", - "shape: (9, 2)\n", - "┌────────────┬──────────┐\n", - "│ statistic ┆ value │\n", - "│ --- ┆ --- │\n", - "│ str ┆ f64 │\n", - "╞════════════╪══════════╡\n", - "│ count ┆ 969665.0 │\n", - "│ null_count ┆ 335.0 │\n", - "│ mean ┆ 9.810091 │\n", - "│ std ┆ 5.346526 │\n", - "│ min ┆ 0.0 │\n", - "│ 25% ┆ 6.0 │\n", - "│ 50% ┆ 10.0 │\n", - "│ 75% ┆ 14.0 │\n", - "│ max ┆ 19.0 │\n", - "└────────────┴──────────┘\n", - "\n", - "开始训练...\n", - "Training until validation scores don't improve for 50 rounds\n", - "Early stopping, best iteration is:\n", - "[50]\ttraining's ndcg@1: 0.676684\ttraining's ndcg@5: 0.440728\ttraining's ndcg@10: 0.361258\ttraining's ndcg@20: 0.296362\tvalid_1's ndcg@1: 0.272472\tvalid_1's ndcg@5: 0.215751\tvalid_1's ndcg@10: 0.198035\tvalid_1's ndcg@20: 0.191275\n", - "训练完成!\n" - ] - } - ], - "execution_count": 9 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.5 训练指标曲线" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.5 训练指标曲线" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:54.767311Z", - "start_time": "2026-03-11T13:28:52.291103Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"训练指标曲线\")\n", @@ -2532,7 +683,9 @@ "\n", "# 创建数据集\n", "train_dataset = lgb.Dataset(X_train_np, label=y_train_np, group=train_group)\n", - "val_dataset = lgb.Dataset(X_val_np, label=y_val_np, group=val_group, reference=train_dataset)\n", + "val_dataset = lgb.Dataset(\n", + " X_val_np, label=y_val_np, group=val_group, reference=train_dataset\n", + ")\n", "\n", "# 用于存储评估结果\n", "evals_result = {}\n", @@ -2574,46 +727,13 @@ " train_ndcg = evals_result[\"train\"][metric][-1]\n", " val_ndcg = evals_result[\"val\"][metric][-1]\n", " print(f\" {metric}: 训练集={train_ndcg:.4f}, 验证集={val_ndcg:.4f}\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "训练指标曲线\n", - "================================================================================\n", - "\n", - "重新训练模型以收集训练指标...\n", - "Training until validation scores don't improve for 50 rounds\n", - "训练完成,指标已收集\n", - "\n", - "评估的 NDCG 指标: ['ndcg@1', 'ndcg@5', 'ndcg@10', 'ndcg@20']\n", - "\n", - "[早停信息]\n", - " 配置的最大轮数: 1000\n", - " 实际训练轮数: 100\n", - " 早停状态: 已触发(连续50轮验证指标未改善)\n", - "\n", - "最终 NDCG 指标:\n", - " ndcg@1: 训练集=0.7563, 验证集=0.2625\n", - " ndcg@5: 训练集=0.5383, 验证集=0.2203\n", - " ndcg@10: 训练集=0.4355, 验证集=0.2053\n", - " ndcg@20: 训练集=0.3464, 验证集=0.1960\n" - ] - } - ], - "execution_count": 10 + ] }, { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:55.115683Z", - "start_time": "2026-03-11T13:28:54.771304Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "# 绘制 NDCG 训练指标曲线\n", "import matplotlib.pyplot as plt\n", @@ -2626,15 +746,19 @@ " train_metric = evals_result[\"train\"][metric]\n", " val_metric = evals_result[\"val\"][metric]\n", " iterations = range(1, len(train_metric) + 1)\n", - " \n", - " ax.plot(iterations, train_metric, label=f\"Train {metric}\", linewidth=2, color=\"blue\")\n", + "\n", + " ax.plot(\n", + " iterations, train_metric, label=f\"Train {metric}\", linewidth=2, color=\"blue\"\n", + " )\n", " ax.plot(iterations, val_metric, label=f\"Val {metric}\", linewidth=2, color=\"red\")\n", " ax.set_xlabel(\"Iteration\", fontsize=10)\n", " ax.set_ylabel(metric.upper(), fontsize=10)\n", - " ax.set_title(f\"Training and Validation {metric.upper()}\", fontsize=12, fontweight=\"bold\")\n", + " ax.set_title(\n", + " f\"Training and Validation {metric.upper()}\", fontsize=12, fontweight=\"bold\"\n", + " )\n", " ax.legend(fontsize=9)\n", " ax.grid(True, alpha=0.3)\n", - " \n", + "\n", " # 标记最佳验证指标点\n", " best_iter = val_metric.index(max(val_metric))\n", " best_metric = max(val_metric)\n", @@ -2659,54 +783,18 @@ " best_val = max(val_metric_list)\n", " print(f\" {metric}: {best_val:.4f} (迭代 {best_iter + 1})\")\n", "print(f\"\\n[重要提醒] 验证集仅用于早停/调参,测试集完全独立于训练过程!\")" - ], - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAABWsAAAPeCAYAAAB6B0gVAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Qd4FGXXxvE7hRBAem/SpSiIVFGsgCgWivIiKiAivmKXV1EsKFj4bIgFRFEUsSEKWFAQQVRsKIgFBAVRmnTpJoFkv+vMuNmUTUhgs/X/u64hs7Ozs7PzLMkzZ86cJ87j8XgEAAAAAAAAAAip+NC+PQAAAAAAAADAEKwFAAAAAAAAgDBAsBYAAAAAAAAAwgDBWgAAAAAAAAAIAwRrAQAAAAAAACAMEKwFAAAAAAAAgDBAsBYAAAAAAAAAwgDBWgAAAAAAAAAIAwRrAQAAAAAAACAMEKwFItzpp5+uuLg4Z/rjjz8OaxsvvfRS5jbuvfdexZoFCxZkfv7LL7887NrTfnqX2fPh8Hnse+J9D/v+AACA6EV/88jR3yw8+psAYhXBWiBA6tatmxm8OtRknTVEnn379qlUqVKZ7fj777/7Xa9Dhw6Z67z66quKRDt37nQ6yDaFezA26wmktc+2bdvy/L+5YsUKv8vj4+NVvHhxVa1aVe3bt9ewYcMOefHj448/Vp8+fXT00UcrOTlZVapUUbt27TRy5EitXbs21/pr1qzR//73Px1//PEqW7asSpQooXr16jn7P3r0aK1atSrP97J9ueWWW9SsWTPnM1aqVMl5r4cfflg7duzw+xpbPnz4cJ122mkqWbJk2FyQAAAcPvqb0Y/+Zniiv7njkBch/E2xmAgEBIQHQEDUqVPHY/+lCjJ98sknATvqP/74o+fzzz93ppSUlMPaxubNmzO38eeff3pijbWHt20GDBiQ77oXX3xx5rqjR4/O9fzatWs9cXFxzvMlSpTw7Nmzp1D7ctppp2Vuf82aNc4ya1dv+1h7B/Lz5MXe27sN26ec7Hvi3Sf7/oRS1mNm0/Dhw/P8v/nLL7/4Xe5vKlasmOfZZ5/N9X5paWmefv365fvaG2+8MdtrJk6c6ElKSsr3NRdeeKHfzzdmzBhPcnJynq+rVq2aZ86cOble9/333/td/3C/EwCA0KO/Gbnob+ZGfzPy+5tZv9f+pnvuuecI/tcAsSsxMCFfAG+99ZZSUlIyD0Tv3r21adMmZ/7JJ5/UCSeckPlc8+bN872SXhh5baswLCPQJhzaxRdfrDfeeMOZf/PNN3X77bdne37atGl2EcyZP/fcc3XUUUcd8WG1jM+OHTuGVfNYNqlN4WjcuHFOZmy5cuUK/Br7P2r/l/7880+9+OKL+vTTT3XgwAH997//VeXKldWzZ8/MdW+++WZNmTLFmbeM3MGDB+u8885zsmt/+umnXJnIM2bM0FVXXZX5vbDMa3uNZUft2bNH3333naZOnep3vyxL15uR0LZtW/Xr109NmzZVWlqali9frtdee03ff/+9LrjgAs2dO1ennHJK5muTkpJ06qmn6qSTTtKWLVs0adKkQh5JAEC4ob8ZG+hvuuhvhn9/M6uc57zeNgRwGEIdLQZiIfMhayZtzivIn376qefEE090rmR6M96ef/55z1lnneWpXbu2p2TJkp7ixYt7GjZs6Lnuuus8W7duPWQmZs73WLRokef00093Mj2rVq3qufPOOz3p6emZ23jxxRf9Xv3Muu0ffvjBef/KlSs7+3r22Wd7/vjjj2z7YtscOXKkp2bNms572Xtadp+/fczL+vXrPQMHDvS0aNHCU7FiRU9iYqKnfPnynjPOOMMzY8aMfDMUZs+e7WnTpo1zvOzYPfHEE7m2790f+wy2n/fee69n7ty5Bc46TE1N9ZQrVy5z/d9++y3b89aW3ufefvvtImnPw/089l276KKLnPcuW7ascyW/evXqnt69ezvt62WvyevquPf97XviXWbfn6wWL17svI991+w97Kddxf/uu++yrZfzezdlyhTPscce62QENGrUyDN16tR828LfMfNO9j0sTGZt1v+jGRkZzv57n6tbt67nwIEDznP2+vj4+MznnnrqqVz7Y69fsWKFM2+vs9d717djnfX/XtbX5Mya/uyzz5z3srZ6//33/X52e9348eM9CQkJTvvv3bvX73rPPPMMmbUAEIXob9LfpL9JfzOU/c2s52OBvHsUiHUEa4EQdp5r1KiR7XYTb2Cta9eueQbLmjZt6vnnn38KHNyzYJwFTnNux26TKUywtn79+rm2cfLJJ2f7zDfccEOudewPf9bOw6GCtV999VW+t9JMnjzZb+fAjnfWIJp3ssCllwVWbX9yrmOB4YIGa80VV1yRuf4DDzyQrTSAtwRCmTJl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JbM2KUkqUSLUewMAAIBot3+/W7PWHHusVLJkqPcIAAAgtoV9sNZcd911zuTPggULsj2+//77nSkSeTNrLav233KVAAAAQJFZulRKT3fnGVwMAAAg9CIiWBsrvJm11KsFYltCXIK6NeyWOQ8AQFGhXi0AANGN88vIQ7A2TFhGw+7d7jz1aoHYViyhmIa0HRLq3QAAxACCtQAARDfOLyOPr9grwiKr1pBZCyDY6tatq8aNGzt1wZs2bapLLrnEqQF+uF566SWtWLGiwOu///77To3xRo0aqVevXtrtvXqVw5NPPqnjjjtOzZs3V4sWLZya5F4PPPCAs//eqUyZMs4glWb+/PnOIJXNmjXTscceq2HDhikjI8N57o8//lBCQkK2165evfqwPzsAROLgYjZmQvPmod4bAAAAEKwNEwRrAXht2rNJL37/op765im98fMb2rx3c1AOztSpU7V06VItW7ZMu3btcgKuwQjW7t27V4MGDdLMmTP122+/qUaNGrrvvvv8rmuB1i+++EI//fSTZs2apZtuuikzsHrnnXc6+2/TN998o2LFiunSSy91nitfvrzeeOMNLV++XIsXL9aXX36pl19+OXO7pUuXznytTQ0aNDjszw4gPI0bN865MJWcnKz27dtr0aJFea47ceJEnXLKKc7vDps6d+6ca/3LL79ccXFx2aazzz5bkWTXLmnlSnf++OPdgC0AAIguHo9Hu1J2OZPNI/wRrA2zwcUMZRCA2PTT5p/U962+qvV4LV3x7hW6YfYN6vu2+9iW2/PBkJaWpv379zsBCq9HH33UyUxt1aqVE4z4888/neXvvfeek+Fq2aiW8frOO+/o+eef13fffaebb77ZWf7BBx/k+34ffvihTjjhBCez1lxzzTV6/fXX/a7bqVMnlS1b1pmvXbu2qlWrpnXr1uVazwK/9nzr1q2dx7b9+vXrO/MWqLH9soxaALHBLkZZpv0999yjJUuW6Pjjj1fXrl21ZcuWPAew7du3rz755BN99dVXzu+Ts846Sxs2bMi2nv0+/OuvvzKnvH53havFi33zDC4GAEB0Sk1P1WUzLnMmm0f4I1gbJsisBWLbnFVz1O75dnpr+VtK9/w7LPe/DmYc1Fu/vOU8b+sVlT59+jhBTAuAxsfH6z//+Y+z/LXXXtPKlSudgIUFOSxb1QKq5q677tKzzz7rZKP+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CxcujCVLlqBbt25mQghm8AZSjhw5fH5mxi6zbUVERETE3dTfFBHJuhSsFRE5DyxNEB8f73NfvXr1MHXqVJO5Gh2d9q/ZlStXmmDpG2+8YWrX0meffXbO10uqatWq2L59u1mc7Nr169ebWrrMsBURERGR8KH+pohI9qIyCCIi54EB2WXLlpms2P3795tga8+ePc3kXu3btzc1Yln6YO7cuejatWuqgdZKlSrhzJkzGDFihJkQbOLEiZ6Jx7xfj5kUrC3L1/NXHqFp06aoWbMmOnTogFWrVmH58uXo1KkTGjdujAYNGqi9RURERMKI+psiItmLgrUiIuehb9++iIqKMhmrxYoVw7Zt21C6dGn88MMPJjDbrFkzEzjlxGGsGetkzPpTu3ZtDB061JRPqFGjBj766CMMGTLEZ50rrrjCTDjWtm1b83pJJyhzyhnMmDEDhQoVwjXXXGOCtxUrVsTkyZPV1iIiIiJhRv1NEZHsJcKyLCvUOyEiIiIiIiIiIiKS3SmzVkRERERERERERMQFFKwVERERERERERERcQEFa0VERERERERERERcQMFaERERERERERERERdQsFZERERERERERETEBRSsFREREREREREREXEBBWtFREREREREREREXEDBWhEREREREREREREXULBWRERERERERERExAUUrBURERERERERERFxAQVrRURERERERERERFxAwVoRERERERERERERF1CwVkRERERERERERMQFFKwVERERERERERERcQEFa0VERERERERERERcQMFaERERERERERERERdQsFZERERERERERETEBRSsFQkT1157LSIiIsyydevWDG3jgw8+8Gzj2WefRXazaNEiz/vv0qWL69qT/zv38XE3vB9+TpzX4OdHREREsi71N8+f+pvpp/6miIgvBWtF0ql8+fKe4NW5FnbWJPwcP34cefLk8bTjX3/95Xe9yy+/3LPORx99hHB06NAh00Hm4vZgrPcJJNtn//79Kf5u/v77737vj4yMRM6cOVGiRAk0atQI/fr1O+fFj3nz5qFt27a48MILERsbi+LFi6Nhw4YYPHgwtm3blmz9LVu2oE+fPqhduzYKFCiAXLlyoUKFCmb/hwwZgj///DPF1+K+9O3bF9WqVTPvsWjRoua1Xn31VRw8eNDvc3h///790bhxY+TOnTtNAfyV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JRJtB2UrVwYqVbIX3uZ9JUro4IqISOaaPHkyevfujTFjxphA7bBhw9C8eXNs3LgRxf0UP1+0aBHat2+PK664wgR3X3nlFTRr1gzr1q1DGUaeAOzatcvnOV9//TW6deuG1q1b+9z/3HPPoXv37p6f82mGJMni1q61yxx8+imQkJD88QsuAJo1Ax5+GKhTJxR7KCIiEv4UrBURv1hrdtIk4JlngB07fB/jue9NNwG33ALccANQoIAOokigxMXHYejSoeZ278t7IyYqRgdXJBVDhw41AdOuXbuanxm0nT17NsaNG4cnn3wy2fofffSRz8/vvfcepk6divnz56NTp07mvpIlS/qsM2PGDFx33XWoWLGiz/0MziZdVySrlTk4dMgudfD66/xd8H08d267vBUDtFyqVLHnJRARcTv1ucXNFKwVEYOTQOzbx2wie2gbJ4b45ZfEgxMZCdx7L8AEogYN/t/efYBHUbVtHH9SCAHp0gRpCoIiAtLEhgqCXUQRFRtix/6qiAVsiKAioii+KlYUxF7xQxQriMCLSrWL0kF6SUiy33WfYZJNSCCBTXZ28/95jZnsbnYne0Jy9t5nnmPucwCRlxXKsm/+/sbt33DYDTzFwE6kp6fbzJkzbcCAAWF/rxJda4OpWumyEDZv3mzbtm2zagU0Ul++fLkLf1988cUdrlPbg/vuu8/q169v5513nt14442WrFNO8pGWluY23/r1693HrKwst0WC7icUCkXs/lC8gjZemv+9/rrZ118n2IoV+tn35obbtu2YvlavHrIbbgi5Vgjhb9or3NUWb4I2VigYYxVbojleGZkZ9vWir93+de2vs+QE4rGgjFUWv2sJa4HSXDk7Zowqisz++subjBf0O1EVtGqD0Lx5SR8lAAAFW7VqlWVmZlqtPH139PmCBQsK9dT179/f6tSp4wLe/CikVQVtjx49cl1+3XXX2aGHHupC3m+//dYFxmqfoErf/AwZMsTuueeeHS5fuXKlbQ1fkWkPX9ysW7fOvZhSaI1gC8J4LV6caO+/n2rvvFPOfvihzC5vX7t2pl111SY7//wtVr58yPT+g4LdeBeEsULhMFaxJZrjtTVjq6Wnpbv9FStWuAXHEIyx2pBf/8VShrcOgFJIK/Vef33uytn8tGljprVUjj22pI4MAICSo8rYcePGuT626l+bH7VT6N279w7X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oIXBwnvNZmWFbMWKrVazZiV60AIAgMiEtevWrbNl25cnrV27tlWuTCUQ4sPmzWYLFiS7UPb3381++cXbZs70FoXISxNvLSymKgoWfACwJ7ZlbrNnZz3r9i899FIrk1SGJxRxLW17qlWWvkGIYTNmmF10kfemvq96de/sq0svNUumRAYAAoU5N4Jst6YNzz77rA0fPtwWLlyY6/KmTZvaf/7zH+vbt2+kjg8oNtu2mb34otmXX5qtWpV727BBZQ/Vd3kfel152GHeRPyooxgsAHsuM5RpH/36kdvv07qPlTHCWsSfSZMm2aOPPmpTp0619dvfBa1UqZJ17NjRbrrpJuvCypyIEenp3jxwyBDvDCy/3cH115vdcYe3QBgAIHiYcyOuwtqHHnrI7r77brvuuuusW7duVqtWLXf58uXL7f/+7//s+uuvtzVr1tjNN99cHMcL7DH1ln3nHbPbbjP7+eeifW3t2mZHHGF2+OHe1ro1C4gBAFAUL774ol166aV21llnucA271zypJNOsueee84uuOACnlgE2uzZXjXtjz/mXHbooV4xwMEHR/PIAABAqQprn3jiCXv++eft7LPPznX5gQceaMccc4y1bNnSbrnlFsJaBNK0aWa33GL29dc7XpeQYLb33t4pa9Wrh6x27a128MFlrUmTRGvc2NxWrVo0jhoAgPgxePBgGzFihPXr12+H6y6++GI78sgj7d577yWsReD8/bfZ1Kk5m1of+NW0anNw111mAwZ4lbUAAAAlFtauWLHCWrRoUeD1um6VziMHAlRJ+913ZsOHm02YkPs6tS7QqWta+KFqVbOkpPAFH9ZZzZo16UELAEAELVq0aKdtDjp37uzaagFBsHGjty7BK6+YLV6c/2300kjVtDrjCgAAYE+FrUdaOO3atbMHH3zQMjIydrguMzPThg4d6m4DRNuGDWajR3sT544dcwe1TZt6rRC++MKsUyevmtYPagEAQPFp3ry5a3NQkDFjxthBBx3EECDqPvjAe0N/6ND8g1rNJ++916uwJagFAABRbYOgXrW1a9e2o48+OlefsS+//NJSUlJcvzEgmlW0zz9vNnas2aZNua+vWdPs7ru9VXk5RQ0AgJL3yCOP2CmnnGITJ050Fbbhc8nJkyfb77//bh9++CFDg6hRMKsFwt58M/eisjojSwvLqghAH2mPBQAAAhHW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fPjhh9amTRsrW7as3XDDDbmuW758uftazZH0PWje5Bs8eLD73vxNZyDpTXXfc8895x57//33d/O3bdu27db3He8o2YmhxcUIawEAAHKkp6fbzJkzbcCAAdmXJSYmurYFqpotjM2bN7sXCtWqVXOf//HHH7Zs2TJ3H77KlSu7UFb3ec4557iPan3Qtm3b7Nvo9npsVeKeccYZOzxOWlqa23z+iyMFxdoiQfejsLmw97dgQYKZaTNr0kTHEZHDQDGNF6KHsYodjFVsieZ4Ld+43Kb8NcU2pG+wiikV7ZgGx1itCiVzKvNrr73mgkx936eddpo9//zz7o3k3Q1rFYgecMABu7yt2jWpbZPOLlJge+2119q9997rzijKS2Gq3pR+44033NeFj9WNN97oQlpdp6BZ7aU6duxo7dq1c3Myf16mec++++7rzmjS12mOddddd9mMGTOsVq1a1r17d3v66ad3+N6z+LtIWBtL/WpbtYrmkQAASoImQSs3r3T7NcrXsIQEL0gBsKNVq1ZZZmamm/CH0+eFrTLp37+/1alTJzucVVDr30fe+/Sv08eaNWvmuj45OdkFvv5t8hoyZIjdc889O1y+cuXKXO0V9oRe3Kxbt879HlFwvCvz5lV3tRsVKmRZUtIKK6BzBIpJUccL0cNYxQ7GKrZEY7zmr55vj/3vMfvg9w8sM5SZfXlSQpKdst8pdn3r6+3AvQ8stsfXvEV979WuSX//9f3re/fbNz311FP23nvvWUZGhlWvXt0FqWrZ9H//93/24IMPutvquttuu81Wr15t33//vat8Va99haSdO3cu8LHff/99dxaS5it6vLPPPtsFqTfffPMOt9Wb0toUuOqNbd3eHyu1ndLX+cesN6+1JkCDBg1y3ce7777r+v/r+HXbF198MfvNbc1/9Ab4Y489ZmeddVaur9uwYYOVdlTWBhyLiwFA6ZKWmWZ93+vr9if0nGCpyanRPiQgbulFj1oXqI+tFicrTnoBFX4aoCpr9eKlRo0ariImUi969QaP7nNXL3qVD//9t/dmULNmCVarVu7wGcWvKOOF6GKsYgdjFVtKerw++e0T6/F2D8vIysgV1Io+//CPD+2TPz+xt3q9Zd3271Ysx5CUlGT9+vVzC5j++eefrtXApZde6t70ffXVV10PfS18qtu9/PLLrie/Whc88sgjLhBVBaue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" - }, - "metadata": {}, - "output_type": "display_data", - "jetTransient": { - "display_id": null - } - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[指标分析]\n", - " 各NDCG指标在验证集上的最佳值:\n", - " ndcg@1: 0.2725 (迭代 50)\n", - " ndcg@5: 0.2203 (迭代 97)\n", - " ndcg@10: 0.2108 (迭代 74)\n", - " ndcg@20: 0.1970 (迭代 86)\n", - "\n", - "[重要提醒] 验证集仅用于早停/调参,测试集完全独立于训练过程!\n" - ] - } - ], - "execution_count": 11 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.6 模型评估" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.6 模型评估" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:55.390466Z", - "start_time": "2026-03-11T13:28:55.124417Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"模型评估\")\n", @@ -2745,63 +833,13 @@ " top_features = importance.sort_values(ascending=False).head(20)\n", " for i, (feature, score) in enumerate(top_features.items(), 1):\n", " print(f\" {i:2d}. {feature:30s} {score:10.2f}\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "模型评估\n", - "================================================================================\n", - "\n", - "生成预测...\n", - "\n", - "计算 NDCG 指标...\n", - "\n", - "NDCG 评估结果:\n", - "----------------------------------------\n", - " ndcg@1: 0.3919\n", - " ndcg@5: 0.3768\n", - " ndcg@10: 0.3831\n", - " ndcg@20: 0.3935\n", - "\n", - "特征重要性(Top 20):\n", - "----------------------------------------\n", - " 1. max_ret_20 4720.20\n", - " 2. turnover_rank 4345.39\n", - " 3. overnight_intraday_diff 3623.13\n", - " 4. volatility_5 2632.23\n", - " 5. turnover_rate_mean_5 2518.52\n", - " 6. std_return_20 1819.15\n", - " 7. close_vwap_deviation 1525.61\n", - " 8. return_20 1014.14\n", - " 9. return_5_rank 694.17\n", - " 10. EP 412.96\n", - " 11. ma_5 403.47\n", - " 12. BP 369.00\n", - " 13. ma_20 345.33\n", - " 14. upper_shadow_ratio 342.03\n", - " 15. bbi_ratio 339.14\n", - " 16. roa 289.77\n", - " 17. roe 269.37\n", - " 18. drawdown_from_high_60 248.74\n", - " 19. min_ret_20 247.30\n", - " 20. high_low_ratio 215.36\n" - ] - } - ], - "execution_count": 12 + ] }, { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:55.620414Z", - "start_time": "2026-03-11T13:28:55.402837Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "# 确保输出目录存在\n", "os.makedirs(OUTPUT_DIR, exist_ok=True)\n", @@ -2841,84 +879,51 @@ ")\n", "topn_to_save.write_csv(topn_output_path, include_header=True)\n", "print(f\" 保存路径: {topn_output_path}\")\n", - "print(f\" 保存行数: {len(topn_to_save)}({len(unique_dates)}个交易日 x 每日top{TOP_N})\")\n", + "print(\n", + " f\" 保存行数: {len(topn_to_save)}({len(unique_dates)}个交易日 x 每日top{TOP_N})\"\n", + ")\n", "print(f\"\\n 预览(前15行):\")\n", "print(topn_to_save.head(15))\n", "\n", "print(\"\\n训练流程完成!\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[1/1] 保存每日 Top 5 股票...\n", - " 保存路径: output\\rank_output.csv\n", - " 保存行数: 1215(243个交易日 x 每日top5)\n", - "\n", - " 预览(前15行):\n", - "shape: (15, 3)\n", - "┌────────────┬──────────┬───────────┐\n", - "│ trade_date ┆ score ┆ ts_code │\n", - "│ --- ┆ --- ┆ --- │\n", - "│ str ┆ f64 ┆ str │\n", - "╞════════════╪══════════╪═══════════╡\n", - "│ 2025-01-02 ┆ 0.603437 ┆ 600530.SH │\n", - "│ 2025-01-02 ┆ 0.580176 ┆ 600322.SH │\n", - "│ 2025-01-02 ┆ 0.538287 ┆ 605080.SH │\n", - "│ 2025-01-02 ┆ 0.488088 ┆ 000679.SZ │\n", - "│ 2025-01-02 ┆ 0.480476 ┆ 603958.SH │\n", - "│ … ┆ … ┆ … │\n", - "│ 2025-01-06 ┆ 0.963227 ┆ 600807.SH │\n", - "│ 2025-01-06 ┆ 0.737975 ┆ 002816.SZ │\n", - "│ 2025-01-06 ┆ 0.644058 ┆ 603617.SH │\n", - "│ 2025-01-06 ┆ 0.637653 ┆ 000573.SZ │\n", - "│ 2025-01-06 ┆ 0.521599 ┆ 605580.SH │\n", - "└────────────┴──────────┴───────────┘\n", - "\n", - "训练流程完成!\n" - ] - } - ], - "execution_count": 13 + ] }, { - "cell_type": "markdown", "metadata": {}, + "cell_type": "markdown", "source": [ "## 5. 总结\n", - "\n", + "#\n", "本 Notebook 实现了完整的 Learn-to-Rank 训练流程:\n", - "\n", + "#\n", "### 核心步骤\n", - "\n", + "#\n", "1. **数据准备**: 计算 49 个特征因子,将 `future_return_5` 转换为 20 分位数标签\n", "2. **模型训练**: 使用 LightGBM LambdaRank 学习每日股票排序\n", "3. **模型评估**: 使用 NDCG@1/5/10/20 评估排序质量\n", "4. **策略分析**: 基于排序分数构建 Top-k 选股策略\n", - "\n", + "#\n", "### 关键参数\n", - "\n", + "#\n", "- **Objective**: lambdarank\n", "- **Metric**: ndcg\n", "- **Learning Rate**: 0.05\n", "- **Num Leaves**: 31\n", "- **N Quantiles**: 20\n", - "\n", + "#\n", "### 输出结果\n", - "\n", + "#\n", "- rank_output.csv: 每日Top-N推荐股票(格式:date, score, ts_code)\n", "- 特征重要性排名\n", "- Top-k 策略统计和图表\n", "- NDCG训练指标曲线\n", - "\n", + "#\n", "### 后续优化方向\n", - "\n", + "#\n", "1. **特征工程**: 尝试更多因子组合\n", "2. **超参数调优**: 使用网格搜索优化 LambdaRank 参数\n", "3. **模型集成**: 结合多个排序模型的预测\n", - "4. **更复杂的分组**: 考虑按行业分组排序" + "4. **更复杂的分组**: 考虑按行业分组排序\n" ] } ], diff --git a/src/experiment/learn_to_rank.py b/src/experiment/learn_to_rank.py new file mode 100644 index 0000000..5a22b14 --- /dev/null +++ b/src/experiment/learn_to_rank.py @@ -0,0 +1,792 @@ +# %% md +# # Learn-to-Rank 排序学习训练流程 +# +# 本 Notebook 实现基于 LightGBM LambdaRank 的排序学习训练,用于股票排序任务。 +# +# ## 核心特点 +# +# 1. **Label 转换**: 将 `future_return_5` 按每日进行 20 分位数划分(qcut) +# 2. **排序学习**: 使用 LambdaRank 目标函数,学习每日股票排序 +# 3. **NDCG 评估**: 使用 NDCG@1/5/10/20 评估排序质量 +# 4. **策略回测**: 基于排序分数构建 Top-k 选股策略 +# %% md +# ## 1. 导入依赖 +# %% +import os +from datetime import datetime +from typing import List, Tuple, Optional + +import numpy as np +import polars as pl +import pandas as pd +import matplotlib.pyplot as plt +from sklearn.metrics import ndcg_score + +from src.factors import FactorEngine +from src.training import ( + DateSplitter, + STFilter, + StockPoolManager, + Trainer, + Winsorizer, + NullFiller, + StandardScaler, +) +from src.training.components.models import LightGBMLambdaRankModel +from src.training.config import TrainingConfig + + +# %% md +# ## 2. 辅助函数 +# %% +def create_factors_with_metadata( + engine: FactorEngine, factor_definitions: dict, label_factor: dict +) -> List[str]: + """使用 metadata 注册因子(特征因子通过名称注册,label 因子通过表达式注册)""" + print("=" * 80) + print("使用 metadata 注册因子") + print("=" * 80) + + # 注册所有特征因子(通过 metadata 名称) + print("\n注册特征因子(从 metadata):") + for name in factor_definitions.keys(): + engine.add_factor_by_name(name) + print(f" - {name}") + + # 注册 label 因子(通过表达式,因为 label 不在 metadata 中) + print("\n注册 Label 因子(表达式):") + for name, expr in label_factor.items(): + engine.add_factor(name, expr) + print(f" - {name}: {expr}") + + # 从字典自动获取特征列 + feature_cols = list(factor_definitions.keys()) + + print(f"\n特征因子数: {len(feature_cols)}") + print(f"Label: {list(label_factor.keys())[0]}") + print(f"已注册因子总数: {len(engine.list_registered())}") + + return feature_cols + + +def prepare_data( + engine: FactorEngine, + feature_cols: List[str], + start_date: str, + end_date: str, +) -> pl.DataFrame: + """准备数据""" + print("\n" + "=" * 80) + print("准备数据") + print("=" * 80) + + # 计算因子(全市场数据) + print(f"\n计算因子: {start_date} - {end_date}") + factor_names = feature_cols + [LABEL_NAME] # 包含 label + + data = engine.compute( + factor_names=factor_names, + start_date=start_date, + end_date=end_date, + ) + + print(f"数据形状: {data.shape}") + print(f"数据列: {data.columns}") + print(f"\n前5行预览:") + print(data.head()) + + return data + + +def prepare_ranking_data( + df: pl.DataFrame, + label_col: str = "future_return_5", + date_col: str = "trade_date", + n_quantiles: int = 20, +) -> Tuple[pl.DataFrame, str]: + """准备排序学习数据 + + 将连续 label 转换为分位数标签,用于排序学习任务。 + + Args: + df: 原始数据 + label_col: 原始标签列名 + date_col: 日期列名 + n_quantiles: 分位数数量 + + Returns: + (处理后的 DataFrame, 新的标签列名) + """ + print("\n" + "=" * 80) + print(f"准备排序学习数据(将 {label_col} 转换为 {n_quantiles} 分位数标签)") + print("=" * 80) + + # 新的标签列名 + rank_col = f"{label_col}_rank" + + # 按日期分组进行分位数划分 + # 使用 rank 生成 0, 1, 2, ..., n_quantiles-1 的标签 + # 方法: 计算每天内的排名,然后映射到 n_quantiles 个分位数组 + df_ranked = ( + df.with_columns( + # 计算每天内的排名 (1-based) + pl.col(label_col).rank(method="min").over(date_col).alias("_rank") + ) + .with_columns( + # 将排名转换为分位数标签 (0 to n_quantiles-1) + ((pl.col("_rank") - 1) / pl.len().over(date_col) * n_quantiles) + .floor() + .cast(pl.Int64) + .clip(0, n_quantiles - 1) + .alias(rank_col) + ) + .drop("_rank") + ) + + # 检查转换结果 + print(f"\n原始 {label_col} 统计:") + print(df_ranked[label_col].describe()) + + print(f"\n转换后 {rank_col} 统计:") + print(df_ranked[rank_col].describe()) + + # 检查每日样本分布 + print(f"\n每日样本数统计:") + daily_counts = df_ranked.group_by(date_col).agg(pl.count().alias("count")) + print(daily_counts["count"].describe()) + + # 检查分位数分布(应该是均匀的) + print(f"\n分位数标签分布:") + rank_dist = df_ranked[rank_col].value_counts().sort(rank_col) + print(rank_dist) + + return df_ranked, rank_col + + +def compute_group_array(df: pl.DataFrame, date_col: str = "trade_date") -> np.ndarray: + """计算 group 数组用于 LambdaRank + + 每个日期作为一个 query,group 数组表示每个 query 的样本数。 + + Args: + df: 数据框 + date_col: 日期列名 + + Returns: + group 数组 + """ + group_counts = df.group_by(date_col, maintain_order=True).agg( + pl.count().alias("count") + ) + return group_counts["count"].to_numpy() + + +def evaluate_ndcg_at_k( + y_true: np.ndarray, + y_pred: np.ndarray, + group: np.ndarray, + k_list: List[int] = [1, 5, 10, 20], +) -> dict: + """计算 NDCG@k 指标 + + Args: + y_true: 真实标签 + y_pred: 预测分数 + group: 分组数组 + k_list: 要计算的 k 值列表 + + Returns: + NDCG 指标字典 + """ + results = {} + + # 按 group 拆分数据 + start_idx = 0 + y_true_groups = [] + y_pred_groups = [] + + for group_size in group: + end_idx = start_idx + group_size + y_true_groups.append(y_true[start_idx:end_idx]) + y_pred_groups.append(y_pred[start_idx:end_idx]) + start_idx = end_idx + + # 计算每个 k 值的平均 NDCG + for k in k_list: + ndcg_scores = [] + for yt, yp in zip(y_true_groups, y_pred_groups): + if len(yt) > 1: + try: + score = ndcg_score([yt], [yp], k=k) + ndcg_scores.append(score) + except ValueError: + # 标签都相同,无法计算 + pass + + results[f"ndcg@{k}"] = np.mean(ndcg_scores) if ndcg_scores else 0.0 + + return results + + +# %% md +# ## 3. 配置参数 +# +# ### 3.1 因子定义 +# %% +# 特征因子定义字典(复用 regression.ipynb 的因子定义) +LABEL_NAME = "future_return_5_rank" + +FACTOR_DEFINITIONS = { + # ================= 1. 价格、趋势与路径依赖 (Trend, Momentum & Path Dependency) ================= + "ma_5": "ts_mean(close, 5)", + "ma_20": "ts_mean(close, 20)", + "ma_ratio_5_20": "ts_mean(close, 5) / (ts_mean(close, 20) + 1e-8) - 1", + "bias_10": "close / (ts_mean(close, 10) + 1e-8) - 1", + "high_low_ratio": "(close - ts_min(low, 20)) / (ts_max(high, 20) - ts_min(low, 20) + 1e-8)", + "bbi_ratio": "(ts_mean(close, 3) + ts_mean(close, 6) + ts_mean(close, 12) + ts_mean(close, 24)) / (4 * close + 1e-8)", + "return_5": "(close / (ts_delay(close, 5) + 1e-8)) - 1", + "return_20": "(close / (ts_delay(close, 20) + 1e-8)) - 1", + "kaufman_ER_20": "abs(close - ts_delay(close, 20)) / (ts_sum(abs(close - ts_delay(close, 1)), 20) + 1e-8)", + "mom_acceleration_10_20": "(close / (ts_delay(close, 10) + 1e-8) - 1) - (ts_delay(close, 10) / (ts_delay(close, 20) + 1e-8) - 1)", + "drawdown_from_high_60": "close / (ts_max(high, 60) + 1e-8) - 1", + "up_days_ratio_20": "ts_sum(close > ts_delay(close, 1), 20) / 20", + # ================= 2. 波动率、风险调整与高阶矩 ================= + "volatility_5": "ts_std(close, 5)", + "volatility_20": "ts_std(close, 20)", + "volatility_ratio": "ts_std(close, 5) / (ts_std(close, 20) + 1e-8)", + "std_return_20": "ts_std((close / (ts_delay(close, 1) + 1e-8)) - 1, 20)", + "sharpe_ratio_20": "ts_mean(close / (ts_delay(close, 1) + 1e-8) - 1, 20) / (ts_std(close / (ts_delay(close, 1) + 1e-8) - 1, 20) + 1e-8)", + "min_ret_20": "ts_min(close / (ts_delay(close, 1) + 1e-8) - 1, 20)", + "volatility_squeeze_5_60": "ts_std(close, 5) / (ts_std(close, 60) + 1e-8)", + # ================= 3. 日内微观结构与异象 ================= + "overnight_intraday_diff": "(open / (ts_delay(close, 1) + 1e-8) - 1) - (close / (open + 1e-8) - 1)", + "upper_shadow_ratio": "(high - ((open + close + abs(open - close)) / 2)) / (high - low + 1e-8)", + "capital_retention_20": "ts_sum(abs(close - open), 20) / (ts_sum(high - low, 20) + 1e-8)", + "max_ret_20": "ts_max(close / (ts_delay(close, 1) + 1e-8) - 1, 20)", + # ================= 4. 量能、流动性与量价背离 ================= + "volume_ratio_5_20": "ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)", + "turnover_rate_mean_5": "ts_mean(turnover_rate, 5)", + "turnover_deviation": "(turnover_rate - ts_mean(turnover_rate, 10)) / (ts_std(turnover_rate, 10) + 1e-8)", + "amihud_illiq_20": "ts_mean(abs(close / (ts_delay(close, 1) + 1e-8) - 1) / (amount + 1e-8), 20)", + "turnover_cv_20": "ts_std(turnover_rate, 20) / (ts_mean(turnover_rate, 20) + 1e-8)", + "pv_corr_20": "ts_corr(close / (ts_delay(close, 1) + 1e-8) - 1, vol, 20)", + "close_vwap_deviation": "close / (amount / (vol * 100 + 1e-8) + 1e-8) - 1", + # ================= 5. 基本面财务特征 ================= + "roe": "n_income / (total_hldr_eqy_exc_min_int + 1e-8)", + "roa": "n_income / (total_assets + 1e-8)", + "profit_margin": "n_income / (revenue + 1e-8)", + "debt_to_equity": "total_liab / (total_hldr_eqy_exc_min_int + 1e-8)", + "current_ratio": "total_cur_assets / (total_cur_liab + 1e-8)", + "net_profit_yoy": "(n_income / (ts_delay(n_income, 252) + 1e-8)) - 1", + "revenue_yoy": "(revenue / (ts_delay(revenue, 252) + 1e-8)) - 1", + "healthy_expansion_velocity": "(total_assets / (ts_delay(total_assets, 252) + 1e-8) - 1) - (total_liab / (ts_delay(total_liab, 252) + 1e-8) - 1)", + # ================= 6. 基本面估值与截面动量共振 ================= + "EP": "n_income / (total_mv * 10000 + 1e-8)", + "BP": "total_hldr_eqy_exc_min_int / (total_mv * 10000 + 1e-8)", + "CP": "n_cashflow_act / (total_mv * 10000 + 1e-8)", + "market_cap_rank": "cs_rank(total_mv)", + "turnover_rank": "cs_rank(turnover_rate)", + "return_5_rank": "cs_rank((close / (ts_delay(close, 5) + 1e-8)) - 1)", + "EP_rank": "cs_rank(n_income / (total_mv + 1e-8))", + "pe_expansion_trend": "(total_mv / (n_income + 1e-8)) / (ts_delay(total_mv, 60) / (ts_delay(n_income, 60) + 1e-8) + 1e-8) - 1", + "value_price_divergence": "cs_rank((n_income - ts_delay(n_income, 252)) / (abs(ts_delay(n_income, 252)) + 1e-8)) - cs_rank(close / (ts_delay(close, 20) + 1e-8))", + "active_market_cap": "total_mv * ts_mean(turnover_rate, 20)", + "ebit_rank": "cs_rank(ebit)", +} + +# Label 因子定义(不参与训练,用于计算目标) +LABEL_FACTOR = { + LABEL_NAME: "(ts_delay(close, -5) / ts_delay(open, -1)) - 1", +} +# %% md +# ### 3.2 训练参数配置 +# %% +# 日期范围配置(正确的 train/val/test 三分法) +TRAIN_START = "20200101" +TRAIN_END = "20231231" +VAL_START = "20240101" +VAL_END = "20241231" +TEST_START = "20250101" +TEST_END = "20251231" + +# LambdaRank 模型参数配置 +MODEL_PARAMS = { + "objective": "lambdarank", + "metric": "ndcg", + "ndcg_at": [1, 5, 10, 20], # 评估 NDCG@k + "learning_rate": 0.05, + "num_leaves": 31, + "max_depth": 6, + "min_data_in_leaf": 20, + "n_estimators": 1000, + "early_stopping_rounds": 50, + "subsample": 0.8, + "colsample_bytree": 0.8, + "reg_alpha": 0.1, + "reg_lambda": 1.0, + "verbose": -1, + "random_state": 42, +} + +# 分位数配置 +N_QUANTILES = 20 # 将 label 分为 20 组 + +# 特征列(用于数据处理器) +FEATURE_COLS = list(FACTOR_DEFINITIONS.keys()) + +# 数据处理器配置 +PROCESSORS = [ + NullFiller(feature_cols=FEATURE_COLS, strategy="mean"), + Winsorizer(feature_cols=FEATURE_COLS, lower=0.01, upper=0.99), + StandardScaler(feature_cols=FEATURE_COLS), +] + + +# 股票池筛选函数 +def stock_pool_filter(df: pl.DataFrame) -> pl.Series: + """股票池筛选函数(单日数据) + + 筛选条件: + 1. 排除创业板(代码以 300 开头) + 2. 排除科创板(代码以 688 开头) + 3. 排除北交所(代码以 8、9 或 4 开头) + 4. 选取当日市值最小的500只股票 + """ + code_filter = ( + ~df["ts_code"].str.starts_with("30") + & ~df["ts_code"].str.starts_with("68") + & ~df["ts_code"].str.starts_with("8") + & ~df["ts_code"].str.starts_with("9") + & ~df["ts_code"].str.starts_with("4") + ) + + valid_df = df.filter(code_filter) + n = min(1000, len(valid_df)) + small_cap_codes = valid_df.sort("total_mv").head(n)["ts_code"] + + return df["ts_code"].is_in(small_cap_codes) + + +STOCK_FILTER_REQUIRED_COLUMNS = ["total_mv"] + +# 输出配置 +OUTPUT_DIR = "output" +SAVE_PREDICTIONS = True +PERSIST_MODEL = False + +# Top N 配置:每日推荐股票数量 +TOP_N = 5 # 可调整为 10, 20 等 +# %% md +# ## 4. 训练流程 +# %% +print("\n" + "=" * 80) +print("LightGBM LambdaRank 排序学习训练") +print("=" * 80) + +# 1. 创建 FactorEngine(启用 metadata 功能) +print("\n[1] 创建 FactorEngine") +engine = FactorEngine(metadata_path="data/factors.jsonl") + +# 2. 使用 metadata 定义因子 +print("\n[2] 定义因子(从 metadata 注册)") +feature_cols = create_factors_with_metadata(engine, FACTOR_DEFINITIONS, LABEL_FACTOR) + +# 3. 准备数据 +print("\n[3] 准备数据") +data = prepare_data( + engine=engine, + feature_cols=feature_cols, + start_date=TRAIN_START, + end_date=TEST_END, +) + +# 4. 转换为排序学习格式(分位数标签) +print("\n[4] 转换为排序学习格式") +data, target_col = prepare_ranking_data( + df=data, + label_col=LABEL_NAME, + n_quantiles=N_QUANTILES, +) + +# 5. 打印配置信息 +print(f"\n[配置] 训练期: {TRAIN_START} - {TRAIN_END}") +print(f"[配置] 验证期: {VAL_START} - {VAL_END}") +print(f"[配置] 测试期: {TEST_START} - {TEST_END}") +print(f"[配置] 特征数: {len(feature_cols)}") +print(f"[配置] 目标变量: {target_col}({N_QUANTILES}分位数)") + +# 6. 创建排序学习模型 +model = LightGBMLambdaRankModel(params=MODEL_PARAMS) + +# 7. 创建数据处理器 +processors = PROCESSORS + +# 8. 创建数据划分器 +splitter = DateSplitter( + train_start=TRAIN_START, + train_end=TRAIN_END, + val_start=VAL_START, + val_end=VAL_END, + test_start=TEST_START, + test_end=TEST_END, +) + +# 9. 创建股票池管理器 +pool_manager = StockPoolManager( + filter_func=stock_pool_filter, + required_columns=STOCK_FILTER_REQUIRED_COLUMNS, + data_router=engine.router, +) + +# 10. 创建 ST 过滤器 +st_filter = STFilter(data_router=engine.router) + +# 11. 创建训练器 +trainer = Trainer( + model=model, + pool_manager=pool_manager, + processors=processors, + filters=[st_filter], + splitter=splitter, + target_col=target_col, + feature_cols=feature_cols, + persist_model=PERSIST_MODEL, +) +# %% md +# ### 4.1 股票池筛选 +# %% +print("\n" + "=" * 80) +print("股票池筛选") +print("=" * 80) + +# 先执行 ST 过滤(在股票池筛选之前,与 Trainer.train() 保持一致) +if st_filter: + print("\n[过滤] 应用 ST 过滤器...") + data = st_filter.filter(data) + print(f" ST 过滤后数据规模: {data.shape}") + +if pool_manager: + print("\n执行每日独立筛选股票池...") + filtered_data = pool_manager.filter_and_select_daily(data) + print(f" 筛选前数据规模: {data.shape}") + print(f" 筛选后数据规模: {filtered_data.shape}") + print(f" 筛选前股票数: {data['ts_code'].n_unique()}") + print(f" 筛选后股票数: {filtered_data['ts_code'].n_unique()}") + print(f" 删除记录数: {len(data) - len(filtered_data)}") +else: + filtered_data = data + print(" 未配置股票池管理器,跳过筛选") +# %% md +# ### 4.2 数据划分 +# %% +print("\n" + "=" * 80) +print("数据划分") +print("=" * 80) + +if splitter: + train_data, val_data, test_data = splitter.split(filtered_data) + print(f"\n训练集数据规模: {train_data.shape}") + print(f"验证集数据规模: {val_data.shape}") + print(f"测试集数据规模: {test_data.shape}") + + # 计算各集的 group 数组 + train_group = compute_group_array(train_data) + val_group = compute_group_array(val_data) + test_group = compute_group_array(test_data) + + print(f"\n训练集 group 数量: {len(train_group)}") + print(f"验证集 group 数量: {len(val_group)}") + print(f"测试集 group 数量: {len(test_group)}") + print(f"训练集日均样本数: {np.mean(train_group):.1f}") + print(f"验证集日均样本数: {np.mean(val_group):.1f}") + print(f"测试集日均样本数: {np.mean(test_group):.1f}") +else: + raise ValueError("必须配置数据划分器") +# %% md +# ### 4.3 数据预处理 +# %% +print("\n" + "=" * 80) +print("数据预处理") +print("=" * 80) + +fitted_processors = [] +if processors: + print("\n训练集处理...") + for i, processor in enumerate(processors, 1): + print(f" [{i}/{len(processors)}] {processor.__class__.__name__}") + train_data = processor.fit_transform(train_data) + fitted_processors.append(processor) + + print("\n验证集处理...") + for processor in fitted_processors: + val_data = processor.transform(val_data) + + print("\n测试集处理...") + for processor in fitted_processors: + test_data = processor.transform(test_data) + +print(f"\n处理后训练集形状: {train_data.shape}") +print(f"处理后验证集形状: {val_data.shape}") +print(f"处理后测试集形状: {test_data.shape}") +# %% md +# ### 4.4 训练 LambdaRank 模型 +# %% +print("\n" + "=" * 80) +print("训练 LambdaRank 模型") +print("=" * 80) + +# 准备数据 +X_train = train_data.select(feature_cols) +y_train = train_data.select(target_col).to_series() + +X_val = val_data.select(feature_cols) +y_val = val_data.select(target_col).to_series() + +print(f"\n训练样本数: {len(X_train)}") +print(f"验证样本数: {len(X_val)}") +print(f"特征数: {len(feature_cols)}") +print(f"目标变量: {target_col}") + +print("\n目标变量统计(训练集):") +print(y_train.describe()) + +print("\n开始训练...") +model.fit( + X=X_train, + y=y_train, + group=train_group, + eval_set=(X_val, y_val, val_group), +) +print("训练完成!") +# %% md +# ### 4.5 训练指标曲线 +# %% +print("\n" + "=" * 80) +print("训练指标曲线") +print("=" * 80) + +# 重新训练以收集指标(因为之前的训练没有保存评估结果) +print("\n重新训练模型以收集训练指标...") + +import lightgbm as lgb + +# 准备数据(使用 val 做验证,test 不参与训练过程) +X_train_np = X_train.to_numpy() +y_train_np = y_train.to_numpy() +X_val_np = val_data.select(feature_cols).to_numpy() +y_val_np = val_data.select(target_col).to_series().to_numpy() + +# 创建数据集 +train_dataset = lgb.Dataset(X_train_np, label=y_train_np, group=train_group) +val_dataset = lgb.Dataset( + X_val_np, label=y_val_np, group=val_group, reference=train_dataset +) + +# 用于存储评估结果 +evals_result = {} + +# 使用与原模型相同的参数重新训练 +# 正确的三分法:train用于训练,val用于验证,test不参与训练过程 +booster_with_eval = lgb.train( + MODEL_PARAMS, + train_dataset, + num_boost_round=MODEL_PARAMS.get("n_estimators", 1000), + valid_sets=[train_dataset, val_dataset], + valid_names=["train", "val"], + callbacks=[ + lgb.record_evaluation(evals_result), + lgb.early_stopping(stopping_rounds=50, verbose=True), + ], +) + +print("训练完成,指标已收集") + +# 获取评估的 NDCG 指标 +ndcg_metrics = [k for k in evals_result["train"].keys() if "ndcg" in k] +print(f"\n评估的 NDCG 指标: {ndcg_metrics}") + +# 显示早停信息 +actual_rounds = len(list(evals_result["train"].values())[0]) +expected_rounds = MODEL_PARAMS.get("n_estimators", 1000) +print(f"\n[早停信息]") +print(f" 配置的最大轮数: {expected_rounds}") +print(f" 实际训练轮数: {actual_rounds}") +if actual_rounds < expected_rounds: + print(f" 早停状态: 已触发(连续50轮验证指标未改善)") +else: + print(f" 早停状态: 未触发(达到最大轮数)") + +# 显示各 NDCG 指标的最终值 +print(f"\n最终 NDCG 指标:") +for metric in ndcg_metrics: + train_ndcg = evals_result["train"][metric][-1] + val_ndcg = evals_result["val"][metric][-1] + print(f" {metric}: 训练集={train_ndcg:.4f}, 验证集={val_ndcg:.4f}") +# %% +# 绘制 NDCG 训练指标曲线 +import matplotlib.pyplot as plt + +fig, axes = plt.subplots(2, 2, figsize=(14, 10)) +axes = axes.flatten() + +for idx, metric in enumerate(ndcg_metrics[:4]): # 最多显示4个NDCG指标 + ax = axes[idx] + train_metric = evals_result["train"][metric] + val_metric = evals_result["val"][metric] + iterations = range(1, len(train_metric) + 1) + + ax.plot( + iterations, train_metric, label=f"Train {metric}", linewidth=2, color="blue" + ) + ax.plot(iterations, val_metric, label=f"Val {metric}", linewidth=2, color="red") + ax.set_xlabel("Iteration", fontsize=10) + ax.set_ylabel(metric.upper(), fontsize=10) + ax.set_title( + f"Training and Validation {metric.upper()}", fontsize=12, fontweight="bold" + ) + ax.legend(fontsize=9) + ax.grid(True, alpha=0.3) + + # 标记最佳验证指标点 + best_iter = val_metric.index(max(val_metric)) + best_metric = max(val_metric) + ax.axvline(x=best_iter + 1, color="green", linestyle="--", alpha=0.7) + ax.scatter([best_iter + 1], [best_metric], color="green", s=80, zorder=5) + ax.annotate( + f"Best: {best_metric:.4f}", + xy=(best_iter + 1, best_metric), + xytext=(best_iter + 1 + len(iterations) * 0.05, best_metric), + fontsize=8, + arrowprops=dict(arrowstyle="->", color="green", alpha=0.7), + ) + +plt.tight_layout() +plt.show() + +print(f"\n[指标分析]") +print(f" 各NDCG指标在验证集上的最佳值:") +for metric in ndcg_metrics: + val_metric_list = evals_result["val"][metric] + best_iter = val_metric_list.index(max(val_metric_list)) + best_val = max(val_metric_list) + print(f" {metric}: {best_val:.4f} (迭代 {best_iter + 1})") +print(f"\n[重要提醒] 验证集仅用于早停/调参,测试集完全独立于训练过程!") +# %% md +# ### 4.6 模型评估 +# %% +print("\n" + "=" * 80) +print("模型评估") +print("=" * 80) + +# 准备测试集 +X_test = test_data.select(feature_cols) +y_test = test_data.select(target_col).to_series() + +# 预测 +print("\n生成预测...") +predictions = model.predict(X_test) + +# 添加预测列 +test_data = test_data.with_columns([pl.Series("prediction", predictions)]) + +# 计算 NDCG 指标 +print("\n计算 NDCG 指标...") +ndcg_results = evaluate_ndcg_at_k( + y_true=y_test.to_numpy(), + y_pred=predictions, + group=test_group, + k_list=[1, 5, 10, 20], +) + +print("\nNDCG 评估结果:") +print("-" * 40) +for metric, value in ndcg_results.items(): + print(f" {metric}: {value:.4f}") + +# 特征重要性 +print("\n特征重要性(Top 20):") +print("-" * 40) +importance = model.feature_importance() +if importance is not None: + top_features = importance.sort_values(ascending=False).head(20) + for i, (feature, score) in enumerate(top_features.items(), 1): + print(f" {i:2d}. {feature:30s} {score:10.2f}") +# %% +# 确保输出目录存在 +os.makedirs(OUTPUT_DIR, exist_ok=True) + +# 生成时间戳 +start_dt = datetime.strptime(TEST_START, "%Y%m%d") +end_dt = datetime.strptime(TEST_END, "%Y%m%d") +date_str = f"{start_dt.strftime('%Y%m%d')}_{end_dt.strftime('%Y%m%d')}" + +# 保存每日 Top N +print(f"\n[1/1] 保存每日 Top {TOP_N} 股票...") +topn_output_path = os.path.join(OUTPUT_DIR, "rank_output.csv") + +# 按日期分组,取每日 top N +topn_by_date = [] +unique_dates = test_data["trade_date"].unique().sort() +for date in unique_dates: + day_data = test_data.filter(test_data["trade_date"] == date) + # 按 prediction 降序排序,取前 N + topn = day_data.sort("prediction", descending=True).head(TOP_N) + topn_by_date.append(topn) + +# 合并所有日期的 top N +topn_results = pl.concat(topn_by_date) + +# 格式化日期并调整列顺序:日期、分数、股票 +topn_to_save = topn_results.select( + [ + pl.col("trade_date").str.slice(0, 4) + + "-" + + pl.col("trade_date").str.slice(4, 2) + + "-" + + pl.col("trade_date").str.slice(6, 2).alias("date"), + pl.col("prediction").alias("score"), + pl.col("ts_code"), + ] +) +topn_to_save.write_csv(topn_output_path, include_header=True) +print(f" 保存路径: {topn_output_path}") +print( + f" 保存行数: {len(topn_to_save)}({len(unique_dates)}个交易日 x 每日top{TOP_N})" +) +print(f"\n 预览(前15行):") +print(topn_to_save.head(15)) + +print("\n训练流程完成!") +# %% md +# ## 5. 总结 +# +# 本 Notebook 实现了完整的 Learn-to-Rank 训练流程: +# +# ### 核心步骤 +# +# 1. **数据准备**: 计算 49 个特征因子,将 `future_return_5` 转换为 20 分位数标签 +# 2. **模型训练**: 使用 LightGBM LambdaRank 学习每日股票排序 +# 3. **模型评估**: 使用 NDCG@1/5/10/20 评估排序质量 +# 4. **策略分析**: 基于排序分数构建 Top-k 选股策略 +# +# ### 关键参数 +# +# - **Objective**: lambdarank +# - **Metric**: ndcg +# - **Learning Rate**: 0.05 +# - **Num Leaves**: 31 +# - **N Quantiles**: 20 +# +# ### 输出结果 +# +# - rank_output.csv: 每日Top-N推荐股票(格式:date, score, ts_code) +# - 特征重要性排名 +# - Top-k 策略统计和图表 +# - NDCG训练指标曲线 +# +# ### 后续优化方向 +# +# 1. **特征工程**: 尝试更多因子组合 +# 2. **超参数调优**: 使用网格搜索优化 LambdaRank 参数 +# 3. **模型集成**: 结合多个排序模型的预测 +# 4. **更复杂的分组**: 考虑按行业分组排序 diff --git a/src/experiment/regression.ipynb b/src/experiment/regression.ipynb index 4baa78e..fa8e0b7 100644 --- a/src/experiment/regression.ipynb +++ b/src/experiment/regression.ipynb @@ -8,13 +8,10 @@ ] }, { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:27:44.613389Z", - "start_time": "2026-03-11T13:27:44.026988Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "import os\n", "from datetime import datetime\n", @@ -34,40 +31,37 @@ " Winsorizer,\n", " NullFiller,\n", ")\n", - "from src.training.config import TrainingConfig" - ], - "outputs": [], - "execution_count": 1 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2. 定义辅助函数" + "from src.training.config import TrainingConfig\n", + "\n" ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:27:44.632791Z", - "start_time": "2026-03-11T13:27:44.624747Z" - } - }, + "metadata": {}, + "cell_type": "markdown", + "source": "## 2. 定义辅助函数" + }, + { + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ - "def create_factors_with_strings(engine: FactorEngine, factor_definitions: dict, label_factor: dict) -> List[str]:\n", + "def create_factors_with_metadata(\n", + " engine: FactorEngine, factor_definitions: dict, label_factor: dict\n", + ") -> List[str]:\n", + " \"\"\"使用 metadata 注册因子(特征因子通过名称注册,label 因子通过表达式注册)\"\"\"\n", " print(\"=\" * 80)\n", - " print(\"使用字符串表达式定义因子\")\n", + " print(\"使用 metadata 注册因子\")\n", " print(\"=\" * 80)\n", "\n", - " # 注册所有特征因子\n", - " print(\"\\n注册特征因子:\")\n", - " for name, expr in factor_definitions.items():\n", - " engine.add_factor(name, expr)\n", - " print(f\" - {name}: {expr}\")\n", + " # 注册所有特征因子(通过 metadata 名称)\n", + " print(\"\\n注册特征因子(从 metadata):\")\n", + " for name in factor_definitions.keys():\n", + " engine.add_factor_by_name(name)\n", + " print(f\" - {name}\")\n", "\n", - " # 注册 label 因子\n", - " print(\"\\n注册 Label 因子:\")\n", + " # 注册 label 因子(通过表达式,因为 label 不在 metadata 中)\n", + " print(\"\\n注册 Label 因子(表达式):\")\n", " for name, expr in label_factor.items():\n", " engine.add_factor(name, expr)\n", " print(f\" - {name}: {expr}\")\n", @@ -83,10 +77,10 @@ "\n", "\n", "def prepare_data(\n", - " engine: FactorEngine,\n", - " feature_cols: List[str],\n", - " start_date: str,\n", - " end_date: str,\n", + " engine: FactorEngine,\n", + " feature_cols: List[str],\n", + " start_date: str,\n", + " end_date: str,\n", ") -> pl.DataFrame:\n", " print(\"\\n\" + \"=\" * 80)\n", " print(\"准备数据\")\n", @@ -107,31 +101,27 @@ " print(f\"\\n前5行预览:\")\n", " print(data.head())\n", "\n", - " return data" - ], - "outputs": [], - "execution_count": 2 + " return data\n", + "\n" + ] }, { - "cell_type": "markdown", "metadata": {}, + "cell_type": "markdown", "source": [ "## 3. 配置参数\n", - "\n", + "#\n", "### 3.1 因子定义" ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:27:44.644952Z", - "start_time": "2026-03-11T13:27:44.640383Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "# 特征因子定义字典:新增因子只需在此处添加一行\n", - "LABEL_NAME = 'future_return_5'\n", + "LABEL_NAME = \"future_return_5\"\n", "\n", "FACTOR_DEFINITIONS = FACTOR_DICT = {\n", " # ================= 1. 价格、趋势与路径依赖 (Trend, Momentum & Path Dependency) =================\n", @@ -143,44 +133,38 @@ " \"bbi_ratio\": \"(ts_mean(close, 3) + ts_mean(close, 6) + ts_mean(close, 12) + ts_mean(close, 24)) / (4 * close + 1e-8)\", # 多空指标比率\n", " \"return_5\": \"(close / (ts_delay(close, 5) + 1e-8)) - 1\", # 5日动量\n", " \"return_20\": \"(close / (ts_delay(close, 20) + 1e-8)) - 1\", # 20日动量\n", - "\n", " # [高阶] Kaufman 趋势效率 (极高价值) - 衡量趋势流畅度,剔除无序震荡\n", " \"kaufman_ER_20\": \"abs(close - ts_delay(close, 20)) / (ts_sum(abs(close - ts_delay(close, 1)), 20) + 1e-8)\",\n", " # [高阶] 动量加速度 - 寻找二阶导数大于0,正在加速爆发的股票\n", " \"mom_acceleration_10_20\": \"(close / (ts_delay(close, 10) + 1e-8) - 1) - (ts_delay(close, 10) / (ts_delay(close, 20) + 1e-8) - 1)\",\n", - " #[高阶] 高点距离衰减 - 衡量套牢盘压力\n", + " # [高阶] 高点距离衰减 - 衡量套牢盘压力\n", " \"drawdown_from_high_60\": \"close / (ts_max(high, 60) + 1e-8) - 1\",\n", " # [高阶] 趋势一致性 - 过去20天内收红的天数比例\n", " \"up_days_ratio_20\": \"ts_sum(close > ts_delay(close, 1), 20) / 20\",\n", - "\n", " # ================= 2. 波动率、风险调整与高阶矩 (Volatility & Risk-Adjusted Returns) =================\n", " \"volatility_5\": \"ts_std(close, 5)\",\n", " \"volatility_20\": \"ts_std(close, 20)\",\n", " \"volatility_ratio\": \"ts_std(close, 5) / (ts_std(close, 20) + 1e-8)\", # 波动率期限结构\n", " \"std_return_20\": \"ts_std((close / (ts_delay(close, 1) + 1e-8)) - 1, 20)\", # 真实收益率波动率\n", - "\n", " # [高阶] 夏普趋势比率 - 惩罚暴涨暴跌,奖励稳健爬坡\n", " \"sharpe_ratio_20\": \"ts_mean(close / (ts_delay(close, 1) + 1e-8) - 1, 20) / (ts_std(close / (ts_delay(close, 1) + 1e-8) - 1, 20) + 1e-8)\",\n", - " #[高阶] 尾部崩盘风险 - 过去一个月最大单日跌幅\n", + " # [高阶] 尾部崩盘风险 - 过去一个月最大单日跌幅\n", " \"min_ret_20\": \"ts_min(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\",\n", " # [高阶] 波动率挤压比 - 寻找盘整到极致面临变盘的股票 (布林带收口)\n", " \"volatility_squeeze_5_60\": \"ts_std(close, 5) / (ts_std(close, 60) + 1e-8)\",\n", - "\n", " # ================= 3. 日内微观结构与异象 (Intraday Microstructure & Anomalies) =================\n", " # [高阶] 隔夜与日内背离 - 差值越小说明主力越喜欢在盘中吸筹\n", " \"overnight_intraday_diff\": \"(open / (ts_delay(close, 1) + 1e-8) - 1) - (close / (open + 1e-8) - 1)\",\n", - " #[高阶] 上影线抛压极值 - 冲高回落被套牢的概率\n", + " # [高阶] 上影线抛压极值 - 冲高回落被套牢的概率\n", " \"upper_shadow_ratio\": \"(high - ((open + close + abs(open - close)) / 2)) / (high - low + 1e-8)\",\n", " # [高阶] 资金沉淀率 - 衡量主力日内高抛低吸洗盘的剧烈程度\n", " \"capital_retention_20\": \"ts_sum(abs(close - open), 20) / (ts_sum(high - low, 20) + 1e-8)\",\n", " # [高阶] MAX 彩票效应 - 反转因子,剔除近期有过妖股连板特征的标的\n", " \"max_ret_20\": \"ts_max(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\",\n", - "\n", " # ================= 4. 量能、流动性与量价背离 (Volume, Liquidity & Divergence) =================\n", " \"volume_ratio_5_20\": \"ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)\", # 相对放量比\n", " \"turnover_rate_mean_5\": \"ts_mean(turnover_rate, 5)\", # 活跃度\n", " \"turnover_deviation\": \"(turnover_rate - ts_mean(turnover_rate, 10)) / (ts_std(turnover_rate, 10) + 1e-8)\", # 换手率偏离度\n", - "\n", " # [高阶] Amihud 非流动性异象 (绝对核心) - 衡量砸盘/拉升的摩擦成本\n", " \"amihud_illiq_20\": \"ts_mean(abs(close / (ts_delay(close, 1) + 1e-8) - 1) / (amount + 1e-8), 20)\",\n", " # [高阶] 换手率惩罚因子 - 换手率忽高忽低说明游资接力,行情极不稳定\n", @@ -189,33 +173,28 @@ " \"pv_corr_20\": \"ts_corr(close / (ts_delay(close, 1) + 1e-8) - 1, vol, 20)\",\n", " # [高阶] 收盘价与均价背离 - 专门抓尾盘突袭拉升骗线的股票\n", " \"close_vwap_deviation\": \"close / (amount / (vol * 100 + 1e-8) + 1e-8) - 1\",\n", - "\n", " # ================= 5. 基本面财务特征 (Fundamental Quality & Structure) =================\n", " \"roe\": \"n_income / (total_hldr_eqy_exc_min_int + 1e-8)\", # 净资产收益率\n", " \"roa\": \"n_income / (total_assets + 1e-8)\", # 总资产收益率\n", " \"profit_margin\": \"n_income / (revenue + 1e-8)\", # 销售净利率\n", " \"debt_to_equity\": \"total_liab / (total_hldr_eqy_exc_min_int + 1e-8)\", # 杠杆率\n", " \"current_ratio\": \"total_cur_assets / (total_cur_liab + 1e-8)\", # 短期偿债安全垫\n", - "\n", - " #[高阶] 利润同比增速 (日频延后252天等于去年同期)\n", + " # [高阶] 利润同比增速 (日频延后252天等于去年同期)\n", " \"net_profit_yoy\": \"(n_income / (ts_delay(n_income, 252) + 1e-8)) - 1\",\n", " # [高阶] 营收同比增速\n", " \"revenue_yoy\": \"(revenue / (ts_delay(revenue, 252) + 1e-8)) - 1\",\n", " # [高阶] 资产负债表扩张斜率 - 剔除单纯靠举债扩张的公司\n", " \"healthy_expansion_velocity\": \"(total_assets / (ts_delay(total_assets, 252) + 1e-8) - 1) - (total_liab / (ts_delay(total_liab, 252) + 1e-8) - 1)\",\n", - "\n", " # ================= 6. 基本面估值与截面动量共振 (Valuation & Cross-Sectional Ranking) =================\n", " # 估值水平绝对值 (Tushare 市值单位需要 * 10000 转换为元)\n", " \"EP\": \"n_income / (total_mv * 10000 + 1e-8)\", # 盈利收益率 (1/PE)\n", " \"BP\": \"total_hldr_eqy_exc_min_int / (total_mv * 10000 + 1e-8)\", # 账面市值比 (1/PB)\n", " \"CP\": \"n_cashflow_act / (total_mv * 10000 + 1e-8)\", # 经营现金流收益率 (1/PCF)\n", - "\n", " # 全市场截面排名因子\n", " \"market_cap_rank\": \"cs_rank(total_mv)\", # 规模因子 (Size)\n", " \"turnover_rank\": \"cs_rank(turnover_rate)\",\n", " \"return_5_rank\": \"cs_rank((close / (ts_delay(close, 5) + 1e-8)) - 1)\",\n", " \"EP_rank\": \"cs_rank(n_income / (total_mv + 1e-8))\", # 谁最便宜\n", - "\n", " # [高阶] 戴维斯双击动量 - 估值相对上一年是否在扩张\n", " \"pe_expansion_trend\": \"(total_mv / (n_income + 1e-8)) / (ts_delay(total_mv, 60) / (ts_delay(n_income, 60) + 1e-8) + 1e-8) - 1\",\n", " # [高阶] 业绩与价格背离度 - 截面做差:利润排名全市场第一,但近20日价格排名倒数第一,捕捉被错杀的潜伏股\n", @@ -229,25 +208,18 @@ "LABEL_FACTOR = {\n", " LABEL_NAME: \"(ts_delay(close, -5) / ts_delay(open, -1)) - 1\", # 未来5日收益率\n", "}" - ], - "outputs": [], - "execution_count": 3 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2 训练参数配置" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 3.2 训练参数配置" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:27:44.654539Z", - "start_time": "2026-03-11T13:27:44.651010Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "# 日期范围配置(正确的 train/val/test 三分法)\n", "# Train: 用于训练模型参数\n", @@ -287,6 +259,7 @@ "# 数据处理器配置(新 API:需要传入 feature_cols)\n", "# 注意:processor 现在需要显式指定要处理的特征列\n", "\n", + "\n", "# 股票池筛选函数\n", "# 使用新的 StockPoolManager API:传入自定义筛选函数和所需列/因子\n", "# 筛选函数接收单日 DataFrame,返回布尔 Series\n", @@ -305,11 +278,11 @@ " \"\"\"\n", " # 代码筛选(排除创业板、科创板、北交所)\n", " code_filter = (\n", - " ~df[\"ts_code\"].str.starts_with(\"30\") & # 排除创业板\n", - " ~df[\"ts_code\"].str.starts_with(\"68\") & # 排除科创板\n", - " ~df[\"ts_code\"].str.starts_with(\"8\") & # 排除北交所\n", - " ~df[\"ts_code\"].str.starts_with(\"9\") & # 排除北交所\n", - " ~df[\"ts_code\"].str.starts_with(\"4\") # 排除北交所\n", + " ~df[\"ts_code\"].str.starts_with(\"30\") # 排除创业板\n", + " & ~df[\"ts_code\"].str.starts_with(\"68\") # 排除科创板\n", + " & ~df[\"ts_code\"].str.starts_with(\"8\") # 排除北交所\n", + " & ~df[\"ts_code\"].str.starts_with(\"9\") # 排除北交所\n", + " & ~df[\"ts_code\"].str.starts_with(\"4\") # 排除北交所\n", " )\n", "\n", " # 在已筛选的股票中,选取市值最小的500只\n", @@ -338,39 +311,34 @@ "\n", "# Top N 配置:每日推荐股票数量\n", "TOP_N = 5 # 可调整为 10, 20 等" - ], - "outputs": [], - "execution_count": 4 + ] }, { - "cell_type": "markdown", "metadata": {}, + "cell_type": "markdown", "source": [ "## 4. 训练流程\n", - "\n", + "#\n", "### 4.1 初始化组件" ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:08.730709Z", - "start_time": "2026-03-11T13:27:44.661048Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"LightGBM 回归模型训练\")\n", "print(\"=\" * 80)\n", "\n", - "# 1. 创建 FactorEngine\n", + "# 1. 创建 FactorEngine(启用 metadata 功能)\n", "print(\"\\n[1] 创建 FactorEngine\")\n", - "engine = FactorEngine()\n", + "engine = FactorEngine(metadata_path=\"data/factors.jsonl\")\n", "\n", - "# 2. 使用字符串表达式定义因子\n", - "print(\"\\n[2] 定义因子(字符串表达式)\")\n", - "feature_cols = create_factors_with_strings(engine, FACTOR_DEFINITIONS, LABEL_FACTOR)\n", + "# 2. 使用 metadata 定义因子\n", + "print(\"\\n[2] 定义因子(从 metadata 注册)\")\n", + "feature_cols = create_factors_with_metadata(engine, FACTOR_DEFINITIONS, LABEL_FACTOR)\n", "target_col = LABEL_NAME\n", "\n", "# 3. 准备数据(使用模块级别的日期配置)\n", @@ -440,136 +408,7 @@ " feature_cols=feature_cols,\n", " persist_model=PERSIST_MODEL,\n", ")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "LightGBM 回归模型训练\n", - "================================================================================\n", - "\n", - "[1] 创建 FactorEngine\n", - "\n", - "[2] 定义因子(字符串表达式)\n", - "================================================================================\n", - "使用字符串表达式定义因子\n", - "================================================================================\n", - "\n", - "注册特征因子:\n", - " - ma_5: ts_mean(close, 5)\n", - " - ma_20: ts_mean(close, 20)\n", - " - ma_ratio_5_20: ts_mean(close, 5) / (ts_mean(close, 20) + 1e-8) - 1\n", - " - bias_10: close / (ts_mean(close, 10) + 1e-8) - 1\n", - " - high_low_ratio: (close - ts_min(low, 20)) / (ts_max(high, 20) - ts_min(low, 20) + 1e-8)\n", - " - bbi_ratio: (ts_mean(close, 3) + ts_mean(close, 6) + ts_mean(close, 12) + ts_mean(close, 24)) / (4 * close + 1e-8)\n", - " - return_5: (close / (ts_delay(close, 5) + 1e-8)) - 1\n", - " - return_20: (close / (ts_delay(close, 20) + 1e-8)) - 1\n", - " - kaufman_ER_20: abs(close - ts_delay(close, 20)) / (ts_sum(abs(close - ts_delay(close, 1)), 20) + 1e-8)\n", - " - mom_acceleration_10_20: (close / (ts_delay(close, 10) + 1e-8) - 1) - (ts_delay(close, 10) / (ts_delay(close, 20) + 1e-8) - 1)\n", - " - drawdown_from_high_60: close / (ts_max(high, 60) + 1e-8) - 1\n", - " - up_days_ratio_20: ts_sum(close > ts_delay(close, 1), 20) / 20\n", - " - volatility_5: ts_std(close, 5)\n", - " - volatility_20: ts_std(close, 20)\n", - " - volatility_ratio: ts_std(close, 5) / (ts_std(close, 20) + 1e-8)\n", - " - std_return_20: ts_std((close / (ts_delay(close, 1) + 1e-8)) - 1, 20)\n", - " - sharpe_ratio_20: ts_mean(close / (ts_delay(close, 1) + 1e-8) - 1, 20) / (ts_std(close / (ts_delay(close, 1) + 1e-8) - 1, 20) + 1e-8)\n", - " - min_ret_20: ts_min(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\n", - " - volatility_squeeze_5_60: ts_std(close, 5) / (ts_std(close, 60) + 1e-8)\n", - " - overnight_intraday_diff: (open / (ts_delay(close, 1) + 1e-8) - 1) - (close / (open + 1e-8) - 1)\n", - " - upper_shadow_ratio: (high - ((open + close + abs(open - close)) / 2)) / (high - low + 1e-8)\n", - " - capital_retention_20: ts_sum(abs(close - open), 20) / (ts_sum(high - low, 20) + 1e-8)\n", - " - max_ret_20: ts_max(close / (ts_delay(close, 1) + 1e-8) - 1, 20)\n", - " - volume_ratio_5_20: ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)\n", - " - turnover_rate_mean_5: ts_mean(turnover_rate, 5)\n", - " - turnover_deviation: (turnover_rate - ts_mean(turnover_rate, 10)) / (ts_std(turnover_rate, 10) + 1e-8)\n", - " - amihud_illiq_20: ts_mean(abs(close / (ts_delay(close, 1) + 1e-8) - 1) / (amount + 1e-8), 20)\n", - " - turnover_cv_20: ts_std(turnover_rate, 20) / (ts_mean(turnover_rate, 20) + 1e-8)\n", - " - pv_corr_20: ts_corr(close / (ts_delay(close, 1) + 1e-8) - 1, vol, 20)\n", - " - close_vwap_deviation: close / (amount / (vol * 100 + 1e-8) + 1e-8) - 1\n", - " - roe: n_income / (total_hldr_eqy_exc_min_int + 1e-8)\n", - " - roa: n_income / (total_assets + 1e-8)\n", - " - profit_margin: n_income / (revenue + 1e-8)\n", - " - debt_to_equity: total_liab / (total_hldr_eqy_exc_min_int + 1e-8)\n", - " - current_ratio: total_cur_assets / (total_cur_liab + 1e-8)\n", - " - net_profit_yoy: (n_income / (ts_delay(n_income, 252) + 1e-8)) - 1\n", - " - revenue_yoy: (revenue / (ts_delay(revenue, 252) + 1e-8)) - 1\n", - " - healthy_expansion_velocity: (total_assets / (ts_delay(total_assets, 252) + 1e-8) - 1) - (total_liab / (ts_delay(total_liab, 252) + 1e-8) - 1)\n", - " - EP: n_income / (total_mv * 10000 + 1e-8)\n", - " - BP: total_hldr_eqy_exc_min_int / (total_mv * 10000 + 1e-8)\n", - " - CP: n_cashflow_act / (total_mv * 10000 + 1e-8)\n", - " - market_cap_rank: cs_rank(total_mv)\n", - " - turnover_rank: cs_rank(turnover_rate)\n", - " - return_5_rank: cs_rank((close / (ts_delay(close, 5) + 1e-8)) - 1)\n", - " - EP_rank: cs_rank(n_income / (total_mv + 1e-8))\n", - " - pe_expansion_trend: (total_mv / (n_income + 1e-8)) / (ts_delay(total_mv, 60) / (ts_delay(n_income, 60) + 1e-8) + 1e-8) - 1\n", - " - value_price_divergence: cs_rank((n_income - ts_delay(n_income, 252)) / (abs(ts_delay(n_income, 252)) + 1e-8)) - cs_rank(close / (ts_delay(close, 20) + 1e-8))\n", - " - active_market_cap: total_mv * ts_mean(turnover_rate, 20)\n", - " - ebit_rank: cs_rank(ebit)\n", - "\n", - "注册 Label 因子:\n", - " - future_return_5: (ts_delay(close, -5) / ts_delay(open, -1)) - 1\n", - "\n", - "特征因子数: 49\n", - "Label: future_return_5\n", - "已注册因子总数: 50\n", - "\n", - "[3] 准备数据\n", - "\n", - "================================================================================\n", - "准备数据\n", - "================================================================================\n", - "\n", - "计算因子: 20200101 - 20261231\n", - "[FinancialLoader] 加载 financial_fina_indicator 失败: Binder Error: Referenced column \"f_ann_date\" not found in FROM clause!\n", - "Candidate bindings: \"ann_date\", \"end_date\", \"ocf_to_debt\", \"arturn_days\", \"nca_to_assets\"\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "D:\\PyProject\\ProStock\\src\\data\\financial_loader.py:148: UserWarning: Sortedness of columns cannot be checked when 'by' groups provided\n", - " merged = df_price.join_asof(\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "数据形状: (7255513, 70)\n", - "数据列: ['ts_code', 'trade_date', 'low', 'open', 'turnover_rate', 'close', 'amount', 'vol', 'high', 'total_assets', 'total_mv', 'f_ann_date', 'n_income', 'revenue', 'total_cur_assets', 'total_liab', 'total_cur_liab', 'total_hldr_eqy_exc_min_int', 'n_cashflow_act', 'ebit', 'ma_5', 'ma_20', 'ma_ratio_5_20', 'bias_10', 'high_low_ratio', 'bbi_ratio', 'return_5', 'return_20', 'kaufman_ER_20', 'mom_acceleration_10_20', 'drawdown_from_high_60', 'up_days_ratio_20', 'volatility_5', 'volatility_20', 'volatility_ratio', 'std_return_20', 'sharpe_ratio_20', 'min_ret_20', 'volatility_squeeze_5_60', 'overnight_intraday_diff', 'upper_shadow_ratio', 'capital_retention_20', 'max_ret_20', 'volume_ratio_5_20', 'turnover_rate_mean_5', 'turnover_deviation', 'amihud_illiq_20', 'turnover_cv_20', 'pv_corr_20', 'close_vwap_deviation', 'roe', 'roa', 'profit_margin', 'debt_to_equity', 'current_ratio', 'net_profit_yoy', 'revenue_yoy', 'healthy_expansion_velocity', 'EP', 'BP', 'CP', 'market_cap_rank', 'turnover_rank', 'return_5_rank', 'EP_rank', 'pe_expansion_trend', 'value_price_divergence', 'active_market_cap', 'ebit_rank', 'future_return_5']\n", - "\n", - "前5行预览:\n", - "shape: (5, 70)\n", - "┌───────────┬────────────┬─────────┬─────────┬───┬────────────┬────────────┬───────────┬───────────┐\n", - "│ ts_code ┆ trade_date ┆ low ┆ open ┆ … ┆ value_pric ┆ active_mar ┆ ebit_rank ┆ future_re │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ e_divergen ┆ ket_cap ┆ --- ┆ turn_5 │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ ce ┆ --- ┆ f64 ┆ --- │\n", - "│ ┆ ┆ ┆ ┆ ┆ --- ┆ f64 ┆ ┆ f64 │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ ┆ ┆ │\n", - "╞═══════════╪════════════╪═════════╪═════════╪═══╪════════════╪════════════╪═══════════╪═══════════╡\n", - "│ 000001.SZ ┆ 20200102 ┆ 1806.75 ┆ 1817.67 ┆ … ┆ null ┆ null ┆ null ┆ -0.008857 │\n", - "│ 000001.SZ ┆ 20200103 ┆ 1847.15 ┆ 1849.33 ┆ … ┆ null ┆ null ┆ null ┆ -0.01881 │\n", - "│ 000001.SZ ┆ 20200106 ┆ 1846.05 ┆ 1856.97 ┆ … ┆ null ┆ null ┆ null ┆ -0.008171 │\n", - "│ 000001.SZ ┆ 20200107 ┆ 1850.42 ┆ 1870.07 ┆ … ┆ null ┆ null ┆ null ┆ -0.014117 │\n", - "│ 000001.SZ ┆ 20200108 ┆ 1815.49 ┆ 1855.88 ┆ … ┆ null ┆ null ┆ null ┆ -0.017252 │\n", - "└───────────┴────────────┴─────────┴─────────┴───┴────────────┴────────────┴───────────┴───────────┘\n", - "\n", - "[配置] 训练期: 20200101 - 20231231\n", - "[配置] 验证期: 20240101 - 20241231\n", - "[配置] 测试期: 20250101 - 20261231\n", - "[配置] 特征数: 49\n", - "[配置] 目标变量: future_return_5\n", - "[股票池筛选] 使用自定义函数进行股票池筛选\n", - "[股票池筛选] 所需基础列: ['total_mv']\n", - "[股票池筛选] 筛选逻辑: 排除创业板/科创板/北交所后,每日选市值最小的500只\n" - ] - } - ], - "execution_count": 5 + ] }, { "metadata": {}, @@ -577,13 +416,10 @@ "source": "### 4.2 执行训练" }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:12.487988Z", - "start_time": "2026-03-11T13:28:08.737960Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"开始训练\")\n", @@ -603,55 +439,13 @@ "else:\n", " filtered_data = data\n", " print(\" 未配置股票池管理器,跳过筛选\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "开始训练\n", - "================================================================================\n", - "\n", - "[步骤 1/6] 股票池筛选\n", - "------------------------------------------------------------\n", - " 执行每日独立筛选股票池...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\liaozhaorun\\AppData\\Local\\Temp\\ipykernel_18404\\3491564681.py:71: DeprecationWarning: `is_in` with a collection of the same datatype is ambiguous and deprecated.\n", - "Please use `implode` to return to previous behavior.\n", - "\n", - "See https://github.com/pola-rs/polars/issues/22149 for more information.\n", - " return df[\"ts_code\"].is_in(small_cap_codes)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 筛选前数据规模: (7255513, 70)\n", - " 筛选后数据规模: (1494000, 70)\n", - " 筛选前股票数: 5694\n", - " 筛选后股票数: 2196\n", - " 删除记录数: 5761513\n" - ] - } - ], - "execution_count": 6 + ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:12.560547Z", - "start_time": "2026-03-11T13:28:12.492037Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "# 步骤 2: 划分训练/验证/测试集(正确的三分法)\n", "print(\"\\n[步骤 2/6] 划分训练集、验证集和测试集\")\n", @@ -685,87 +479,13 @@ " train_data = filtered_data\n", " test_data = filtered_data\n", " print(\" 未配置划分器,全部作为训练集\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[步骤 2/6] 划分训练集、验证集和测试集\n", - "------------------------------------------------------------\n", - " 训练集数据规模: (970000, 70)\n", - " 验证集数据规模: (242000, 70)\n", - " 测试集数据规模: (282000, 70)\n", - " 训练集股票数: 1705\n", - " 验证集股票数: 1308\n", - " 测试集股票数: 1774\n", - " 训练集日期范围: 20200102 - 20231229\n", - " 验证集日期范围: 20240102 - 20241231\n", - " 测试集日期范围: 20250102 - 20260306\n", - "\n", - " 训练集前5行预览:\n", - "shape: (5, 70)\n", - "┌───────────┬────────────┬───────┬───────┬───┬─────────────┬─────────────┬───────────┬─────────────┐\n", - "│ ts_code ┆ trade_date ┆ low ┆ open ┆ … ┆ value_price ┆ active_mark ┆ ebit_rank ┆ future_retu │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ _divergence ┆ et_cap ┆ --- ┆ rn_5 │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ --- ┆ --- ┆ f64 ┆ --- │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ f64 │\n", - "╞═══════════╪════════════╪═══════╪═══════╪═══╪═════════════╪═════════════╪═══════════╪═════════════╡\n", - "│ 000004.SZ ┆ 20200102 ┆ 90.1 ┆ 92.05 ┆ … ┆ null ┆ null ┆ null ┆ 0.000441 │\n", - "│ 000004.SZ ┆ 20200103 ┆ 89.53 ┆ 90.67 ┆ … ┆ null ┆ null ┆ null ┆ 0.005875 │\n", - "│ 000004.SZ ┆ 20200106 ┆ 87.58 ┆ 90.22 ┆ … ┆ null ┆ null ┆ null ┆ 0.05644 │\n", - "│ 000004.SZ ┆ 20200107 ┆ 88.06 ┆ 88.59 ┆ … ┆ null ┆ null ┆ null ┆ 0.049753 │\n", - "│ 000004.SZ ┆ 20200108 ┆ 88.51 ┆ 89.04 ┆ … ┆ null ┆ null ┆ null ┆ 0.019922 │\n", - "└───────────┴────────────┴───────┴───────┴───┴─────────────┴─────────────┴───────────┴─────────────┘\n", - "\n", - " 验证集前5行预览:\n", - "shape: (5, 70)\n", - "┌───────────┬────────────┬───────┬───────┬───┬─────────────┬─────────────┬───────────┬─────────────┐\n", - "│ ts_code ┆ trade_date ┆ low ┆ open ┆ … ┆ value_price ┆ active_mark ┆ ebit_rank ┆ future_retu │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ _divergence ┆ et_cap ┆ --- ┆ rn_5 │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ --- ┆ --- ┆ f64 ┆ --- │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ f64 │\n", - "╞═══════════╪════════════╪═══════╪═══════╪═══╪═════════════╪═════════════╪═══════════╪═════════════╡\n", - "│ 000004.SZ ┆ 20240102 ┆ 65.23 ┆ 65.43 ┆ … ┆ null ┆ 770442.9948 ┆ null ┆ -0.014188 │\n", - "│ ┆ ┆ ┆ ┆ ┆ ┆ 33 ┆ ┆ │\n", - "│ 000004.SZ ┆ 20240103 ┆ 64.62 ┆ 65.55 ┆ … ┆ null ┆ 751492.2017 ┆ null ┆ 0.002432 │\n", - "│ ┆ ┆ ┆ ┆ ┆ ┆ 8 ┆ ┆ │\n", - "│ 000004.SZ ┆ 20240104 ┆ 64.7 ┆ 65.8 ┆ … ┆ null ┆ 866443.5445 ┆ null ┆ 0.016919 │\n", - "│ ┆ ┆ ┆ ┆ ┆ ┆ 25 ┆ ┆ │\n", - "│ 000004.SZ ┆ 20240105 ┆ 65.19 ┆ 67.38 ┆ … ┆ null ┆ 907980.5905 ┆ null ┆ -0.013477 │\n", - "│ ┆ ┆ ┆ ┆ ┆ ┆ 95 ┆ ┆ │\n", - "│ 000004.SZ ┆ 20240108 ┆ 65.02 ┆ 66.04 ┆ … ┆ null ┆ 931205.3950 ┆ null ┆ -0.024684 │\n", - "│ ┆ ┆ ┆ ┆ ┆ ┆ 63 ┆ ┆ │\n", - "└───────────┴────────────┴───────┴───────┴───┴─────────────┴─────────────┴───────────┴─────────────┘\n", - "\n", - " 测试集前5行预览:\n", - "shape: (5, 70)\n", - "┌───────────┬────────────┬───────┬───────┬───┬─────────────┬─────────────┬───────────┬─────────────┐\n", - "│ ts_code ┆ trade_date ┆ low ┆ open ┆ … ┆ value_price ┆ active_mark ┆ ebit_rank ┆ future_retu │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ _divergence ┆ et_cap ┆ --- ┆ rn_5 │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ --- ┆ --- ┆ f64 ┆ --- │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ f64 │\n", - "╞═══════════╪════════════╪═══════╪═══════╪═══╪═════════════╪═════════════╪═══════════╪═════════════╡\n", - "│ 000004.SZ ┆ 20250102 ┆ 54.17 ┆ 55.8 ┆ … ┆ null ┆ 2.3754e6 ┆ null ┆ -0.066193 │\n", - "│ 000004.SZ ┆ 20250103 ┆ 51.86 ┆ 57.71 ┆ … ┆ null ┆ 2.1884e6 ┆ null ┆ 0.00893 │\n", - "│ 000004.SZ ┆ 20250106 ┆ 49.17 ┆ 50.39 ┆ … ┆ null ┆ 2.1549e6 ┆ null ┆ -0.0142 │\n", - "│ 000004.SZ ┆ 20250107 ┆ 51.41 ┆ 51.41 ┆ … ┆ null ┆ 2.2770e6 ┆ null ┆ 0.013031 │\n", - "│ 000004.SZ ┆ 20250108 ┆ 52.38 ┆ 52.95 ┆ … ┆ null ┆ 2.3533e6 ┆ null ┆ 0.00442 │\n", - "└───────────┴────────────┴───────┴───────┴───┴─────────────┴─────────────┴───────────┴─────────────┘\n" - ] - } - ], - "execution_count": 7 + ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:13.045107Z", - "start_time": "2026-03-11T13:28:12.565811Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "# 步骤 3: 训练集数据处理\n", "print(\"\\n[步骤 3/6] 训练集数据处理\")\n", @@ -773,9 +493,7 @@ "fitted_processors = []\n", "if processors:\n", " for i, processor in enumerate(processors, 1):\n", - " print(\n", - " f\" [{i}/{len(processors)}] 应用处理器: {processor.__class__.__name__}\"\n", - " )\n", + " print(f\" [{i}/{len(processors)}] 应用处理器: {processor.__class__.__name__}\")\n", " train_data_before = len(train_data)\n", " train_data = processor.fit_transform(train_data)\n", " train_data_after = len(train_data)\n", @@ -794,65 +512,14 @@ "for col in feature_cols[:5]: # 只显示前5个特征的缺失值\n", " null_count = train_data[col].null_count()\n", " if null_count > 0:\n", - " print(\n", - " f\" {col}: {null_count} ({null_count / len(train_data) * 100:.2f}%)\"\n", - " )" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[步骤 3/6] 训练集数据处理\n", - "------------------------------------------------------------\n", - " [1/3] 应用处理器: NullFiller\n", - " 处理前记录数: 970000\n", - " 处理后记录数: 970000\n", - " [2/3] 应用处理器: Winsorizer\n", - " 处理前记录数: 970000\n", - " 处理后记录数: 970000\n", - " [3/3] 应用处理器: StandardScaler\n", - " 处理前记录数: 970000\n", - " 处理后记录数: 970000\n", - "\n", - " 训练集处理后前5行预览:\n", - "shape: (5, 70)\n", - "┌───────────┬────────────┬───────┬───────┬───┬─────────────┬─────────────┬───────────┬─────────────┐\n", - "│ ts_code ┆ trade_date ┆ low ┆ open ┆ … ┆ value_price ┆ active_mark ┆ ebit_rank ┆ future_retu │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ _divergence ┆ et_cap ┆ --- ┆ rn_5 │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ --- ┆ --- ┆ f64 ┆ --- │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ f64 │\n", - "╞═══════════╪════════════╪═══════╪═══════╪═══╪═════════════╪═════════════╪═══════════╪═════════════╡\n", - "│ 000004.SZ ┆ 20200102 ┆ 90.1 ┆ 92.05 ┆ … ┆ null ┆ null ┆ null ┆ 0.000441 │\n", - "│ 000004.SZ ┆ 20200103 ┆ 89.53 ┆ 90.67 ┆ … ┆ null ┆ null ┆ null ┆ 0.005875 │\n", - "│ 000004.SZ ┆ 20200106 ┆ 87.58 ┆ 90.22 ┆ … ┆ null ┆ null ┆ null ┆ 0.05644 │\n", - "│ 000004.SZ ┆ 20200107 ┆ 88.06 ┆ 88.59 ┆ … ┆ null ┆ null ┆ null ┆ 0.049753 │\n", - "│ 000004.SZ ┆ 20200108 ┆ 88.51 ┆ 89.04 ┆ … ┆ null ┆ null ┆ null ┆ 0.019922 │\n", - "└───────────┴────────────┴───────┴───────┴───┴─────────────┴─────────────┴───────────┴─────────────┘\n", - "\n", - " 训练集特征统计:\n", - " 特征数: 49\n", - " 样本数: 970000\n", - " 缺失值统计:\n", - " ma_5: 4000 (0.41%)\n", - " ma_20: 19000 (1.96%)\n", - " ma_ratio_5_20: 19000 (1.96%)\n", - " bias_10: 9000 (0.93%)\n", - " high_low_ratio: 19000 (1.96%)\n" - ] - } - ], - "execution_count": 8 + " print(f\" {col}: {null_count} ({null_count / len(train_data) * 100:.2f}%)\")" + ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:26.439057Z", - "start_time": "2026-03-11T13:28:13.048971Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "# 步骤 4: 训练模型\n", "print(\"\\n[步骤 4/6] 训练模型\")\n", @@ -875,42 +542,13 @@ "print(\"\\n 开始训练...\")\n", "model.fit(X_train, y_train)\n", "print(\" 训练完成!\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[步骤 4/6] 训练模型\n", - "------------------------------------------------------------\n", - " 模型类型: LightGBM\n", - " 训练样本数: 970000\n", - " 特征数: 49\n", - " 目标变量: future_return_5\n", - "\n", - " 目标变量统计:\n", - " 均值: 0.004737\n", - " 标准差: 0.066054\n", - " 最小值: -0.910839\n", - " 最大值: 5.130794\n", - " 缺失值: 465\n", - "\n", - " 开始训练...\n", - " 训练完成!\n" - ] - } - ], - "execution_count": 9 + ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:26.494851Z", - "start_time": "2026-03-11T13:28:26.443216Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "# 步骤 5: 测试集数据处理\n", "print(\"\\n[步骤 5/6] 测试集数据处理\")\n", @@ -927,37 +565,13 @@ " print(f\" 处理后记录数: {test_data_after}\")\n", "else:\n", " print(\" 跳过测试集处理\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[步骤 5/6] 测试集数据处理\n", - "------------------------------------------------------------\n", - " [1/3] 应用处理器: NullFiller\n", - " 处理前记录数: 282000\n", - " 处理后记录数: 282000\n", - " [2/3] 应用处理器: Winsorizer\n", - " 处理前记录数: 282000\n", - " 处理后记录数: 282000\n", - " [3/3] 应用处理器: StandardScaler\n", - " 处理前记录数: 282000\n", - " 处理后记录数: 282000\n" - ] - } - ], - "execution_count": 10 + ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:26.994246Z", - "start_time": "2026-03-11T13:28:26.501158Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "# 步骤 6: 生成预测\n", "print(\"\\n[步骤 6/6] 生成预测\")\n", @@ -976,28 +590,7 @@ "\n", "# 保存结果到 trainer\n", "trainer.results = test_data.with_columns([pl.Series(\"prediction\", predictions)])" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[步骤 6/6] 生成预测\n", - "------------------------------------------------------------\n", - " 测试样本数: 282000\n", - " 预测中...\n", - " 预测完成!\n", - "\n", - " 预测结果统计:\n", - " 均值: 0.002399\n", - " 标准差: 0.009874\n", - " 最小值: -0.299069\n", - " 最大值: 0.122588\n" - ] - } - ], - "execution_count": 11 + ] }, { "metadata": {}, @@ -1005,13 +598,10 @@ "source": "### 4.3 训练指标曲线" }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:34.229526Z", - "start_time": "2026-03-11T13:28:27.000586Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"训练指标曲线\")\n", @@ -1074,46 +664,13 @@ "print(f\"\\n最终指标:\")\n", "print(f\" 训练 {metric_name}: {train_metric[-1]:.6f}\")\n", "print(f\" 验证 {metric_name}: {val_metric[-1]:.6f}\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "训练指标曲线\n", - "================================================================================\n", - "\n", - "重新训练模型以收集训练指标...\n", - "Training until validation scores don't improve for 100 rounds\n", - "Early stopping, best iteration is:\n", - "[301]\ttrain's l1: 0.0421507\tval's l1: 0.0620576\n", - "训练完成,指标已收集\n", - "\n", - "评估指标: l1\n", - "\n", - "[早停信息]\n", - " 配置的最大轮数: 1000\n", - " 实际训练轮数: 401\n", - " 早停状态: 已触发(连续100轮验证指标未改善)\n", - "\n", - "最终指标:\n", - " 训练 l1: 0.041986\n", - " 验证 l1: 0.062072\n" - ] - } - ], - "execution_count": 12 + ] }, { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:34.643007Z", - "start_time": "2026-03-11T13:28:34.233779Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "# 绘制训练指标曲线\n", "import matplotlib.pyplot as plt\n", @@ -1122,19 +679,33 @@ "\n", "# 绘制训练集和验证集的指标曲线(注意:val用于验证,test不参与训练)\n", "iterations = range(1, len(train_metric) + 1)\n", - "ax.plot(iterations, train_metric, label=f\"Train {metric_name}\", linewidth=2, color=\"blue\")\n", - "ax.plot(iterations, val_metric, label=f\"Validation {metric_name}\", linewidth=2, color=\"red\")\n", + "ax.plot(\n", + " iterations, train_metric, label=f\"Train {metric_name}\", linewidth=2, color=\"blue\"\n", + ")\n", + "ax.plot(\n", + " iterations, val_metric, label=f\"Validation {metric_name}\", linewidth=2, color=\"red\"\n", + ")\n", "\n", "ax.set_xlabel(\"Iteration\", fontsize=12)\n", "ax.set_ylabel(metric_name.upper(), fontsize=12)\n", - "ax.set_title(f\"Training and Validation {metric_name.upper()} Curve\", fontsize=14, fontweight=\"bold\")\n", + "ax.set_title(\n", + " f\"Training and Validation {metric_name.upper()} Curve\",\n", + " fontsize=14,\n", + " fontweight=\"bold\",\n", + ")\n", "ax.legend(fontsize=10)\n", "ax.grid(True, alpha=0.3)\n", "\n", "# 标记最佳验证指标点(用于早停决策)\n", "best_iter = val_metric.index(min(val_metric))\n", "best_metric = min(val_metric)\n", - "ax.axvline(x=best_iter + 1, color=\"green\", linestyle=\"--\", alpha=0.7, label=f\"Best Iteration ({best_iter + 1})\")\n", + "ax.axvline(\n", + " x=best_iter + 1,\n", + " color=\"green\",\n", + " linestyle=\"--\",\n", + " alpha=0.7,\n", + " label=f\"Best Iteration ({best_iter + 1})\",\n", + ")\n", "ax.scatter([best_iter + 1], [best_metric], color=\"green\", s=100, zorder=5)\n", "ax.annotate(\n", " f\"Best: {best_metric:.6f}\\nIter: {best_iter + 1}\",\n", @@ -1152,52 +723,18 @@ "print(f\" 最佳迭代轮数: {best_iter + 1}\")\n", "print(f\" 早停建议: 如果验证指标连续10轮不下降,建议在第 {best_iter + 1} 轮停止训练\")\n", "print(f\"\\n[重要提醒] 验证集仅用于早停/调参,测试集完全独立于训练过程!\")" - ], - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ], - "image/png": "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atWqlbz++uu5vpXh3ff++9//ysUXXyyJiYnSvHlzE4SFe/jhh+Wcc84xz6GBz2OPPSbp6elm3SuvvCJTpkyR7777Trxer8THxwf2Obz73vfffy+XXXaZlCpVSqpUqWIqtvT1WG699Vbp16+fPPvss1KrVi2zzciRIwPPlR8dOnSQZ555Rq6//nrbArECX31v/fr1+d529+7dBX14AAAAAEAu9GS1QmIFcxILILvY2Fi55ZZbTMDz6KOPmmNGaSCVmZlpwigNdNq1a2dCo/Lly8v7778vN998s5x99tnSsWPHPN9Wn88n/fv3lxo1asg333wjR44cCRl/ylKuXDmzH7Vr1zbB0vDhw82yhx56SK677jrZtGmTLF261ARaGRkZJkwKd+LECenVq5d07tzZdCFMTk6W22+/XUaNGhUSvH366acmkNKfW7duNY+vXQP1OUuqAodSWuZmNWh+BjnP77YAAAAAAMAB2rcX2bvX3ufU7mRr1+Z789tuu81U/Xz++edmwHKr656OmVShQgUzPfjgg4Ht77nnHvnwww/ljTfeyFco9fHHH8vmzZvNfTRwUk888US2caAmTJgQUmmlz7lgwQITSpUqVUrKli1rQjTtLqehlM6Hmz9/vqSkpMg//vEPKVOmjFk2a9YsM3bWU089ZYIxValSJbM8JiZGmjVrJn379pXly5dHVyiljQgAAAAAODPSM9PlhbUviNfjldvb3i5xMXE0BeylgdSuXSX6XddQpkuXLvLyyy+bUEorh3SQ88cff9ys14opDZE0hNq1a5ekpaVJampqvseM+vHHH6Vu3bqBQEppJVO4hQsXyp///Gf56aefTHWWBk9amVUQP/74o7Ru3ToQSKmuXbuaaq0tW7YEQqkWLVqYQMqiVVNanVWSFTiUGjJkSPHsCQAAAAAgT5n+TPlg6wemV8rQ84dKnBBKwWY2DYJ9us+pY0dpBdTs2bNNgY12zevWrZtZp1VUM2fONGNE6XhSGvho9zsNp4rKypUr5cYbbzTjRmn3O63O0iqp6dOnS3GIiwv9LtDvCA2uoiqUAgAAAAAALlaAbnRn0rXXXiujR4823d+069uIESMCQwx9/fXXcvXVV8tNN91kbmt485///McMWJ4f5557rvzyyy+yZ88eU5GkVq1aFbLNihUrpH79+mZcK8vPP/8csk18fLyp2srruXTsKB1byqqW0v3XceWaNm0qTsbIeAAAAAAAIOroeE062Pe4ceNMeKRXqLM0adLEDC6uwZF2j7vzzjtl3759+X7sHj16mKvqaW8yvXqedg0MDp+s59ixY4epjtLue9qNb9GiRSHbNGjQQLZt2yYbNmyQAwcOmC6E4bTaSq/wp8+lA6PrQOZaAaYDs1td94qCVonpfuik89qtUee162NxIZQCAAAAAABRSbvwHTp0yHSfCx7/SQcgb9u2rVmuY07pQOP9+vXL9+NqlZIGTKdOnTIDo+vV8P70pz+FbHPVVVfJfffdZ66Sp1fB0wDsscceC9lmwIAB0rt3b7nsssvM/r3++uvZnkvHudIB1X/99Vfp0KGDDBw4ULp3724GNS9Ku3fvlvPPP99MGuI9++yzZl5fW3Hx+PUSebDF0aNHTR9SvVRkQQc2O9O0lFEvO1m9enUuPRvlaGt3ob3dhfZ2D9raXWhv97X3jt07ZNQXo0w3pKRBSZIYm3imdwtRemzrFd+0iqdhw4amUgfFx+/3B66+Z3UxLOly+3zkN/+gUgoAAAAAAAC2I5QCAAAAAACA7bj6HgAAAAA4SEJMgrx05UumS5fOA4BTEUoBAAAAgIPoeDPVyzDWKwDno/seAAAAAADIEddHQ3F9LgilAAAAAMBBMnwZ8vKGl+Xlb18280BxiYuLMz9PnjzJm4xsrM+F9TkpDLrvAQAAAICDaBC1ePNi043vhlY3SKyX0zoUj5iYGKlYsaIkJyeb26VLlzafOxRP1VFGRobExsaW+PdY91UDKf1c6OdDPyeFxbcXAAAAAACIqGbNmuanFUyh+IIen89nLmBQ0kMpiwZS1uejsAilAAAAAABARBqQ1KpVS6pXry7p6em8S8XE5/PJwYMHpUqVKiaYKum0y97pVEhZCKUAAAAAAECuNIAoihACOYdScXFxkpiY6IhQqqi455UCAAAAAACgxCCUAgAAAAAAgO0IpQAAAAAAAGA7xpQCAAAAAAdJiEmQWX1mmXFndB4AnIpQCgAAAAAcdjW0ehXquWowZADRiW8xAAAAAAAA2I5KKQAAAABwkAxfhsz/fr6plLq2xbUS6+W0DoAz8e0FAAAAAA4LpRb8sMB04+t/bn9CKQCORfc9AAAAAAAA2I5QCgAAAAAAALYjlAIAAAAAAIDtCKUAAAAAAABgO0IpAAAAAAAA2I5QCgAAAAAAALaLtf8pAQAAAACFFR8TL9P/MF28Xq+ZBwCnIpQCAAAAAAfxerzSpEoTE0oBgJPxLQYAAAAAAADblchQavbs2dKgQQNJTEyUTp06yerVq3PdPikpSZo1a2a2b9WqlSxZsiRk/a233ioejydk6t27d8g2v/76q9x4441Svnx5qVixogwbNkyOHz8ess3GjRvloosuMs9Tt25defrpp4vwVQMAAABA3jJ8GfLWj2+ZSecBwKlKXCi1cOFCuf/++2XSpEmyfv16ad26tfTq1UuSk5Mjbr9ixQoZPHiwCZG+/fZb6devn5k2bdoUsp2GUHv27AlMr7/+esh6DaR++OEHWbZsmbz33nvyxRdfyB133BFYf/ToUenZs6fUr19f1q1bJ88884xMnjxZ5s6dW0zvBAAAAABkp0HUK9+9IvM2zCOUAuBoJS6Ueu6552T48OEydOhQad68ucyZM0dKly4tL7/8csTtZ86caQKnsWPHyrnnnitTp06Vtm3byqxZs0K2S0hIkJo1awamSpUqBdb9+OOPsnTpUnnppZdMZdaFF14of/nLX2TBggWye/dus81rr70maWlpZj9atGgh119/vdx7771mfwEAAAAAAODgUEpDH61C6tGjR2CZDt6nt1euXBnxPro8eHullVXh23/22WdSvXp1adq0qYwYMUIOHjwY8hjaZa99+/aBZfqY+tzffPNNYJuLL75Y4uPjQ55ny5YtcujQoSJ49QAAAAAAAO5Roq6+d+DAAcnMzJQaNWqELNfbmzdvjnifvXv3Rtxel1u0kqp///7SsGFD+emnn2T8+PHSp08fEzTFxMSYbTWwChYbGyuVK1cOPI7+1PuHP4+1LrjyypKammqm4C6AyufzmclJdH/9fr/j9hsFR1u7C+3tLrS3e9DW7kJ7u7O9xfyX9fs5v6NHJ45td/FF2Tl3fl9HiQqliot2tbPoQOjnnXeenH322aZ6qnv37sX2vNOmTZMpU6ZkW75//35JSUkRp32gjhw5Yg4SLj0b3Whrd6G93YX2dg/a2l1ob3e2d2paqnjEY8beTYxNPNO7hWLAse0uvig75z527JjzQqmqVauayqV9+/aFLNfbOg5UJLq8INurRo0amefaunWrCaV02/CB1DMyMswV+azHyel5rHWRjBs3zgzaHlwppVftq1atmrnKn9MOEL1qoe57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" - }, - "metadata": {}, - "output_type": "display_data", - "jetTransient": { - "display_id": null - } - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[指标分析]\n", - " 最佳验证 l1: 0.062058\n", - " 最佳迭代轮数: 301\n", - " 早停建议: 如果验证指标连续10轮不下降,建议在第 301 轮停止训练\n", - "\n", - "[重要提醒] 验证集仅用于早停/调参,测试集完全独立于训练过程!\n" - ] - } - ], - "execution_count": 13 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4 查看结果" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.4 查看结果" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:34.669584Z", - "start_time": "2026-03-11T13:28:34.650632Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"训练结果\")\n", @@ -1223,98 +760,18 @@ "sample_data = results.filter(results[\"trade_date\"] == sample_date).head(10)\n", "print(f\"\\n示例日期 {sample_date} 的前10条预测:\")\n", "print(sample_data.select([\"ts_code\", \"trade_date\", target_col, \"prediction\"]))" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "训练结果\n", - "================================================================================\n", - "\n", - "结果数据形状: (282000, 71)\n", - "结果列: ['ts_code', 'trade_date', 'low', 'open', 'turnover_rate', 'close', 'amount', 'vol', 'high', 'total_assets', 'total_mv', 'f_ann_date', 'n_income', 'revenue', 'total_cur_assets', 'total_liab', 'total_cur_liab', 'total_hldr_eqy_exc_min_int', 'n_cashflow_act', 'ebit', 'ma_5', 'ma_20', 'ma_ratio_5_20', 'bias_10', 'high_low_ratio', 'bbi_ratio', 'return_5', 'return_20', 'kaufman_ER_20', 'mom_acceleration_10_20', 'drawdown_from_high_60', 'up_days_ratio_20', 'volatility_5', 'volatility_20', 'volatility_ratio', 'std_return_20', 'sharpe_ratio_20', 'min_ret_20', 'volatility_squeeze_5_60', 'overnight_intraday_diff', 'upper_shadow_ratio', 'capital_retention_20', 'max_ret_20', 'volume_ratio_5_20', 'turnover_rate_mean_5', 'turnover_deviation', 'amihud_illiq_20', 'turnover_cv_20', 'pv_corr_20', 'close_vwap_deviation', 'roe', 'roa', 'profit_margin', 'debt_to_equity', 'current_ratio', 'net_profit_yoy', 'revenue_yoy', 'healthy_expansion_velocity', 'EP', 'BP', 'CP', 'market_cap_rank', 'turnover_rank', 'return_5_rank', 'EP_rank', 'pe_expansion_trend', 'value_price_divergence', 'active_market_cap', 'ebit_rank', 'future_return_5', 'prediction']\n", - "\n", - "结果前10行预览:\n", - "shape: (10, 71)\n", - "┌───────────┬────────────┬───────┬───────┬───┬──────────────┬───────────┬─────────────┬────────────┐\n", - "│ ts_code ┆ trade_date ┆ low ┆ open ┆ … ┆ active_marke ┆ ebit_rank ┆ future_retu ┆ prediction │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ t_cap ┆ --- ┆ rn_5 ┆ --- │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ --- ┆ f64 ┆ --- ┆ f64 │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ ┆ f64 ┆ │\n", - "╞═══════════╪════════════╪═══════╪═══════╪═══╪══════════════╪═══════════╪═════════════╪════════════╡\n", - "│ 000004.SZ ┆ 20250102 ┆ 54.17 ┆ 55.8 ┆ … ┆ 2.027703 ┆ null ┆ -0.066193 ┆ 0.015616 │\n", - "│ 000004.SZ ┆ 20250103 ┆ 51.86 ┆ 57.71 ┆ … ┆ 1.80063 ┆ null ┆ 0.00893 ┆ 0.03083 │\n", - "│ 000004.SZ ┆ 20250106 ┆ 49.17 ┆ 50.39 ┆ … ┆ 1.759968 ┆ null ┆ -0.0142 ┆ 0.044376 │\n", - "│ 000004.SZ ┆ 20250107 ┆ 51.41 ┆ 51.41 ┆ … ┆ 1.908269 ┆ null ┆ 0.013031 ┆ 0.014036 │\n", - "│ 000004.SZ ┆ 20250108 ┆ 52.38 ┆ 52.95 ┆ … ┆ 2.000828 ┆ null ┆ 0.00442 ┆ 0.006524 │\n", - "│ 000004.SZ ┆ 20250109 ┆ 53.69 ┆ 54.3 ┆ … ┆ 2.005907 ┆ null ┆ 0.024865 ┆ -0.002277 │\n", - "│ 000004.SZ ┆ 20250110 ┆ 50.8 ┆ 53.89 ┆ … ┆ 1.795423 ┆ null ┆ 0.073486 ┆ 0.007954 │\n", - "│ 000004.SZ ┆ 20250113 ┆ 48.24 ┆ 50.35 ┆ … ┆ 1.563935 ┆ null ┆ -0.04458 ┆ 0.005756 │\n", - "│ 000004.SZ ┆ 20250114 ┆ 50.92 ┆ 50.92 ┆ … ┆ 1.572468 ┆ null ┆ -0.156301 ┆ 0.000774 │\n", - "│ 000004.SZ ┆ 20250115 ┆ 53.97 ┆ 55.15 ┆ … ┆ 1.570886 ┆ null ┆ -0.203593 ┆ 0.000368 │\n", - "└───────────┴────────────┴───────┴───────┴───┴──────────────┴───────────┴─────────────┴────────────┘\n", - "\n", - "结果后5行预览:\n", - "shape: (5, 71)\n", - "┌───────────┬────────────┬───────┬───────┬───┬──────────────┬───────────┬─────────────┬────────────┐\n", - "│ ts_code ┆ trade_date ┆ low ┆ open ┆ … ┆ active_marke ┆ ebit_rank ┆ future_retu ┆ prediction │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ t_cap ┆ --- ┆ rn_5 ┆ --- │\n", - "│ str ┆ str ┆ f64 ┆ f64 ┆ ┆ --- ┆ f64 ┆ --- ┆ f64 │\n", - "│ ┆ ┆ ┆ ┆ ┆ f64 ┆ ┆ f64 ┆ │\n", - "╞═══════════╪════════════╪═══════╪═══════╪═══╪══════════════╪═══════════╪═════════════╪════════════╡\n", - "│ 605588.SH ┆ 20260305 ┆ 54.89 ┆ 55.01 ┆ … ┆ 0.108525 ┆ null ┆ null ┆ 0.006038 │\n", - "│ 605588.SH ┆ 20260306 ┆ 54.63 ┆ 55.23 ┆ … ┆ 0.082701 ┆ null ┆ null ┆ 0.005326 │\n", - "│ 605589.SH ┆ 20260303 ┆ 36.77 ┆ 39.02 ┆ … ┆ 4.992206 ┆ null ┆ null ┆ -0.000194 │\n", - "│ 605598.SH ┆ 20260303 ┆ 72.72 ┆ 77.17 ┆ … ┆ 3.20713 ┆ null ┆ null ┆ 0.010633 │\n", - "│ 605599.SH ┆ 20260303 ┆ 28.23 ┆ 30.23 ┆ … ┆ 4.008987 ┆ null ┆ null ┆ 0.005141 │\n", - "└───────────┴────────────┴───────┴───────┴───┴──────────────┴───────────┴─────────────┴────────────┘\n", - "\n", - "每日预测样本数统计:\n", - " 最小: 1000\n", - " 最大: 1000\n", - " 平均: 1000.00\n", - "\n", - "示例日期 20250102 的前10条预测:\n", - "shape: (10, 4)\n", - "┌───────────┬────────────┬─────────────────┬────────────┐\n", - "│ ts_code ┆ trade_date ┆ future_return_5 ┆ prediction │\n", - "│ --- ┆ --- ┆ --- ┆ --- │\n", - "│ str ┆ str ┆ f64 ┆ f64 │\n", - "╞═══════════╪════════════╪═════════════════╪════════════╡\n", - "│ 000004.SZ ┆ 20250102 ┆ -0.066193 ┆ 0.015616 │\n", - "│ 000007.SZ ┆ 20250102 ┆ 0.019858 ┆ -0.000471 │\n", - "│ 000010.SZ ┆ 20250102 ┆ 0.076274 ┆ 0.001351 │\n", - "│ 000014.SZ ┆ 20250102 ┆ -0.064651 ┆ 0.007245 │\n", - "│ 000020.SZ ┆ 20250102 ┆ -0.035224 ┆ 0.02038 │\n", - "│ 000040.SZ ┆ 20250102 ┆ -0.093583 ┆ -0.140064 │\n", - "│ 000042.SZ ┆ 20250102 ┆ -0.035958 ┆ 0.015733 │\n", - "│ 000056.SZ ┆ 20250102 ┆ -0.033205 ┆ 0.017907 │\n", - "│ 000068.SZ ┆ 20250102 ┆ -0.021277 ┆ 0.006877 │\n", - "│ 000153.SZ ┆ 20250102 ┆ -0.018193 ┆ 0.002956 │\n", - "└───────────┴────────────┴─────────────────┴────────────┘\n" - ] - } - ], - "execution_count": 14 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4 保存结果" ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:35.113238Z", - "start_time": "2026-03-11T13:28:34.675124Z" - } - }, + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.4 保存结果" + }, + { + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "print(\"\\n\" + \"=\" * 80)\n", "print(\"保存预测结果\")\n", @@ -1358,63 +815,23 @@ ")\n", "topn_to_save.write_csv(topn_output_path, include_header=True)\n", "print(f\" 保存路径: {topn_output_path}\")\n", - "print(f\" 保存行数: {len(topn_to_save)}({len(unique_dates)}个交易日 × 每日top{TOP_N})\")\n", + "print(\n", + " f\" 保存行数: {len(topn_to_save)}({len(unique_dates)}个交易日 × 每日top{TOP_N})\"\n", + ")\n", "print(f\"\\n 预览(前15行):\")\n", "print(topn_to_save.head(15))" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "================================================================================\n", - "保存预测结果\n", - "================================================================================\n", - "\n", - "[1/1] 保存每日 Top 5 股票...\n", - " 保存路径: output\\regression_output.csv\n", - " 保存行数: 1410(282个交易日 × 每日top5)\n", - "\n", - " 预览(前15行):\n", - "shape: (15, 3)\n", - "┌────────────┬──────────┬───────────┐\n", - "│ trade_date ┆ score ┆ ts_code │\n", - "│ --- ┆ --- ┆ --- │\n", - "│ str ┆ f64 ┆ str │\n", - "╞════════════╪══════════╪═══════════╡\n", - "│ 2025-01-02 ┆ 0.061083 ┆ 600421.SH │\n", - "│ 2025-01-02 ┆ 0.05972 ┆ 000668.SZ │\n", - "│ 2025-01-02 ┆ 0.046336 ┆ 002848.SZ │\n", - "│ 2025-01-02 ┆ 0.040149 ┆ 000586.SZ │\n", - "│ 2025-01-02 ┆ 0.038014 ┆ 603963.SH │\n", - "│ … ┆ … ┆ … │\n", - "│ 2025-01-06 ┆ 0.072982 ┆ 600421.SH │\n", - "│ 2025-01-06 ┆ 0.067706 ┆ 000668.SZ │\n", - "│ 2025-01-06 ┆ 0.067522 ┆ 603316.SH │\n", - "│ 2025-01-06 ┆ 0.062621 ┆ 002072.SZ │\n", - "│ 2025-01-06 ┆ 0.061637 ┆ 600847.SH │\n", - "└────────────┴──────────┴───────────┘\n" - ] - } - ], - "execution_count": 15 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.5 特征重要性" ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### 4.5 特征重要性" + }, + { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:35.122694Z", - "start_time": "2026-03-11T13:28:35.117401Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "importance = model.feature_importance()\n", "if importance is not None:\n", @@ -1424,92 +841,24 @@ "print(\"\\n\" + \"=\" * 80)\n", "print(\"训练完成!\")\n", "print(\"=\" * 80)" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "特征重要性:\n", - "bias_10 1379.975546\n", - "turnover_rank 1233.056754\n", - "return_5_rank 1211.083106\n", - "pe_expansion_trend 1194.518072\n", - "return_5 1067.753329\n", - "overnight_intraday_diff 864.510148\n", - "high_low_ratio 737.870126\n", - "amihud_illiq_20 699.716207\n", - "revenue_yoy 591.354167\n", - "min_ret_20 586.062664\n", - "drawdown_from_high_60 544.946004\n", - "roa 492.201997\n", - "close_vwap_deviation 456.329131\n", - "volatility_ratio 425.847030\n", - "active_market_cap 391.611939\n", - "healthy_expansion_velocity 381.013310\n", - "bbi_ratio 350.895088\n", - "ma_ratio_5_20 333.176295\n", - "turnover_deviation 320.594954\n", - "net_profit_yoy 312.797814\n", - "turnover_rate_mean_5 294.216230\n", - "return_20 292.148741\n", - "EP_rank 270.906632\n", - "turnover_cv_20 255.994465\n", - "ma_20 249.024118\n", - "mom_acceleration_10_20 245.051260\n", - "volume_ratio_5_20 236.906485\n", - "max_ret_20 233.119360\n", - "profit_margin 231.406188\n", - "EP 223.520549\n", - "ma_5 222.848019\n", - "std_return_20 211.703293\n", - "sharpe_ratio_20 200.874590\n", - "BP 182.380531\n", - "capital_retention_20 167.152835\n", - "roe 162.483161\n", - "volatility_squeeze_5_60 158.716820\n", - "volatility_20 152.922347\n", - "current_ratio 149.282750\n", - "debt_to_equity 142.640424\n", - "CP 133.383919\n", - "market_cap_rank 112.134213\n", - "volatility_5 104.388842\n", - "pv_corr_20 102.753917\n", - "kaufman_ER_20 79.014202\n", - "upper_shadow_ratio 58.782669\n", - "up_days_ratio_20 42.695102\n", - "value_price_divergence 0.000000\n", - "ebit_rank 0.000000\n", - "dtype: float64\n", - "\n", - "================================================================================\n", - "训练完成!\n", - "================================================================================\n" - ] - } - ], - "execution_count": 16 + ] }, { - "cell_type": "markdown", "metadata": {}, + "cell_type": "markdown", "source": [ "## 5. 可视化分析\n", - "\n", + "#\n", "使用训练好的模型直接绘图。\n", "- **特征重要性图**:辅助特征选择\n", "- **决策树图**:理解决策逻辑" ] }, { + "metadata": {}, "cell_type": "code", - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:35.137085Z", - "start_time": "2026-03-11T13:28:35.126226Z" - } - }, + "outputs": [], + "execution_count": null, "source": [ "# 导入可视化库\n", "import matplotlib.pyplot as plt\n", @@ -1520,25 +869,14 @@ "booster = model.model\n", "print(f\"模型类型: {type(booster)}\")\n", "print(f\"特征数量: {len(feature_cols)}\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "模型类型: \n", - "特征数量: 49\n" - ] - } - ], - "execution_count": 17 + ] }, { - "cell_type": "markdown", "metadata": {}, + "cell_type": "markdown", "source": [ "### 5.1 绘制特征重要性(辅助特征选择)\n", - "\n", + "#\n", "**解读**:\n", "- 重要性高的特征对模型贡献大\n", "- 重要性为0的特征可以考虑删除\n", @@ -1546,13 +884,10 @@ ] }, { - "metadata": { - "ExecuteTime": { - "end_time": "2026-03-11T13:28:35.308547Z", - "start_time": "2026-03-11T13:28:35.141844Z" - } - }, + "metadata": {}, "cell_type": "code", + "outputs": [], + "execution_count": null, "source": [ "print(\"绘制特征重要性...\")\n", "\n", @@ -1560,18 +895,17 @@ "lgb.plot_importance(\n", " booster,\n", " max_num_features=20,\n", - " importance_type='gain',\n", - " title='Feature Importance (Gain)',\n", - " ax=ax\n", + " importance_type=\"gain\",\n", + " title=\"Feature Importance (Gain)\",\n", + " ax=ax,\n", ")\n", - "ax.set_xlabel('Importance (Gain)')\n", + "ax.set_xlabel(\"Importance (Gain)\")\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "# 打印重要性排名\n", "importance_gain = pd.Series(\n", - " booster.feature_importance(importance_type='gain'),\n", - " index=feature_cols\n", + " booster.feature_importance(importance_type=\"gain\"), index=feature_cols\n", ").sort_values(ascending=False)\n", "\n", "print(\"\\n[特征重要性排名 - Gain]\")\n", @@ -1584,93 +918,8 @@ " for feat in zero_importance:\n", " print(f\" - {feat}\")\n", "else:\n", - " print(\"\\n所有特征都有一定重要性\")" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "绘制特征重要性...\n" - ] - }, - { - "data": { - "text/plain": [ - "
" - ], - "image/png": "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HjuVoFvl454SJUq4/zWnPPi+nTt3+oNulagE/uGVKlXKPX4if/31l8ukP/fcc65sJZxrr73W/7WORceo11P2u2XLlim2HzdunPtjDjasbpLlyXP8hMeFzG10/ZSLgiD20I6xjzaMD7RjfKAdY89HH32U7HtVrnpzoEOVXXvTSJWw+v3331M8/thjj7nAWkG3pnsqs60+s15HixVremhwFa2y5M2aNbM77rgjomP+559/3P/anxfUezZs2OBeP/jnUnm6NG3a1J95V9WsAvHJkye7KtZ44rVjVnYowikIGRp0V65c2Y34pPdiafoDDA7oQ41CBP6ReyNPoe4LXA0x+INB20QyeKCstRZ+0OqKHm+/2bNnt/Xr16cYRRPN+1aQrqqAUEG3yl80/92jDwANUIxZlmDHcqTMjCN2RvPVqRi+JMEOJ8XHqGhWRDvGPtowPtCO8YF2jF2rRrb298cVqF166aX+OdChFlXzFlLTSuYnuiywysE1d1qZbQW1mo/tVX6Kgl9NI3311VetYcOGdtZZZ0V0zN988437X333wESdKKhX8i/42JUk07EH3u8F3wr6VUEbDwLbMavPVd8f8LuWaYPuIkWKuLKNp59+2l33LnhEau/evW7Bsq1bt7qbl+1es2aNe0wZ71BUDhK4uJlKQFatWmXNmze3jKIyFZXJBxo2bJjLgOuyCYGZ/ECaB6I53cqoh6L5IqFWN1egdoxVr2Oe2pHVy2Mf7Rj7aMP4QDvGB9ox9niBmcqttTbT6tWr3ffq3+trxQRnn322W8NJ6yV52W1tq+d6iwuLFilTfKD+vqZfKnM9aNAgF2xLcBLLW5BYAbmmb8pvv/3mklmasqpAXMkxBeUKlnWNcK1Mrn0qY62BAY+SYPoZtPCyMuHez6GY5IwzznABuvr1qkS97rrrXD9fU0W1YLOqc+MtQNXPE28/U1pF/PP7MtjPP//sK1mypK969eq+t99+2/fTTz/51qxZ43v88cd9VatW9SUlJfnq1Knju/jii30//PCDb9GiRb569er5mjVr5t/HAw884DvvvPP830+dOtWXJ08e3wcffOBbu3at7+abb/YVKFDA17NnT/825cqV802aNCnZsejtePfdd/3fb9q0yd23bNky9/20adN8BQsWTPYcbX+yb6OOp0OHDv7v//rrL9/gwYN93377rXvtzz77zHf++ef7Kleu7Pvnn38i2ue+ffvc8ezevfukjgmZw5EjR3zvvfee+x+xi3aMfbRhfKAd4wPtGPvmzp3r+qnBN6+Prr52qMfV1/cMGTLEV6JECV+OHDlcH/nRRx918UI4wf35wPu++OIL9/2WLVt8TZs29RUpUsSXM2dOX6VKlXx3332361cHUvwR6vi0P89rr73mq1u3ri9v3ry+YsWK+dq3b+/ikXjC32LK2Cv4dyVYhl+nW+XTWil87Nixdtddd7kMtUauNKqkhc1Uvj1r1iy3YIJGm1Q6rsXGnnzyybD71EXrV6xY4eZQqHRbI1UZmeWOlBZK08iarjeoTH7p0qXtsssus9GjR5/UtboBAACAzEJzqt977z2XUQ6VIdTc7MBL/IYyfvx4d4uULhMcPBU0+D5VnOoqSSei8vET0fpMgWs0AZJNkTdvRXzNKyhYsKDt3r3blccgdufKaHGOcCclxAbaMfbRhvGBdowPtGPsow3jA+2YMvbSugIFChSwTHmdbgAAAAAA4hlBdzrSJQvC3RYuXJieLwUAAAAAiAEZPqc7nixfvjzsY2XKlDmtxwIAAAAAyHgE3emoUqVK6bk7AAAAAECMo7wcAAAAAIAoIegGAAAAACBKCLoBAAAAAIgSgm4AAAAAAKKEoBsAAAAAgCgh6AYAAAAAIEoIugEAAAAAiBKCbgAAAAAAooSgGwAAAACAKCHoBgAAAAAgSgi6AQAAAACIEoJuAAAAAACihKAbAAAAAIAoIegGAAAAACBKCLoBAAAAAIgSgm4AAAAAAKKEoBsAAAAAgCgh6AYAAADSwZdffmnt2rWz0qVLW7Zs2ey9995L9rjP57MRI0ZYqVKlLHfu3NaqVSvbsGFDiv18+OGHdsEFF7htChcubB07dvQ/Nn36dLfvULedO3eGPK758+eHfc7ixYvdNps3bw75+HfffeffzzvvvGP169e3QoUKWd68ea1OnTo2Y8YMfneAE8gSQffIkSPdhwIAAAAQLQcPHrTzzjvPnn766ZCPT5gwwZ544gmbOnWqLVq0yAWurVu3tn/++ce/zcyZM6179+52ww032IoVK+zrr7+266+/3v94ly5dbNu2bclu2kezZs2sePHiIV/3oosuSvGcm266yc455xwXRAf67LPPkm1Xr149/2NFihSx+++/37799lv78ccf3THqNmfOnHR494D4ld1iwPbt223s2LFu1O+3335zHygKogcOHGgtW7a0eLJ37173YaaRxD179li5cuVs8uTJdsUVV2T0oQEAACAVl19+ubuFoiy3+nTDhg2zDh06uPteeuklK1GihMuIX3vttXbs2DG74447bOLEiXbjjTf6n1u9enX/18p+6+bZtWuXff755/bCCy+EPa4zzjjDSpYs6f/+6NGjNmvWLOvfv7/LZgcqWrRosm0DXXLJJcm+17G++OKL9tVXX7nAH0CMBt0qdWncuLErY9EHUK1atdwHhUbU+vbta+vWrbN4ceTIEbv00kvdoMLbb79tZcqUsf/+97/uZ0+rC8bNs2PZ80blOBF9ORN9NqGhWc2Rc+zw8eQnQ8QO2jH20YbxgXaMD5m5HTePb3vCbTZt2uQSSSop9xQsWNCVkStzrKB76dKlLsGUkJBgdevWddsr0aQ+cM2aNUPuV4F7njx57Jprron4eGfPnm1//PGHy1IHa9++vcu8V6lSxe655x73fbhBBAX769evt4cffjji1wayokxfXn777be7Ebjvv//err76avcBUKNGDbvzzjv9c0y2bNniRgzz5ctnBQoUsM6dO9uOHTvC7lOjdMqSB9JcmV69evm/L1++vI0ZM8Z69Ojh9quMsz6gNJrovVbt2rVtyZIlyebYKEDWgEC1atXcNm3atHGlOZH4z3/+47LbGu3UQIOOQaVCKlMCAABA7FIALcpsB9L33mO//PKLf2qkMuIffPCBm9Otvqv6iKEow63y88Ds94noOcpMn3XWWf771G999NFH7a233nLVpU2aNHH9Y/V/A+3bt89tq+x527Zt7cknn3RJIwAxmunWh8snn3ziSss15yWYAtykpCR/ELxgwQJXlqMMuOa7aNGIUzFp0iR76KGHbPjw4e5rza/RnJjevXu7EcchQ4a4oHz16tX+0pxDhw7ZI4884haV0Chlt27dbPDgwfbKK6+c8PX0odaoUSN3/Cr5KVasmPsQ1eskJiaGfM7hw4fdzbN//373f84EnyUm+k7p50fGUfsF/o/YRDvGPtowPtCO8SEzt6OqMENRv9R7TF972wZur76s+pG6T1WPcu+99/ozzM8++6ybe/3666/bzTffnGz/SkCtXbvWpk2bFvYYgv36668uQfTqq68me46y7io39yjDrm01Dz2wZD5Xrlxu8bUDBw7YF198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AAAAiBKCbgAAAAAAooSgGwAAAACAKCHoBgAAAAAgSgi6AQAAAACIEoJuAAAAAACihKAbAAAAAIAoIegGAAAAACBKCLoBAAAAAIgSgm4AAAAAAKKEoBsAAAAAgCgh6AYAAAAAIEoIugEAAAAAiBKCbgAAAAAAooSgGwAAAACAKIn5oHvkyJFWp06djD4MAABi3m+//WbdunWzokWLWu7cua1WrVq2ZMkS/+M7duywXr16WenSpS1PnjzWpk0b27BhQ7J9/Pzzz3bllVdasWLFrECBAta5c2f3vNSUL1/esmXLluLWt29f/zbPPvusXXLJJW6femzv3r0h9/Xhhx/aBRdc4I6/cOHC1rFjx1N+XwAAiOmge/v27da/f3+rUKGC5cyZ08qWLWvt2rWzefPmWTx57rnn7OKLL3YdAN1atWpl33//fYrt1q5da+3bt7eCBQta3rx5rUGDBrZly5YMOWYAQNbx559/WuPGjS1Hjhz28ccf25o1a+zRRx915yzx+XwugP3ll19s1qxZtmzZMitXrpw7nx08eNBto/8vu+wyFxR//vnn9vXXX9uRI0fceT0pKSnsay9evNi2bdvmv82dO9fd36lTJ/82hw4dckH+fffdF3Y/M2fOtO7du9sNN9xgK1ascK9//fXXp+O7BABA2mW3DLR582Z3gi9UqJBNnDjRjagfPXrU5syZ40a3161bZ/Fi/vz5dt1119lFF11kuXLlsocffth1TFavXm1lypTxZweaNGliN954oz344INuNF+Pa/u0umDcPDuWPW8UfhKcDjkTfTahoVnNkXPs8PFsvOkxinaMfVmlDTePb+vOSxr4njZtmv/+c845x/+1MtrfffedrVq1ymrUqOHumzJlipUsWdJee+01u+mmm1yQq3O7AnKdw+TFF190gbuCcAXooSgrHmj8+PFWsWJFa9asmf++gQMH+s+noRw7dszuuOMO15/QedRTvXp117cAACBLZrpvv/12NxqujO/VV19tVapUcSfyO++8053YRVneDh06WL58+SIqU1PpmXdi9mhkXuVwgWVsY8aMsR49erj9aqR+9uzZtmvXLv9r1a5dO1lJ3fTp093ggAYEqlWr5rbRiLtG5CPxyiuvuJ9XpfBVq1a1559/3o36B2b077//frviiitswoQJVrduXdfhUNa7ePHiaXpfAQBIK50H69ev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l8/S/1oxPKvRomjhhLqGKgAAAAAg/p1U0L1p06b0P5IYF7gCOQAAAAAAJx10s4AaAAAAAABRCrpfeumlVB/X5boAAAAAAMjqTirovuOOO1IsG6/rdZ9xxhnucmIE3QAAAAAAnOQlw/78889ktwMHDtj69eutSZMm9tprr/G+AgAAAABwskF3KJUrV7bx48enyIIDAAAAAJBVpVvQLdmzZ7fff/89PXcJAAAAAEDWmtM9e/bsZN/r+tzbtm2zp556yho3bpxexwYAAAAAQNYLujt27Jjs+2zZslmxYsWsRYsW9uijj6bXsQEAAAAAkPWC7qSkpPQ/EgAAAAAA4sxJzekeNWqUu0RYsL///ts9BgAAAAAATjLofvDBB91lwoIpENdjAAAAAADgJINuLZymedzBVqxYYUWKFOF9BQAAAAAgrXO6Cxcu7IJt3apUqZIs8D5+/LjLft966628sQAAAAAApDXonjx5ssty9+7d25WRFyxY0P/YGWecYeXLl7dGjRrxxgIAAAAAkNagu2fPnu7/c845xy666CLLkSMHbyIAAAAAAOl5ybBmzZr5v/7nn3/syJEjyR4vUKDAyewWAAAAAIC4clILqWmV8n79+lnx4sUtb968bq534A0AAAAAAJxk0H333Xfb559/blOmTLGcOXPa888/7+Z4ly5d2l566SXeVwBAVIwcOdK/oKd3q1q1aorttP7I5Zdf7h5/7733Qu7rjz/+sLPOOstts3fv3lRfd9myZXbppZdaoUKFrGjRonbLLbeEvHTmifZ7+PBhu//++61cuXLu/Km1UP7zn/+k6T0AAABZIOh+//337ZlnnrGrr77asmfPbhdffLENGzbMHnroIXvllVfsdHfA6tSpc1pfEwCQcWrUqGHbtm3z37766quQC3+GurRloBtvvNFq1659wtfbs2ePtWnTxipVqmSLFi2yTz75xFavXm29evVK8347d+5s8+bNsxdeeMHWr19vr732mp177rknPAYAAJDFgm51QCpUqOCfv63vpUmTJvbll1+maV/bt2+3/v37u/1p1L9s2bLWrl071ymJJ+qgaZBCWQ11BNUhDOXpp5922+TKlcsuuOAC+/7770/7sQJAZqbB3pIlS/pvZ555ZrLHly9fbo8++miqGWRVaikLPXjw4BO+3uLFi93Cofp8VoDcoEEDmzp1qs2cOdM2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4BT7KViwYLLXXLJkif355592ww03pMv7AgAAEAuyZ+SLb9682Ro3buw6gxMnTrRatWrZ0aNHbc6cOda3b19bt26dxQt1VjWwoAzPoEGD0pzRSqsLxs2zY9nznvTzkbFyJvpsQkOzmiPn2OHj2WiOLNiOm8e39X+tz8O2bdtaq1atbMyYMak+T6XlKgfPnj35x7v2cdNNN7nPoVtvvdUFvhrYC6Vo0aKuZP2ll16y888/3w2I6jOpePHiVq9ePf92a9assVGjRtmiRYvsl19+OeHP9MILL7ifoVy5chG8AwAAAPEhQzPdt99+u+v0ff/99y4LXKVKFTfX784777TvvvvObbNlyxY3rzBfvnyuI9m5c2fbsWNH2H1ecsklKbLDKqPU3EKPss3quPbo0cPtVx3A2bNn265du/yvpYBXWRmPyjY1OKABgWrVqrlt2rRp40omI9GgQQM3sHDttde6DmxaM1oAsibNvV66dKmNGzfuhNsqQz169Gi75ZZbkt2vwPjNN9+0uXPnus9affY++eSTYfejz+XPPvvMli1bZvnz53dZ8ccee8yVrnufS4cPH7brrrvOfa5pLvmJqAz+448/doE/AABAVpJhmW4tAKQOnEoh8+ZNmZFVgJuUlOQPghcsWODKJZWt6dKli82fP/+UXn/SpEn20EMP2fDhw93X3bt3t4suush69+7tOpFDhgxxQbnKwr1skLLVmjs5Y8YMS0hIsG7durmSyldeecXSS1oyWl7HVzfP/v373f85E3yWmOhLt+PC6aX2C/wfWa8dVfWjOdB33HGHffTRR5aYmOju8/l87rNRXwfS3/4VV1zhBgXvv//+ZI+rTDywJF3b6nPutttuC/naeg09VqxYMbd4mhZp+89//uPK2L/55hsrVaqU+4xUNlyfx3otr5xdXwcfm+j5+lzX51uoxzMr71hj6ZiREu0YH2jH2Ecbxgfa8X8i7R9kWNC9ceNG17GrWrVq2G00r3vlypW2adMmN9dbVO6obLhKsJU9PlnqnPbp08d9PWLECDcvUfvzFvhRh7JRo0Yuq665iN6bOnXqVDd3Uvr16+cySOmd0dLPFillvx588MEU9w+rm2R58hxPt2NDxhhdP4m3Pou2owJtVfzs3LnTGjZs6L9fAffChQvt6aeftrfeessF43///bdbVFJVNFrUTBnt1GjQ8Ndff7VZ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AAAAABAhp0TQPXjwYDv77LOjvRsAYsT48eOtbt26VrBgQfdo3LixzZgxw7/8wgsvtGzZsgU97rjjjqBtbNy40dq1a2d58+a1EiVKWN++fS0lJSXDz/3uu++sQ4cOdtppp7nPPf/8823evHlB68yZM8fOO+88K1CggJUqVcr69esXtN0NGzak2Tc9Fi1alGXfDwAAAE6xoHvbtm3Ws2dPq1y5suXKlcvKlStn7du3dxeniWTChAlpLqRz584d7d0CEk7ZsmVt+PDh9tVXX9nSpUutefPmLhj+5ptv/OvceuuttnXrVv9jxIgR/mVHjx51Affhw4ftiy++sIkTJ7rj96GHHsrwcy+99FIXQM+dO9d99llnneVe0zlOVq5caZdccom1adPGli9fbm+++aa9//779sADD6TZ1ieffBK0f/Xr18/S7wgAAABZI7vFOGV1mjRpYoULF7aRI0danTp17MiRIzZr1izr0aOHffvtt5ZIlP1at26d/7kC7xNx7rA5lpI9XxbuGU6mXMk+G9HIrPbgWXbo6In9P4DwNgxv5zrtAj322GMu+61sca1atdxrymAr0xzOxx9/bGvWrHGBb8mSJV0lzZAhQ1xWWpU1OXPmTPOenTt32vfff28vvfSSy7KLAv9x48bZ6tWr3WcpyNYyL3g/44wzXLB/zTXX2MMPP+yy355ixYqlu38AAACIHTGf6e7evbsLPBcvXmxXXnmlnXnmme6iuHfv3v5ySpV5KkuVP39+F7TqAnX79u3pblOlo7169Qp6rWPHjnbTTTf5n1esWNGGDh1qN954o9tuhQoVXMbpl19+8X+WLo6VJfMo06XOAXUI1KhRw62jjJWyUJml31UX0t5DF/QAIkdZ6ylTptiBAwdcmbln0qRJrgy8du3a1r9/fzt48KB/2cKFC10HYODx2bp1a9u7d29QtjyQguRq1arZq6++6j5LGe/nn3/elaZ7WepDhw6lqW7JkyeP/fHHHy4zHuiyyy5z71WJus5NAAAAiE0xHXTv3r3bZs6c6TLa+fKlzdoqwE1NTXVBsNadP3++zZ4923788Ue79tpr//bnjx492mXZVeapUtIuXbq4IPyGG26wZcuWWZUqVdxzn8/nf48uzJ988kl77bXX7LPPPnMdAvfdd1+mP3P//v0uwFcJfWi5K4Css2rVKtcxpiErGq89bdo0q1mz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PwAAADj5Tomge/DgwXb22WdHezcARFjZsmVt+PDh9tVXX9nSpUutefPmLrD+5ptv3PL69evbK6+8YmvXrrVZs2aZz+ezVq1a2dGjR93ypKQkt/77779v3333nU2YMME++eQTu+OOOzL83MOHD9vVV19td955Z9jlWrZ169agR+vWra1Zs2ZWokQJ/3rXXHONzZkzx1566SVbt26dvfHGG1atWrUs/Y4AAABwcmW3OLBt2zaXSfroo49sy5Yt7iJVQXSvXr2sRYsWliheeOEFlxFbvXq1P0B4/PHHrVGjRtHeNSAutG/fPui5zhvKfi9atMhq1aplt912m3+ZsshDhw61s846yzZs2OAy4EWKFAkKnJVx7t69u40cOTLDz33kkUfcTwXp4Sizrsy755dffrG5c+e64Nozc+ZMmz9/vv34449WtGhR/z4CAAAgvsV80K2L4SZNmriSTV341qlTx44cOeKyVD169AgqDY13n376qXXq1MmVqebOndueeOIJl4VTlq5MmTLHta1zh82xlOz5IraviKxcyT4b0cis9uBZduhoNr7uTNgwvF3Qc2Wv3377bTtw4IArMw+l15X1rlSpkisjD+fnn3+2qVOnuox0VlLnmkrRr7rqKv9ryq43aNDARowYYa+99prly5fPLrvsMhsyZIgL2gEAABCfYr68XFkmjXtcvHixXXnllXbmmWe6jFXv3r1d9ko2btzoSkLz58/vskkq0dy+fXu627zwwgtdljxQx44d7aabbkqTBbvxxhvddpXx0kWxMlTeZ2nsqEpYPcpyqXNAHQI1atRw62h8qEpJM2PSpEnu91UWv3r16vbiiy9aamqqKzcFkDmrVq1yx57GRKssfNq0aVazZk3/8nHjxrnlemi89+zZsy1nzpxB21Dnl4JidXbpnKJjMSspw3399dcHBdPKcH/++eeu0kX7PGbMGHvnnXfcOQEAAADxK6Yz3bt373YllyoRVdYnlAJcBaVeEKzSzJSUFJcBv/baa13m+O8YPXq0K+8eNGiQ+3eXLl1cFrpbt24u696vXz8XlCsTrY4BOXjwoD355JMuU6XxoTfccIPdd999LqA+XtqWsvpeqWk4mnhJD4834VOuJJ8lJ/tO6PdG9Kn9An/i2HSsSOXKlW3JkiXuWHj33Xeta9eubly2F3irU04dbxq2MmrUKDfeWucOVZd4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UcP9TtWrV7dx48Zl+P1Nnz7d/X76/T2LFi2yESNGuEyzHvqM8uXLW/369W3gwIFB36U+W1lyfe/58+e3hg0b2ieffJJheXlmfk99V7t377b58+dnuP8AgPhH0A0AQIybOHGiC2YXL17sAvA777zTrr76ajvvvPNcYNuqVSvr0qWLy+oG6tu3rwukFRArG9u+fXs7cuSIW/bVV1/ZNddcY9ddd52tWrXKBg8ebIMGDbIJEyYEbePJJ5+0s846y5Vca7n2QRR4bt261aZOneqe79u3z7p27Wqff/65C2oVaF5yySXu9UCPPPKI+9yvv/7aLe/cubMLPmXLli3WtGlTFyTPnTvX7aPKvb1s8KRJk+yhhx5y5eJr1661xx9/3O2Tvp/0LFiwwAXTgd544w0XQHfv3j3sexQ0e/bv3+/2c86cOe47aNOmjfseN27cmGGbZfR7Ss6cOV2WXfsHAEhwPgAAEDO6du3q69Chg/95s2bNfOeff77/eUpKii9fvny+Ll26+F/bunWrT3/SFy5c6J7PmzfPPZ8yZYp/nV27dvny5Mnje/PNN93z66+/3teyZcugz+7bt6+vZs2a/ucVKlTwdezYMWid9evXu20vX748w9/j6NGjvgIFCvg++OAD/2t638CBA/3P9+/f716bMWOGe96/f39fpUqVfIcPHw67zSpVqvgmT54c9NqQIUN8jRs3Tnc/9F1269Yt6LU2bdr46tatG/TaU0895b5X77Fnz550t1mrVi3f2LFjg76n0aNHZ/r39Fx++eW+m266Kd3PAQAkBjLdAADEOJWIe5KTk61YsWJWp04d/2sqfZYdO3YEva9x48b+fxctWtRNFKYMsehnkyZNgtbX8++//96OHj3qf61BgwaZ2sft27fbrbfe6jLcKi9XebiyxKEZ4cDfJV++fG49b781OZtKvXPkyJFm+yqnV6m3xmYrS+09hg4dGlR+Hur33393pejHooy6Pv/55593n/Vn7Pxnpvu+++5zJe2FCxd2n6nv7liZ7ox+T48mbwutTgAAJJ7s0d4BAACQsdAgVOXPga955dCpqalZ/lUqYMwMlZbr1lxPP/20VahQwZWIK+gPnXwt3O/i7beC0PQo+BWNZz/33HODlqkjIj0qy//111+DXlPHgMrgVWrv7Y8Caj02b94ctK4C7tmzZ7sye42d1z5eddVVx5xULqPf06Ny8ypVqmS4HQBA/CPTDQBAgtLYao8Cz++++85lbEU///vf/watr+dnnnlmhkGsxiJLYDbce+/dd9/txi97k7Pt3LnzuPZX2WGNcfbGnQdSNr906dL2448/uuA38OFN7haOJnzTfbEDderUyQXxx5qEzfu9dBs3TYqm6oJSpUpl2f2+NbGd9g8AkNjIdAMAkKAeffRRV4qugHXAgAEu6+vdA7xPnz5uJm7NTq5bZy1cuNCeeeaZYwaiJUqUcNnemTNnWtmyZV3ptsrJlT1+7bXXXDn63r173SRuGWWuw7nrrrts7NixbnI33bZL21XHQaNGjVxpvCYnU2Cv1zWh2aFDh2zp0qWuQ6F3795ht9m6dWu3La2j2d9FGXj9/nr89NNPdsUVV1i5cuXcxHC6vZiy0klJf+Yl9HtpsjhNnqbXNXFbVlQUKHDXxHEXX3zx394WACC2kekGACBBDR8+3O655x43e/e2bdvsgw8+8GeqzznnHHvrrbdsypQpVrt2bTcruIJ0ZXUzkj17dvvXv/7lxj4r86zbaYmCVQW22q5mUldwrAD9eKiDQLOWKwutW45pv1VO7pVq//Of/3S34nrllVdc1lnraLb1jDLdWs/7XQOpXFz35daM5LpFmYJrzQivgFodEBqDLbqlmIJ1zRSvwFtBvLb3d2kGdc06r1J8AEBiy6bZ1KK9EwAAIOvoPt0XXXSRC4I1TvlUp/uVK/Oucm4vgx1NGg+uIF9Bf+hkdgCAxEN5OQAASGjt2rVzs7KrnFtl5NGmmc8ffPBBAm4AOEWQ6QYAIMGQ6QYAIHYQdAMAAAAAECHRH9gEAAAAAECCIugGAAAAACBCCLoBAAAAAIgQgm4AAAAAACKEoBsAAAAAgAgh6AYAAAAAIEIIugEAAAAAiBCCbgAAAAAAIoSgGwAAAAAAi4z/A5osy5Y7O3HhAAAAAElFTkSuQmCC" - }, - "metadata": {}, - "output_type": "display_data", - "jetTransient": { - "display_id": null - } - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[特征重要性排名 - Gain]\n", - "bias_10 1379.975546\n", - "turnover_rank 1233.056754\n", - "return_5_rank 1211.083106\n", - "pe_expansion_trend 1194.518072\n", - "return_5 1067.753329\n", - "overnight_intraday_diff 864.510148\n", - "high_low_ratio 737.870126\n", - "amihud_illiq_20 699.716207\n", - "revenue_yoy 591.354167\n", - "min_ret_20 586.062664\n", - "drawdown_from_high_60 544.946004\n", - "roa 492.201997\n", - "close_vwap_deviation 456.329131\n", - "volatility_ratio 425.847030\n", - "active_market_cap 391.611939\n", - "healthy_expansion_velocity 381.013310\n", - "bbi_ratio 350.895088\n", - "ma_ratio_5_20 333.176295\n", - "turnover_deviation 320.594954\n", - "net_profit_yoy 312.797814\n", - "turnover_rate_mean_5 294.216230\n", - "return_20 292.148741\n", - "EP_rank 270.906632\n", - "turnover_cv_20 255.994465\n", - "ma_20 249.024118\n", - "mom_acceleration_10_20 245.051260\n", - "volume_ratio_5_20 236.906485\n", - "max_ret_20 233.119360\n", - "profit_margin 231.406188\n", - "EP 223.520549\n", - "ma_5 222.848019\n", - "std_return_20 211.703293\n", - "sharpe_ratio_20 200.874590\n", - "BP 182.380531\n", - "capital_retention_20 167.152835\n", - "roe 162.483161\n", - "volatility_squeeze_5_60 158.716820\n", - "volatility_20 152.922347\n", - "current_ratio 149.282750\n", - "debt_to_equity 142.640424\n", - "CP 133.383919\n", - "market_cap_rank 112.134213\n", - "volatility_5 104.388842\n", - "pv_corr_20 102.753917\n", - "kaufman_ER_20 79.014202\n", - "upper_shadow_ratio 58.782669\n", - "up_days_ratio_20 42.695102\n", - "value_price_divergence 0.000000\n", - "ebit_rank 0.000000\n", - "dtype: float64\n", - "\n", - "[低重要性特征] 以下2个特征重要性为0,可考虑删除:\n", - " - value_price_divergence\n", - " - ebit_rank\n" - ] - } - ], - "execution_count": 18 + " print(\"\\n所有特征都有一定重要性\")\n" + ] } ], "metadata": { diff --git a/src/experiment/regression.py b/src/experiment/regression.py new file mode 100644 index 0000000..57c054c --- /dev/null +++ b/src/experiment/regression.py @@ -0,0 +1,751 @@ +# %% md +# ## 1. 导入依赖 +# %% +import os +from datetime import datetime +from typing import List + +import polars as pl + +from src.factors import FactorEngine +from src.training import ( + DateSplitter, + LightGBMModel, + STFilter, + StandardScaler, + # StockFilterConfig, # 已删除,使用 StockPoolManager + filter_func 替代 + StockPoolManager, + Trainer, + Winsorizer, + NullFiller, +) +from src.training.config import TrainingConfig + + +# %% md +# ## 2. 定义辅助函数 +# %% +def create_factors_with_metadata( + engine: FactorEngine, factor_definitions: dict, label_factor: dict +) -> List[str]: + """使用 metadata 注册因子(特征因子通过名称注册,label 因子通过表达式注册)""" + print("=" * 80) + print("使用 metadata 注册因子") + print("=" * 80) + + # 注册所有特征因子(通过 metadata 名称) + print("\n注册特征因子(从 metadata):") + for name in factor_definitions.keys(): + engine.add_factor_by_name(name) + print(f" - {name}") + + # 注册 label 因子(通过表达式,因为 label 不在 metadata 中) + print("\n注册 Label 因子(表达式):") + for name, expr in label_factor.items(): + engine.add_factor(name, expr) + print(f" - {name}: {expr}") + + # 从字典自动获取特征列 + feature_cols = list(factor_definitions.keys()) + + print(f"\n特征因子数: {len(feature_cols)}") + print(f"Label: {list(label_factor.keys())[0]}") + print(f"已注册因子总数: {len(engine.list_registered())}") + + return feature_cols + + +def prepare_data( + engine: FactorEngine, + feature_cols: List[str], + start_date: str, + end_date: str, +) -> pl.DataFrame: + print("\n" + "=" * 80) + print("准备数据") + print("=" * 80) + + # 计算因子(全市场数据) + print(f"\n计算因子: {start_date} - {end_date}") + factor_names = feature_cols + [LABEL_NAME] # 包含 label + + data = engine.compute( + factor_names=factor_names, + start_date=start_date, + end_date=end_date, + ) + + print(f"数据形状: {data.shape}") + print(f"数据列: {data.columns}") + print(f"\n前5行预览:") + print(data.head()) + + return data + + +# %% md +# ## 3. 配置参数 +# +# ### 3.1 因子定义 +# %% +# 特征因子定义字典:新增因子只需在此处添加一行 +LABEL_NAME = "future_return_5" + +FACTOR_DEFINITIONS = FACTOR_DICT = { + # ================= 1. 价格、趋势与路径依赖 (Trend, Momentum & Path Dependency) ================= + "ma_5": "ts_mean(close, 5)", + "ma_20": "ts_mean(close, 20)", + "ma_ratio_5_20": "ts_mean(close, 5) / (ts_mean(close, 20) + 1e-8) - 1", # 均线发散度 + "bias_10": "close / (ts_mean(close, 10) + 1e-8) - 1", # 10日乖离率 + "high_low_ratio": "(close - ts_min(low, 20)) / (ts_max(high, 20) - ts_min(low, 20) + 1e-8)", # 威廉指标变形 + "bbi_ratio": "(ts_mean(close, 3) + ts_mean(close, 6) + ts_mean(close, 12) + ts_mean(close, 24)) / (4 * close + 1e-8)", # 多空指标比率 + "return_5": "(close / (ts_delay(close, 5) + 1e-8)) - 1", # 5日动量 + "return_20": "(close / (ts_delay(close, 20) + 1e-8)) - 1", # 20日动量 + # [高阶] Kaufman 趋势效率 (极高价值) - 衡量趋势流畅度,剔除无序震荡 + "kaufman_ER_20": "abs(close - ts_delay(close, 20)) / (ts_sum(abs(close - ts_delay(close, 1)), 20) + 1e-8)", + # [高阶] 动量加速度 - 寻找二阶导数大于0,正在加速爆发的股票 + "mom_acceleration_10_20": "(close / (ts_delay(close, 10) + 1e-8) - 1) - (ts_delay(close, 10) / (ts_delay(close, 20) + 1e-8) - 1)", + # [高阶] 高点距离衰减 - 衡量套牢盘压力 + "drawdown_from_high_60": "close / (ts_max(high, 60) + 1e-8) - 1", + # [高阶] 趋势一致性 - 过去20天内收红的天数比例 + "up_days_ratio_20": "ts_sum(close > ts_delay(close, 1), 20) / 20", + # ================= 2. 波动率、风险调整与高阶矩 (Volatility & Risk-Adjusted Returns) ================= + "volatility_5": "ts_std(close, 5)", + "volatility_20": "ts_std(close, 20)", + "volatility_ratio": "ts_std(close, 5) / (ts_std(close, 20) + 1e-8)", # 波动率期限结构 + "std_return_20": "ts_std((close / (ts_delay(close, 1) + 1e-8)) - 1, 20)", # 真实收益率波动率 + # [高阶] 夏普趋势比率 - 惩罚暴涨暴跌,奖励稳健爬坡 + "sharpe_ratio_20": "ts_mean(close / (ts_delay(close, 1) + 1e-8) - 1, 20) / (ts_std(close / (ts_delay(close, 1) + 1e-8) - 1, 20) + 1e-8)", + # [高阶] 尾部崩盘风险 - 过去一个月最大单日跌幅 + "min_ret_20": "ts_min(close / (ts_delay(close, 1) + 1e-8) - 1, 20)", + # [高阶] 波动率挤压比 - 寻找盘整到极致面临变盘的股票 (布林带收口) + "volatility_squeeze_5_60": "ts_std(close, 5) / (ts_std(close, 60) + 1e-8)", + # ================= 3. 日内微观结构与异象 (Intraday Microstructure & Anomalies) ================= + # [高阶] 隔夜与日内背离 - 差值越小说明主力越喜欢在盘中吸筹 + "overnight_intraday_diff": "(open / (ts_delay(close, 1) + 1e-8) - 1) - (close / (open + 1e-8) - 1)", + # [高阶] 上影线抛压极值 - 冲高回落被套牢的概率 + "upper_shadow_ratio": "(high - ((open + close + abs(open - close)) / 2)) / (high - low + 1e-8)", + # [高阶] 资金沉淀率 - 衡量主力日内高抛低吸洗盘的剧烈程度 + "capital_retention_20": "ts_sum(abs(close - open), 20) / (ts_sum(high - low, 20) + 1e-8)", + # [高阶] MAX 彩票效应 - 反转因子,剔除近期有过妖股连板特征的标的 + "max_ret_20": "ts_max(close / (ts_delay(close, 1) + 1e-8) - 1, 20)", + # ================= 4. 量能、流动性与量价背离 (Volume, Liquidity & Divergence) ================= + "volume_ratio_5_20": "ts_mean(vol, 5) / (ts_mean(vol, 20) + 1e-8)", # 相对放量比 + "turnover_rate_mean_5": "ts_mean(turnover_rate, 5)", # 活跃度 + "turnover_deviation": "(turnover_rate - ts_mean(turnover_rate, 10)) / (ts_std(turnover_rate, 10) + 1e-8)", # 换手率偏离度 + # [高阶] Amihud 非流动性异象 (绝对核心) - 衡量砸盘/拉升的摩擦成本 + "amihud_illiq_20": "ts_mean(abs(close / (ts_delay(close, 1) + 1e-8) - 1) / (amount + 1e-8), 20)", + # [高阶] 换手率惩罚因子 - 换手率忽高忽低说明游资接力,行情极不稳定 + "turnover_cv_20": "ts_std(turnover_rate, 20) / (ts_mean(turnover_rate, 20) + 1e-8)", + # [高阶] 纯粹量价相关性 - 检验是否是"放量上涨,缩量下跌"的良性多头 + "pv_corr_20": "ts_corr(close / (ts_delay(close, 1) + 1e-8) - 1, vol, 20)", + # [高阶] 收盘价与均价背离 - 专门抓尾盘突袭拉升骗线的股票 + "close_vwap_deviation": "close / (amount / (vol * 100 + 1e-8) + 1e-8) - 1", + # ================= 5. 基本面财务特征 (Fundamental Quality & Structure) ================= + "roe": "n_income / (total_hldr_eqy_exc_min_int + 1e-8)", # 净资产收益率 + "roa": "n_income / (total_assets + 1e-8)", # 总资产收益率 + "profit_margin": "n_income / (revenue + 1e-8)", # 销售净利率 + "debt_to_equity": "total_liab / (total_hldr_eqy_exc_min_int + 1e-8)", # 杠杆率 + "current_ratio": "total_cur_assets / (total_cur_liab + 1e-8)", # 短期偿债安全垫 + # [高阶] 利润同比增速 (日频延后252天等于去年同期) + "net_profit_yoy": "(n_income / (ts_delay(n_income, 252) + 1e-8)) - 1", + # [高阶] 营收同比增速 + "revenue_yoy": "(revenue / (ts_delay(revenue, 252) + 1e-8)) - 1", + # [高阶] 资产负债表扩张斜率 - 剔除单纯靠举债扩张的公司 + "healthy_expansion_velocity": "(total_assets / (ts_delay(total_assets, 252) + 1e-8) - 1) - (total_liab / (ts_delay(total_liab, 252) + 1e-8) - 1)", + # ================= 6. 基本面估值与截面动量共振 (Valuation & Cross-Sectional Ranking) ================= + # 估值水平绝对值 (Tushare 市值单位需要 * 10000 转换为元) + "EP": "n_income / (total_mv * 10000 + 1e-8)", # 盈利收益率 (1/PE) + "BP": "total_hldr_eqy_exc_min_int / (total_mv * 10000 + 1e-8)", # 账面市值比 (1/PB) + "CP": "n_cashflow_act / (total_mv * 10000 + 1e-8)", # 经营现金流收益率 (1/PCF) + # 全市场截面排名因子 + "market_cap_rank": "cs_rank(total_mv)", # 规模因子 (Size) + "turnover_rank": "cs_rank(turnover_rate)", + "return_5_rank": "cs_rank((close / (ts_delay(close, 5) + 1e-8)) - 1)", + "EP_rank": "cs_rank(n_income / (total_mv + 1e-8))", # 谁最便宜 + # [高阶] 戴维斯双击动量 - 估值相对上一年是否在扩张 + "pe_expansion_trend": "(total_mv / (n_income + 1e-8)) / (ts_delay(total_mv, 60) / (ts_delay(n_income, 60) + 1e-8) + 1e-8) - 1", + # [高阶] 业绩与价格背离度 - 截面做差:利润排名全市场第一,但近20日价格排名倒数第一,捕捉被错杀的潜伏股 + "value_price_divergence": "cs_rank((n_income - ts_delay(n_income, 252)) / (abs(ts_delay(n_income, 252)) + 1e-8)) - cs_rank(close / (ts_delay(close, 20) + 1e-8))", + # [高阶] 流动性溢价调整后市值 - 识别僵尸大盘股和极度活跃的小微盘 + "active_market_cap": "total_mv * ts_mean(turnover_rate, 20)", + "ebit_rank": "cs_rank(ebit)", +} + +# Label 因子定义(不参与训练,用于计算目标) +LABEL_FACTOR = { + LABEL_NAME: "(ts_delay(close, -5) / ts_delay(open, -1)) - 1", # 未来5日收益率 +} +# %% md +# ### 3.2 训练参数配置 +# %% +# 日期范围配置(正确的 train/val/test 三分法) +# Train: 用于训练模型参数 +# Val: 用于验证/早停/调参(位于 train 之后,test 之前) +# Test: 仅用于最终评估,完全独立于训练过程 +TRAIN_START = "20200101" +TRAIN_END = "20231231" +VAL_START = "20240101" +VAL_END = "20241231" +TEST_START = "20250101" +TEST_END = "20261231" + +# 模型参数配置 +MODEL_PARAMS = { + "objective": "regression", + "metric": "mae", # 改为 MAE,对异常值更稳健 + # 树结构控制(防过拟合核心) + # "num_leaves": 20, # 从31降为20,降低模型复杂度 + # "max_depth": 16, # 显式限制深度,防止过度拟合噪声 + # "min_child_samples": 50, # 叶子最小样本数,防止学习极端样本 + # "min_child_weight": 0.001, + # 学习参数 + "learning_rate": 0.01, # 降低学习率,配合更多树 + "n_estimators": 1000, # 增加树数量,配合早停 + # 采样策略(关键防过拟合) + "subsample": 0.8, # 每棵树随机采样80%数据(行采样) + "subsample_freq": 5, # 每5轮迭代进行一次 subsample + "colsample_bytree": 0.8, # 每棵树随机选择80%特征(列采样) + # 正则化 + "reg_alpha": 0.1, # L1正则,增加稀疏性 + "reg_lambda": 1.0, # L2正则,平滑权重 + # 数值稳定性 + "verbose": -1, + "random_state": 42, +} + +# 数据处理器配置(新 API:需要传入 feature_cols) +# 注意:processor 现在需要显式指定要处理的特征列 + + +# 股票池筛选函数 +# 使用新的 StockPoolManager API:传入自定义筛选函数和所需列/因子 +# 筛选函数接收单日 DataFrame,返回布尔 Series +# +# 筛选逻辑(针对单日数据): +# 1. 先排除创业板、科创板、北交所(ST过滤由STFilter组件处理) +# 2. 然后选取市值最小的500只股票 +def stock_pool_filter(df: pl.DataFrame) -> pl.Series: + """股票池筛选函数(单日数据) + + 筛选条件: + 1. 排除创业板(代码以 300 开头) + 2. 排除科创板(代码以 688 开头) + 3. 排除北交所(代码以 8、9 或 4 开头) + 4. 选取当日市值最小的500只股票 + """ + # 代码筛选(排除创业板、科创板、北交所) + code_filter = ( + ~df["ts_code"].str.starts_with("30") # 排除创业板 + & ~df["ts_code"].str.starts_with("68") # 排除科创板 + & ~df["ts_code"].str.starts_with("8") # 排除北交所 + & ~df["ts_code"].str.starts_with("9") # 排除北交所 + & ~df["ts_code"].str.starts_with("4") # 排除北交所 + ) + + # 在已筛选的股票中,选取市值最小的500只 + # 按市值升序排序,取前500 + valid_df = df.filter(code_filter) + n = min(1000, len(valid_df)) + small_cap_codes = valid_df.sort("total_mv").head(n)["ts_code"] + + # 返回布尔 Series:是否在被选中的股票中 + return df["ts_code"].is_in(small_cap_codes) + + +# 定义筛选所需的基础列 +STOCK_FILTER_REQUIRED_COLUMNS = ["total_mv"] # ST过滤由STFilter组件处理 + +# 可选:定义筛选所需的因子(如果需要用因子进行筛选) +# STOCK_FILTER_REQUIRED_FACTORS = { +# "market_cap_rank": "cs_rank(total_mv)", +# } + + +# 输出配置(相对于本文件所在目录) +OUTPUT_DIR = "output" +SAVE_PREDICTIONS = True +PERSIST_MODEL = False + +# Top N 配置:每日推荐股票数量 +TOP_N = 5 # 可调整为 10, 20 等 +# %% md +# ## 4. 训练流程 +# +# ### 4.1 初始化组件 +# %% +print("\n" + "=" * 80) +print("LightGBM 回归模型训练") +print("=" * 80) + +# 1. 创建 FactorEngine(启用 metadata 功能) +print("\n[1] 创建 FactorEngine") +engine = FactorEngine(metadata_path="data/factors.jsonl") + +# 2. 使用 metadata 定义因子 +print("\n[2] 定义因子(从 metadata 注册)") +feature_cols = create_factors_with_metadata(engine, FACTOR_DEFINITIONS, LABEL_FACTOR) +target_col = LABEL_NAME + +# 3. 准备数据(使用模块级别的日期配置) +print("\n[3] 准备数据") + +data = prepare_data( + engine=engine, + feature_cols=feature_cols, + start_date=TRAIN_START, + end_date=TEST_END, +) + +# 4. 打印配置信息 +print(f"\n[配置] 训练期: {TRAIN_START} - {TRAIN_END}") +print(f"[配置] 验证期: {VAL_START} - {VAL_END}") +print(f"[配置] 测试期: {TEST_START} - {TEST_END}") +print(f"[配置] 特征数: {len(feature_cols)}") +print(f"[配置] 目标变量: {target_col}") + +# 5. 创建模型 +model = LightGBMModel(params=MODEL_PARAMS) + +# 6. 创建数据处理器(新 API:需要传入 feature_cols) +processors = [ + NullFiller(feature_cols=feature_cols, strategy="mean"), + Winsorizer(feature_cols=feature_cols, lower=0.01, upper=0.99), + StandardScaler(feature_cols=feature_cols), +] + +# 7. 创建数据划分器(正确的 train/val/test 三分法) +# Train: 训练模型参数 | Val: 验证/早停 | Test: 最终评估 +splitter = DateSplitter( + train_start=TRAIN_START, + train_end=TRAIN_END, + val_start=VAL_START, + val_end=VAL_END, + test_start=TEST_START, + test_end=TEST_END, +) + +# 8. 创建股票池管理器 +# 使用新的 API:传入自定义筛选函数和所需列 +pool_manager = StockPoolManager( + filter_func=stock_pool_filter, + required_columns=STOCK_FILTER_REQUIRED_COLUMNS, # 筛选所需的额外列 + # required_factors=STOCK_FILTER_REQUIRED_FACTORS, # 可选:筛选所需的因子 + data_router=engine.router, +) +print("[股票池筛选] 使用自定义函数进行股票池筛选") +print(f"[股票池筛选] 所需基础列: {STOCK_FILTER_REQUIRED_COLUMNS}") +print("[股票池筛选] 筛选逻辑: 排除创业板/科创板/北交所后,每日选市值最小的500只") +# print(f"[股票池筛选] 所需因子: {list(STOCK_FILTER_REQUIRED_FACTORS.keys())}") + +# 9. 创建 ST 股票过滤器 +st_filter = STFilter( + data_router=engine.router, +) + +# 10. 创建训练器 +trainer = Trainer( + model=model, + pool_manager=pool_manager, + processors=processors, + filters=[st_filter], # 使用STFilter过滤ST股票 + splitter=splitter, + target_col=target_col, + feature_cols=feature_cols, + persist_model=PERSIST_MODEL, +) +# %% md +# ### 4.2 执行训练 +# %% +print("\n" + "=" * 80) +print("开始训练") +print("=" * 80) + +# 步骤 1: 股票池筛选 +print("\n[步骤 1/6] 股票池筛选") +print("-" * 60) +if pool_manager: + print(" 执行每日独立筛选股票池...") + filtered_data = pool_manager.filter_and_select_daily(data) + print(f" 筛选前数据规模: {data.shape}") + print(f" 筛选后数据规模: {filtered_data.shape}") + print(f" 筛选前股票数: {data['ts_code'].n_unique()}") + print(f" 筛选后股票数: {filtered_data['ts_code'].n_unique()}") + print(f" 删除记录数: {len(data) - len(filtered_data)}") +else: + filtered_data = data + print(" 未配置股票池管理器,跳过筛选") +# %% +# 步骤 2: 划分训练/验证/测试集(正确的三分法) +print("\n[步骤 2/6] 划分训练集、验证集和测试集") +print("-" * 60) +if splitter: + # 正确的三分法:train用于训练,val用于验证/早停,test仅用于最终评估 + train_data, val_data, test_data = splitter.split(filtered_data) + print(f" 训练集数据规模: {train_data.shape}") + print(f" 验证集数据规模: {val_data.shape}") + print(f" 测试集数据规模: {test_data.shape}") + print(f" 训练集股票数: {train_data['ts_code'].n_unique()}") + print(f" 验证集股票数: {val_data['ts_code'].n_unique()}") + print(f" 测试集股票数: {test_data['ts_code'].n_unique()}") + print( + f" 训练集日期范围: {train_data['trade_date'].min()} - {train_data['trade_date'].max()}" + ) + print( + f" 验证集日期范围: {val_data['trade_date'].min()} - {val_data['trade_date'].max()}" + ) + print( + f" 测试集日期范围: {test_data['trade_date'].min()} - {test_data['trade_date'].max()}" + ) + + print("\n 训练集前5行预览:") + print(train_data.head()) + print("\n 验证集前5行预览:") + print(val_data.head()) + print("\n 测试集前5行预览:") + print(test_data.head()) +else: + train_data = filtered_data + test_data = filtered_data + print(" 未配置划分器,全部作为训练集") +# %% +# 步骤 3: 训练集数据处理 +print("\n[步骤 3/6] 训练集数据处理") +print("-" * 60) +fitted_processors = [] +if processors: + for i, processor in enumerate(processors, 1): + print(f" [{i}/{len(processors)}] 应用处理器: {processor.__class__.__name__}") + train_data_before = len(train_data) + train_data = processor.fit_transform(train_data) + train_data_after = len(train_data) + fitted_processors.append(processor) + print(f" 处理前记录数: {train_data_before}") + print(f" 处理后记录数: {train_data_after}") + if train_data_before != train_data_after: + print(f" 删除记录数: {train_data_before - train_data_after}") + +print("\n 训练集处理后前5行预览:") +print(train_data.head()) +print(f"\n 训练集特征统计:") +print(f" 特征数: {len(feature_cols)}") +print(f" 样本数: {len(train_data)}") +print(f" 缺失值统计:") +for col in feature_cols[:5]: # 只显示前5个特征的缺失值 + null_count = train_data[col].null_count() + if null_count > 0: + print(f" {col}: {null_count} ({null_count / len(train_data) * 100:.2f}%)") +# %% +# 步骤 4: 训练模型 +print("\n[步骤 4/6] 训练模型") +print("-" * 60) +print(f" 模型类型: LightGBM") +print(f" 训练样本数: {len(train_data)}") +print(f" 特征数: {len(feature_cols)}") +print(f" 目标变量: {target_col}") + +X_train = train_data.select(feature_cols) +y_train = train_data.select(target_col).to_series() + +print(f"\n 目标变量统计:") +print(f" 均值: {y_train.mean():.6f}") +print(f" 标准差: {y_train.std():.6f}") +print(f" 最小值: {y_train.min():.6f}") +print(f" 最大值: {y_train.max():.6f}") +print(f" 缺失值: {y_train.null_count()}") + +print("\n 开始训练...") +model.fit(X_train, y_train) +print(" 训练完成!") +# %% +# 步骤 5: 测试集数据处理 +print("\n[步骤 5/6] 测试集数据处理") +print("-" * 60) +if processors and test_data is not train_data: + for i, processor in enumerate(fitted_processors, 1): + print( + f" [{i}/{len(fitted_processors)}] 应用处理器: {processor.__class__.__name__}" + ) + test_data_before = len(test_data) + test_data = processor.transform(test_data) + test_data_after = len(test_data) + print(f" 处理前记录数: {test_data_before}") + print(f" 处理后记录数: {test_data_after}") +else: + print(" 跳过测试集处理") +# %% +# 步骤 6: 生成预测 +print("\n[步骤 6/6] 生成预测") +print("-" * 60) +X_test = test_data.select(feature_cols) +print(f" 测试样本数: {len(X_test)}") +print(" 预测中...") +predictions = model.predict(X_test) +print(f" 预测完成!") + +print(f"\n 预测结果统计:") +print(f" 均值: {predictions.mean():.6f}") +print(f" 标准差: {predictions.std():.6f}") +print(f" 最小值: {predictions.min():.6f}") +print(f" 最大值: {predictions.max():.6f}") + +# 保存结果到 trainer +trainer.results = test_data.with_columns([pl.Series("prediction", predictions)]) +# %% md +# ### 4.3 训练指标曲线 +# %% +print("\n" + "=" * 80) +print("训练指标曲线") +print("=" * 80) + +# 重新训练以收集指标(因为之前的训练没有保存评估结果) +print("\n重新训练模型以收集训练指标...") + +import lightgbm as lgb + +# 准备数据(使用 val 做验证,test 不参与训练过程) +X_train_np = X_train.to_numpy() +y_train_np = y_train.to_numpy() +X_val_np = val_data.select(feature_cols).to_numpy() +y_val_np = val_data.select(target_col).to_series().to_numpy() + +# 创建数据集 +train_dataset = lgb.Dataset(X_train_np, label=y_train_np) +val_dataset = lgb.Dataset(X_val_np, label=y_val_np, reference=train_dataset) + +# 用于存储评估结果 +evals_result = {} + +# 使用与原模型相同的参数重新训练 +# 正确的三分法:train用于训练,val用于验证,test不参与训练过程 +# 添加早停:如果验证指标连续100轮没有改善则停止训练 +booster_with_eval = lgb.train( + MODEL_PARAMS, + train_dataset, + num_boost_round=MODEL_PARAMS.get("n_estimators", 100), + valid_sets=[train_dataset, val_dataset], + valid_names=["train", "val"], + callbacks=[ + lgb.record_evaluation(evals_result), + lgb.early_stopping(stopping_rounds=100, verbose=True), + ], +) + +print("训练完成,指标已收集") + +# 获取指标名称 +metric_name = list(evals_result["train"].keys())[0] +print(f"\n评估指标: {metric_name}") + +# 提取训练和验证指标 +train_metric = evals_result["train"][metric_name] +val_metric = evals_result["val"][metric_name] + +# 显示早停信息 +actual_rounds = len(train_metric) +expected_rounds = MODEL_PARAMS.get("n_estimators", 100) +print(f"\n[早停信息]") +print(f" 配置的最大轮数: {expected_rounds}") +print(f" 实际训练轮数: {actual_rounds}") +if actual_rounds < expected_rounds: + print(f" 早停状态: 已触发(连续100轮验证指标未改善)") +else: + print(f" 早停状态: 未触发(达到最大轮数)") + +print(f"\n最终指标:") +print(f" 训练 {metric_name}: {train_metric[-1]:.6f}") +print(f" 验证 {metric_name}: {val_metric[-1]:.6f}") +# %% +# 绘制训练指标曲线 +import matplotlib.pyplot as plt + +fig, ax = plt.subplots(figsize=(12, 6)) + +# 绘制训练集和验证集的指标曲线(注意:val用于验证,test不参与训练) +iterations = range(1, len(train_metric) + 1) +ax.plot( + iterations, train_metric, label=f"Train {metric_name}", linewidth=2, color="blue" +) +ax.plot( + iterations, val_metric, label=f"Validation {metric_name}", linewidth=2, color="red" +) + +ax.set_xlabel("Iteration", fontsize=12) +ax.set_ylabel(metric_name.upper(), fontsize=12) +ax.set_title( + f"Training and Validation {metric_name.upper()} Curve", + fontsize=14, + fontweight="bold", +) +ax.legend(fontsize=10) +ax.grid(True, alpha=0.3) + +# 标记最佳验证指标点(用于早停决策) +best_iter = val_metric.index(min(val_metric)) +best_metric = min(val_metric) +ax.axvline( + x=best_iter + 1, + color="green", + linestyle="--", + alpha=0.7, + label=f"Best Iteration ({best_iter + 1})", +) +ax.scatter([best_iter + 1], [best_metric], color="green", s=100, zorder=5) +ax.annotate( + f"Best: {best_metric:.6f}\nIter: {best_iter + 1}", + xy=(best_iter + 1, best_metric), + xytext=(best_iter + 1 + len(iterations) * 0.1, best_metric), + fontsize=9, + arrowprops=dict(arrowstyle="->", color="green", alpha=0.7), +) + +plt.tight_layout() +plt.show() + +print(f"\n[指标分析]") +print(f" 最佳验证 {metric_name}: {best_metric:.6f}") +print(f" 最佳迭代轮数: {best_iter + 1}") +print(f" 早停建议: 如果验证指标连续10轮不下降,建议在第 {best_iter + 1} 轮停止训练") +print(f"\n[重要提醒] 验证集仅用于早停/调参,测试集完全独立于训练过程!") +# %% md +# ### 4.4 查看结果 +# %% +print("\n" + "=" * 80) +print("训练结果") +print("=" * 80) + +results = trainer.results + +print(f"\n结果数据形状: {results.shape}") +print(f"结果列: {results.columns}") +print(f"\n结果前10行预览:") +print(results.head(10)) +print(f"\n结果后5行预览:") +print(results.tail()) + +print(f"\n每日预测样本数统计:") +daily_counts = results.group_by("trade_date").agg(pl.len()).sort("trade_date") +print(f" 最小: {daily_counts['len'].min()}") +print(f" 最大: {daily_counts['len'].max()}") +print(f" 平均: {daily_counts['len'].mean():.2f}") + +# 展示某一天的前10个预测结果 +sample_date = results["trade_date"][0] +sample_data = results.filter(results["trade_date"] == sample_date).head(10) +print(f"\n示例日期 {sample_date} 的前10条预测:") +print(sample_data.select(["ts_code", "trade_date", target_col, "prediction"])) +# %% md +# ### 4.4 保存结果 +# %% +print("\n" + "=" * 80) +print("保存预测结果") +print("=" * 80) + +# 确保输出目录存在 +os.makedirs(OUTPUT_DIR, exist_ok=True) + +# 生成时间戳 +start_dt = datetime.strptime(TEST_START, "%Y%m%d") +end_dt = datetime.strptime(TEST_END, "%Y%m%d") +date_str = f"{start_dt.strftime('%Y%m%d')}_{end_dt.strftime('%Y%m%d')}" + +# 保存每日 Top N +print(f"\n[1/1] 保存每日 Top {TOP_N} 股票...") +topn_output_path = os.path.join(OUTPUT_DIR, f"regression_output.csv") + +# 按日期分组,取每日 top N +topn_by_date = [] +unique_dates = results["trade_date"].unique().sort() +for date in unique_dates: + day_data = results.filter(results["trade_date"] == date) + # 按 prediction 降序排序,取前 N + topn = day_data.sort("prediction", descending=True).head(TOP_N) + topn_by_date.append(topn) + +# 合并所有日期的 top N +topn_results = pl.concat(topn_by_date) + +# 格式化日期并调整列顺序:日期、分数、股票 +topn_to_save = topn_results.select( + [ + pl.col("trade_date").str.slice(0, 4) + + "-" + + pl.col("trade_date").str.slice(4, 2) + + "-" + + pl.col("trade_date").str.slice(6, 2).alias("date"), + pl.col("prediction").alias("score"), + pl.col("ts_code"), + ] +) +topn_to_save.write_csv(topn_output_path, include_header=True) +print(f" 保存路径: {topn_output_path}") +print( + f" 保存行数: {len(topn_to_save)}({len(unique_dates)}个交易日 × 每日top{TOP_N})" +) +print(f"\n 预览(前15行):") +print(topn_to_save.head(15)) +# %% md +# ### 4.5 特征重要性 +# %% +importance = model.feature_importance() +if importance is not None: + print("\n特征重要性:") + print(importance.sort_values(ascending=False)) + +print("\n" + "=" * 80) +print("训练完成!") +print("=" * 80) +# %% md +# ## 5. 可视化分析 +# +# 使用训练好的模型直接绘图。 +# - **特征重要性图**:辅助特征选择 +# - **决策树图**:理解决策逻辑 +# %% +# 导入可视化库 +import matplotlib.pyplot as plt +import lightgbm as lgb +import pandas as pd + +# 从封装的model中取出底层Booster +booster = model.model +print(f"模型类型: {type(booster)}") +print(f"特征数量: {len(feature_cols)}") +# %% md +# ### 5.1 绘制特征重要性(辅助特征选择) +# +# **解读**: +# - 重要性高的特征对模型贡献大 +# - 重要性为0的特征可以考虑删除 +# - 可以帮助理解哪些因子最有效 +# %% +print("绘制特征重要性...") + +fig, ax = plt.subplots(figsize=(10, 8)) +lgb.plot_importance( + booster, + max_num_features=20, + importance_type="gain", + title="Feature Importance (Gain)", + ax=ax, +) +ax.set_xlabel("Importance (Gain)") +plt.tight_layout() +plt.show() + +# 打印重要性排名 +importance_gain = pd.Series( + booster.feature_importance(importance_type="gain"), index=feature_cols +).sort_values(ascending=False) + +print("\n[特征重要性排名 - Gain]") +print(importance_gain) + +# 识别低重要性特征 +zero_importance = importance_gain[importance_gain == 0].index.tolist() +if zero_importance: + print(f"\n[低重要性特征] 以下{len(zero_importance)}个特征重要性为0,可考虑删除:") + for feat in zero_importance: + print(f" - {feat}") +else: + print("\n所有特征都有一定重要性") diff --git a/src/factors/engine/factor_engine.py b/src/factors/engine/factor_engine.py index 160abcd..a931d0f 100644 --- a/src/factors/engine/factor_engine.py +++ b/src/factors/engine/factor_engine.py @@ -16,6 +16,7 @@ import polars as pl if TYPE_CHECKING: from src.factors.registry import FunctionRegistry + from src.factors.metadata import FactorManager from src.factors.dsl import ( Node, @@ -57,6 +58,7 @@ class FactorEngine: data_source: Optional[Dict[str, pl.DataFrame]] = None, max_workers: int = 4, registry: Optional["FunctionRegistry"] = None, + metadata_path: Optional[str] = None, ) -> None: """初始化因子引擎。 @@ -64,6 +66,7 @@ class FactorEngine: data_source: 内存数据源,为 None 时使用数据库连接 max_workers: 并行计算的最大工作线程数 registry: 函数注册表,None 时创建独立实例 + metadata_path: 因子元数据文件路径,为 None 时不启用 metadata 功能 """ from src.factors.registry import FunctionRegistry from src.factors.parser import FormulaParser @@ -78,6 +81,13 @@ class FactorEngine: self._registry = registry if registry is not None else FunctionRegistry() self._parser = FormulaParser(self._registry) + # 初始化 metadata 管理器(可选) + self._metadata: Optional["FactorManager"] = None + if metadata_path is not None: + from src.factors.metadata import FactorManager + + self._metadata = FactorManager(metadata_path) + def register( self, name: str, @@ -175,6 +185,76 @@ class FactorEngine: # 委托给现有的 register 方法 return self.register(name, node, data_specs) + def add_factor_by_name( + self, + name: str, + factor_name_in_metadata: Optional[str] = None, + data_specs: Optional[List[DataSpec]] = None, + ) -> "FactorEngine": + """根据 metadata 中的因子名称注册因子。 + + 从 metadata 管理器中根据因子名称查询 DSL 表达式, + 然后解析并注册到引擎中。 + + Args: + name: 要注册的因子名称(引擎中使用的名称) + factor_name_in_metadata: metadata 中的因子名称, + 为 None 时默认使用 name 参数 + data_specs: 可选的数据规格 + + Returns: + self,支持链式调用 + + Raises: + RuntimeError: 当引擎未配置 metadata 路径时 + ValueError: 当在 metadata 中未找到因子时 + FormulaParseError: 当 DSL 表达式解析失败时 + + Example: + >>> # 初始化时启用 metadata + >>> engine = FactorEngine(metadata_path="data/factors.jsonl") + >>> + >>> # 注册 metadata 中的因子(使用相同名称) + >>> engine.add_factor_by_name("return_5") + >>> + >>> # 使用不同名称注册 + >>> engine.add_factor_by_name("my_mom", "momentum_5d") + >>> + >>> # 链式调用 + >>> (engine + ... .add_factor_by_name("ma20") + ... .add_factor_by_name("rsi14") + ... .compute(["ma20", "rsi14"], "20240101", "20240131")) + """ + if self._metadata is None: + raise RuntimeError( + "引擎未配置 metadata 路径。请在初始化时传入 metadata_path 参数," + + "例如:FactorEngine(metadata_path='data/factors.jsonl')" + ) + + # 使用传入的名称或默认使用 name + query_name = ( + factor_name_in_metadata if factor_name_in_metadata is not None else name + ) + + # 从 metadata 查询因子 + df = self._metadata.get_factors_by_name(query_name) + + if len(df) == 0: + raise ValueError( + f"在 metadata 中未找到因子 '{query_name}'。" + + "请确认因子名称正确,或先使用 FactorManager 添加该因子。" + ) + + # 获取 DSL 表达式 + dsl_expr = df["dsl"][0] + + # 解析表达式为 Node + node = self._parser.parse(dsl_expr) + + # 委托给 register 方法 + return self.register(name, node, data_specs) + def compute( self, factor_names: Union[str, List[str]], diff --git a/src/training/components/filters.py b/src/training/components/filters.py index d4f165c..e381118 100644 --- a/src/training/components/filters.py +++ b/src/training/components/filters.py @@ -101,7 +101,8 @@ class STFilter(BaseFilter): # 打印过滤信息 n_removed = len(daily_codes) - len(daily_filtered) if n_removed > 0: - print(f" [{date}] 过滤 {n_removed} 只 ST 股票") + pass + # print(f" [{date}] 过滤 {n_removed} 只 ST 股票") return pl.concat(result_frames) diff --git a/tests/test_factor_engine_metadata.py b/tests/test_factor_engine_metadata.py new file mode 100644 index 0000000..6752f1e --- /dev/null +++ b/tests/test_factor_engine_metadata.py @@ -0,0 +1,106 @@ +"""FactorEngine 与 Metadata 集成测试。 + +测试 add_factor_by_name 方法的功能。 +""" + +import pytest + +from src.factors import FactorEngine +from src.factors.metadata import FactorManager + + +class TestFactorEngineMetadataIntegration: + """测试 FactorEngine 与 Metadata 的集成功能。""" + + @pytest.fixture + def metadata_file(self): + """使用 data 目录下的 factors.jsonl 文件。""" + return "data/factors.jsonl" + + def test_init_without_metadata(self): + """测试不启用 metadata 时初始化引擎。""" + engine = FactorEngine() + assert engine._metadata is None + + def test_init_with_metadata(self, metadata_file): + """测试启用 metadata 时初始化引擎。""" + engine = FactorEngine(metadata_path=metadata_file) + assert engine._metadata is not None + assert isinstance(engine._metadata, FactorManager) + + def test_add_factor_by_name_success(self, metadata_file): + """测试从 metadata 成功添加因子。""" + engine = FactorEngine(metadata_path=metadata_file) + + # 添加 return_5 因子 + result = engine.add_factor_by_name("return_5") + + # 验证链式调用返回自身 + assert result is engine + + # 验证因子已注册 + assert "return_5" in engine.list_registered() + + def test_add_factor_by_name_with_alias(self, metadata_file): + """测试使用别名添加因子。""" + engine = FactorEngine(metadata_path=metadata_file) + + # 使用不同名称注册 metadata 中的因子 + engine.add_factor_by_name("my_ma", "ma_5") + + # 验证使用别名注册的因子 + assert "my_ma" in engine.list_registered() + assert "ma_5" not in engine.list_registered() + + def test_add_factor_by_name_not_found(self, metadata_file): + """测试添加不存在的因子时抛出异常。""" + engine = FactorEngine(metadata_path=metadata_file) + + with pytest.raises(ValueError) as exc_info: + engine.add_factor_by_name("nonexistent_factor") + + assert "未找到因子" in str(exc_info.value) + assert "nonexistent_factor" in str(exc_info.value) + + def test_add_factor_by_name_without_metadata(self): + """测试未配置 metadata 时调用 add_factor_by_name 抛出异常。""" + engine = FactorEngine() # 不传入 metadata_path + + with pytest.raises(RuntimeError) as exc_info: + engine.add_factor_by_name("return_5") + + assert "未配置 metadata 路径" in str(exc_info.value) + + def test_chain_calls(self, metadata_file): + """测试链式调用。""" + engine = FactorEngine(metadata_path=metadata_file) + + # 链式添加多个因子 + ( + engine.add_factor_by_name("return_5") + .add_factor_by_name("ma_5") + .add_factor_by_name("custom_ma20", "ma_20") + ) + + # 验证所有因子都已注册 + assert "return_5" in engine.list_registered() + assert "ma_5" in engine.list_registered() + assert "custom_ma20" in engine.list_registered() + + def test_add_factor_by_name_preserves_existing_add_factor(self, metadata_file): + """测试 add_factor_by_name 不影响原有的 add_factor 方法。""" + engine = FactorEngine(metadata_path=metadata_file) + + # 使用 add_factor 添加字符串表达式 + engine.add_factor("manual_factor", "ts_mean(close, 10)") + + # 使用 add_factor_by_name 添加 metadata 因子 + engine.add_factor_by_name("return_5") + + # 验证两者都正常工作 + assert "manual_factor" in engine.list_registered() + assert "return_5" in engine.list_registered() + + +if __name__ == "__main__": + pytest.main([__file__, "-v"])