From c5ad56a9e812917f62a6493b79d7621fd9efc4e2 Mon Sep 17 00:00:00 2001 From: liaozhaorun <1300336796@qq.com> Date: Thu, 5 Jun 2025 20:21:01 +0800 Subject: [PATCH] Rank2 --- .../factor/__pycache__/factor.cpython-313.pyc | Bin 167375 -> 167358 bytes main/train/Rank2_polars.ipynb | 2473 +++++++++++++++++ .../__pycache__/data_process.cpython-313.pyc | Bin 0 -> 12337 bytes .../__pycache__/indicators.cpython-313.pyc | Bin 0 -> 4384 bytes main/utils/data_process.py | 268 ++ main/utils/indicators.py | 130 + predictions_test.tsv | 1462 +++++----- 7 files changed, 3602 insertions(+), 731 deletions(-) create mode 100644 main/train/Rank2_polars.ipynb create mode 100644 main/utils/__pycache__/data_process.cpython-313.pyc create mode 100644 main/utils/__pycache__/indicators.cpython-313.pyc create mode 100644 main/utils/data_process.py create mode 100644 main/utils/indicators.py diff --git a/main/factor/__pycache__/factor.cpython-313.pyc b/main/factor/__pycache__/factor.cpython-313.pyc index 6d7b8cc5bee698118ad840f5966aa5000f0f4d73..f4d6cae2b74b4b3d2881527179b2b6761f881c96 100644 GIT binary patch delta 41 wcmX>Dkdh*;QMTwbt`g(dm)Xb{i&Z^J2omHP{ GXB+^n01q|* diff --git a/main/train/Rank2_polars.ipynb b/main/train/Rank2_polars.ipynb new file mode 100644 index 0000000..5481bf0 --- /dev/null +++ b/main/train/Rank2_polars.ipynb @@ -0,0 +1,2473 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "79a7758178bafdd3", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:46:06.987506Z", + "start_time": "2025-04-03T12:46:06.259551Z" + }, + "jupyter": { + "source_hidden": true + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mnt/d/PyProject/NewStock\n" + ] + } + ], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "import gc\n", + "import os\n", + "import sys\n", + "sys.path.append('/mnt/d/PyProject/NewStock/')\n", + "print(os.getcwd())\n", + "import pandas as pd\n", + "from main.factor.factor import get_rolling_factor, get_simple_factor\n", + "from main.utils.factor import read_industry_data\n", + "from main.utils.factor_processor import calculate_score\n", + "from main.utils.utils import read_and_merge_h5_data, merge_with_industry_data\n", + "\n", + "import warnings\n", + "\n", + "warnings.filterwarnings(\"ignore\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a79cafb06a7e0e43", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:47:00.212859Z", + "start_time": "2025-04-03T12:46:06.998047Z" + }, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "daily data\n", + "daily basic\n", + "inner merge on ['ts_code', 'trade_date']\n", + "stk limit\n", + "left merge on ['ts_code', 'trade_date']\n", + "money flow\n", + "left merge on ['ts_code', 'trade_date']\n", + "cyq perf\n", + "left merge on ['ts_code', 'trade_date']\n", + "\n", + "RangeIndex: 8692146 entries, 0 to 8692145\n", + "Data columns (total 33 columns):\n", + " # Column Dtype \n", + "--- ------ ----- \n", + " 0 ts_code object \n", + " 1 trade_date datetime64[ns]\n", + " 2 open float64 \n", + " 3 close float64 \n", + " 4 high float64 \n", + " 5 low float64 \n", + " 6 vol float64 \n", + " 7 pct_chg float64 \n", + " 8 amount float64 \n", + " 9 turnover_rate float64 \n", + " 10 pe_ttm float64 \n", + " 11 circ_mv float64 \n", + " 12 total_mv float64 \n", + " 13 volume_ratio float64 \n", + " 14 is_st bool \n", + " 15 up_limit float64 \n", + " 16 down_limit float64 \n", + " 17 buy_sm_vol float64 \n", + " 18 sell_sm_vol float64 \n", + " 19 buy_lg_vol float64 \n", + " 20 sell_lg_vol float64 \n", + " 21 buy_elg_vol float64 \n", + " 22 sell_elg_vol float64 \n", + " 23 net_mf_vol float64 \n", + " 24 his_low float64 \n", + " 25 his_high float64 \n", + " 26 cost_5pct float64 \n", + " 27 cost_15pct float64 \n", + " 28 cost_50pct float64 \n", + " 29 cost_85pct float64 \n", + " 30 cost_95pct float64 \n", + " 31 weight_avg float64 \n", + " 32 winner_rate float64 \n", + "dtypes: bool(1), datetime64[ns](1), float64(30), object(1)\n", + "memory usage: 2.1+ GB\n", + "None\n" + ] + } + ], + "source": [ + "from main.utils.utils import read_and_merge_h5_data\n", + "\n", + "print('daily data')\n", + "df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/daily_data.h5', key='daily_data',\n", + " columns=['ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'vol', 'pct_chg', 'amount'],\n", + " df=None)\n", + "\n", + "print('daily basic')\n", + "df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/daily_basic.h5', key='daily_basic',\n", + " columns=['ts_code', 'trade_date', 'turnover_rate', 'pe_ttm', 'circ_mv', 'total_mv', 'volume_ratio',\n", + " 'is_st'], df=df, join='inner')\n", + "\n", + "print('stk limit')\n", + "df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/stk_limit.h5', key='stk_limit',\n", + " columns=['ts_code', 'trade_date', 'pre_close', 'up_limit', 'down_limit'],\n", + " df=df)\n", + "print('money flow')\n", + "df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/money_flow.h5', key='money_flow',\n", + " columns=['ts_code', 'trade_date', 'buy_sm_vol', 'sell_sm_vol', 'buy_lg_vol', 'sell_lg_vol',\n", + " 'buy_elg_vol', 'sell_elg_vol', 'net_mf_vol'],\n", + " df=df)\n", + "print('cyq perf')\n", + "df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/cyq_perf.h5', key='cyq_perf',\n", + " columns=['ts_code', 'trade_date', 'his_low', 'his_high', 'cost_5pct', 'cost_15pct',\n", + " 'cost_50pct',\n", + " 'cost_85pct', 'cost_95pct', 'weight_avg', 'winner_rate'],\n", + " df=df)\n", + "print(df.info())" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "cac01788dac10678", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:47:10.527104Z", + "start_time": "2025-04-03T12:47:00.488715Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "industry\n" + ] + } + ], + "source": [ + "print('industry')\n", + "industry_df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/industry_data.h5', key='industry_data',\n", + " columns=['ts_code', 'l2_code', 'in_date'],\n", + " df=None, on=['ts_code'], join='left')\n", + "\n", + "\n", + "def merge_with_industry_data(df, industry_df):\n", + " # 确保日期字段是 datetime 类型\n", + " df['trade_date'] = pd.to_datetime(df['trade_date'])\n", + " industry_df['in_date'] = pd.to_datetime(industry_df['in_date'])\n", + "\n", + " # 对 industry_df 按 ts_code 和 in_date 排序\n", + " industry_df_sorted = industry_df.sort_values(['in_date', 'ts_code'])\n", + "\n", + " # 对原始 df 按 ts_code 和 trade_date 排序\n", + " df_sorted = df.sort_values(['trade_date', 'ts_code'])\n", + "\n", + " # 使用 merge_asof 进行向后合并\n", + " merged = pd.merge_asof(\n", + " df_sorted,\n", + " industry_df_sorted,\n", + " by='ts_code', # 按 ts_code 分组\n", + " left_on='trade_date',\n", + " right_on='in_date',\n", + " direction='backward'\n", + " )\n", + "\n", + " # 获取每个 ts_code 的最早 in_date 记录\n", + " min_in_date_per_ts = (industry_df_sorted\n", + " .groupby('ts_code')\n", + " .first()\n", + " .reset_index()[['ts_code', 'l2_code']])\n", + "\n", + " # 填充未匹配到的记录(trade_date 早于所有 in_date 的情况)\n", + " merged['l2_code'] = merged['l2_code'].fillna(\n", + " merged['ts_code'].map(min_in_date_per_ts.set_index('ts_code')['l2_code'])\n", + " )\n", + "\n", + " # 保留需要的列并重置索引\n", + " result = merged.reset_index(drop=True)\n", + " return result\n", + "\n", + "\n", + "# 使用示例\n", + "df = merge_with_industry_data(df, industry_df)\n", + "# print(mdf[mdf['ts_code'] == '600751.SH'][['ts_code', 'trade_date', 'l2_code']])" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c4e9e1d31da6dba6", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:47:10.719252Z", + "start_time": "2025-04-03T12:47:10.541247Z" + }, + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "from main.factor.factor import *\n", + "\n", + "def calculate_indicators(df):\n", + " \"\"\"\n", + " 计算四个指标:当日涨跌幅、5日移动平均、RSI、MACD。\n", + " \"\"\"\n", + " df = df.sort_values('trade_date')\n", + " df['daily_return'] = (df['close'] - df['pre_close']) / df['pre_close'] * 100\n", + " # df['5_day_ma'] = df['close'].rolling(window=5).mean()\n", + " delta = df['close'].diff()\n", + " gain = delta.where(delta > 0, 0)\n", + " loss = -delta.where(delta < 0, 0)\n", + " avg_gain = gain.rolling(window=14).mean()\n", + " avg_loss = loss.rolling(window=14).mean()\n", + " rs = avg_gain / avg_loss\n", + " df['RSI'] = 100 - (100 / (1 + rs))\n", + "\n", + " # 计算MACD\n", + " ema12 = df['close'].ewm(span=12, adjust=False).mean()\n", + " ema26 = df['close'].ewm(span=26, adjust=False).mean()\n", + " df['MACD'] = ema12 - ema26\n", + " df['Signal_line'] = df['MACD'].ewm(span=9, adjust=False).mean()\n", + " df['MACD_hist'] = df['MACD'] - df['Signal_line']\n", + "\n", + " # 4. 情绪因子1:市场上涨比例(Up Ratio)\n", + " df['up_ratio'] = df['daily_return'].apply(lambda x: 1 if x > 0 else 0)\n", + " df['up_ratio_20d'] = df['up_ratio'].rolling(window=20).mean() # 过去20天上涨比例\n", + "\n", + " # 5. 情绪因子2:成交量变化率(Volume Change Rate)\n", + " df['volume_mean'] = df['vol'].rolling(window=20).mean() # 过去20天的平均成交量\n", + " df['volume_change_rate'] = (df['vol'] - df['volume_mean']) / df['volume_mean'] * 100 # 成交量变化率\n", + "\n", + " # 6. 情绪因子3:波动率(Volatility)\n", + " df['volatility'] = df['daily_return'].rolling(window=20).std() # 过去20天的日收益率标准差\n", + "\n", + " # 7. 情绪因子4:成交额变化率(Amount Change Rate)\n", + " df['amount_mean'] = df['amount'].rolling(window=20).mean() # 过去20天的平均成交额\n", + " df['amount_change_rate'] = (df['amount'] - df['amount_mean']) / df['amount_mean'] * 100 # 成交额变化率\n", + "\n", + " # df = sentiment_panic_greed_index(df)\n", + " # df = sentiment_market_breadth_proxy(df)\n", + " # df = sentiment_reversal_indicator(df)\n", + "\n", + " return df\n", + "\n", + "\n", + "def generate_index_indicators(h5_filename):\n", + " df = pd.read_hdf(h5_filename, key='index_data')\n", + " df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d')\n", + " df = df.sort_values('trade_date')\n", + "\n", + " # 计算每个ts_code的相关指标\n", + " df_indicators = []\n", + " for ts_code in df['ts_code'].unique():\n", + " df_index = df[df['ts_code'] == ts_code].copy()\n", + " df_index = calculate_indicators(df_index)\n", + " df_indicators.append(df_index)\n", + "\n", + " # 合并所有指数的结果\n", + " df_all_indicators = pd.concat(df_indicators, ignore_index=True)\n", + "\n", + " # 保留trade_date列,并将同一天的数据按ts_code合并成一行\n", + " df_final = df_all_indicators.pivot_table(\n", + " index='trade_date',\n", + " columns='ts_code',\n", + " values=['daily_return', \n", + " 'RSI', 'MACD', 'Signal_line', 'MACD_hist', \n", + " # 'sentiment_panic_greed_index',\n", + " 'up_ratio_20d', 'volume_change_rate', 'volatility',\n", + " 'amount_change_rate', 'amount_mean'],\n", + " aggfunc='last'\n", + " )\n", + "\n", + " df_final.columns = [f\"{col[1]}_{col[0]}\" for col in df_final.columns]\n", + " df_final = df_final.reset_index()\n", + "\n", + " return df_final\n", + "\n", + "\n", + "# 使用函数\n", + "h5_filename = '/mnt/d/PyProject/NewStock/data/index_data.h5'\n", + "index_data = generate_index_indicators(h5_filename)\n", + "index_data = index_data.dropna()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a735bc02ceb4d872", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:47:10.821169Z", + "start_time": "2025-04-03T12:47:10.751831Z" + } + }, + "outputs": [], + "source": [ + "import talib\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "53f86ddc0677a6d7", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:47:15.944254Z", + "start_time": "2025-04-03T12:47:10.826179Z" + }, + "jupyter": { + "source_hidden": true + }, + "scrolled": true + }, + "outputs": [], + "source": [ + "from main.utils.factor import get_act_factor\n", + "\n", + "\n", + "def read_industry_data(h5_filename):\n", + " # 读取 H5 文件中所有的行业数据\n", + " industry_data = pd.read_hdf(h5_filename, key='sw_daily', columns=[\n", + " 'ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'pe', 'pb', 'vol'\n", + " ]) # 假设 H5 文件的键是 'industry_data'\n", + " industry_data = industry_data.sort_values(by=['ts_code', 'trade_date'])\n", + " industry_data = industry_data.reindex()\n", + " industry_data['trade_date'] = pd.to_datetime(industry_data['trade_date'], format='%Y%m%d')\n", + "\n", + " grouped = industry_data.groupby('ts_code', group_keys=False)\n", + " industry_data['obv'] = grouped.apply(\n", + " lambda x: pd.Series(talib.OBV(x['close'].values, x['vol'].values), index=x.index)\n", + " )\n", + " industry_data['return_5'] = grouped['close'].apply(lambda x: x / x.shift(5) - 1)\n", + " industry_data['return_20'] = grouped['close'].apply(lambda x: x / x.shift(20) - 1)\n", + "\n", + " industry_data = get_act_factor(industry_data, cat=False)\n", + " industry_data = industry_data.sort_values(by=['trade_date', 'ts_code'])\n", + "\n", + " # # 计算每天每个 ts_code 的因子和当天所有 ts_code 的中位数的偏差\n", + " # factor_columns = ['obv', 'return_5', 'return_20', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4'] # 因子列\n", + " # \n", + " # for factor in factor_columns:\n", + " # if factor in industry_data.columns:\n", + " # # 计算每天每个 ts_code 的因子值与当天所有 ts_code 的中位数的偏差\n", + " # industry_data[f'{factor}_deviation'] = industry_data.groupby('trade_date')[factor].transform(\n", + " # lambda x: x - x.mean())\n", + "\n", + " industry_data['return_5_percentile'] = industry_data.groupby('trade_date')['return_5'].transform(\n", + " lambda x: x.rank(pct=True))\n", + " industry_data['return_20_percentile'] = industry_data.groupby('trade_date')['return_20'].transform(\n", + " lambda x: x.rank(pct=True))\n", + "\n", + " # cs_rank_intraday_range(industry_data)\n", + " # cs_rank_close_pos_in_range(industry_data)\n", + "\n", + " industry_data = industry_data.drop(columns=['open', 'close', 'high', 'low', 'pe', 'pb', 'vol'])\n", + "\n", + " industry_data = industry_data.rename(\n", + " columns={col: f'industry_{col}' for col in industry_data.columns if col not in ['ts_code', 'trade_date']})\n", + "\n", + " industry_data = industry_data.rename(columns={'ts_code': 'cat_l2_code'})\n", + " return industry_data\n", + "\n", + "\n", + "industry_df = read_industry_data('/mnt/d/PyProject/NewStock/data/sw_daily.h5')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "dbe2fd8021b9417f", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:47:15.969344Z", + "start_time": "2025-04-03T12:47:15.963327Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['ts_code', 'open', 'close', 'high', 'low', 'amount', 'circ_mv', 'total_mv', 'is_st', 'up_limit', 'down_limit', 'buy_sm_vol', 'sell_sm_vol', 'buy_lg_vol', 'sell_lg_vol', 'buy_elg_vol', 'sell_elg_vol', 'net_mf_vol', 'his_low', 'his_high', 'cost_5pct', 'cost_15pct', 'cost_50pct', 'cost_85pct', 'cost_95pct', 'weight_avg', 'in_date']\n" + ] + } + ], + "source": [ + "origin_columns = df.columns.tolist()\n", + "origin_columns = [col for col in origin_columns if\n", + " col not in ['turnover_rate', 'pe_ttm', 'volume_ratio', 'vol', 'pct_chg', 'l2_code', 'winner_rate']]\n", + "origin_columns = [col for col in origin_columns if col not in index_data.columns]\n", + "origin_columns = [col for col in origin_columns if 'cyq' not in col]\n", + "print(origin_columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "85c3e3d0235ffffa", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T12:47:16.089879Z", + "start_time": "2025-04-03T12:47:15.990101Z" + } + }, + "outputs": [], + "source": [ + "fina_indicator_df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/fina_indicator.h5', key='fina_indicator',\n", + " columns=['ts_code', 'ann_date', 'undist_profit_ps', 'ocfps', 'bps'],\n", + " df=None)\n", + "cashflow_df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/cashflow.h5', key='cashflow',\n", + " columns=['ts_code', 'ann_date', 'n_cashflow_act'],\n", + " df=None)\n", + "balancesheet_df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/balancesheet.h5', key='balancesheet',\n", + " columns=['ts_code', 'ann_date', 'money_cap', 'total_liab'],\n", + " df=None)\n", + "top_list_df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/top_list.h5', key='top_list',\n", + " columns=['ts_code', 'trade_date', 'reason'],\n", + " df=None)\n", + "\n", + "top_list_df = top_list_df.sort_values(by='trade_date', ascending=False).drop_duplicates(subset=['ts_code', 'trade_date'], keep='first').sort_values(by='trade_date')\n", + "\n", + "stk_holdertrade_df = read_and_merge_h5_data('/mnt/d/PyProject/NewStock/data/stk_holdertrade.h5', key='stk_holdertrade',\n", + " columns=['ts_code', 'ann_date', 'in_de', 'change_ratio'],\n", + " df=None)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "92d84ce15a562ec6", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T13:08:01.612695Z", + "start_time": "2025-04-03T12:47:16.121802Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "开始计算股东增减持因子...\n", + "警告: 'in_de' 列中存在未映射的值,可能导致 _direction 列出现NaN。\n", + "股东增减持因子计算完成。\n", + "Calculating cat_senti_mom_vol_spike...\n", + "Finished cat_senti_mom_vol_spike.\n", + "Calculating cat_senti_pre_breakout...\n", + "Calculating atr_10 as it's missing...\n", + "Calculating atr_40 as it's missing...\n", + "Finished cat_senti_pre_breakout.\n", + "计算因子 ts_turnover_rate_acceleration_5_20\n", + "计算因子 ts_vol_sustain_10_30\n", + "计算因子 cs_amount_outlier_10\n", + "计算因子 ts_ff_to_total_turnover_ratio\n", + "计算因子 ts_price_volume_trend_coherence_5_20\n", + "计算因子 ts_ff_turnover_rate_surge_10\n", + "使用 'ann_date' 作为财务数据生效日期。\n", + "警告: 从 financial_data_subset 中移除了 366 行,因为其 'ts_code' 或 'ann_date' 列存在空值。\n", + "使用 'ann_date' 作为财务数据生效日期。\n", + "警告: 从 financial_data_subset 中移除了 366 行,因为其 'ts_code' 或 'ann_date' 列存在空值。\n", + "开始计算因子: AR, BR (原地修改)...\n", + "因子 AR, BR 计算成功。\n", + "因子 AR, BR 计算流程结束。\n", + "使用 'ann_date' 作为财务数据生效日期。\n", + "使用 'ann_date' 作为财务数据生效日期。\n", + "使用 'ann_date' 作为财务数据生效日期。\n", + "使用 'ann_date' 作为财务数据生效日期。\n", + "警告: 从 financial_data_subset 中移除了 366 行,因为其 'ts_code' 或 'ann_date' 列存在空值。\n", + "计算 BBI...\n", + "--- 计算日级别偏离度 (使用 pct_chg) ---\n", + "--- 计算日级别动量基准 (使用 pct_chg) ---\n", + "日级别动量基准计算完成 (使用 pct_chg)。\n", + "日级别偏离度计算完成 (使用 pct_chg)。\n", + "--- 计算日级别行业偏离度 (使用 pct_chg 和行业基准) ---\n", + "--- 计算日级别行业动量基准 (使用 pct_chg 和 cat_l2_code) ---\n", + "错误: 计算日级别行业动量基准需要以下列: ['pct_chg', 'cat_l2_code', 'trade_date', 'ts_code']。\n", + "错误: 计算日级别行业偏离度需要以下列: ['pct_chg', 'daily_industry_positive_benchmark', 'daily_industry_negative_benchmark']。请先运行 daily_industry_momentum_benchmark(df)。\n", + "Index(['ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'vol',\n", + " 'pct_chg', 'amount', 'turnover_rate', 'pe_ttm', 'circ_mv', 'total_mv',\n", + " 'volume_ratio', 'is_st', 'up_limit', 'down_limit', 'buy_sm_vol',\n", + " 'sell_sm_vol', 'buy_lg_vol', 'sell_lg_vol', 'buy_elg_vol',\n", + " 'sell_elg_vol', 'net_mf_vol', 'his_low', 'his_high', 'cost_5pct',\n", + " 'cost_15pct', 'cost_50pct', 'cost_85pct', 'cost_95pct', 'weight_avg',\n", + " 'winner_rate', 'l2_code', 'holder_net_change_sum_10d',\n", + " 'holder_increase_days_10d', 'holder_decrease_days_10d',\n", + " 'holder_any_increase_flag_10d', 'holder_any_decrease_flag_10d',\n", + " 'holder_direction_score_10d', 'cat_senti_mom_vol_spike',\n", + " 'cat_senti_pre_breakout', 'ts_turnover_rate_acceleration_5_20',\n", + " 'ts_vol_sustain_10_30', 'cs_amount_outlier_10',\n", + " 'ts_ff_to_total_turnover_ratio', 'ts_price_volume_trend_coherence_5_20',\n", + " 'ts_ff_turnover_rate_surge_10', 'undist_profit_ps', 'ocfps', 'AR', 'BR',\n", + " 'AR_BR', 'log_circ_mv', 'cashflow_to_ev_factor', 'book_to_price_ratio',\n", + " 'turnover_rate_mean_5', 'variance_20', 'bbi_ratio_factor',\n", + " 'daily_deviation', 'lg_elg_net_buy_vol', 'flow_lg_elg_intensity',\n", + " 'sm_net_buy_vol', 'flow_divergence_diff', 'flow_divergence_ratio',\n", + " 'total_buy_vol', 'lg_elg_buy_prop', 'flow_struct_buy_change',\n", + " 'lg_elg_net_buy_vol_change', 'flow_lg_elg_accel',\n", + " 'chip_concentration_range', 'chip_skewness', 'floating_chip_proxy',\n", + " 'cost_support_15pct_change', 'cat_winner_price_zone',\n", + " 'flow_chip_consistency', 'profit_taking_vs_absorb', '_is_positive',\n", + " '_is_negative', 'cat_is_positive', '_pos_returns', '_neg_returns',\n", + " '_pos_returns_sq', '_neg_returns_sq', 'upside_vol', 'downside_vol',\n", + " 'vol_ratio', 'return_skew', 'return_kurtosis', 'volume_change_rate',\n", + " 'cat_volume_breakout', 'turnover_deviation', 'cat_turnover_spike',\n", + " 'avg_volume_ratio', 'cat_volume_ratio_breakout', 'vol_spike',\n", + " 'vol_std_5', 'atr_24', 'atr_6', 'obv'],\n", + " dtype='object')\n", + "Calculating senti_strong_inflow...\n", + "Finished senti_strong_inflow.\n", + "Calculating lg_flow_mom_corr_20_60...\n", + "Finished lg_flow_mom_corr_20_60.\n", + "Calculating lg_flow_accel...\n", + "Finished lg_flow_accel.\n", + "Calculating profit_pressure...\n", + "Finished profit_pressure.\n", + "Calculating underwater_resistance...\n", + "Finished underwater_resistance.\n", + "Calculating cost_conc_std_20...\n", + "Finished cost_conc_std_20.\n", + "Calculating profit_decay_20...\n", + "Finished profit_decay_20.\n", + "Calculating vol_amp_loss_20...\n", + "Finished vol_amp_loss_20.\n", + "Calculating vol_drop_profit_cnt_5...\n", + "Finished vol_drop_profit_cnt_5.\n", + "Calculating lg_flow_vol_interact_20...\n", + "Finished lg_flow_vol_interact_20.\n", + "Calculating cost_break_confirm_cnt_5...\n", + "Finished cost_break_confirm_cnt_5.\n", + "Calculating atr_norm_channel_pos_14...\n", + "Finished atr_norm_channel_pos_14.\n", + "Calculating turnover_diff_skew_20...\n", + "Finished turnover_diff_skew_20.\n", + "Calculating lg_sm_flow_diverge_20...\n", + "Finished lg_sm_flow_diverge_20.\n", + "Calculating pullback_strong_20_20...\n", + "Finished pullback_strong_20_20.\n", + "Calculating vol_wgt_hist_pos_20...\n", + "Finished vol_wgt_hist_pos_20.\n", + "Calculating vol_adj_roc_20...\n", + "Finished vol_adj_roc_20.\n", + "Calculating cs_rank_net_lg_flow_val...\n", + "Finished cs_rank_net_lg_flow_val.\n", + "Calculating cs_rank_flow_divergence...\n", + "Finished cs_rank_flow_divergence.\n", + "Calculating cs_rank_ind_adj_lg_flow...\n", + "Finished cs_rank_ind_adj_lg_flow.\n", + "Calculating cs_rank_elg_buy_ratio...\n", + "Finished cs_rank_elg_buy_ratio.\n", + "Calculating cs_rank_rel_profit_margin...\n", + "Finished cs_rank_rel_profit_margin.\n", + "Calculating cs_rank_cost_breadth...\n", + "Finished cs_rank_cost_breadth.\n", + "Calculating cs_rank_dist_to_upper_cost...\n", + "Finished cs_rank_dist_to_upper_cost.\n", + "Calculating cs_rank_winner_rate...\n", + "Finished cs_rank_winner_rate.\n", + "Calculating cs_rank_intraday_range...\n", + "Finished cs_rank_intraday_range.\n", + "Calculating cs_rank_close_pos_in_range...\n", + "Finished cs_rank_close_pos_in_range.\n", + "Calculating cs_rank_opening_gap...\n", + "Error calculating cs_rank_opening_gap: Missing 'pre_close' column. Assigning NaN.\n", + "Calculating cs_rank_pos_in_hist_range...\n", + "Finished cs_rank_pos_in_hist_range.\n", + "Calculating cs_rank_vol_x_profit_margin...\n", + "Finished cs_rank_vol_x_profit_margin.\n", + "Calculating cs_rank_lg_flow_price_concordance...\n", + "Finished cs_rank_lg_flow_price_concordance.\n", + "Calculating cs_rank_turnover_per_winner...\n", + "Finished cs_rank_turnover_per_winner.\n", + "Calculating cs_rank_ind_cap_neutral_pe (Placeholder - requires statsmodels)...\n", + "Finished cs_rank_ind_cap_neutral_pe (Placeholder).\n", + "Calculating cs_rank_volume_ratio...\n", + "Finished cs_rank_volume_ratio.\n", + "Calculating cs_rank_elg_buy_sell_sm_ratio...\n", + "Finished cs_rank_elg_buy_sell_sm_ratio.\n", + "Calculating cs_rank_cost_dist_vol_ratio...\n", + "Finished cs_rank_cost_dist_vol_ratio.\n", + "Calculating cs_rank_size...\n", + "Finished cs_rank_size.\n", + "\n", + "RangeIndex: 4554725 entries, 0 to 4554724\n", + "Columns: 194 entries, ts_code to cs_rank_size\n", + "dtypes: bool(10), datetime64[ns](1), float64(173), int64(6), object(4)\n", + "memory usage: 6.3+ GB\n", + "None\n", + "['ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'vol', 'pct_chg', 'amount', 'turnover_rate', 'pe_ttm', 'circ_mv', 'total_mv', 'volume_ratio', 'is_st', 'up_limit', 'down_limit', 'buy_sm_vol', 'sell_sm_vol', 'buy_lg_vol', 'sell_lg_vol', 'buy_elg_vol', 'sell_elg_vol', 'net_mf_vol', 'his_low', 'his_high', 'cost_5pct', 'cost_15pct', 'cost_50pct', 'cost_85pct', 'cost_95pct', 'weight_avg', 'winner_rate', 'cat_l2_code', 'holder_net_change_sum_10d', 'holder_increase_days_10d', 'holder_decrease_days_10d', 'holder_any_increase_flag_10d', 'holder_any_decrease_flag_10d', 'holder_direction_score_10d', 'cat_senti_mom_vol_spike', 'cat_senti_pre_breakout', 'ts_turnover_rate_acceleration_5_20', 'ts_vol_sustain_10_30', 'cs_amount_outlier_10', 'ts_ff_to_total_turnover_ratio', 'ts_price_volume_trend_coherence_5_20', 'ts_ff_turnover_rate_surge_10', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', 'log_circ_mv', 'cashflow_to_ev_factor', 'book_to_price_ratio', 'turnover_rate_mean_5', 'variance_20', 'bbi_ratio_factor', 'daily_deviation', 'lg_elg_net_buy_vol', 'flow_lg_elg_intensity', 'sm_net_buy_vol', 'flow_divergence_diff', 'flow_divergence_ratio', 'total_buy_vol', 'lg_elg_buy_prop', 'flow_struct_buy_change', 'lg_elg_net_buy_vol_change', 'flow_lg_elg_accel', 'chip_concentration_range', 'chip_skewness', 'floating_chip_proxy', 'cost_support_15pct_change', 'cat_winner_price_zone', 'flow_chip_consistency', 'profit_taking_vs_absorb', 'cat_is_positive', 'upside_vol', 'downside_vol', 'vol_ratio', 'return_skew', 'return_kurtosis', 'volume_change_rate', 'cat_volume_breakout', 'turnover_deviation', 'cat_turnover_spike', 'avg_volume_ratio', 'cat_volume_ratio_breakout', 'vol_spike', 'vol_std_5', 'atr_24', 'atr_6', 'obv', 'maobv_6', 'rsi_3', 'return_5', 'return_20', 'std_return_5', 'std_return_90', 'std_return_90_2', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4', 'rank_act_factor1', 'rank_act_factor2', 'rank_act_factor3', 'cov', 'delta_cov', 'alpha_22_improved', 'alpha_003', 'alpha_007', 'alpha_013', 'vol_break', 'weight_roc5', 'price_cost_divergence', 'smallcap_concentration', 'cost_stability', 'high_cost_break_days', 'liquidity_risk', 'turnover_std', 'mv_volatility', 'volume_growth', 'mv_growth', 'momentum_factor', 'resonance_factor', 'log_close', 'cat_vol_spike', 'up', 'down', 'obv_maobv_6', 'std_return_5_over_std_return_90', 'std_return_90_minus_std_return_90_2', 'cat_af2', 'cat_af3', 'cat_af4', 'act_factor5', 'act_factor6', 'active_buy_volume_large', 'active_buy_volume_big', 'active_buy_volume_small', 'buy_lg_vol_minus_sell_lg_vol', 'buy_elg_vol_minus_sell_elg_vol', 'ctrl_strength', 'low_cost_dev', 'asymmetry', 'lock_factor', 'cat_vol_break', 'cost_atr_adj', 'cat_golden_resonance', 'mv_turnover_ratio', 'mv_adjusted_volume', 'mv_weighted_turnover', 'nonlinear_mv_volume', 'mv_volume_ratio', 'mv_momentum', 'senti_strong_inflow', 'lg_flow_mom_corr_20_60', 'lg_flow_accel', 'profit_pressure', 'underwater_resistance', 'cost_conc_std_20', 'profit_decay_20', 'vol_amp_loss_20', 'vol_drop_profit_cnt_5', 'lg_flow_vol_interact_20', 'cost_break_confirm_cnt_5', 'atr_norm_channel_pos_14', 'turnover_diff_skew_20', 'lg_sm_flow_diverge_20', 'pullback_strong_20_20', 'vol_wgt_hist_pos_20', 'vol_adj_roc_20', 'cs_rank_net_lg_flow_val', 'cs_rank_flow_divergence', 'cs_rank_ind_adj_lg_flow', 'cs_rank_elg_buy_ratio', 'cs_rank_rel_profit_margin', 'cs_rank_cost_breadth', 'cs_rank_dist_to_upper_cost', 'cs_rank_winner_rate', 'cs_rank_intraday_range', 'cs_rank_close_pos_in_range', 'cs_rank_opening_gap', 'cs_rank_pos_in_hist_range', 'cs_rank_vol_x_profit_margin', 'cs_rank_lg_flow_price_concordance', 'cs_rank_turnover_per_winner', 'cs_rank_ind_cap_neutral_pe', 'cs_rank_volume_ratio', 'cs_rank_elg_buy_sell_sm_ratio', 'cs_rank_cost_dist_vol_ratio', 'cs_rank_size']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from main.factor.factor import *\n", + "from main.factor.money_factor import * \n", + "\n", + "\n", + "def filter_data(df):\n", + " # df = df.groupby('trade_date').apply(lambda x: x.nlargest(1000, 'act_factor1'))\n", + " df = df[~df[\"is_st\"]]\n", + " df = df[~df[\"ts_code\"].str.endswith(\"BJ\")]\n", + " df = df[~df[\"ts_code\"].str.startswith(\"30\")]\n", + " df = df[~df[\"ts_code\"].str.startswith(\"68\")]\n", + " df = df[~df[\"ts_code\"].str.startswith(\"8\")]\n", + " df = df[df[\"trade_date\"] >= \"2019-01-01\"]\n", + " if \"in_date\" in df.columns:\n", + " df = df.drop(columns=[\"in_date\"])\n", + " df = df.reset_index(drop=True)\n", + " return df\n", + "\n", + "\n", + "gc.collect()\n", + "\n", + "df = filter_data(df)\n", + "df = df.sort_values(by=[\"ts_code\", \"trade_date\"])\n", + "\n", + "# df = price_minus_deduction_price(df, n=120)\n", + "# df = price_deduction_price_diff_ratio_to_sma(df, n=120)\n", + "# df = cat_price_vs_sma_vs_deduction_price(df, n=120)\n", + "# df = cat_reason(df, top_list_df)\n", + "# df = cat_is_on_top_list(df, top_list_df)\n", + "df = holder_trade_factors(df, stk_holdertrade_df)\n", + "\n", + "df = cat_senti_mom_vol_spike(\n", + " df,\n", + " return_period=3,\n", + " return_threshold=0.03, # 近3日涨幅超3%\n", + " volume_ratio_threshold=1.3,\n", + " current_pct_chg_min=0.0, # 当日必须收红\n", + " current_pct_chg_max=0.05,\n", + ") # 当日涨幅不宜过大\n", + "\n", + "df = cat_senti_pre_breakout(\n", + " df,\n", + " atr_short_N=10,\n", + " atr_long_M=40,\n", + " vol_atrophy_N=10,\n", + " vol_atrophy_M=40,\n", + " price_stab_N=5,\n", + " price_stab_threshold=0.06,\n", + " current_pct_chg_min_signal=0.002,\n", + " current_pct_chg_max_signal=0.05,\n", + " volume_ratio_signal_threshold=1.1,\n", + ")\n", + "\n", + "df = ts_turnover_rate_acceleration_5_20(df)\n", + "df = ts_vol_sustain_10_30(df)\n", + "# df = cs_turnover_rate_relative_strength_20(df)\n", + "df = cs_amount_outlier_10(df)\n", + "df = ts_ff_to_total_turnover_ratio(df)\n", + "df = ts_price_volume_trend_coherence_5_20(df)\n", + "# df = ts_turnover_rate_trend_strength_5(df)\n", + "df = ts_ff_turnover_rate_surge_10(df)\n", + "\n", + "df = add_financial_factor(df, fina_indicator_df, factor_value_col=\"undist_profit_ps\")\n", + "df = add_financial_factor(df, fina_indicator_df, factor_value_col=\"ocfps\")\n", + "calculate_arbr(df, N=26)\n", + "df[\"log_circ_mv\"] = np.log(df[\"circ_mv\"])\n", + "df = calculate_cashflow_to_ev_factor(df, cashflow_df, balancesheet_df)\n", + "df = caculate_book_to_price_ratio(df, fina_indicator_df)\n", + "df = turnover_rate_n(df, n=5)\n", + "df = variance_n(df, n=20)\n", + "df = bbi_ratio_factor(df)\n", + "df = daily_deviation(df)\n", + "df = daily_industry_deviation(df)\n", + "df, _ = get_rolling_factor(df)\n", + "df, _ = get_simple_factor(df)\n", + "\n", + "df = calculate_strong_inflow_signal(df)\n", + "\n", + "df = df.rename(columns={\"l1_code\": \"cat_l1_code\"})\n", + "df = df.rename(columns={\"l2_code\": \"cat_l2_code\"})\n", + "\n", + "lg_flow_mom_corr(df, N=20, M=60)\n", + "lg_flow_accel(df)\n", + "profit_pressure(df)\n", + "underwater_resistance(df)\n", + "cost_conc_std(df, N=20)\n", + "profit_decay(df, N=20)\n", + "vol_amp_loss(df, N=20)\n", + "vol_drop_profit_cnt(df, N=20, M=5)\n", + "lg_flow_vol_interact(df, N=20)\n", + "cost_break_confirm_cnt(df, M=5)\n", + "atr_norm_channel_pos(df, N=14)\n", + "turnover_diff_skew(df, N=20)\n", + "lg_sm_flow_diverge(df, N=20)\n", + "pullback_strong(df, N=20, M=20)\n", + "vol_wgt_hist_pos(df, N=20)\n", + "vol_adj_roc(df, N=20)\n", + "\n", + "cs_rank_net_lg_flow_val(df)\n", + "cs_rank_flow_divergence(df)\n", + "cs_rank_industry_adj_lg_flow(df) # Needs cat_l2_code\n", + "cs_rank_elg_buy_ratio(df)\n", + "cs_rank_rel_profit_margin(df)\n", + "cs_rank_cost_breadth(df)\n", + "cs_rank_dist_to_upper_cost(df)\n", + "cs_rank_winner_rate(df)\n", + "cs_rank_intraday_range(df)\n", + "cs_rank_close_pos_in_range(df)\n", + "cs_rank_opening_gap(df) # Needs pre_close\n", + "cs_rank_pos_in_hist_range(df) # Needs his_low, his_high\n", + "cs_rank_vol_x_profit_margin(df)\n", + "cs_rank_lg_flow_price_concordance(df)\n", + "cs_rank_turnover_per_winner(df)\n", + "cs_rank_ind_cap_neutral_pe(df) # Placeholder - needs external libraries\n", + "cs_rank_volume_ratio(df) # Needs volume_ratio\n", + "cs_rank_elg_buy_sell_sm_ratio(df)\n", + "cs_rank_cost_dist_vol_ratio(df) # Needs volume_ratio\n", + "cs_rank_size(df) # Needs circ_mv\n", + "\n", + "\n", + "# df = df.merge(index_data, on='trade_date', how='left')\n", + "\n", + "print(df.info())\n", + "print(df.columns.tolist())" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "b87b938028afa206", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T13:08:03.658725Z", + "start_time": "2025-04-03T13:08:02.469611Z" + } + }, + "outputs": [], + "source": [ + "from scipy.stats import ks_2samp, wasserstein_distance\n", + "\n", + "\n", + "def remove_shifted_features(train_data, test_data, feature_columns, ks_threshold=0.05, wasserstein_threshold=0.1,\n", + " importance_threshold=0.05):\n", + " dropped_features = []\n", + "\n", + " # **统计数据漂移**\n", + " numeric_columns = train_data.select_dtypes(include=['float64', 'int64']).columns\n", + " numeric_columns = [col for col in numeric_columns if col in feature_columns]\n", + " for feature in numeric_columns:\n", + " ks_stat, p_value = ks_2samp(train_data[feature], test_data[feature])\n", + " wasserstein_dist = wasserstein_distance(train_data[feature], test_data[feature])\n", + "\n", + " if p_value < ks_threshold or wasserstein_dist > wasserstein_threshold:\n", + " dropped_features.append(feature)\n", + "\n", + " print(f\"检测到 {len(dropped_features)} 个可能漂移的特征: {dropped_features}\")\n", + "\n", + " # **应用阈值进行最终筛选**\n", + " filtered_features = [f for f in feature_columns if f not in dropped_features]\n", + "\n", + " return filtered_features, dropped_features\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "f4f16d63ad18d1bc", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T13:08:03.670700Z", + "start_time": "2025-04-03T13:08:03.665739Z" + } + }, + "outputs": [], + "source": [ + "import polars as pl\n", + "import numpy as np\n", + "# from tqdm import tqdm # Polars 通常处理速度快,可能不需要 tqdm,但如果需要可以保留\n", + "\n", + "def cs_mad_filter_polars(df: pl.DataFrame,\n", + " features: list[str],\n", + " k: float = 3.0,\n", + " scale_factor: float = 1.4826) -> pl.DataFrame:\n", + " \"\"\"\n", + " 对指定特征列进行截面 MAD 去极值处理 (Polars 版本)。\n", + "\n", + " 方法: 对每日截面数据,计算 median 和 MAD,\n", + " 将超出 [median - k * scale * MAD, median + k * scale * MAD] 范围的值\n", + " 替换为边界值 (Winsorization)。\n", + " scale_factor=1.4826 使得 MAD 约等于正态分布的标准差。\n", + "\n", + " Args:\n", + " df (pl.DataFrame): 输入 Polars DataFrame,需包含 'trade_date' 和 features 列。\n", + " features (list): 需要处理的特征列名列表。\n", + " k (float): MAD 的倍数,用于确定边界。默认为 3.0。\n", + " scale_factor (float): MAD 的缩放因子。默认为 1.4826。\n", + "\n", + " Returns:\n", + " pl.DataFrame: 处理后的 Polars DataFrame (返回新 DataFrame,原 DataFrame 不变)。\n", + " \"\"\"\n", + " print(f\"开始截面 MAD 去极值处理 (k={k})...\")\n", + "\n", + " # 检查特征列是否存在\n", + " existing_features = [col for col in features if col in df.columns]\n", + " missing_features = [col for col in features if col not in df.columns]\n", + "\n", + " if missing_features:\n", + " print(f\"警告: DataFrame 中缺少以下特征列: {missing_features}。这些列将跳过去极值处理。\")\n", + "\n", + " if not existing_features:\n", + " print(\"没有找到需要处理的特征列。跳过去极值处理。\")\n", + " return df # 返回原始 DataFrame\n", + "\n", + " # 构建一个表达式列表,用于一次性处理所有特征列\n", + " expressions = []\n", + " for col in existing_features:\n", + " col_expr = pl.col(col)\n", + "\n", + " try:\n", + " # 计算截面中位数 (median) - 使用 over()\n", + " median_val = col_expr.median().over('trade_date')\n", + "\n", + " # 计算截面 MAD (Median Absolute Deviation from Median) - 使用 over()\n", + " mad_val = (col_expr - median_val).abs().median().over('trade_date')\n", + "\n", + " # 计算上下边界\n", + " # 确保 mad_val 不为 null 或 0,否则边界会是 NaN\n", + " lower_bound = median_val - k * scale_factor * mad_val\n", + " upper_bound = median_val + k * scale_factor * mad_val\n", + "\n", + " # 应用 Winsorization (裁剪值到边界内)\n", + " # 使用 when/then/otherwise 来确保边界值为 NaN 或 MAD 为 0 时不进行过滤,保留原始值\n", + " clipped_col_expr = pl.when(\n", + " lower_bound.is_not_null() &\n", + " upper_bound.is_not_null() &\n", + " mad_val.is_not_null() &\n", + " (mad_val != 0) # MAD 为 0 意味着所有值都相同,此时不应裁剪\n", + " ).then(col_expr.clip(lower_bound, upper_bound)).otherwise(col_expr).alias(col) # 保持列名不变\n", + "\n", + " expressions.append(clipped_col_expr)\n", + "\n", + " except Exception as e:\n", + " print(f\"警告: 处理列 '{col}' 时发生错误: {e},跳过此列的 MAD 处理。保留原始列。\")\n", + " expressions.append(col_expr) # 发生错误时保留原始列\n", + "\n", + " # 使用 with_columns 一次性应用所有表达式,创建新的 DataFrame\n", + " result_df = df.with_columns(expressions)\n", + "\n", + " print(\"截面 MAD 去极值处理完成。\")\n", + " return result_df\n", + "\n", + "\n", + "# --- 您的 cs_zscore_standardize_polars 函数 (确保其也是全 Polars 实现) ---\n", + "# (如果您的 cs_zscore_standardize_polars 也有类似问题,也需要按此模式修改)\n", + "def cs_zscore_standardize_polars(df: pl.DataFrame, features: list[str], epsilon: float = 1e-10) -> pl.DataFrame:\n", + " print(\"开始截面 Z-Score 标准化...\")\n", + "\n", + " existing_features = [col for col in features if col in df.columns]\n", + " missing_features = [col for col in features if col not in df.columns]\n", + "\n", + " if missing_features:\n", + " print(f\"警告: DataFrame 中缺少以下特征列: {missing_features}。这些列将跳过标准化处理。\")\n", + "\n", + " if not existing_features:\n", + " print(\"没有找到需要标准化的特征列。跳过标准化处理。\")\n", + " return df\n", + "\n", + " expressions = []\n", + " for col in existing_features:\n", + " col_expr = pl.col(col)\n", + "\n", + " if not col_expr.dtype.is_numeric():\n", + " print(f\"警告: 列 '{col}' 不是数值类型 ({col_expr.dtype}),跳过此列的标准化处理。\")\n", + " expressions.append(col_expr)\n", + " continue\n", + "\n", + " mean_val = col_expr.mean().over('trade_date')\n", + " std_val = col_expr.std().over('trade_date')\n", + "\n", + " # 处理标准差为 0 或 NaN 的情况,防止 Inf/NaN 扩散\n", + " z_score_expr = pl.when(std_val.is_null() | (std_val == 0)).then(0) # 如果标准差为 null 或 0,设为 0 (或 np.nan,取决于业务逻辑).otherwise((col_expr - mean_val) / (std_val + epsilon)).alias(col)\n", + " expressions.append(z_score_expr)\n", + "\n", + " result_df = df.with_columns(expressions)\n", + " print(\"截面 Z-Score 标准化完成。\")\n", + " return result_df\n", + "\n", + "\n", + "# --- 2. 行业市值中性化 ---\n", + "def cs_neutralize_industry_cap(df: pd.DataFrame,\n", + " features: list,\n", + " industry_col: str = 'cat_l2_code',\n", + " market_cap_col: str = 'circ_mv'):\n", + " \"\"\"\n", + " 对指定特征列进行截面行业和对数市值中性化 (原地修改)。\n", + " 使用 OLS 回归: feature ~ 1 + log(market_cap) + C(industry)\n", + " 将回归残差写回原特征列。\n", + "\n", + " Args:\n", + " df (pd.DataFrame): 输入 DataFrame,需包含 'trade_date', features 列,\n", + " industry_col, market_cap_col。\n", + " features (list): 需要处理的特征列名列表。\n", + " industry_col (str): 行业分类列名。\n", + " market_cap_col (str): 流通市值列名。\n", + "\n", + " WARNING: 此函数会原地修改输入的 DataFrame 'df' 的 features 列。\n", + " 计算量较大,可能耗时较长。\n", + " 需要安装 statsmodels 库 (pip install statsmodels)。\n", + " \"\"\"\n", + " print(\"开始截面行业市值中性化...\")\n", + " required_cols = features + ['trade_date', industry_col, market_cap_col]\n", + " if not all(col in df.columns for col in required_cols):\n", + " missing = [col for col in required_cols if col not in df.columns]\n", + " print(f\"错误: DataFrame 中缺少必需列: {missing}。无法进行中性化。\")\n", + " return\n", + "\n", + " # 预处理:计算 log 市值,处理 industry code 可能的 NaN\n", + " log_cap_col = '_log_market_cap'\n", + " df[log_cap_col] = np.log1p(df[market_cap_col]) # log1p 处理 0 值\n", + " # df[industry_col] = df[industry_col].cat.add_categories('UnknownIndustry')\n", + " # df[industry_col] = df[industry_col].fillna('UnknownIndustry') # 填充行业 NaN\n", + " # df[industry_col] = df[industry_col].astype('category') # 转为类别,ols 会自动处理\n", + "\n", + " dates = df['trade_date'].unique()\n", + " all_residuals = [] # 用于收集所有日期的残差\n", + "\n", + " for date in tqdm(dates, desc=\"Neutralizing\"):\n", + " daily_data = df.loc[df['trade_date'] == date, features + [log_cap_col, industry_col]].copy() # 使用 .loc 获取副本\n", + "\n", + " # 准备自变量 X (常数项 + log市值 + 行业哑变量)\n", + " X = daily_data[[log_cap_col]]\n", + " X = sm.add_constant(X, prepend=True) # 添加常数项\n", + " # 创建行业哑变量 (drop_first=True 避免共线性)\n", + " industry_dummies = pd.get_dummies(daily_data[industry_col], prefix=industry_col, drop_first=True)\n", + " industry_dummies = industry_dummies.astype(int)\n", + " X = pd.concat([X, industry_dummies], axis=1)\n", + "\n", + " daily_residuals = daily_data[[col for col in features]].copy() # 创建用于存储残差的df\n", + "\n", + " for col in features:\n", + " Y = daily_data[col]\n", + "\n", + " # 处理 NaN 值,确保 X 和 Y 在相同位置有有效值\n", + " valid_mask = Y.notna() & X.notna().all(axis=1)\n", + " if valid_mask.sum() < (X.shape[1] + 1): # 数据点不足以估计模型\n", + " print(f\"警告: 日期 {date}, 特征 {col} 有效数据不足 ({valid_mask.sum()}个),无法中性化,填充 NaN。\")\n", + " daily_residuals[col] = np.nan\n", + " continue\n", + "\n", + " Y_valid = Y[valid_mask]\n", + " X_valid = X[valid_mask]\n", + "\n", + " # 执行 OLS 回归\n", + " try:\n", + " model = sm.OLS(Y_valid.to_numpy(), X_valid.to_numpy())\n", + " results = model.fit()\n", + " # 将残差填回对应位置\n", + " daily_residuals.loc[valid_mask, col] = results.resid\n", + " daily_residuals.loc[~valid_mask, col] = np.nan # 原本无效的位置填充 NaN\n", + " except Exception as e:\n", + " print(f\"警告: 日期 {date}, 特征 {col} 回归失败: {e},填充 NaN。\")\n", + " daily_residuals[col] = np.nan\n", + " break\n", + "\n", + " all_residuals.append(daily_residuals)\n", + "\n", + " # 合并所有日期的残差结果\n", + " if all_residuals:\n", + " residuals_df = pd.concat(all_residuals)\n", + " # 将残差结果更新回原始 df (原地修改)\n", + " # 使用 update 比 merge 更适合基于索引的原地更新\n", + " # 确保 residuals_df 的索引与 df 中对应部分一致\n", + " df.update(residuals_df)\n", + " else:\n", + " print(\"没有有效的残差结果可以合并。\")\n", + "\n", + "\n", + " # 清理临时列\n", + " df.drop(columns=[log_cap_col], inplace=True)\n", + " print(\"截面行业市值中性化完成。\")\n", + "\n", + "\n", + "# --- 3. Z-Score 标准化 ---\n", + "\n", + "import polars as pl\n", + "import numpy as np # 用于 np.float64, np.nan 等\n", + "\n", + "def cs_zscore_standardize_polars(df: pl.DataFrame,\n", + " features: list,\n", + " epsilon: float = 1e-10) -> pl.DataFrame:\n", + " \"\"\"\n", + " 对指定特征列进行截面 Z-Score 标准化 (Polars 版本)。\n", + " 方法: Z = (value - cross_sectional_mean) / (cross_sectional_std + epsilon)\n", + "\n", + " Args:\n", + " df (pl.DataFrame): 输入 Polars DataFrame,需包含 'trade_date' 和 features 列。\n", + " features (list): 需要处理的特征列名列表。\n", + " epsilon (float): 防止除以零的小常数。\n", + "\n", + " Returns:\n", + " pl.DataFrame: 处理后的 Polars DataFrame (返回新 DataFrame,原 DataFrame 不变)。\n", + " \"\"\"\n", + " print(\"开始截面 Z-Score 标准化...\")\n", + "\n", + " # 检查特征列是否存在\n", + " existing_features = [col for col in features if col in df.columns]\n", + " missing_features = [col for col in features if col not in df.columns]\n", + "\n", + " if missing_features:\n", + " print(f\"警告: DataFrame 中缺少以下特征列: {missing_features}。这些列将跳过标准化处理。\")\n", + "\n", + " if not existing_features:\n", + " print(\"没有找到需要标准化的特征列。跳过标准化处理。\")\n", + " return df # 返回原始 DataFrame\n", + "\n", + " # 构建一个表达式列表,用于一次性处理所有特征列\n", + " expressions = []\n", + " for col in existing_features:\n", + " col_expr = pl.col(col)\n", + "\n", + " # 确保列是数值类型,否则跳过\n", + " if not col_expr.dtype.is_numeric():\n", + " print(f\"警告: 列 '{col}' 不是数值类型 ({col_expr.dtype}),跳过此列的标准化处理。\")\n", + " expressions.append(col_expr) # 保留原始列\n", + " continue\n", + "\n", + " try:\n", + " # 计算截面均值和标准差\n", + " mean_val = col_expr.mean().over('trade_date')\n", + " std_val = col_expr.std().over('trade_date')\n", + "\n", + " # 计算 Z-Score\n", + " # 这里需要处理 std_val 可能是 0 的情况,即使有 epsilon,也可能因浮点精度问题导致问题\n", + " # 或当 trade_date 组内只有少数几个相同的值时 std_val 可能会是 NaN 或 0\n", + " # 使用 when/then/otherwise 来处理 std_val 为 0 或 NaN 的情况,防止 Inf/NaN 扩散\n", + " z_score_expr = pl.when(std_val.is_null() | (std_val == 0)).then(0).otherwise((col_expr - mean_val) / (std_val + epsilon)).alias(col)\n", + "\n", + " expressions.append(z_score_expr)\n", + "\n", + " except Exception as e:\n", + " print(f\"警告: 处理列 '{col}' 时发生错误: {e},跳过此列的标准化处理。保留原始列。\")\n", + " expressions.append(col_expr) # 发生错误时保留原始列\n", + "\n", + " # 使用 with_columns 一次性应用所有表达式,创建新的 DataFrame\n", + " result_df = df.with_columns(expressions)\n", + "\n", + " print(\"截面 Z-Score 标准化完成。\")\n", + " return result_df\n", + "\n", + "\n", + "def fill_nan_with_daily_median(df: pd.DataFrame, feature_columns: list[str]) -> pd.DataFrame:\n", + " \"\"\"\n", + " 对指定特征列进行每日截面中位数填充缺失值 (NaN)。\n", + "\n", + " 参数:\n", + " df (pd.DataFrame): 包含多日数据的DataFrame,需要包含 'trade_date' 和 feature_columns 中的列。\n", + " feature_columns (list[str]): 需要进行缺失值填充的特征列名称列表。\n", + "\n", + " 返回:\n", + " pd.DataFrame: 包含缺失值填充后特征列的DataFrame。在输入DataFrame的副本上操作。\n", + " \"\"\"\n", + " processed_df = df.copy() # 在副本上操作,保留原始数据\n", + "\n", + " # 确保 trade_date 是 datetime 类型以便正确分组\n", + " processed_df['trade_date'] = pd.to_datetime(processed_df['trade_date'])\n", + "\n", + " def _fill_daily_nan(group):\n", + " # group 是某一个交易日的 DataFrame\n", + "\n", + " # 遍历指定的特征列\n", + " for feature_col in feature_columns:\n", + " # 检查列是否存在于当前分组中\n", + " if feature_col in group.columns:\n", + " # 计算当日该特征的中位数\n", + " median_val = group[feature_col].median()\n", + "\n", + " # 使用当日中位数填充该特征列的 NaN 值\n", + " # inplace=True 会直接修改 group DataFrame\n", + " group[feature_col].fillna(median_val, inplace=True)\n", + " # else:\n", + " # print(f\"Warning: Feature column '{feature_col}' not found in daily group for {group['trade_date'].iloc[0]}. Skipping.\")\n", + "\n", + " return group\n", + "\n", + " # 按交易日期分组,并应用每日填充函数\n", + " # group_keys=False 避免将分组键添加到结果索引中\n", + " filled_df = processed_df.groupby('trade_date', group_keys=False).apply(_fill_daily_nan)\n", + "\n", + " return filled_df" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "40e6b68a91b30c79", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T13:08:04.694262Z", + "start_time": "2025-04-03T13:08:03.694904Z" + } + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "\n", + "\n", + "def remove_outliers_label_percentile(label: pd.Series, lower_percentile: float = 0.01, upper_percentile: float = 0.99,\n", + " log=True):\n", + " if not (0 <= lower_percentile < upper_percentile <= 1):\n", + " raise ValueError(\"Percentile values must satisfy 0 <= lower_percentile < upper_percentile <= 1.\")\n", + "\n", + " # Calculate lower and upper bounds based on percentiles\n", + " lower_bound = label.quantile(lower_percentile)\n", + " upper_bound = label.quantile(upper_percentile)\n", + "\n", + " # Filter out values outside the bounds\n", + " filtered_label = label[(label >= lower_bound) & (label <= upper_bound)]\n", + "\n", + " # Print the number of removed outliers\n", + " if log:\n", + " print(f\"Removed {len(label) - len(filtered_label)} outliers.\")\n", + " return filtered_label\n", + "\n", + "\n", + "def calculate_risk_adjusted_target(df, days=5):\n", + " df = df.sort_values(by=['ts_code', 'trade_date'])\n", + "\n", + " df['future_close'] = df.groupby('ts_code')['close'].shift(-days)\n", + " df['future_open'] = df.groupby('ts_code')['open'].shift(-1)\n", + " df['future_return'] = (df['future_close'] - df['future_open']) / df['future_open']\n", + "\n", + " df['future_volatility'] = df.groupby('ts_code')['future_return'].rolling(days, min_periods=1).std().reset_index(\n", + " level=0, drop=True)\n", + " sharpe_ratio = df['future_return'] * df['future_volatility']\n", + " sharpe_ratio.replace([np.inf, -np.inf], np.nan, inplace=True)\n", + "\n", + " return sharpe_ratio\n", + "\n", + "\n", + "def calculate_score(df, days=5, lambda_param=1.0):\n", + " def calculate_max_drawdown(prices):\n", + " peak = prices.iloc[0] # 初始化峰值\n", + " max_drawdown = 0 # 初始化最大回撤\n", + "\n", + " for price in prices:\n", + " if price > peak:\n", + " peak = price # 更新峰值\n", + " else:\n", + " drawdown = (peak - price) / peak # 计算当前回撤\n", + " max_drawdown = max(max_drawdown, drawdown) # 更新最大回撤\n", + "\n", + " return max_drawdown\n", + "\n", + " def compute_stock_score(stock_df):\n", + " stock_df = stock_df.sort_values(by=['trade_date'])\n", + " future_return = stock_df['future_return']\n", + " # 使用已有的 pct_chg 字段计算波动率\n", + " volatility = stock_df['pct_chg'].rolling(days).std().shift(-days)\n", + " max_drawdown = stock_df['close'].rolling(days).apply(calculate_max_drawdown, raw=False).shift(-days)\n", + " score = future_return - lambda_param * max_drawdown\n", + " return score\n", + "\n", + " # # 确保 DataFrame 按照股票代码和交易日期排序\n", + " # df = df.sort_values(by=['ts_code', 'trade_date'])\n", + "\n", + " # 对每个股票分别计算 score\n", + " df['score'] = df.groupby('ts_code').apply(compute_stock_score).reset_index(level=0, drop=True)\n", + "\n", + " return df['score']\n", + "\n", + "\n", + "def remove_highly_correlated_features(df, feature_columns, threshold=0.9):\n", + " numeric_features = df[feature_columns].select_dtypes(include=[np.number]).columns.tolist()\n", + " if not numeric_features:\n", + " raise ValueError(\"No numeric features found in the provided data.\")\n", + "\n", + " corr_matrix = df[numeric_features].corr().abs()\n", + " upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))\n", + " to_drop = [column for column in upper.columns if any(upper[column] > threshold)]\n", + " remaining_features = [col for col in feature_columns if col not in to_drop\n", + " or 'act' in col or 'af' in col]\n", + " return remaining_features\n", + "\n", + "\n", + "def cross_sectional_standardization(df, features):\n", + " df_sorted = df.sort_values(by='trade_date') # 按时间排序\n", + " df_standardized = df_sorted.copy()\n", + "\n", + " for date in df_sorted['trade_date'].unique():\n", + " # 获取当前时间点的数据\n", + " current_data = df_standardized[df_standardized['trade_date'] == date]\n", + "\n", + " # 只对指定特征进行标准化\n", + " scaler = StandardScaler()\n", + " standardized_values = scaler.fit_transform(current_data[features])\n", + "\n", + " # 将标准化结果重新赋值回去\n", + " df_standardized.loc[df_standardized['trade_date'] == date, features] = standardized_values\n", + "\n", + " return df_standardized\n", + "\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "\n", + "def neutralize_manual_revised(df: pd.DataFrame, features: list, industry_col: str, mkt_cap_col: str) -> pd.DataFrame:\n", + " \"\"\"\n", + " 手动实现简单回归以提升速度,通过构建 Series 确保索引对齐。\n", + " 对特征在行业内部进行市值中性化。\n", + "\n", + " Args:\n", + " df: 输入的 DataFrame,包含特征、行业分类和市值列。\n", + " features: 需要进行中性化的特征列名列表。\n", + " industry_col: 行业分类列的列名。\n", + " mkt_cap_col: 市值列的列名。\n", + "\n", + " Returns:\n", + " 中性化后的 DataFrame。\n", + " \"\"\"\n", + "\n", + " df[mkt_cap_col] = pd.to_numeric(df[mkt_cap_col], errors='coerce')\n", + " df_cleaned = df.dropna(subset=[mkt_cap_col]).copy()\n", + " df_cleaned = df_cleaned[df_cleaned[mkt_cap_col] > 0].copy()\n", + "\n", + " if df_cleaned.empty:\n", + " print(\"警告: 清理市值异常值后 DataFrame 为空。\")\n", + " return df # 返回原始或空df,取决于清理前的状态\n", + "\n", + " processed_df = df\n", + "\n", + " for col in features:\n", + " if col not in df_cleaned.columns:\n", + " print(f\"警告: 特征列 '{col}' 不存在于清理后的 DataFrame 中,已跳过。\")\n", + " # 对于原始 df 中该列不存在的,在结果 df 中也保持原样(可能全是NaN)\n", + " processed_df[col] = df[col] if col in df.columns else np.nan\n", + " continue\n", + "\n", + " # 跳过对控制变量本身进行中性化\n", + " if col == mkt_cap_col or col == industry_col:\n", + " print(f\"警告: 特征列 '{col}' 是控制变量或内部使用的列,跳过中性化。\")\n", + " # 在结果 df 中也保持原样\n", + " processed_df[col] = df[col] if col in df.columns else np.nan\n", + " continue\n", + "\n", + " residual_series = pd.Series(index=df_cleaned.index, dtype=float)\n", + "\n", + " # 在分组前处理特征列的 NaN,只对有因子值的行进行回归计算\n", + " df_subset_factor = df_cleaned.dropna(subset=[col]).copy()\n", + "\n", + " if not df_subset_factor.empty:\n", + " for industry, group in df_subset_factor.groupby(industry_col):\n", + " x = group[mkt_cap_col] # 市值对数\n", + " y = group[col] # 因子值\n", + "\n", + " # 确保有足够的数据点 (>1) 且市值对数有方差 (>0) 进行回归计算\n", + " # 检查 np.var > 一个很小的正数,避免浮点数误差导致的零方差判断问题\n", + " if len(group) > 1 and np.var(x) > 1e-9:\n", + " try:\n", + " beta = np.cov(y, x)[0, 1] / np.var(x)\n", + " alpha = np.mean(y) - beta * np.mean(x)\n", + "\n", + " # 计算残差\n", + " resid = y - (alpha + beta * x)\n", + "\n", + " # 将计算出的残差存储到 residual_series 中,通过索引自动对齐\n", + " residual_series.loc[resid.index] = resid\n", + "\n", + " except Exception as e:\n", + " # 捕获可能的计算异常,例如np.cov或np.var因为极端数据报错\n", + " print(f\"警告: 在行业 {industry} 计算回归时发生错误: {e}。该组残差将设为原始值或 NaN。\")\n", + " # 此时该组的残差会保持 residual_series 初始化时的 NaN 或后续处理\n", + " # 也可以选择保留原始值:residual_series.loc[group.index] = group[col]\n", + "\n", + " else:\n", + " residual_series.loc[group.index] = group[col] # 保留原始因子值\n", + " processed_df.loc[residual_series.index, col] = residual_series\n", + "\n", + "\n", + " else:\n", + " processed_df[col] = np.nan # 或 df[col] if col in df.columns else np.nan\n", + "\n", + " return processed_df\n", + "\n", + "\n", + "import gc\n", + "\n", + "gc.collect()\n", + "\n", + "\n", + "def mad_filter(df, features, n=3):\n", + " for col in features:\n", + " median = df[col].median()\n", + " mad = np.median(np.abs(df[col] - median))\n", + " upper = median + n * mad\n", + " lower = median - n * mad\n", + " df[col] = np.clip(df[col], lower, upper) # 截断极值\n", + " return df\n", + "\n", + "\n", + "def percentile_filter(df, features, lower_percentile=0.01, upper_percentile=0.99):\n", + " for col in features:\n", + " # 按日期分组计算上下百分位数\n", + " lower_bound = df.groupby('trade_date')[col].transform(\n", + " lambda x: x.quantile(lower_percentile)\n", + " )\n", + " upper_bound = df.groupby('trade_date')[col].transform(\n", + " lambda x: x.quantile(upper_percentile)\n", + " )\n", + " # 截断超出范围的值\n", + " df[col] = np.clip(df[col], lower_bound, upper_bound)\n", + " return df\n", + "\n", + "\n", + "from scipy.stats import iqr\n", + "\n", + "\n", + "def iqr_filter(df, features):\n", + " for col in features:\n", + " df[col] = df.groupby('trade_date')[col].transform(\n", + " lambda x: (x - x.median()) / iqr(x) if iqr(x) != 0 else x\n", + " )\n", + " return df\n", + "\n", + "\n", + "def quantile_filter(df, features, lower_quantile=0.01, upper_quantile=0.99, window=60):\n", + " df = df.copy()\n", + " for col in features:\n", + " # 计算 rolling 统计量,需要按日期进行 groupby\n", + " rolling_lower = df.groupby('trade_date')[col].transform(lambda x: x.rolling(window=min(len(x), window)).quantile(lower_quantile))\n", + " rolling_upper = df.groupby('trade_date')[col].transform(lambda x: x.rolling(window=min(len(x), window)).quantile(upper_quantile))\n", + "\n", + " # 对数据进行裁剪\n", + " df[col] = np.clip(df[col], rolling_lower, rolling_upper)\n", + " \n", + " return df\n", + "\n", + "def select_top_features_by_rankic(df: pd.DataFrame, feature_columns: list, n: int, target_column: str = 'future_return') -> list:\n", + " \"\"\"\n", + " 计算给定特征与目标列的 RankIC,并返回 RankIC 绝对值最高的 n 个特征。\n", + "\n", + " Args:\n", + " df: 包含特征列和目标列的 Pandas DataFrame。\n", + " feature_columns: 包含所有待评估特征列名的列表。\n", + " n: 希望选取的 RankIC 绝对值最高的特征数量。\n", + " target_column: 目标列的名称,用于计算 RankIC。默认为 'future_return'。\n", + "\n", + " Returns:\n", + " 包含 RankIC 绝对值最高的 n 个特征列名的列表。\n", + " \"\"\"\n", + " numeric_columns = df.select_dtypes(include=['float64', 'int64']).columns\n", + " numeric_columns = [col for col in numeric_columns if col in feature_columns]\n", + " if target_column not in df.columns:\n", + " raise ValueError(f\"目标列 '{target_column}' 不存在于 DataFrame 中。\")\n", + "\n", + " rankic_scores = {}\n", + " for feature in numeric_columns:\n", + " if feature not in df.columns:\n", + " print(f\"警告: 特征列 '{feature}' 不存在于 DataFrame 中,已跳过。\")\n", + " continue\n", + "\n", + " # 计算特征与目标列的 RankIC (斯皮尔曼相关系数)\n", + " # dropna() 是为了处理缺失值,确保相关性计算不失败\n", + " valid_data = df[[feature, target_column]].dropna()\n", + " if len(valid_data) > 1: # 确保有足够的数据点进行相关性计算\n", + " # 计算斯皮尔曼相关性\n", + " correlation = valid_data[feature].corr(valid_data[target_column], method='spearman')\n", + " rankic_scores[feature] = abs(correlation) # 使用绝对值来衡量相关性强度\n", + " else:\n", + " rankic_scores[feature] = 0 # 数据不足,RankIC设为0或跳过\n", + "\n", + " # 将 RankIC 分数转换为 Series 便于排序\n", + " rankic_series = pd.Series(rankic_scores)\n", + "\n", + " # 按 RankIC 绝对值降序排序,选取前 n 个特征\n", + " # handle case where n might be larger than available features\n", + " n_actual = min(n, len(rankic_series))\n", + " top_features = rankic_series.sort_values(ascending=False).head(n_actual).index.tolist()\n", + " top_features = [col for col in feature_columns if col in top_features or col not in numeric_columns]\n", + " return top_features\n", + "\n", + "def create_deviation_within_dates(df, feature_columns):\n", + " groupby_col = 'cat_l2_code' # 使用 trade_date 进行分组\n", + " new_columns = {}\n", + " ret_feature_columns = feature_columns[:]\n", + "\n", + " # 自动选择所有数值型特征\n", + " num_features = [col for col in feature_columns if 'cat' not in col and 'index' not in col]\n", + "\n", + " # num_features = ['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'cat_vol_spike', 'obv', 'maobv_6', 'return_5', 'return_10', 'return_20', 'std_return_5', 'std_return_15', 'std_return_90', 'std_return_90_2', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4', 'act_factor5', 'act_factor6', 'rank_act_factor1', 'rank_act_factor2', 'rank_act_factor3', 'active_buy_volume_large', 'active_buy_volume_big', 'active_buy_volume_small', 'alpha_022', 'alpha_003', 'alpha_007', 'alpha_013']\n", + " num_features = [col for col in num_features if 'cat' not in col and 'industry' not in col]\n", + " num_features = [col for col in num_features if 'limit' not in col]\n", + " num_features = [col for col in num_features if 'cyq' not in col]\n", + "\n", + " # 遍历所有数值型特征\n", + " for feature in num_features:\n", + " if feature == 'trade_date': # 不需要对 'trade_date' 计算偏差\n", + " continue\n", + "\n", + " # grouped_mean = df.groupby(['trade_date'])[feature].transform('mean')\n", + " # deviation_col_name = f'deviation_mean_{feature}'\n", + " # new_columns[deviation_col_name] = df[feature] - grouped_mean\n", + " # ret_feature_columns.append(deviation_col_name)\n", + "\n", + " grouped_mean = df.groupby(['trade_date', groupby_col])[feature].transform('mean')\n", + " deviation_col_name = f'deviation_mean_{feature}'\n", + " new_columns[deviation_col_name] = df[feature] - grouped_mean\n", + " ret_feature_columns.append(deviation_col_name)\n", + "\n", + " # 将新计算的偏差特征与原始 DataFrame 合并\n", + " df = pd.concat([df, pd.DataFrame(new_columns)], axis=1)\n", + "\n", + " # for feature in ['obv', 'return_20', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4']:\n", + " # df[f'deviation_industry_{feature}'] = df[feature] - df[f'industry_{feature}']\n", + "\n", + " return df, ret_feature_columns\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "47c12bb34062ae7a", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T14:57:50.841165Z", + "start_time": "2025-04-03T14:49:25.889057Z" + } + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import polars as pl\n", + "import numpy as np\n", + "import gc\n", + "\n", + "# --- 配置参数 ---\n", + "days = 5\n", + "validation_days = 120 # 此处未使用,保留用于上下文\n", + "\n", + "\n", + "# --- 核心处理逻辑: Pandas 转 Polars,处理,再转回 Pandas ---\n", + "\n", + "# 1. Pandas DataFrame 转 Polars DataFrame\n", + "gc.collect() # 清理内存,为 Polars 腾出空间\n", + "df = pl.DataFrame(df)\n", + "\n", + "# 2. Polars 处理\n", + "# 确保数据已排序,对于 shift 操作至关重要\n", + "df = df.sort(['ts_code', 'trade_date'])\n", + "\n", + "# 计算 future_return\n", + "df = df.with_columns(\n", + " (\n", + " (pl.col('close').shift(-days).over('ts_code') / pl.col('close')) - 1\n", + " ).alias('future_return_1'),\n", + " (\n", + " (pl.col('close').shift(-2 * days).over('ts_code') / pl.col('close')) - 1\n", + " ).alias('future_return_2')\n", + ").with_columns(\n", + " (pl.col('future_return_1') + pl.col('future_return_2')).alias('future_return')\n", + ").drop(['future_return_1', 'future_return_2']) # 删除中间列\n", + "\n", + "# --- 修正:安全地计算 label ---\n", + "# 使用 pl.when().then().otherwise() 来处理 future_return 中的 NaN\n", + "# 如果 future_return 为空 (NaN),则 label 也设为 None (Polars 中整数列的空值)\n", + "# 否则,计算 qcut 并转换为整数\n", + "df = df.with_columns(\n", + " pl.col(\"future_return\").qcut(50, allow_duplicates=True).over(\"trade_date\").alias(\"label\")\n", + ")\n", + "\n", + "# 根据 future_return 的全局分位数进行过滤\n", + "lower_bound_quantile = df['future_return'].quantile(0.001)\n", + "upper_bound_fixed = 0.6 # 固定上限值\n", + "\n", + "# 3. Polars DataFrame 转回 Pandas DataFrame\n", + "# df_final_pd = df.to_pandas()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "29221dde", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "205\n" + ] + } + ], + "source": [ + "industry_df = pl.DataFrame(industry_df).sort('trade_date')\n", + "index_data = pl.DataFrame(index_data).sort('trade_date')\n", + "\n", + "feature_columns = (\n", + " df.head(10)\n", + " .join(industry_df, on=[\"cat_l2_code\", \"trade_date\"], how=\"left\")\n", + " .join(index_data, on=\"trade_date\", how=\"left\")\n", + " .columns\n", + ")\n", + "feature_columns = [col for col in feature_columns if col not in ['trade_date',\n", + " 'ts_code',\n", + " 'label']]\n", + "feature_columns = [col for col in feature_columns if 'future' not in col]\n", + "feature_columns = [col for col in feature_columns if 'label' not in col]\n", + "feature_columns = [col for col in feature_columns if 'score' not in col]\n", + "feature_columns = [col for col in feature_columns if 'gen' not in col]\n", + "feature_columns = [col for col in feature_columns if 'is_st' not in col]\n", + "feature_columns = [col for col in feature_columns if 'pe_ttm' not in col]\n", + "# feature_columns = [col for col in feature_columns if 'volatility' not in col]\n", + "# feature_columns = [col for col in feature_columns if 'circ_mv' not in col]\n", + "feature_columns = [col for col in feature_columns if 'code' not in col]\n", + "feature_columns = [col for col in feature_columns if col not in origin_columns]\n", + "feature_columns = [col for col in feature_columns if not col.startswith('_')]\n", + "# feature_columns = [col for col in feature_columns if col not in ['ts_code', 'trade_date', 'vol_std_5', 'cov', 'delta_cov', 'alpha_22_improved', 'alpha_007', 'consecutive_up_limit', 'mv_volatility', 'volume_growth', 'mv_growth', 'arbr']]\n", + "feature_columns = [col for col in feature_columns if col not in ['intraday_lg_flow_corr_20', \n", + " 'cap_neutral_cost_metric', \n", + " 'hurst_net_mf_vol_60', \n", + " 'complex_factor_deap_1', \n", + " 'lg_buy_consolidation_20',\n", + " 'cs_rank_ind_cap_neutral_pe',\n", + " 'cs_rank_opening_gap',\n", + " 'cs_rank_ind_adj_lg_flow']]\n", + "feature_columns = [col for col in feature_columns if col not in ['cat_reason', 'cat_is_on_top_list']]\n", + "print(len(feature_columns))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "03ee5daf", + "metadata": {}, + "outputs": [], + "source": [ + "# df = fill_nan_with_daily_median(df, feature_columns)\n", + "for feature_col in [col for col in feature_columns if col in df.columns]:\n", + " pl.col(feature_col).fill_null(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "b76ea08a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "shape: (3, 3)\n", + "┌───────────┬─────────────────────┬─────────────┐\n", + "│ ts_code ┆ trade_date ┆ log_circ_mv │\n", + "│ --- ┆ --- ┆ --- │\n", + "│ str ┆ datetime[ns] ┆ f64 │\n", + "╞═══════════╪═════════════════════╪═════════════╡\n", + "│ 000001.SZ ┆ 2019-01-02 00:00:00 ┆ 16.574219 │\n", + "│ 000001.SZ ┆ 2019-01-03 00:00:00 ┆ 16.583965 │\n", + "│ 000001.SZ ┆ 2019-01-04 00:00:00 ┆ 16.633371 │\n", + "└───────────┴─────────────────────┴─────────────┘\n", + "['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'winner_rate', 'holder_net_change_sum_10d', 'holder_increase_days_10d', 'holder_decrease_days_10d', 'holder_any_increase_flag_10d', 'holder_any_decrease_flag_10d', 'cat_senti_mom_vol_spike', 'cat_senti_pre_breakout', 'ts_turnover_rate_acceleration_5_20', 'ts_vol_sustain_10_30', 'cs_amount_outlier_10', 'ts_ff_to_total_turnover_ratio', 'ts_price_volume_trend_coherence_5_20', 'ts_ff_turnover_rate_surge_10', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', 'log_circ_mv', 'cashflow_to_ev_factor', 'book_to_price_ratio', 'turnover_rate_mean_5', 'variance_20', 'bbi_ratio_factor', 'daily_deviation', 'lg_elg_net_buy_vol', 'flow_lg_elg_intensity', 'sm_net_buy_vol', 'total_buy_vol', 'lg_elg_buy_prop', 'flow_struct_buy_change', 'lg_elg_net_buy_vol_change', 'flow_lg_elg_accel', 'chip_concentration_range', 'chip_skewness', 'floating_chip_proxy', 'cost_support_15pct_change', 'cat_winner_price_zone', 'flow_chip_consistency', 'profit_taking_vs_absorb', 'cat_is_positive', 'upside_vol', 'downside_vol', 'vol_ratio', 'return_skew', 'return_kurtosis', 'volume_change_rate', 'cat_volume_breakout', 'turnover_deviation', 'cat_turnover_spike', 'avg_volume_ratio', 'cat_volume_ratio_breakout', 'vol_spike', 'vol_std_5', 'atr_24', 'atr_6', 'obv', 'maobv_6', 'rsi_3', 'return_5', 'return_20', 'std_return_5', 'std_return_90', 'std_return_90_2', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4', 'rank_act_factor1', 'rank_act_factor2', 'rank_act_factor3', 'cov', 'delta_cov', 'alpha_22_improved', 'alpha_003', 'alpha_007', 'alpha_013', 'vol_break', 'weight_roc5', 'smallcap_concentration', 'cost_stability', 'high_cost_break_days', 'liquidity_risk', 'turnover_std', 'mv_volatility', 'volume_growth', 'mv_growth', 'momentum_factor', 'resonance_factor', 'log_close', 'cat_vol_spike', 'up', 'down', 'obv_maobv_6', 'std_return_5_over_std_return_90', 'std_return_90_minus_std_return_90_2', 'cat_af2', 'cat_af3', 'cat_af4', 'act_factor5', 'act_factor6', 'active_buy_volume_large', 'active_buy_volume_big', 'active_buy_volume_small', 'buy_lg_vol_minus_sell_lg_vol', 'buy_elg_vol_minus_sell_elg_vol', 'ctrl_strength', 'low_cost_dev', 'asymmetry', 'lock_factor', 'cat_vol_break', 'cost_atr_adj', 'cat_golden_resonance', 'mv_turnover_ratio', 'mv_adjusted_volume', 'mv_weighted_turnover', 'nonlinear_mv_volume', 'mv_volume_ratio', 'mv_momentum', 'senti_strong_inflow', 'lg_flow_mom_corr_20_60', 'lg_flow_accel', 'profit_pressure', 'underwater_resistance', 'cost_conc_std_20', 'profit_decay_20', 'vol_amp_loss_20', 'vol_drop_profit_cnt_5', 'lg_flow_vol_interact_20', 'cost_break_confirm_cnt_5', 'atr_norm_channel_pos_14', 'turnover_diff_skew_20', 'lg_sm_flow_diverge_20', 'pullback_strong_20_20', 'vol_wgt_hist_pos_20', 'vol_adj_roc_20', 'cs_rank_net_lg_flow_val', 'cs_rank_elg_buy_ratio', 'cs_rank_rel_profit_margin', 'cs_rank_cost_breadth', 'cs_rank_dist_to_upper_cost', 'cs_rank_winner_rate', 'cs_rank_intraday_range', 'cs_rank_close_pos_in_range', 'cs_rank_pos_in_hist_range', 'cs_rank_vol_x_profit_margin', 'cs_rank_lg_flow_price_concordance', 'cs_rank_turnover_per_winner', 'cs_rank_volume_ratio', 'cs_rank_elg_buy_sell_sm_ratio', 'cs_rank_cost_dist_vol_ratio', 'cs_rank_size', 'industry_obv', 'industry_return_5', 'industry_return_20', 'industry__ema_5', 'industry__ema_13', 'industry__ema_20', 'industry__ema_60', 'industry_act_factor1', 'industry_act_factor2', 'industry_act_factor3', 'industry_act_factor4', 'industry_act_factor5', 'industry_act_factor6', 'industry_rank_act_factor1', 'industry_rank_act_factor2', 'industry_rank_act_factor3', 'industry_return_5_percentile', 'industry_return_20_percentile', '000852.SH_MACD', '000905.SH_MACD', '399006.SZ_MACD', '000852.SH_MACD_hist', '000905.SH_MACD_hist', '399006.SZ_MACD_hist', '000852.SH_RSI', '000905.SH_RSI', '399006.SZ_RSI', '000852.SH_Signal_line', '000905.SH_Signal_line', '399006.SZ_Signal_line', '000852.SH_amount_change_rate', '000905.SH_amount_change_rate', '399006.SZ_amount_change_rate', '000852.SH_amount_mean', '000905.SH_amount_mean', '399006.SZ_amount_mean', '000852.SH_daily_return', '000905.SH_daily_return', '399006.SZ_daily_return', '000852.SH_up_ratio_20d', '000905.SH_up_ratio_20d', '399006.SZ_up_ratio_20d', '000852.SH_volatility', '000905.SH_volatility', '399006.SZ_volatility', '000852.SH_volume_change_rate', '000905.SH_volume_change_rate', '399006.SZ_volume_change_rate']\n", + "去除极值\n", + "开始截面 MAD 去极值处理 (k=3.0)...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "MAD Filtering: 100%|██████████| 144/144 [00:00<00:00, 170.19it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "截面 MAD 去极值处理完成。\n", + "标准化\n", + "开始截面 Z-Score 标准化...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Standardizing: 100%|██████████| 144/144 [00:00<00:00, 767.01it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "截面 Z-Score 标准化完成。\n", + "开始截面 MAD 去极值处理 (k=3.0)...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "MAD Filtering: 100%|██████████| 144/144 [00:26<00:00, 5.49it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "截面 MAD 去极值处理完成。\n", + "开始截面 Z-Score 标准化...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Standardizing: 100%|██████████| 144/144 [00:03<00:00, 37.17it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "截面 Z-Score 标准化完成。\n", + "开始截面 MAD 去极值处理 (k=3.0)...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "MAD Filtering: 0it [00:00, ?it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "截面 MAD 去极值处理完成。\n", + "开始截面 MAD 去极值处理 (k=3.0)...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "MAD Filtering: 0it [00:00, ?it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "截面 MAD 去极值处理完成。\n", + "feature_columns: ['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'winner_rate', 'holder_net_change_sum_10d', 'holder_increase_days_10d', 'holder_decrease_days_10d', 'holder_any_increase_flag_10d', 'holder_any_decrease_flag_10d', 'cat_senti_mom_vol_spike', 'cat_senti_pre_breakout', 'ts_turnover_rate_acceleration_5_20', 'ts_vol_sustain_10_30', 'cs_amount_outlier_10', 'ts_ff_to_total_turnover_ratio', 'ts_price_volume_trend_coherence_5_20', 'ts_ff_turnover_rate_surge_10', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', 'log_circ_mv', 'cashflow_to_ev_factor', 'book_to_price_ratio', 'turnover_rate_mean_5', 'variance_20', 'bbi_ratio_factor', 'daily_deviation', 'lg_elg_net_buy_vol', 'flow_lg_elg_intensity', 'sm_net_buy_vol', 'total_buy_vol', 'lg_elg_buy_prop', 'flow_struct_buy_change', 'lg_elg_net_buy_vol_change', 'flow_lg_elg_accel', 'chip_concentration_range', 'chip_skewness', 'floating_chip_proxy', 'cost_support_15pct_change', 'cat_winner_price_zone', 'flow_chip_consistency', 'profit_taking_vs_absorb', 'cat_is_positive', 'upside_vol', 'downside_vol', 'vol_ratio', 'return_skew', 'return_kurtosis', 'volume_change_rate', 'cat_volume_breakout', 'turnover_deviation', 'cat_turnover_spike', 'avg_volume_ratio', 'cat_volume_ratio_breakout', 'vol_spike', 'vol_std_5', 'atr_24', 'atr_6', 'obv', 'maobv_6', 'rsi_3', 'return_5', 'return_20', 'std_return_5', 'std_return_90', 'std_return_90_2', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4', 'rank_act_factor1', 'rank_act_factor2', 'rank_act_factor3', 'cov', 'delta_cov', 'alpha_22_improved', 'alpha_003', 'alpha_007', 'alpha_013', 'vol_break', 'weight_roc5', 'smallcap_concentration', 'cost_stability', 'high_cost_break_days', 'liquidity_risk', 'turnover_std', 'mv_volatility', 'volume_growth', 'mv_growth', 'momentum_factor', 'resonance_factor', 'log_close', 'cat_vol_spike', 'up', 'down', 'obv_maobv_6', 'std_return_5_over_std_return_90', 'std_return_90_minus_std_return_90_2', 'cat_af2', 'cat_af3', 'cat_af4', 'act_factor5', 'act_factor6', 'active_buy_volume_large', 'active_buy_volume_big', 'active_buy_volume_small', 'buy_lg_vol_minus_sell_lg_vol', 'buy_elg_vol_minus_sell_elg_vol', 'ctrl_strength', 'low_cost_dev', 'asymmetry', 'lock_factor', 'cat_vol_break', 'cost_atr_adj', 'cat_golden_resonance', 'mv_turnover_ratio', 'mv_adjusted_volume', 'mv_weighted_turnover', 'nonlinear_mv_volume', 'mv_volume_ratio', 'mv_momentum', 'senti_strong_inflow', 'lg_flow_mom_corr_20_60', 'lg_flow_accel', 'profit_pressure', 'underwater_resistance', 'cost_conc_std_20', 'profit_decay_20', 'vol_amp_loss_20', 'vol_drop_profit_cnt_5', 'lg_flow_vol_interact_20', 'cost_break_confirm_cnt_5', 'atr_norm_channel_pos_14', 'turnover_diff_skew_20', 'lg_sm_flow_diverge_20', 'pullback_strong_20_20', 'vol_wgt_hist_pos_20', 'vol_adj_roc_20', 'cs_rank_net_lg_flow_val', 'cs_rank_elg_buy_ratio', 'cs_rank_rel_profit_margin', 'cs_rank_cost_breadth', 'cs_rank_dist_to_upper_cost', 'cs_rank_winner_rate', 'cs_rank_intraday_range', 'cs_rank_close_pos_in_range', 'cs_rank_pos_in_hist_range', 'cs_rank_vol_x_profit_margin', 'cs_rank_lg_flow_price_concordance', 'cs_rank_turnover_per_winner', 'cs_rank_volume_ratio', 'cs_rank_elg_buy_sell_sm_ratio', 'cs_rank_cost_dist_vol_ratio', 'cs_rank_size', 'industry_obv', 'industry_return_5', 'industry_return_20', 'industry__ema_5', 'industry__ema_13', 'industry__ema_20', 'industry__ema_60', 'industry_act_factor1', 'industry_act_factor2', 'industry_act_factor3', 'industry_act_factor4', 'industry_act_factor5', 'industry_act_factor6', 'industry_rank_act_factor1', 'industry_rank_act_factor2', 'industry_rank_act_factor3', 'industry_return_5_percentile', 'industry_return_20_percentile', '000852.SH_MACD', '000905.SH_MACD', '399006.SZ_MACD', '000852.SH_MACD_hist', '000905.SH_MACD_hist', '399006.SZ_MACD_hist', '000852.SH_RSI', '000905.SH_RSI', '399006.SZ_RSI', '000852.SH_Signal_line', '000905.SH_Signal_line', '399006.SZ_Signal_line', '000852.SH_amount_change_rate', '000905.SH_amount_change_rate', '399006.SZ_amount_change_rate', '000852.SH_amount_mean', '000905.SH_amount_mean', '399006.SZ_amount_mean', '000852.SH_daily_return', '000905.SH_daily_return', '399006.SZ_daily_return', '000852.SH_up_ratio_20d', '000905.SH_up_ratio_20d', '399006.SZ_up_ratio_20d', '000852.SH_volatility', '000905.SH_volatility', '399006.SZ_volatility', '000852.SH_volume_change_rate', '000905.SH_volume_change_rate', '399006.SZ_volume_change_rate']\n", + "df最小日期: 2019-01-02\n", + "df最大日期: 2025-05-30\n", + "148609\n", + "train_data最小日期: 2020-01-02\n", + "train_data最大日期: 2020-03-31\n", + "3591195\n", + "test_data最小日期: 2020-03-31\n", + "test_data最大日期: 2025-05-30\n", + "shape: (3, 3)\n", + "┌───────────┬─────────────────────┬─────────────┐\n", + "│ ts_code ┆ trade_date ┆ log_circ_mv │\n", + "│ --- ┆ --- ┆ --- │\n", + "│ str ┆ datetime[ns] ┆ f64 │\n", + "╞═══════════╪═════════════════════╪═════════════╡\n", + "│ 000001.SZ ┆ 2019-01-02 00:00:00 ┆ 16.574219 │\n", + "│ 000001.SZ ┆ 2019-01-03 00:00:00 ┆ 16.583965 │\n", + "│ 000001.SZ ┆ 2019-01-04 00:00:00 ┆ 16.633371 │\n", + "└───────────┴─────────────────────┴─────────────┘\n" + ] + } + ], + "source": [ + "from main.utils.data_process import * \n", + "\n", + "split_date = '2023-01-01'\n", + "split_date = pd.to_datetime('2020-03-31') # 将你的分割日期转换为 Pandas Timestamp\n", + "\n", + "# --- 训练数据处理 ---\n", + "train_data = df.filter(\n", + " (pl.col('trade_date') <= split_date) &\n", + " (pl.col('trade_date') >= pd.to_datetime('2020-01-01')) &\n", + " (pl.col('future_return') >= lower_bound_quantile) &\n", + " (pl.col('future_return') <= upper_bound_fixed)\n", + ")\n", + "\n", + "# --- 测试数据处理 ---\n", + "test_data = (\n", + " df.filter(\n", + " pl.col('trade_date') >= split_date\n", + " )\n", + ")\n", + "\n", + "print(df[['ts_code', 'trade_date', 'log_circ_mv']].head(3))\n", + "\n", + "numeric_columns = [\n", + " col for col, dtype in zip(df.columns, df.dtypes)\n", + " if dtype in [pl.Float64, pl.Float32, pl.Int64, pl.Int32]\n", + "]\n", + "numeric_columns = [col for col in numeric_columns if col in feature_columns]\n", + "print(feature_columns)\n", + "\n", + "train_data = train_data.with_columns([\n", + " pl.when(pl.col(col).is_infinite())\n", + " .then(np.nan)\n", + " .otherwise(pl.col(col))\n", + " .alias(col)\n", + " for col in numeric_columns\n", + "])\n", + "test_data = test_data.with_columns([\n", + " pl.when(pl.col(col).is_infinite())\n", + " .then(np.nan)\n", + " .otherwise(pl.col(col))\n", + " .alias(col)\n", + " for col in numeric_columns\n", + "])\n", + "\n", + "\n", + "train_data = train_data.drop_nulls(subset=[col for col in feature_columns if col in train_data.columns])\n", + "test_data = test_data.drop_nulls(subset=[col for col in feature_columns if col in test_data.columns])\n", + "\n", + "transform_feature_columns = feature_columns\n", + "transform_feature_columns = [col for col in transform_feature_columns if col in feature_columns and not col.startswith('cat') and col in train_data.columns]\n", + "# transform_feature_columns.remove('undist_profit_ps')\n", + "print('去除极值')\n", + "train_data = train_data.to_pandas()\n", + "test_data = test_data.to_pandas()\n", + "gc.collect()\n", + "cs_mad_filter(train_data, transform_feature_columns)\n", + "print('标准化')\n", + "cs_zscore_standardize(train_data, transform_feature_columns)\n", + "\n", + "cs_mad_filter(test_data, transform_feature_columns)\n", + "cs_zscore_standardize(test_data, transform_feature_columns)\n", + "\n", + "mad_filter_feature_columns = [col for col in feature_columns if col not in transform_feature_columns and not col.startswith('cat') and col in train_data.columns]\n", + "cs_mad_filter(train_data, mad_filter_feature_columns)\n", + "cs_mad_filter(test_data, mad_filter_feature_columns)\n", + "\n", + "\n", + "print(f'feature_columns: {feature_columns}')\n", + "\n", + "\n", + "print(f\"df最小日期: {df['trade_date'].min().strftime('%Y-%m-%d')}\")\n", + "print(f\"df最大日期: {df['trade_date'].max().strftime('%Y-%m-%d')}\")\n", + "print(len(train_data))\n", + "print(f\"train_data最小日期: {train_data['trade_date'].min().strftime('%Y-%m-%d')}\")\n", + "print(f\"train_data最大日期: {train_data['trade_date'].max().strftime('%Y-%m-%d')}\")\n", + "print(len(test_data))\n", + "print(f\"test_data最小日期: {test_data['trade_date'].min().strftime('%Y-%m-%d')}\")\n", + "print(f\"test_data最大日期: {test_data['trade_date'].max().strftime('%Y-%m-%d')}\")\n", + "\n", + "cat_columns = [col for col in feature_columns if col.startswith('cat')]\n", + "for col in cat_columns:\n", + " train_data[col] = train_data[col].astype('category')\n", + " test_data[col] = test_data[col].astype('category')\n", + "\n", + "print(df[['ts_code', 'trade_date', 'log_circ_mv']].head(3))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "3ff2d1c5", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.linear_model import LogisticRegression\n", + "import matplotlib.pyplot as plt # 保持 matplotlib 导入,尽管LightGBM的绘图功能已移除\n", + "from sklearn.decomposition import PCA\n", + "import pandas as pd\n", + "import numpy as np\n", + "import datetime # 用于日期计算\n", + "from catboost import CatBoostClassifier, CatBoostRanker, CatBoostRegressor\n", + "from catboost import Pool\n", + "import lightgbm as lgb\n", + "from lightgbm import LGBMRanker, LGBMRegressor\n", + "\n", + "def train_model(train_data_df, feature_columns,\n", + " print_info=True, # 调整参数名,更通用\n", + " validation_days=180, use_pca=False, split_date=None,\n", + " target_column='label', type='light'): # 增加目标列参数\n", + "\n", + " print('train data size: ', len(train_data_df))\n", + " print(train_data_df[['ts_code', 'trade_date', 'log_circ_mv']])\n", + " # 确保数据按时间排序\n", + " train_data_df = train_data_df.sort_values(by='trade_date')\n", + "\n", + " # 去除标签为空的样本\n", + " initial_len = len(train_data_df)\n", + " train_data_df = train_data_df.dropna(subset=[target_column])\n", + "\n", + " if print_info:\n", + " print(f'原始样本数: {initial_len}, 去除标签为空后样本数: {len(train_data_df)}')\n", + "\n", + " # 提取特征和标签,只取数值型特征用于线性回归\n", + " \n", + " if split_date is None:\n", + " all_dates = train_data_df['trade_date'].unique() # 获取所有唯一的 trade_date\n", + " split_date = all_dates[-validation_days] # 划分点为倒数第 validation_days 天\n", + " train_data_split = train_data_df[train_data_df['trade_date'] < split_date] # 训练集\n", + " val_data_split = train_data_df[train_data_df['trade_date'] >= split_date] # 验证集\n", + "\n", + " train_data_split = train_data_split.sort_values('trade_date')\n", + " val_data_split = val_data_split.sort_values('trade_date')\n", + "\n", + " \n", + " X_train = train_data_split[feature_columns]\n", + " y_train = train_data_split[target_column]\n", + " \n", + " X_val = val_data_split[feature_columns]\n", + " y_val = val_data_split[target_column]\n", + "\n", + "\n", + " # # 标准化数值特征 (使用 StandardScaler 对训练集fit并transform, 对验证集只transform)\n", + " scaler = StandardScaler()\n", + " # X_train = scaler.fit_transform(X_train)\n", + "\n", + " # 训练线性回归模型\n", + " # model = LogisticRegression(random_state=42)\n", + " \n", + " # # 使用处理后的特征和样本权重进行训练\n", + " # model.fit(X_train, y_train)\n", + "\n", + "\n", + " if type == 'cat':\n", + " params = {\n", + " 'loss_function': 'QueryRMSE', # 适用于二分类\n", + " 'eval_metric': 'NDCG', # 评估指标\n", + " 'iterations': 1500,\n", + " 'learning_rate': 0.03,\n", + " 'depth': 8, # 控制模型复杂度\n", + " 'l2_leaf_reg': 1, # L2 正则化\n", + " 'verbose': 5000,\n", + " 'early_stopping_rounds': 300,\n", + " 'one_hot_max_size': 50,\n", + " # 'class_weights': [0.6, 1.2],\n", + " 'task_type': 'GPU',\n", + " 'has_time': True,\n", + " 'random_seed': 7\n", + " }\n", + " cat_features = [i for i, col in enumerate(feature_columns) if col.startswith('cat')]\n", + " group_train = train_data_split['trade_date'].factorize()[0]\n", + " group_val = val_data_split['trade_date'].factorize()[0]\n", + " train_pool = Pool(\n", + " data=X_train,\n", + " label=y_train,\n", + " group_id=group_train,\n", + " cat_features=cat_features\n", + " )\n", + " val_pool = Pool(\n", + " data=X_val,\n", + " label=y_val,\n", + " group_id=group_val,\n", + " cat_features=cat_features\n", + " )\n", + "\n", + "\n", + " model = CatBoostRanker(**params)\n", + " model.fit(train_pool,\n", + " eval_set=val_pool, \n", + " plot=True, \n", + " use_best_model=True\n", + " )\n", + " elif type == 'light':\n", + " label_gain = list(range(len(train_data_split[target_column].unique())))\n", + " \n", + " params = {\n", + " 'label_gain': [gain * gain for gain in label_gain],\n", + " 'objective': 'lambdarank',\n", + " 'metric': 'ndcg',\n", + " 'learning_rate': 0.01,\n", + " # 'num_leaves': 1024,\n", + " # 'min_data_in_leaf': 256,\n", + " # 'max_depth': 10,\n", + " # 'max_bin': 1024,\n", + " 'feature_fraction': 0.5,\n", + " 'bagging_fraction': 0.5,\n", + " 'bagging_freq': 5,\n", + " # 'lambda_l1': 1,\n", + " 'lambda_l2': 50,\n", + " 'boosting': 'gbdt',\n", + " 'verbosity': -1,\n", + " 'extra_trees': True,\n", + " # 'max_position': 5,\n", + " 'ndcg_at': '5',\n", + " 'quant_train_renew_leaf': True,\n", + " 'lambdarank_truncation_level': 10,\n", + " # 'lambdarank_position_bias_regularization': 1,\n", + " 'seed': 7\n", + " }\n", + " # feature_contri = [2 if feat.startswith('act_factor') or 'buy' in feat or 'sell' in feat else 1 for feat in feature_columns]\n", + " # params['feature_contri'] = feature_contri\n", + "\n", + " train_groups = train_data_split.groupby('trade_date').size().tolist()\n", + " val_groups = val_data_split.groupby('trade_date').size().tolist()\n", + "\n", + " categorical_feature = [col for col in feature_columns if 'cat' in col]\n", + " train_dataset = lgb.Dataset(\n", + " X_train, label=y_train, \n", + " group=train_groups,\n", + " categorical_feature=categorical_feature\n", + " )\n", + " val_dataset = lgb.Dataset(\n", + " X_val, label=y_val, \n", + " group=val_groups,\n", + " categorical_feature=categorical_feature\n", + " )\n", + "\n", + " evals = {}\n", + " callbacks = [lgb.log_evaluation(period=1000),\n", + " lgb.callback.record_evaluation(evals),\n", + " lgb.early_stopping(300, first_metric_only=False)\n", + " ]\n", + " # 训练模型\n", + " model = lgb.train(\n", + " params, train_dataset, num_boost_round=1000,\n", + " valid_sets=[train_dataset, val_dataset], valid_names=['train', 'valid'],\n", + " callbacks=callbacks\n", + " )\n", + "\n", + " # 打印特征重要性(如果需要)\n", + " if True:\n", + " lgb.plot_metric(evals)\n", + " lgb.plot_importance(model, importance_type='split', max_num_features=20)\n", + " plt.show()\n", + "\n", + " # from flaml import AutoML\n", + " # from sklearn.datasets import fetch_california_housing\n", + "\n", + " # # Initialize an AutoML instance\n", + " # model = AutoML()\n", + " # # Specify automl goal and constraint\n", + " # automl_settings = {\n", + " # \"time_budget\": 600, # in seconds\n", + " # \"metric\": \"ndcg@1\",\n", + " # \"task\": \"rank\",\n", + " # \"estimator_list\": [\n", + " # \"catboost\",\n", + " # \"lgbm\",\n", + " # \"xgboost\"\n", + " # ], \n", + " # \"ensemble\": {\n", + " # \"final_estimator\": LGBMRanker(),\n", + " # \"passthrough\": False,\n", + " # },\n", + " # }\n", + " # model.fit(X_train=X_train, y_train=y_train, groups=train_groups,\n", + " # X_val=X_val, y_val=y_val,groups_val=val_groups,\n", + " # mlflow_logging=False, **automl_settings)\n", + "\n", + "\n", + " return model, scaler, None # 返回训练好的模型、scaler 和 pca 对象" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c6eb5cd4-e714-420a-ac48-39af3e11ee81", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T15:03:18.426481Z", + "start_time": "2025-04-03T15:02:19.926352Z" + } + }, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[18]\u001b[39m\u001b[32m, line 9\u001b[39m\n\u001b[32m 4\u001b[39m \u001b[38;5;28mtype\u001b[39m = \u001b[33m'\u001b[39m\u001b[33mlight\u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m 6\u001b[39m train_data[\u001b[33m'\u001b[39m\u001b[33mlabel2\u001b[39m\u001b[33m'\u001b[39m] = train_data.groupby(\u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, group_keys=\u001b[38;5;28;01mFalse\u001b[39;00m).apply(\u001b[38;5;28;01mlambda\u001b[39;00m x: x.nsmallest(\u001b[32m1000\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtotal_mv\u001b[39m\u001b[33m'\u001b[39m))[\u001b[33m'\u001b[39m\u001b[33mfuture_return\u001b[39m\u001b[33m'\u001b[39m].transform(\n\u001b[32m 7\u001b[39m \u001b[38;5;28;01mlambda\u001b[39;00m x: pd.qcut(x, q=\u001b[32m50\u001b[39m, labels=\u001b[38;5;28;01mFalse\u001b[39;00m, duplicates=\u001b[33m'\u001b[39m\u001b[33mdrop\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 8\u001b[39m )\n\u001b[32m----> \u001b[39m\u001b[32m9\u001b[39m test_data[\u001b[33m'\u001b[39m\u001b[33mlabel2\u001b[39m\u001b[33m'\u001b[39m] = \u001b[43mtest_data\u001b[49m\u001b[43m.\u001b[49m\u001b[43mgroupby\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mtrade_date\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgroup_keys\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mapply\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43;01mlambda\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mx\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mx\u001b[49m\u001b[43m.\u001b[49m\u001b[43mnsmallest\u001b[49m\u001b[43m(\u001b[49m\u001b[32;43m1000\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mtotal_mv\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m[\u001b[33m'\u001b[39m\u001b[33mfuture_return\u001b[39m\u001b[33m'\u001b[39m].transform(\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01mlambda\u001b[39;00m x: pd.qcut(x, q=\u001b[32m50\u001b[39m, labels=\u001b[38;5;28;01mFalse\u001b[39;00m, duplicates=\u001b[33m'\u001b[39m\u001b[33mdrop\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 11\u001b[39m )\n\u001b[32m 13\u001b[39m \u001b[38;5;66;03m# feature_contri = [2 if feat.startswith('act_factor') or 'buy' in feat or 'sell' in feat else 1 for feat in feature_columns]\u001b[39;00m\n\u001b[32m 14\u001b[39m \u001b[38;5;66;03m# light_params['feature_contri'] = feature_contri\u001b[39;00m\n\u001b[32m 15\u001b[39m \u001b[38;5;66;03m# print(f'feature_contri: {feature_contri}')\u001b[39;00m\n\u001b[32m 16\u001b[39m model, scaler, pca = train_model(train_data.groupby(\u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, group_keys=\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[32m 17\u001b[39m .apply(\u001b[38;5;28;01mlambda\u001b[39;00m x: x.nsmallest(\u001b[32m1000\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtotal_mv\u001b[39m\u001b[33m'\u001b[39m))\n\u001b[32m 18\u001b[39m .merge(industry_df, on=[\u001b[33m'\u001b[39m\u001b[33mcat_l2_code\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m], how=\u001b[33m'\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 19\u001b[39m .merge(index_data, on=\u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, how=\u001b[33m'\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m'\u001b[39m), \n\u001b[32m 20\u001b[39m feature_columns, \u001b[38;5;28mtype\u001b[39m=\u001b[38;5;28mtype\u001b[39m, target_column=\u001b[33m'\u001b[39m\u001b[33mlabel2\u001b[39m\u001b[33m'\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/groupby/groupby.py:1824\u001b[39m, in \u001b[36mGroupBy.apply\u001b[39m\u001b[34m(self, func, include_groups, *args, **kwargs)\u001b[39m\n\u001b[32m 1822\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m option_context(\u001b[33m\"\u001b[39m\u001b[33mmode.chained_assignment\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[32m 1823\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1824\u001b[39m result = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_python_apply_general\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_selected_obj\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1825\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[32m 1826\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(\u001b[38;5;28mself\u001b[39m.obj, Series)\n\u001b[32m 1827\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m._selection \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 1828\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m._selected_obj.shape != \u001b[38;5;28mself\u001b[39m._obj_with_exclusions.shape\n\u001b[32m 1829\u001b[39m ):\n\u001b[32m 1830\u001b[39m warnings.warn(\n\u001b[32m 1831\u001b[39m message=_apply_groupings_depr.format(\n\u001b[32m 1832\u001b[39m \u001b[38;5;28mtype\u001b[39m(\u001b[38;5;28mself\u001b[39m).\u001b[34m__name__\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mapply\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m (...)\u001b[39m\u001b[32m 1835\u001b[39m stacklevel=find_stack_level(),\n\u001b[32m 1836\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/groupby/groupby.py:1885\u001b[39m, in \u001b[36mGroupBy._python_apply_general\u001b[39m\u001b[34m(self, f, data, not_indexed_same, is_transform, is_agg)\u001b[39m\n\u001b[32m 1850\u001b[39m \u001b[38;5;129m@final\u001b[39m\n\u001b[32m 1851\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_python_apply_general\u001b[39m(\n\u001b[32m 1852\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 1857\u001b[39m is_agg: \u001b[38;5;28mbool\u001b[39m = \u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[32m 1858\u001b[39m ) -> NDFrameT:\n\u001b[32m 1859\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 1860\u001b[39m \u001b[33;03m Apply function f in python space\u001b[39;00m\n\u001b[32m 1861\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 1883\u001b[39m \u001b[33;03m data after applying f\u001b[39;00m\n\u001b[32m 1884\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1885\u001b[39m values, mutated = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_grouper\u001b[49m\u001b[43m.\u001b[49m\u001b[43mapply_groupwise\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1886\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m not_indexed_same \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 1887\u001b[39m not_indexed_same = mutated\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/groupby/ops.py:919\u001b[39m, in \u001b[36mBaseGrouper.apply_groupwise\u001b[39m\u001b[34m(self, f, data, axis)\u001b[39m\n\u001b[32m 917\u001b[39m \u001b[38;5;66;03m# group might be modified\u001b[39;00m\n\u001b[32m 918\u001b[39m group_axes = group.axes\n\u001b[32m--> \u001b[39m\u001b[32m919\u001b[39m res = \u001b[43mf\u001b[49m\u001b[43m(\u001b[49m\u001b[43mgroup\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 920\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m mutated \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m _is_indexed_like(res, group_axes, axis):\n\u001b[32m 921\u001b[39m mutated = \u001b[38;5;28;01mTrue\u001b[39;00m\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[18]\u001b[39m\u001b[32m, line 9\u001b[39m, in \u001b[36m\u001b[39m\u001b[34m(x)\u001b[39m\n\u001b[32m 4\u001b[39m \u001b[38;5;28mtype\u001b[39m = \u001b[33m'\u001b[39m\u001b[33mlight\u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m 6\u001b[39m train_data[\u001b[33m'\u001b[39m\u001b[33mlabel2\u001b[39m\u001b[33m'\u001b[39m] = train_data.groupby(\u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, group_keys=\u001b[38;5;28;01mFalse\u001b[39;00m).apply(\u001b[38;5;28;01mlambda\u001b[39;00m x: x.nsmallest(\u001b[32m1000\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtotal_mv\u001b[39m\u001b[33m'\u001b[39m))[\u001b[33m'\u001b[39m\u001b[33mfuture_return\u001b[39m\u001b[33m'\u001b[39m].transform(\n\u001b[32m 7\u001b[39m \u001b[38;5;28;01mlambda\u001b[39;00m x: pd.qcut(x, q=\u001b[32m50\u001b[39m, labels=\u001b[38;5;28;01mFalse\u001b[39;00m, duplicates=\u001b[33m'\u001b[39m\u001b[33mdrop\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 8\u001b[39m )\n\u001b[32m----> \u001b[39m\u001b[32m9\u001b[39m test_data[\u001b[33m'\u001b[39m\u001b[33mlabel2\u001b[39m\u001b[33m'\u001b[39m] = test_data.groupby(\u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, group_keys=\u001b[38;5;28;01mFalse\u001b[39;00m).apply(\u001b[38;5;28;01mlambda\u001b[39;00m x: \u001b[43mx\u001b[49m\u001b[43m.\u001b[49m\u001b[43mnsmallest\u001b[49m\u001b[43m(\u001b[49m\u001b[32;43m1000\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mtotal_mv\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m)[\u001b[33m'\u001b[39m\u001b[33mfuture_return\u001b[39m\u001b[33m'\u001b[39m].transform(\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01mlambda\u001b[39;00m x: pd.qcut(x, q=\u001b[32m50\u001b[39m, labels=\u001b[38;5;28;01mFalse\u001b[39;00m, duplicates=\u001b[33m'\u001b[39m\u001b[33mdrop\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 11\u001b[39m )\n\u001b[32m 13\u001b[39m \u001b[38;5;66;03m# feature_contri = [2 if feat.startswith('act_factor') or 'buy' in feat or 'sell' in feat else 1 for feat in feature_columns]\u001b[39;00m\n\u001b[32m 14\u001b[39m \u001b[38;5;66;03m# light_params['feature_contri'] = feature_contri\u001b[39;00m\n\u001b[32m 15\u001b[39m \u001b[38;5;66;03m# print(f'feature_contri: {feature_contri}')\u001b[39;00m\n\u001b[32m 16\u001b[39m model, scaler, pca = train_model(train_data.groupby(\u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, group_keys=\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[32m 17\u001b[39m .apply(\u001b[38;5;28;01mlambda\u001b[39;00m x: x.nsmallest(\u001b[32m1000\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtotal_mv\u001b[39m\u001b[33m'\u001b[39m))\n\u001b[32m 18\u001b[39m .merge(industry_df, on=[\u001b[33m'\u001b[39m\u001b[33mcat_l2_code\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m], how=\u001b[33m'\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 19\u001b[39m .merge(index_data, on=\u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, how=\u001b[33m'\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m'\u001b[39m), \n\u001b[32m 20\u001b[39m feature_columns, \u001b[38;5;28mtype\u001b[39m=\u001b[38;5;28mtype\u001b[39m, target_column=\u001b[33m'\u001b[39m\u001b[33mlabel2\u001b[39m\u001b[33m'\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/frame.py:7756\u001b[39m, in \u001b[36mDataFrame.nsmallest\u001b[39m\u001b[34m(self, n, columns, keep)\u001b[39m\n\u001b[32m 7646\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mnsmallest\u001b[39m(\n\u001b[32m 7647\u001b[39m \u001b[38;5;28mself\u001b[39m, n: \u001b[38;5;28mint\u001b[39m, columns: IndexLabel, keep: NsmallestNlargestKeep = \u001b[33m\"\u001b[39m\u001b[33mfirst\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 7648\u001b[39m ) -> DataFrame:\n\u001b[32m 7649\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 7650\u001b[39m \u001b[33;03m Return the first `n` rows ordered by `columns` in ascending order.\u001b[39;00m\n\u001b[32m 7651\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 7754\u001b[39m \u001b[33;03m Nauru 337000 182 NR\u001b[39;00m\n\u001b[32m 7755\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m7756\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mselectn\u001b[49m\u001b[43m.\u001b[49m\u001b[43mSelectNFrame\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkeep\u001b[49m\u001b[43m=\u001b[49m\u001b[43mkeep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcolumns\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcolumns\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mnsmallest\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/methods/selectn.py:61\u001b[39m, in \u001b[36mSelectN.nsmallest\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 59\u001b[39m \u001b[38;5;129m@final\u001b[39m\n\u001b[32m 60\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mnsmallest\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[32m---> \u001b[39m\u001b[32m61\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mcompute\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mnsmallest\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/methods/selectn.py:218\u001b[39m, in \u001b[36mSelectNFrame.compute\u001b[39m\u001b[34m(self, method)\u001b[39m\n\u001b[32m 216\u001b[39m \u001b[38;5;66;03m# Below we save and reset the index in case index contains duplicates\u001b[39;00m\n\u001b[32m 217\u001b[39m original_index = frame.index\n\u001b[32m--> \u001b[39m\u001b[32m218\u001b[39m cur_frame = frame = \u001b[43mframe\u001b[49m\u001b[43m.\u001b[49m\u001b[43mreset_index\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdrop\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[32m 219\u001b[39m cur_n = n\n\u001b[32m 220\u001b[39m indexer = Index([], dtype=np.int64)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/frame.py:6417\u001b[39m, in \u001b[36mDataFrame.reset_index\u001b[39m\u001b[34m(self, level, drop, inplace, col_level, col_fill, allow_duplicates, names)\u001b[39m\n\u001b[32m 6415\u001b[39m new_obj = \u001b[38;5;28mself\u001b[39m\n\u001b[32m 6416\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m6417\u001b[39m new_obj = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mcopy\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdeep\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[32m 6418\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m allow_duplicates \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m lib.no_default:\n\u001b[32m 6419\u001b[39m allow_duplicates = validate_bool_kwarg(allow_duplicates, \u001b[33m\"\u001b[39m\u001b[33mallow_duplicates\u001b[39m\u001b[33m\"\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/generic.py:6811\u001b[39m, in \u001b[36mNDFrame.copy\u001b[39m\u001b[34m(self, deep)\u001b[39m\n\u001b[32m 6662\u001b[39m \u001b[38;5;129m@final\u001b[39m\n\u001b[32m 6663\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcopy\u001b[39m(\u001b[38;5;28mself\u001b[39m, deep: bool_t | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mTrue\u001b[39;00m) -> Self:\n\u001b[32m 6664\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 6665\u001b[39m \u001b[33;03m Make a copy of this object's indices and data.\u001b[39;00m\n\u001b[32m 6666\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 6809\u001b[39m \u001b[33;03m dtype: int64\u001b[39;00m\n\u001b[32m 6810\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m6811\u001b[39m data = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_mgr\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcopy\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdeep\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdeep\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 6812\u001b[39m \u001b[38;5;28mself\u001b[39m._clear_item_cache()\n\u001b[32m 6813\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._constructor_from_mgr(data, axes=data.axes).__finalize__(\n\u001b[32m 6814\u001b[39m \u001b[38;5;28mself\u001b[39m, method=\u001b[33m\"\u001b[39m\u001b[33mcopy\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 6815\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/internals/managers.py:593\u001b[39m, in \u001b[36mBaseBlockManager.copy\u001b[39m\u001b[34m(self, deep)\u001b[39m\n\u001b[32m 590\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 591\u001b[39m new_axes = \u001b[38;5;28mlist\u001b[39m(\u001b[38;5;28mself\u001b[39m.axes)\n\u001b[32m--> \u001b[39m\u001b[32m593\u001b[39m res = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mapply\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcopy\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdeep\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdeep\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 594\u001b[39m res.axes = new_axes\n\u001b[32m 596\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.ndim > \u001b[32m1\u001b[39m:\n\u001b[32m 597\u001b[39m \u001b[38;5;66;03m# Avoid needing to re-compute these\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/internals/managers.py:363\u001b[39m, in \u001b[36mBaseBlockManager.apply\u001b[39m\u001b[34m(self, f, align_keys, **kwargs)\u001b[39m\n\u001b[32m 361\u001b[39m applied = b.apply(f, **kwargs)\n\u001b[32m 362\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m363\u001b[39m applied = \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mb\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mf\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 364\u001b[39m result_blocks = extend_blocks(applied, result_blocks)\n\u001b[32m 366\u001b[39m out = \u001b[38;5;28mtype\u001b[39m(\u001b[38;5;28mself\u001b[39m).from_blocks(result_blocks, \u001b[38;5;28mself\u001b[39m.axes)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/core/internals/blocks.py:796\u001b[39m, in \u001b[36mBlock.copy\u001b[39m\u001b[34m(self, deep)\u001b[39m\n\u001b[32m 794\u001b[39m refs: BlockValuesRefs | \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 795\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m deep:\n\u001b[32m--> \u001b[39m\u001b[32m796\u001b[39m values = \u001b[43mvalues\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcopy\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 797\u001b[39m refs = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 798\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "\u001b[31mKeyboardInterrupt\u001b[39m: " + ] + } + ], + "source": [ + "\n", + "gc.collect()\n", + "\n", + "use_pca = False\n", + "type = 'light'\n", + "\n", + "train_data['label2'] = train_data.groupby('trade_date', group_keys=False).apply(lambda x: x.nsmallest(1000, 'total_mv'))['future_return'].transform(\n", + " lambda x: pd.qcut(x, q=50, labels=False, duplicates='drop')\n", + ")\n", + "test_data['label2'] = test_data.groupby('trade_date', group_keys=False).apply(lambda x: x.nsmallest(1000, 'total_mv'))['future_return'].transform(\n", + " lambda x: pd.qcut(x, q=50, labels=False, duplicates='drop')\n", + ")\n", + "\n", + "# feature_contri = [2 if feat.startswith('act_factor') or 'buy' in feat or 'sell' in feat else 1 for feat in feature_columns]\n", + "# light_params['feature_contri'] = feature_contri\n", + "# print(f'feature_contri: {feature_contri}')\n", + "model, scaler, pca = train_model(train_data.groupby('trade_date', group_keys=False)\n", + " .apply(lambda x: x.nsmallest(1000, 'total_mv'))\n", + " .merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left')\n", + " .merge(index_data, on='trade_date', how='left'), \n", + " feature_columns, type=type, target_column='label2')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5d1522a7538db91b", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T15:04:39.656944Z", + "start_time": "2025-04-03T15:04:39.298483Z" + } + }, + "outputs": [], + "source": [ + "score_df = test_data.groupby('trade_date', group_keys=False).apply(lambda x: x.nsmallest(1000, 'total_mv'))\n", + "# score_df = fill_nan_with_daily_median(score_df, ['pe_ttm'])\n", + "# score_df = score_df[score_df['pe_ttm'] > 0]\n", + "score_df = score_df.merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left')\n", + "score_df = score_df.merge(index_data, on='trade_date', how='left')\n", + "# score_df = score_df.groupby('trade_date', group_keys=False).apply(lambda x: x.nsmallest(50, 'total_mv')).reset_index()\n", + "numeric_columns = score_df.select_dtypes(include=['float64', 'int64']).columns\n", + "numeric_columns = [col for col in feature_columns if col in numeric_columns]\n", + "\n", + "if type == 'cat':\n", + " score_df['score'] = model.predict(score_df[feature_columns])\n", + "elif type == 'light':\n", + " score_df['score'] = model.predict(score_df[feature_columns])\n", + "score_df['score_ranks'] = score_df.groupby('trade_date')['score'].rank(ascending=True)\n", + "\n", + "score_df = score_df.groupby('trade_date', group_keys=False).apply(\n", + " lambda x: \n", + " x[\n", + " # (x['score'] <= x['score'].quantile(0.99)) & \n", + " (x['score'] >= x['score'].quantile(0.90))\n", + " ] # 计算90%分位数作为阈值,筛选分数>=阈值的行\n", + ").reset_index(drop=True) # drop=True 避免添加旧索引列\n", + "# df_to_drop = score_df.loc[score_df.groupby('trade_date')['score'].idxmax()]\n", + "# score_df = score_df.drop(df_to_drop.index)\n", + "save_df = score_df.groupby('trade_date', group_keys=False).apply(lambda x: x.nlargest(5, 'score')).reset_index()\n", + "# save_df = score_df.groupby('trade_date', group_keys=False).apply(lambda x: x.nsmallest(2, 'total_mv')).reset_index()\n", + "save_df = save_df.sort_values(['trade_date', 'score'])\n", + "save_df[['trade_date', 'score', 'ts_code']].to_csv('predictions_test.tsv', index=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fed2d6c3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2023-01-03 00:00:00\n" + ] + } + ], + "source": [ + "print(test_data['trade_date'].min())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f3c1331", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "成功连接到 Redis 服务器: 140.143.91.66:6389,数据库 0\n", + "DataFrame 已使用 Pickle 序列化并写入 Redis,键为 'save_df'\n", + "从 Redis 读取到的 Pickle 序列化数据 (前 20 字节):\n", + "b'\\x80\\x04\\x95\\xbf\\x04\\x01\\x00\\x00\\x00\\x00\\x00\\x8c\\x11pandas.'\n", + "\n", + "从 Redis 加载的 DataFrame (使用 Pickle):\n", + " index ts_code trade_date open close high low vol \\\n", + "4 36 002247.SZ 2023-01-03 16.15 16.80 16.87 16.09 0.514578 \n", + "3 26 002513.SZ 2023-01-03 15.41 15.77 15.95 15.41 -0.499029 \n", + "2 14 002629.SZ 2023-01-03 15.17 15.54 15.58 15.13 0.631716 \n", + "1 5 603030.SH 2023-01-03 8.08 8.32 8.32 8.05 -0.033641 \n", + "0 3 000691.SZ 2023-01-03 13.87 14.24 14.36 13.63 -0.030740 \n", + "... ... ... ... ... ... ... ... ... \n", + "2904 58031 002524.SZ 2025-05-30 19.49 19.40 20.27 19.31 0.455783 \n", + "2903 58034 002084.SZ 2025-05-30 11.88 11.68 11.88 11.58 0.610122 \n", + "2902 58029 600159.SH 2025-05-30 13.66 13.55 13.86 13.50 -0.170606 \n", + "2901 58035 002775.SZ 2025-05-30 17.84 17.55 17.84 17.41 -0.705858 \n", + "2900 58019 600408.SH 2025-05-30 8.64 8.51 8.64 8.43 0.684604 \n", + "\n", + " pct_chg amount ... 000905.SH_up_ratio_20d \\\n", + "4 0.715898 31834.487 ... 0.3 \n", + "3 0.121763 25452.447 ... 0.3 \n", + "2 0.299045 55379.071 ... 0.3 \n", + "1 0.241548 22271.706 ... 0.3 \n", + "0 0.279880 38602.205 ... 0.3 \n", + "... ... ... ... ... \n", + "2904 0.552905 76113.818 ... 0.6 \n", + "2903 -0.070682 67595.352 ... 0.6 \n", + "2902 0.005989 28573.069 ... 0.6 \n", + "2901 0.241111 19025.635 ... 0.6 \n", + "2900 0.788027 40827.689 ... 0.6 \n", + "\n", + " 399006.SZ_up_ratio_20d 000852.SH_volatility 000905.SH_volatility \\\n", + "4 0.40 1.036997 0.828596 \n", + "3 0.40 1.036997 0.828596 \n", + "2 0.40 1.036997 0.828596 \n", + "1 0.40 1.036997 0.828596 \n", + "0 0.40 1.036997 0.828596 \n", + "... ... ... ... \n", + "2904 0.45 1.089861 0.850444 \n", + "2903 0.45 1.089861 0.850444 \n", + "2902 0.45 1.089861 0.850444 \n", + "2901 0.45 1.089861 0.850444 \n", + "2900 0.45 1.089861 0.850444 \n", + "\n", + " 399006.SZ_volatility 000852.SH_volume_change_rate \\\n", + "4 0.935322 5.203088 \n", + "3 0.935322 5.203088 \n", + "2 0.935322 5.203088 \n", + "1 0.935322 5.203088 \n", + "0 0.935322 5.203088 \n", + "... ... ... \n", + "2904 1.195355 -2.039466 \n", + "2903 1.195355 -2.039466 \n", + "2902 1.195355 -2.039466 \n", + "2901 1.195355 -2.039466 \n", + "2900 1.195355 -2.039466 \n", + "\n", + " 000905.SH_volume_change_rate 399006.SZ_volume_change_rate score \\\n", + "4 -0.750721 8.827360 0.042645 \n", + "3 -0.750721 8.827360 0.047474 \n", + "2 -0.750721 8.827360 0.055433 \n", + "1 -0.750721 8.827360 0.061053 \n", + "0 -0.750721 8.827360 0.068349 \n", + "... ... ... ... \n", + "2904 -12.002493 5.078672 0.064251 \n", + "2903 -12.002493 5.078672 0.064517 \n", + "2902 -12.002493 5.078672 0.065030 \n", + "2901 -12.002493 5.078672 0.068848 \n", + "2900 -12.002493 5.078672 0.074780 \n", + "\n", + " score_ranks \n", + "4 996.0 \n", + "3 997.0 \n", + "2 998.0 \n", + "1 999.0 \n", + "0 1000.0 \n", + "... ... \n", + "2904 996.0 \n", + "2903 997.0 \n", + "2902 998.0 \n", + "2901 999.0 \n", + "2900 1000.0 \n", + "\n", + "[2905 rows x 248 columns]\n", + "\n", + "验证成功:原始 DataFrame 和从 Redis 加载的 DataFrame 一致。\n", + "\n", + "清理了 Redis 中键 'save_df' 的数据。\n" + ] + } + ], + "source": [ + "import redis\n", + "import pickle\n", + "\n", + "redis_host = '140.143.91.66'\n", + "redis_port = 6389\n", + "redis_db = 0\n", + "redis_key = 'save_df'\n", + "\n", + "try:\n", + " # 1. 连接到 Redis 服务器\n", + " r = redis.Redis(host=redis_host, port=redis_port, db=redis_db, password='Redis520102')\n", + " r.ping()\n", + " print(f\"\\n成功连接到 Redis 服务器: {redis_host}:{redis_port},数据库 {redis_db}\")\n", + "\n", + " # 2. 将 DataFrame 写入 Redis (使用 Pickle 序列化)\n", + " df_serialized = pickle.dumps(save_df)\n", + " r.set(redis_key, df_serialized)\n", + " print(f\"DataFrame 已使用 Pickle 序列化并写入 Redis,键为 '{redis_key}'\")\n", + "\n", + " # 3. 从 Redis 读取数据 (获取 Pickle 序列化的字节流)\n", + " retrieved_serialized = r.get(redis_key)\n", + "\n", + " if retrieved_serialized:\n", + " print(f\"从 Redis 读取到的 Pickle 序列化数据 (前 20 字节):\")\n", + " print(retrieved_serialized[:20])\n", + "\n", + " # 4. 使用 Pickle 反序列化回 Pandas DataFrame\n", + " loaded_df = pickle.loads(retrieved_serialized)\n", + " print(\"\\n从 Redis 加载的 DataFrame (使用 Pickle):\")\n", + " print(loaded_df)\n", + "\n", + " # 5. 验证原始 DataFrame 和加载的 DataFrame 是否一致\n", + " if save_df.equals(loaded_df):\n", + " print(\"\\n验证成功:原始 DataFrame 和从 Redis 加载的 DataFrame 一致。\")\n", + " else:\n", + " print(\"\\n验证失败:原始 DataFrame 和从 Redis 加载的 DataFrame 不一致!\")\n", + "\n", + " else:\n", + " print(f\"错误:无法从 Redis 获取键 '{redis_key}' 的值。\")\n", + "\n", + " # 6. 清理测试数据 (可选)\n", + " r.delete(redis_key)\n", + " print(f\"\\n清理了 Redis 中键 '{redis_key}' 的数据。\")\n", + "\n", + "except redis.exceptions.ConnectionError as e:\n", + " print(f\"无法连接到 Redis 服务器: {e}\")\n", + " print(\"请确保您的 Redis 服务器已启动并且主机和端口配置正确。\")\n", + "except redis.exceptions.TimeoutError as e:\n", + " print(f\"连接 Redis 服务器超时: {e}\")\n", + " print(\"请检查您的网络连接和 Redis 服务器状态。\")\n", + "except Exception as e:\n", + " print(f\"测试 Redis 时发生未知错误: {e}\")\n", + " print(f\"测试 Redis 时发生未知错误: {e}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09b1799e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "205\n", + "['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'winner_rate', 'holder_net_change_sum_10d', 'holder_increase_days_10d', 'holder_decrease_days_10d', 'holder_any_increase_flag_10d', 'holder_any_decrease_flag_10d', 'cat_senti_mom_vol_spike', 'cat_senti_pre_breakout', 'ts_turnover_rate_acceleration_5_20', 'ts_vol_sustain_10_30', 'cs_amount_outlier_10', 'ts_ff_to_total_turnover_ratio', 'ts_price_volume_trend_coherence_5_20', 'ts_ff_turnover_rate_surge_10', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', 'log_circ_mv', 'cashflow_to_ev_factor', 'book_to_price_ratio', 'turnover_rate_mean_5', 'variance_20', 'bbi_ratio_factor', 'daily_deviation', 'lg_elg_net_buy_vol', 'flow_lg_elg_intensity', 'sm_net_buy_vol', 'total_buy_vol', 'lg_elg_buy_prop', 'flow_struct_buy_change', 'lg_elg_net_buy_vol_change', 'flow_lg_elg_accel', 'chip_concentration_range', 'chip_skewness', 'floating_chip_proxy', 'cost_support_15pct_change', 'cat_winner_price_zone', 'flow_chip_consistency', 'profit_taking_vs_absorb', 'cat_is_positive', 'upside_vol', 'downside_vol', 'vol_ratio', 'return_skew', 'return_kurtosis', 'volume_change_rate', 'cat_volume_breakout', 'turnover_deviation', 'cat_turnover_spike', 'avg_volume_ratio', 'cat_volume_ratio_breakout', 'vol_spike', 'vol_std_5', 'atr_14', 'atr_6', 'obv', 'maobv_6', 'rsi_3', 'return_5', 'return_20', 'std_return_5', 'std_return_90', 'std_return_90_2', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4', 'rank_act_factor1', 'rank_act_factor2', 'rank_act_factor3', 'cov', 'delta_cov', 'alpha_22_improved', 'alpha_003', 'alpha_007', 'alpha_013', 'vol_break', 'weight_roc5', 'smallcap_concentration', 'cost_stability', 'high_cost_break_days', 'liquidity_risk', 'turnover_std', 'mv_volatility', 'volume_growth', 'mv_growth', 'momentum_factor', 'resonance_factor', 'log_close', 'cat_vol_spike', 'up', 'down', 'obv_maobv_6', 'std_return_5_over_std_return_90', 'std_return_90_minus_std_return_90_2', 'cat_af2', 'cat_af3', 'cat_af4', 'act_factor5', 'act_factor6', 'active_buy_volume_large', 'active_buy_volume_big', 'active_buy_volume_small', 'buy_lg_vol_minus_sell_lg_vol', 'buy_elg_vol_minus_sell_elg_vol', 'ctrl_strength', 'low_cost_dev', 'asymmetry', 'lock_factor', 'cat_vol_break', 'cost_atr_adj', 'cat_golden_resonance', 'mv_turnover_ratio', 'mv_adjusted_volume', 'mv_weighted_turnover', 'nonlinear_mv_volume', 'mv_volume_ratio', 'mv_momentum', 'senti_strong_inflow', 'lg_flow_mom_corr_20_60', 'lg_flow_accel', 'profit_pressure', 'underwater_resistance', 'cost_conc_std_20', 'profit_decay_20', 'vol_amp_loss_20', 'vol_drop_profit_cnt_5', 'lg_flow_vol_interact_20', 'cost_break_confirm_cnt_5', 'atr_norm_channel_pos_14', 'turnover_diff_skew_20', 'lg_sm_flow_diverge_20', 'pullback_strong_20_20', 'vol_wgt_hist_pos_20', 'vol_adj_roc_20', 'cs_rank_net_lg_flow_val', 'cs_rank_elg_buy_ratio', 'cs_rank_rel_profit_margin', 'cs_rank_cost_breadth', 'cs_rank_dist_to_upper_cost', 'cs_rank_winner_rate', 'cs_rank_intraday_range', 'cs_rank_close_pos_in_range', 'cs_rank_pos_in_hist_range', 'cs_rank_vol_x_profit_margin', 'cs_rank_lg_flow_price_concordance', 'cs_rank_turnover_per_winner', 'cs_rank_volume_ratio', 'cs_rank_elg_buy_sell_sm_ratio', 'cs_rank_cost_dist_vol_ratio', 'cs_rank_size', 'industry_obv', 'industry_return_5', 'industry_return_20', 'industry__ema_5', 'industry__ema_13', 'industry__ema_20', 'industry__ema_60', 'industry_act_factor1', 'industry_act_factor2', 'industry_act_factor3', 'industry_act_factor4', 'industry_act_factor5', 'industry_act_factor6', 'industry_rank_act_factor1', 'industry_rank_act_factor2', 'industry_rank_act_factor3', 'industry_return_5_percentile', 'industry_return_20_percentile', '000852.SH_MACD', '000905.SH_MACD', '399006.SZ_MACD', '000852.SH_MACD_hist', '000905.SH_MACD_hist', '399006.SZ_MACD_hist', '000852.SH_RSI', '000905.SH_RSI', '399006.SZ_RSI', '000852.SH_Signal_line', '000905.SH_Signal_line', '399006.SZ_Signal_line', '000852.SH_amount_change_rate', '000905.SH_amount_change_rate', '399006.SZ_amount_change_rate', '000852.SH_amount_mean', '000905.SH_amount_mean', '399006.SZ_amount_mean', '000852.SH_daily_return', '000905.SH_daily_return', '399006.SZ_daily_return', '000852.SH_up_ratio_20d', '000905.SH_up_ratio_20d', '399006.SZ_up_ratio_20d', '000852.SH_volatility', '000905.SH_volatility', '399006.SZ_volatility', '000852.SH_volume_change_rate', '000905.SH_volume_change_rate', '399006.SZ_volume_change_rate']\n" + ] + } + ], + "source": [ + "print(len(feature_columns))\n", + "print(feature_columns)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bceabd1f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "警告: DataFrame 中没有 'group_id' 列。假设整个 DataFrame 是一个需要排序的组。\n", + "\n", + "NDCG 结果\n", + "{'ndcg@1': np.float64(0.4489795918367347), 'ndcg@3': np.float64(0.40668217598446815), 'ndcg@5': np.float64(0.45584495629735)}\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "def calculate_ndcg(df: pd.DataFrame, score_col: str, label_col: str, group_id: str = 'trade_date', k_values: list = [1, 3, 5, 10]):\n", + " \"\"\"\n", + " 计算 DataFrame 中 score 列和 label 列的 NDCG 值。\n", + "\n", + " Args:\n", + " df (pd.DataFrame): 包含 score (排序学习预测分数) 和 label (相关性标签) 的 DataFrame。\n", + " 假设每个需要排序的组(例如,每天的股票)在 DataFrame 中是连续的。\n", + " score_col (str): 包含模型预测分数的列名。\n", + " label_col (str): 包含相关性标签的列名。标签值越高表示相关性越高。\n", + " k_values (list): 一个整数列表,表示计算 NDCG 的 top-k 值。\n", + " 例如,[1, 3, 5] 将计算 NDCG@1, NDCG@3 和 NDCG@5。\n", + "\n", + " Returns:\n", + " dict: 一个字典,包含每个 k 值对应的平均 NDCG 值。\n", + " 例如: {'ndcg@1': 0.85, 'ndcg@3': 0.78, 'ndcg@5': 0.72, 'ndcg@10': 0.65}\n", + " \"\"\"\n", + " ndcg_scores = {f'ndcg@{k}': [] for k in k_values}\n", + "\n", + " def dcg_at_k(r, k):\n", + " r = np.asarray(r)[:k] if len(r) > 0 else np.zeros(k)\n", + " return np.sum(r / np.log2(np.arange(2, r.size + 2)))\n", + "\n", + " def ndcg_at_k(r, k):\n", + " dcg_max = dcg_at_k(sorted(r, reverse=True), k)\n", + " if not dcg_max:\n", + " return 0.\n", + " return dcg_at_k(r, k) / dcg_max\n", + "\n", + " # 假设 DataFrame 已经按照需要排序的组(例如,'trade_date')进行了分组,\n", + " # 并且每个组内的顺序不重要,我们只需要计算每个组的 NDCG。\n", + " # 如果需要按特定组计算 NDCG,请先对 DataFrame 进行分组。\n", + " if group_id not in df.columns:\n", + " print(\"警告: DataFrame 中没有 'group_id' 列。假设整个 DataFrame 是一个需要排序的组。\")\n", + " group_df = df.sort_values(by=score_col, ascending=False)\n", + " relevant_labels = group_df[label_col].values\n", + " for k in k_values:\n", + " ndcg_scores[f'ndcg@{k}'].append(ndcg_at_k(relevant_labels, k))\n", + " else:\n", + " for _, group_df in df.groupby(group_id):\n", + " group_df_sorted = group_df.sort_values(by=score_col, ascending=False)\n", + " relevant_labels = group_df_sorted[label_col].values\n", + " for k in k_values:\n", + " ndcg_scores[f'ndcg@{k}'].append(ndcg_at_k(relevant_labels, k))\n", + "\n", + " avg_ndcg = {k: np.mean(v) if v else np.nan for k, v in ndcg_scores.items()}\n", + " return avg_ndcg\n", + "\n", + "\n", + "ndcg_results_single_group = calculate_ndcg(score_df, score_col='score', label_col='label', k_values=[1, 3, 5], group_id=None)\n", + "print(\"\\nNDCG 结果\")\n", + "print(ndcg_results_single_group)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44f64679", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " ts_code trade_date open close high low vol pct_chg \\\n", + "1632028 002652.SZ 2019-01-02 19.59 19.64 19.89 19.28 20196.79 1.03 \n", + "1632029 002652.SZ 2019-01-03 19.74 19.44 19.84 19.33 15731.99 -1.02 \n", + "1632030 002652.SZ 2019-01-04 19.33 19.94 19.99 19.08 21099.93 2.57 \n", + "1632031 002652.SZ 2019-01-07 20.04 21.95 21.95 20.04 83534.19 10.08 \n", + "1632032 002652.SZ 2019-01-08 23.21 21.65 23.87 21.65 149377.97 -1.37 \n", + "... ... ... ... ... ... ... ... ... \n", + "1633576 002652.SZ 2025-05-26 14.75 14.85 15.11 14.55 99560.80 1.02 \n", + "1633577 002652.SZ 2025-05-27 14.90 15.00 15.11 14.70 101184.00 1.01 \n", + "1633578 002652.SZ 2025-05-28 15.11 14.85 15.16 14.80 75859.20 -1.00 \n", + "1633579 002652.SZ 2025-05-29 15.00 15.36 15.36 14.85 126044.40 3.43 \n", + "1633580 002652.SZ 2025-05-30 15.36 15.11 15.41 14.95 107732.00 -1.63 \n", + "\n", + " amount turnover_rate ... cs_rank_vol_x_profit_margin \\\n", + "1632028 7867.047 0.3964 ... 0.608839 \n", + "1632029 6121.460 0.3088 ... 0.586710 \n", + "1632030 8245.083 0.4141 ... 0.682847 \n", + "1632031 35514.117 1.6394 ... 0.987591 \n", + "1632032 67160.354 2.9317 ... 0.765693 \n", + "... ... ... ... ... \n", + "1633576 29428.560 1.9443 ... 0.652159 \n", + "1633577 30112.801 1.9760 ... 0.657694 \n", + "1633578 22507.876 1.4814 ... 0.664673 \n", + "1633579 38068.857 2.4615 ... 0.921236 \n", + "1633580 32385.927 2.1039 ... 0.702990 \n", + "\n", + " cs_rank_lg_flow_price_concordance cs_rank_turnover_per_winner \\\n", + "1632028 0.203142 0.864865 \n", + "1632029 0.156684 0.763417 \n", + "1632030 0.184009 0.660949 \n", + "1632031 0.734940 0.700000 \n", + "1632032 0.874042 0.914234 \n", + "... ... ... \n", + "1633576 0.122259 0.394684 \n", + "1633577 0.092722 0.414756 \n", + "1633578 0.684945 0.323363 \n", + "1633579 0.295779 0.390828 \n", + "1633580 0.705316 0.419934 \n", + "\n", + " cs_rank_ind_cap_neutral_pe cs_rank_volume_ratio \\\n", + "1632028 NaN 0.646930 \n", + "1632029 NaN 0.251279 \n", + "1632030 NaN 0.311724 \n", + "1632031 NaN 0.988313 \n", + "1632032 NaN 0.990142 \n", + "... ... ... \n", + "1633576 NaN 0.400997 \n", + "1633577 NaN 0.450150 \n", + "1633578 NaN 0.199236 \n", + "1633579 NaN 0.640744 \n", + "1633580 NaN 0.537542 \n", + "\n", + " cs_rank_elg_buy_sell_sm_ratio cs_rank_cost_dist_vol_ratio \\\n", + "1632028 0.341855 0.678941 \n", + "1632029 0.318912 0.402916 \n", + "1632030 0.260036 0.460713 \n", + "1632031 0.796350 0.988501 \n", + "1632032 0.598905 0.991571 \n", + "... ... ... \n", + "1633576 0.153987 0.620930 \n", + "1633577 0.156198 0.643403 \n", + "1633578 0.153373 0.484546 \n", + "1633579 0.623795 0.764374 \n", + "1633580 0.133056 0.703987 \n", + "\n", + " cs_rank_size future_return label \n", + "1632028 0.258948 0.158859 40.0 \n", + "1632029 0.258123 0.136831 37.0 \n", + "1632030 0.257664 0.106319 39.0 \n", + "1632031 0.290146 -0.072893 4.0 \n", + "1632032 0.282482 -0.057737 5.0 \n", + "... ... ... ... \n", + "1633576 0.032226 NaN NaN \n", + "1633577 0.032901 NaN NaN \n", + "1633578 0.032237 NaN NaN \n", + "1633579 0.034231 NaN NaN \n", + "1633580 0.033887 NaN NaN \n", + "\n", + "[1553 rows x 196 columns]\n" + ] + } + ], + "source": [ + "print(df[df['ts_code'] == '002652.SZ'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "stock", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/main/utils/__pycache__/data_process.cpython-313.pyc b/main/utils/__pycache__/data_process.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ba8266a1d48f5b418c7b1a41bd7ec36bffacb71 GIT binary patch literal 12337 zcmd5?eQ*;;mY>o0mn~Vc3>ae%m=6iCjX!{3z{FrajSaC-;>2bhA<0G{%g&5MLN=Q- zNdS?MU?*X1K6a5=vY6}vg56CFgpgcvwW->>I?al#oLP2{tF>hF*O@r%C3jU<_qs+ausug5boR0JfevU;byh#>xmUWBBKXU4aY1aXwG5EinQ zph^5IqQ&@EvPnwIDD+KKE8iri<&YQC3QM*{(o8n!1y;#li}V5IvSyV<-mI=rSQNR$ zF3B#E*5niUgvDr4K7>NmthT5zl_pM=fvIvHN|n)^X~}HPgtoMCDlPQ*VeO!v$t=2f zZQTRwW;LstGo>(Gi+=K60~Z70LT9y+<|%iOVCu~zC-FYxXdk(DJ@UoBzVN%1oWe`n zT%Hz3D<}6l886BxTAenpk9IPg+}X*v+#MdfBq>$`O_mt`$8{ot_#RAG6HFSPEac*N zo+6r19h|I01!)mMR}@x}fmj?b6>6H|?~Za%4*34Kgb|ex4CFTC5JX4KHliW5^?2>& z(2fJzugeB1$yQO_RDw_w6ycG2Bq{w7Tcw$VMN%#nTBC?IX_Gw81lqI6Eb?WjtxW{s zk>nHGfEyBOgP@W^Rrs|i1TG%gL+dFM_2fc5tE>przmWmWCyLYrZf73k8?#Ys>0cYO z(YLzI{FqY4qZK%#aWEnZUUVD#XD=;0qyrsx}| zq9=pHH!j59zGD7k*GsC{53j_2ezcN$idspT_SoD$Csjn*=?;czVVriatHWb+x3oKL z9y3)!nbJQnUI(>+itDdgrK+aem`W7|$^d1{`8$=XNIr6bLYf+KpYJoi4G3N zjs_8p>WS)x`i=GLE2-G|GtqEsmu!lG*rHDEsuf=V| zQgJJJj;udNa&miz+t==4%wkSdyoeLSD~;9xgW95~F0P`a-Qz8Blx*F*mG0ODvt3f} zeAeRauRg9%ON zRRYTExeQC9cP>vG$VK9CGImaal$sNR2H(p77Nh5X8tr+t5@{PX?;h+^1gPPWi=!`J zA0B)?dcH4uav0R?#8*=ZsVbx@x+y8XrOv#Wx%`qToVh%r zUe2nQe=%!*SikACsjqx+YGm0)7XFGi_LldX{PK`~(=A0tNVj6}iNTGbwNHmKZ8sG= zh7_4!$p~F`_lCf#o7!@}cub^Gy2#sx>3wT@Rz?i-S;PE+C1FFEzh+3E+gILG6w#Ym zy?J0xSii`>W=uxp&kfj*Z6Dai&L|DqFSWCIHU16VmP2(zd4e%V4 z{p(-bd^d~GReY7t58!i2@i$+Z2}3RUH5BQljuWJkA#Z82y6Xak0b^)xXGs4{L_^=w z;!iI0DU>~LKpgOe7Owh;9ArYPTSNM`h-T++G&}!mOiV)0|C2%T`k7&MmE>cQ3_VTN zvNdASC*o-}Qt2lJO7t}8YY6G5gcS0e2+#$&o6|6`4xKHnHoLcjo*Y}8nFL!{MQ{>{ zQctloj3LGtgZvhZ0pI_s7(;?FhBUQbZGaCN5-0;?6i*hpaEf|lO$mfyB`pez5~Gm6 z<55VX17i@t3F*nAN^nSG3pv6T4QQ`OO9IxKtS{RLiyXBg@N0N@Yl=qNDlP&7s{%by ziymcK8F2Hcnlgn>H0Xp}@^@AOVKp9KjFvhigpn}b*>@k_(Fwf+yd#@{cM^bq61=0v z$VHPnBY<~;fOh~b@+ppY)G2r;15;&M)u3hCG`u78sH@d=EZ`lSOTjx?zIQ-XzYXuy zRo76_H?GBgyf51I0e=Eaf_M^;2cf5nM`FG2@H;3R@v+x0pl$a;|Hy@2s@>^u**qAF z0Anb}5QL(l!2_f3?T6i;YKm7WqIOgBDZJd^7b-6lh!>=P*-nifemQ#L7jRBMALATj zCvL=EKRrBnb@an4BS#Oz2g>w>%focguIFudCq|%x-&Io=^~%!Xibu+pP{Y@6L_h3B z4O1gme>!sh(D2naV&{Jn>jFf0AUgPR@=$vJ0^;=l7pCn_0yI1tB&FA3VnF&MZx6t* zM*1%R+~ws2L%DOUZ}h?$kQ`NByhspIs)+96H}b)`*xMgQPXwap(bS-UxA@%+0ZaFe-d#PreygS4-S7>Ka2^fTB;lKY$TSQD%J3ZYUQ zUQIHINr0uMQB4}nJcd`Cyp8Vgb?(@UaTYxX$^m=rU^tPdlatupu1>x&pn4VUjqtyW?3W-Lj*@=YbbrXQ%K&o1qSa?9He7?E*h} zB$hE@hUt}1sRY%w#X*<}VHnM#U{+8ZtO%(dxhYwO(b(d18^W23BkIMhdND?0H5iTQ zZ{%LdWsBDcSgdApEOt9ncVyS0U441s%(-3bhqZ|b}=VC=T{EbV)oH55klCRT3>>*q)GWvsp|SQd1%?Qs3^x~J zxRTE$i@y1?oG`2f3}=dCxQwt&^fWwzVs-A-?d z-PVcTCxAIL+31KLuK}F?U`G+aA5mjri5MvtIB(*h0DuN^8}X1%@-2`KzCRA`kQBF( z^*gwYq$zGAnMaxe1teA(fPgeeXOVm4O~~TFsR5Y@X$gZHaVn?+Xd_2U3BZ;Jl}`q; z1d!%YlmMh^O29ZP_$PT-xSrhb2L!EPObKw6Y+B%LRaI^Phtd?Qs6>QhS;4o6jH0xZ zXi?qxehG>C<wWl=8^K~1!g;?#gP-Ly1|XuOO#f@@7>(JT{t zGOQU5XxB|kO~^9CNq~5sj1vzHP1mhSCvpy~dtt~ajahS&t!zm(WQ@sjpagwMPgZ#e39B<_nFzEX zsY_FmbO~ci+6rrlUr*T0yhz{$1{93kV@#n>)kTBV2>O=&ztuNzEz3N{Y9qJ}FJfa0 z@+rpFRNs%j-Pi&z^YGwtaMU6z>S!=J_!5{c;1!E?ot@m#3`Pn-cxuaL3l%-_!qVHdb9yo?x-#C?U1!Cm>*YQ6u z6ne%Wci_Uf<&^@c_^i-5bR>htH{pmzy+O79e2;Z1cgh4%0C~`Pp@RqV(lzKAc)5jk zCbllrkNtArov!2j+$8J&`MzxmEXm}MfTPen76@-Q-#K_>^uw2PgZE0|;3AfPGlq@A5kkHakDWRPujJ;$jWbVnx`j5OoDgCvZ?p0?*) zj1PI31%EnnubezZ`H&xOA;qs&%4dW(Dt7Wv?5Ll2yMU8@^u3=`COov^!FSD|J$#=N zy+!)e|Fh`+{ZzfJ9=eX3iSH%RGnYnx@eT|Z*}3;sME=v*<$ly2ZW8%J@GdfP?XB34 zPlA?0SRvZ&k6w8X_?ks=8_wnFbldDstZTd#IH{H;&A_}gGmu870w)FemUeP7pU3r# z&&hk<#SkO`L$CwFDI%tw)7Tsi*hP@CgO^^^2}WHTzIIr)<<_>Ge{#xqj9 zNpNx?@wvSWHhDQsf&s+VnJLiur}3V2--EY>b054a>1Tl04*$%5!zqZO6WB0TExIWw z9m>uNXa?M&f?77awyO@C$Cc;m!kLv3btS8={9;x~SikXf5dy zs@RCl<0ZjogRao3r$U)cHxX7JKx;dM+b`8g3@qKS=Z{W@9*0( zrXn)5{ufwHUPM#KY6`=eIbCaqvU9rXh9SUV4dj2WTjZAv8K?9<-t&0h>b@7)yoEst zn^zIs`PmDh>SlIHb11KwHExd>cd*7CVWY#Zf)+ETbpL?W%<+Tint5c)t6Tc21723M z&`%CepK+?{c-6pscK+(mR)ico+3Bv3V(QTJ1(E4x?DVo-^eb!*u_eAzf~d)?W>M z$en&_%CRXYrUf25`$Yc}KY8-(_WtdIWMF$}P9;07(!Xg)JMGAehh7Y83j(EQm-a6m zDDAHdlKoX-ZP_iIu}?c73G5koGROp-q2*gck2OUeYhfR22|s2FZQU`3w)~AE_?fav z^c6v5)rxM-GoRhlzo%Qv>SlkTn|eEEN}sBy-M@ZF$c)L989BG6=AM!rm-RgxDJWqJ zO2P%D!KIP%HOS>qzBW8{UAJ^7x8RidnEAwlZu#w{Rqy}c(hs_|5nUmxD-3K3iUV6% zUB#_ODsRZH$P(pG1!{wa(Cmtvy2W?r5!rcTWrQ*(qR3+vd3`MrMbX_llE^CkQv*pT zjJLo;vG>irff?Z`C4SAAf>5fDC=V&S7k;iN7=~C^X5~%AawwL{53b+0zPqWrZlI!T zJu6vsOQH;^7JV)${pQQ{BEqnV{N~FtV(zN1zgkFS&lo4fFt&+O8(j5S>1TzZy6vHy z@7>h3q{`}Uh3eWFieH(kt7>OSemzUIxj_Ewh4VJ& z%Ks@>3VAy^TZM!+eDpr9hh_9&zeJiRg1^A>U4l#E37&}Z@8F3Lr+6YH9&rk$7UQ5q z+65NiC>I8k{I$pg{0_d1)ZmibqQJqWO2F&le4^2UE#t|;JxQBG_K;c=Lr~b?5x>BK z9fa}gEn;jxu6SrjN4UZw#vA_aqPXOk&h+mccy2e*IDo|E7H*dvObdz;}j3EGUaeqpi0Q!LL)nuUWOit7(DO( zMOv9S{rL0FIO!;9AJqH@_-FKh-zEvf|Lt7AY8;Z!?O72qm|25)U~bq@iURV}dKU6N z-vMJ-UxHn`Q*-+Yd!7ws_q;ezc&>=ec_i+%)gq^D-o(H=a@zhC1Mg;#4Fuj-;lMjQ zmn~T%5q%<=RwI*sLMhSHtgj)ZpOR9@bK1DEhrklLcf-kOC*1J!*kJ=qB(y8wZSh^m ze2+wTd|>ClFCkq($s=k?P)~M44_rVZ3wACF+Y)+5n}U@T?gM(nR?(ze8906|l4YXF zZsA!IclkULt7JA|mik_TZaz2yn-WL`#6El-MeTUFjxO$;xrBq70NkWSYT3xyATW&IE>n%(cpF?1m8#U+Zg7tX_b-i4wEK;Ozan*1V0FOFBK}5M zVyI9ddgx;86%4^99(s9>|s|O0lFft2aA#31eMKV{<;wkUCAJ} z==Rvm5>AT4W1Ko=J~$O0@-UFlzIGYK8?_K;3rbUrSHy9GgoIrL?Iev#+%d;-; z&iDtOM{@U0Bl;8KyAd9+*NrQPyaoQ++uGby?Z?_b*Dkm{V-`E3Br;W&_g<)kJhynLoF;y~4h$_vEBzv>r9{KS?+g+=g*J3v z61fi^IDG)B#^9fM0v<5Pu^b{hr*~=3(zlj%ZH55Ytl4MtPv-|UgU#%sP2rifU7Ne} zSV{gpiB4)9GZ9%cBD&dtkOR$w&X8_)NLLflZDMtsK3f&mHFa>bPmtjyBgF

tr~biEi`J*nYz&8*wo86jGK(w;=+EZ$ z=Zz7N9TeTrT+!fcXzMoqx5aS}eHw!;Jb&hpsrWAVd`lrH?(T7q5s)3qqsGMWd)t^h zCWT)xd}hwQhboP^Nur{f99mp;SN;@9mIcbruIOJeMxgwVxoAv`GPjEsjY&}k=oXdV z!xitoD1sLIcARn_gEk-=bl{(ltbA8CkaJ0+zzwn=&Hjk_*gQr+Hng=NvbCAr+I$ba HVY&Pd+Jw2Q literal 0 HcmV?d00001 diff --git a/main/utils/__pycache__/indicators.cpython-313.pyc b/main/utils/__pycache__/indicators.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6ce69fd98613a172c34ab2eecb9296abac62351 GIT binary patch literal 4384 zcmbVP>r)e17Vo@6ctm*xQDUPEAufobVhxLoI-~B^%%aj}7DvXmO&X1cPNqB2#jSF( zDjFRWm=OVGM^s$F2T;3HKJYpJL3&fQq49DwMte+C<#@QszIOF z{<2+!5$aV6c}!?lstIkAqCvXn1*_kq zux3u9!}Ze|sQ3IacVyGQ4xN2(`eztTE1?pUj%GnyPdcbpPRL`O+9-yfjHM zjE`~&xpM0~M0uTVhHR$nUNWEXjEtf|jMdK9;eg+Y$x!Rq%fi zfoi8>r)sBqr+#NzH)g{ajZM=Ke|us(Y6%6QtOSX@tB`h}(=!U8NXkr&E@()-F}`Bs^edHw9*r0+@HFdgguSJ|M8 zlTB%C+5|U@&ZaBDtm(cOkT6W&=#6v-q9d24MtUNn9b(7z=#fiPSBJ#@As9~Hy*@cU z80q~g(sMP^e?9W&t9U&Q{i*ZE#CzX}?dQb7j!54~Wc2LRnG@od?Ni@ej&yWJN5|!v zA0D(%KJ1^oJ02amHFf_eocf5`O}oDLA2En09!9#yCLf%Sp1C7-oJ$fH2Zv!BT#ar# zdwc4_DMWd^Lk#o)HSykU@#6U8_?gJ9L3vWCu z<)t>VR10mb!K07965Fog$tfT{-R~FM+r-WrxW&tncDIAJltY)L95fi8R~p$}ZjQF# zzzw3-K>UfJJ%xnpJr8($Li4xV%$7wJKFt3G%ag3traja#QF&S%;CHf$1w}ru&A) zz%U3qadtMBdU=39y96O$>r|83*U=yJ4IN^l;&|5AHh_^cNGWjVu<5|jm#(K-D zR#jQ8i5q8e*Mwx^20Cy;JaJsSGZH!J2W=rk0iBI?MEXyH5reEEr$?ra+>?d&Cha5? z1`>^Y-7gET9*H`Ih&a|2H!}YNWOji*T(Vpo-iFsx^@w9bg9IdT6H7HO5bT+Y;-gcpdHK3RzV|~?IDc^x8q(`4d7u<1wJiI z>CY(kdVT zF$$ZaA#KKS7$$CJl)xFl>CBQ`SH1l%Mr~6OikgGKH9%_PVg$|G^c4W)jJgqcsDb!| zP@U2I4>}02GiGvuVP)|t$C_7UlJ)w|MX55IHALGqvP=kN1*|7zo@f#1r@X|H@)B+1 zMkG_K%GUw+8lsQd#8bmEJcE73@%3~!z)R%*dGXZH)b$>*N%2w9DwG8Ecy?2n&Zg$w2+NXlCMk( zMxaAF=mW`3TG?ZTIS%(hhI2wJNF3M2T~^3WF2O;kl!CCxDurAJ<#e@@uc9!EGA9mM zWde!(e!oyv*}`}$9hF;Jx3KPgwB1`-Pah<_Zu|bq7Rt#~`n*mTSLtLNPCEs;4Y$Lf5m!X1vJo12|>C(U@5*1FuVnX6m+ zR*EP?;r&*AwM{QUL7ji2y^ zpLFV;8S?_42leI`@W5A*51F5Ye02!)#wQMfzXY)`6K?@T!EXC}h1+^1Ag+<0-O%t*>Sary;t+Jip~3HG7sE&>ASLKbdO3X5z{d<+ zE`0b)ocs;M9O(AHLWTTWj}q{VckKeTtz9dt%=&*ThOLF;C?n!dK=rd9i!H;9bN!n@fX4iZtYSW^c)&TfAoxyQ zFsnG2^`5j+u(0RzuFnTrL#E|p7T#1dVcNi(HiS%@{F?%scy%tq%H?A#`1#dAb-};Y zg_?yw9a7|L%&{tLZb6T+%Q%oWMt2&6b808%tmo&f55B)6G^fe`+Zf<_UQnGY2^4Hx z>!BD2#R*CegjdGb0&91sA4LGLh&7z^BtBQ(_=Zg;l-BlqLOQt%a)6^gvD-q4Y8G9#u! ugJ&7Wm%V&}iK`H@Nh literal 0 HcmV?d00001 diff --git a/main/utils/data_process.py b/main/utils/data_process.py new file mode 100644 index 0000000..9df9a2a --- /dev/null +++ b/main/utils/data_process.py @@ -0,0 +1,268 @@ +import pandas as pd +import numpy as np +import statsmodels.api as sm # 用于中性化回归 +from tqdm import tqdm + +epsilon = 1e-10 # 防止除零 + +def zscore_standardize(train_df: pd.DataFrame, test_df: pd.DataFrame, features: list, epsilon: float = 1e-10): + """ + 对指定特征列进行截面 Z-Score 标准化 (原地修改)。 + 方法: Z = (value - cross_sectional_mean) / (cross_sectional_std + epsilon) + + Args: + df (pd.DataFrame): 输入 DataFrame,需包含 'trade_date' 和 features 列。 + features (list): 需要处理的特征列名列表。 + epsilon (float): 防止除以零的小常数。 + + WARNING: 此函数会原地修改输入的 DataFrame 'df'。 + """ + print("开始截面 Z-Score 标准化...") + if not all(col in train_df.columns for col in features): + missing = [col for col in features if col not in train_df.columns] + print(f"错误: DataFrame 中缺少以下特征列: {missing}。跳过标准化处理。") + return + + + for col in tqdm(features, desc="Standardizing"): + try: + # 使用 transform 计算截面均值和标准差 + mean = train_df[col].transform('mean') + std = train_df[col].transform('std') + + # 计算 Z-Score 并原地赋值 + train_df[col] = (train_df[col] - mean) / (std + epsilon) + test_df[col] = (test_df[col] - mean) / (std + epsilon) + + except KeyError: + print(f"警告: 列 '{col}' 可能不存在或在分组中出错,跳过此列的标准化处理。") + except Exception as e: + print(f"警告: 处理列 '{col}' 时发生错误: {e},跳过此列的标准化处理。") + + print("截面 Z-Score 标准化完成。") + + +# --- 1. 中位数去极值 (MAD) --- + +def cs_mad_filter(df: pd.DataFrame, + features: list, + k: float = 3.0, + scale_factor: float = 1.4826): + """ + 对指定特征列进行截面 MAD 去极值处理 (原地修改)。 + + 方法: 对每日截面数据,计算 median 和 MAD, + 将超出 [median - k * scale * MAD, median + k * scale * MAD] 范围的值 + 替换为边界值 (Winsorization)。 + scale_factor=1.4826 使得 MAD 约等于正态分布的标准差。 + + Args: + df (pd.DataFrame): 输入 DataFrame,需包含 'trade_date' 和 features 列。 + features (list): 需要处理的特征列名列表。 + k (float): MAD 的倍数,用于确定边界。默认为 3.0。 + scale_factor (float): MAD 的缩放因子。默认为 1.4826。 + + WARNING: 此函数会原地修改输入的 DataFrame 'df'。 + """ + print(f"开始截面 MAD 去极值处理 (k={k})...") + if not all(col in df.columns for col in features): + missing = [col for col in features if col not in df.columns] + print(f"错误: DataFrame 中缺少以下特征列: {missing}。跳过去极值处理。") + return + + grouped = df.groupby('trade_date') + + for col in tqdm(features, desc="MAD Filtering"): + try: + # 计算截面中位数 + median = grouped[col].transform('median') + # 计算截面 MAD (Median Absolute Deviation from Median) + mad = (df[col] - median).abs().groupby(df['trade_date']).transform('median') + + # 计算上下边界 + lower_bound = median - k * scale_factor * mad + upper_bound = median + k * scale_factor * mad + + # 原地应用 clip + df[col] = np.clip(df[col], lower_bound, upper_bound) + + except KeyError: + print(f"警告: 列 '{col}' 可能不存在或在分组中出错,跳过此列的 MAD 处理。") + except Exception as e: + print(f"警告: 处理列 '{col}' 时发生错误: {e},跳过此列的 MAD 处理。") + + print("截面 MAD 去极值处理完成。") + + +# --- 2. 行业市值中性化 --- + +def cs_neutralize_industry_cap(df: pd.DataFrame, + features: list, + industry_col: str = 'cat_l2_code', + market_cap_col: str = 'circ_mv'): + """ + 对指定特征列进行截面行业和对数市值中性化 (原地修改)。 + 使用 OLS 回归: feature ~ 1 + log(market_cap) + C(industry) + 将回归残差写回原特征列。 + + Args: + df (pd.DataFrame): 输入 DataFrame,需包含 'trade_date', features 列, + industry_col, market_cap_col。 + features (list): 需要处理的特征列名列表。 + industry_col (str): 行业分类列名。 + market_cap_col (str): 流通市值列名。 + + WARNING: 此函数会原地修改输入的 DataFrame 'df' 的 features 列。 + 计算量较大,可能耗时较长。 + 需要安装 statsmodels 库 (pip install statsmodels)。 + """ + print("开始截面行业市值中性化...") + required_cols = features + ['trade_date', industry_col, market_cap_col] + if not all(col in df.columns for col in required_cols): + missing = [col for col in required_cols if col not in df.columns] + print(f"错误: DataFrame 中缺少必需列: {missing}。无法进行中性化。") + return + + # 预处理:计算 log 市值,处理 industry code 可能的 NaN + log_cap_col = '_log_market_cap' + df[log_cap_col] = np.log1p(df[market_cap_col]) # log1p 处理 0 值 + # df[industry_col] = df[industry_col].cat.add_categories('UnknownIndustry') + # df[industry_col] = df[industry_col].fillna('UnknownIndustry') # 填充行业 NaN + # df[industry_col] = df[industry_col].astype('category') # 转为类别,ols 会自动处理 + + dates = df['trade_date'].unique() + all_residuals = [] # 用于收集所有日期的残差 + + for date in tqdm(dates, desc="Neutralizing"): + daily_data = df.loc[df['trade_date'] == date, features + [log_cap_col, industry_col]].copy() # 使用 .loc 获取副本 + + # 准备自变量 X (常数项 + log市值 + 行业哑变量) + X = daily_data[[log_cap_col]] + X = sm.add_constant(X, prepend=True) # 添加常数项 + # 创建行业哑变量 (drop_first=True 避免共线性) + industry_dummies = pd.get_dummies(daily_data[industry_col], prefix=industry_col, drop_first=True) + industry_dummies = industry_dummies.astype(int) + X = pd.concat([X, industry_dummies], axis=1) + + daily_residuals = daily_data[[col for col in features]].copy() # 创建用于存储残差的df + + for col in features: + Y = daily_data[col] + + # 处理 NaN 值,确保 X 和 Y 在相同位置有有效值 + valid_mask = Y.notna() & X.notna().all(axis=1) + if valid_mask.sum() < (X.shape[1] + 1): # 数据点不足以估计模型 + print(f"警告: 日期 {date}, 特征 {col} 有效数据不足 ({valid_mask.sum()}个),无法中性化,填充 NaN。") + daily_residuals[col] = np.nan + continue + + Y_valid = Y[valid_mask] + X_valid = X[valid_mask] + + # 执行 OLS 回归 + try: + model = sm.OLS(Y_valid.to_numpy(), X_valid.to_numpy()) + results = model.fit() + # 将残差填回对应位置 + daily_residuals.loc[valid_mask, col] = results.resid + daily_residuals.loc[~valid_mask, col] = np.nan # 原本无效的位置填充 NaN + except Exception as e: + print(f"警告: 日期 {date}, 特征 {col} 回归失败: {e},填充 NaN。") + daily_residuals[col] = np.nan + break + + all_residuals.append(daily_residuals) + + # 合并所有日期的残差结果 + if all_residuals: + residuals_df = pd.concat(all_residuals) + # 将残差结果更新回原始 df (原地修改) + # 使用 update 比 merge 更适合基于索引的原地更新 + # 确保 residuals_df 的索引与 df 中对应部分一致 + df.update(residuals_df) + else: + print("没有有效的残差结果可以合并。") + + + # 清理临时列 + df.drop(columns=[log_cap_col], inplace=True) + print("截面行业市值中性化完成。") + + +# --- 3. Z-Score 标准化 --- + +def cs_zscore_standardize(df: pd.DataFrame, features: list, epsilon: float = 1e-10): + """ + 对指定特征列进行截面 Z-Score 标准化 (原地修改)。 + 方法: Z = (value - cross_sectional_mean) / (cross_sectional_std + epsilon) + + Args: + df (pd.DataFrame): 输入 DataFrame,需包含 'trade_date' 和 features 列。 + features (list): 需要处理的特征列名列表。 + epsilon (float): 防止除以零的小常数。 + + WARNING: 此函数会原地修改输入的 DataFrame 'df'。 + """ + print("开始截面 Z-Score 标准化...") + if not all(col in df.columns for col in features): + missing = [col for col in features if col not in df.columns] + print(f"错误: DataFrame 中缺少以下特征列: {missing}。跳过标准化处理。") + return + + grouped = df.groupby('trade_date') + + for col in tqdm(features, desc="Standardizing"): + try: + # 使用 transform 计算截面均值和标准差 + mean = grouped[col].transform('mean') + std = grouped[col].transform('std') + + # 计算 Z-Score 并原地赋值 + df[col] = (df[col] - mean) / (std + epsilon) + + except KeyError: + print(f"警告: 列 '{col}' 可能不存在或在分组中出错,跳过此列的标准化处理。") + except Exception as e: + print(f"警告: 处理列 '{col}' 时发生错误: {e},跳过此列的标准化处理。") + + print("截面 Z-Score 标准化完成。") + +def fill_nan_with_daily_median(df: pd.DataFrame, feature_columns: list[str]) -> pd.DataFrame: + """ + 对指定特征列进行每日截面中位数填充缺失值 (NaN)。 + + 参数: + df (pd.DataFrame): 包含多日数据的DataFrame,需要包含 'trade_date' 和 feature_columns 中的列。 + feature_columns (list[str]): 需要进行缺失值填充的特征列名称列表。 + + 返回: + pd.DataFrame: 包含缺失值填充后特征列的DataFrame。在输入DataFrame的副本上操作。 + """ + processed_df = df.copy() # 在副本上操作,保留原始数据 + + # 确保 trade_date 是 datetime 类型以便正确分组 + processed_df['trade_date'] = pd.to_datetime(processed_df['trade_date']) + + def _fill_daily_nan(group): + # group 是某一个交易日的 DataFrame + + # 遍历指定的特征列 + for feature_col in feature_columns: + # 检查列是否存在于当前分组中 + if feature_col in group.columns: + # 计算当日该特征的中位数 + median_val = group[feature_col].median() + + # 使用当日中位数填充该特征列的 NaN 值 + # inplace=True 会直接修改 group DataFrame + group[feature_col].fillna(median_val, inplace=True) + # else: + # print(f"Warning: Feature column '{feature_col}' not found in daily group for {group['trade_date'].iloc[0]}. Skipping.") + + return group + + # 按交易日期分组,并应用每日填充函数 + # group_keys=False 避免将分组键添加到结果索引中 + filled_df = processed_df.groupby('trade_date', group_keys=False).apply(_fill_daily_nan) + + return filled_df \ No newline at end of file diff --git a/main/utils/indicators.py b/main/utils/indicators.py new file mode 100644 index 0000000..dfe3c13 --- /dev/null +++ b/main/utils/indicators.py @@ -0,0 +1,130 @@ +import pandas as pd +import numpy as np + +def calculate_sharpe_sortino_labels_efficient( + df: pd.DataFrame, + N_days: int = 5, # 未来考察的天数,用于计算收益率序列 + risk_free_rate_annual: float = 0.02, # 年化无风险利率 (例如 0.02 表示 2%) + annualization_factor: float = np.sqrt(252), # 年化因子,日数据通常用sqrt(252) + min_periods_for_std: int = 2 # 计算标准差所需的最小有效数据点数 +) -> pd.DataFrame: + """ + 高效计算每只股票在每个交易日未来 N 日的年化夏普比率和索提诺比率,作为训练的Label。 + 函数会获取未来 N 天的每日收益率序列,并基于此序列计算夏普/索提诺。 + + Args: + df (pd.DataFrame): 输入 DataFrame,需包含 'ts_code', 'trade_date', 'close' 列。 + 'close' 列必须是股票收盘价。 + N_days (int): 未来考察的天数。例如,N_days=5 表示考察未来5个交易日。 + risk_free_rate_annual (float): 年化无风险利率。 + annualization_factor (float): 用于将日收益率转化为年化收益率的因子 (例如 np.sqrt(252))。 + min_periods_for_std (int): 计算标准差所需的最小有效数据点数。 + 如果未来N天有效数据少于此值,则 Label 为 NaN。 + + Returns: + pd.DataFrame: 原始DataFrame,新增 'sharpe_ratio_label' 和 'sortino_ratio_label' 列。 + 注意:数据末尾 N_days 行的 Label 将为 NaN。 + """ + df_copy = df + + # 确保数据已按股票和日期排序,这对于高效计算至关重要 + df_copy = df_copy.sort_values(by=['ts_code', 'trade_date']) + + # # 计算每日收益率 + # df_copy['pct_chg'] = df_copy.groupby('ts_code')['close'].pct_change() + + # 将年化无风险利率转换为每日无风险利率 + daily_risk_free_rate = risk_free_rate_annual / 252 # 假设每年252个交易日 + + def _calculate_metrics_for_window(returns_series): + """ + 辅助函数:计算单个滚动窗口内的夏普和索提诺比率。 + 这个函数将被 apply 调用于每个 (N_days) 收益率序列。 + """ + if len(returns_series.dropna()) < min_periods_for_std: + return np.nan, np.nan # 数据不足,返回NaN + + excess_returns = returns_series - daily_risk_free_rate + + # --- 夏普比率 --- + mean_excess_return = excess_returns.mean() + std_dev_returns = returns_series.std() # 夏普比率使用总收益率的标准差 + + sharpe = np.nan + if std_dev_returns != 0: + sharpe = (mean_excess_return / std_dev_returns) * annualization_factor + + # --- 索提诺比率 --- + downside_returns = returns_series[returns_series < daily_risk_free_rate] + sortino = np.nan + if not downside_returns.empty: + downside_deviation = np.sqrt(np.mean((downside_returns - daily_risk_free_rate)**2)) + if downside_deviation != 0: + sortino = (mean_excess_return / downside_deviation) * annualization_factor + + return sharpe, sortino + + # 使用 groupby().rolling() 结合 apply 来高效计算 + # 注意: 这里使用 shift(-N_days) 来获取未来 N_days 的窗口 + # 同时 rolling 窗口需要是 N_days 大小,并对 pct_chg 序列进行操作 + # 结果会被放置在窗口的末尾,但我们实际上需要它对应到窗口的起始位置 + # 因此,我们先计算,然后将其向上 shift N_days + 1 (或者根据 rolling 的行为调整) + + # 获取未来 N_days 的每日收益率序列 + # 为了避免在每一行中循环,我们构造一个辅助的DataFrame,其中包含未来N天的收益率 + # 这里使用一个更高效的思路:对每只股票,生成一个N天的收益率列表 + + # 使用 groupby().apply() 和 list comprehension 来构建未来N天的收益率列表 + # 为了获得未来N天的收益率,需要对pct_chg进行shift(-N_days) + # 然后再对每个N_days的窗口进行处理 + + # 方法一:先获取未来N天的收益率列,然后进行滑动窗口计算 (更推荐,效率高) + # 创建一个辅助列,表示未来 N 天的每日收益率列表 + # 注意:这里需要 N_days 长度的窗口,且数据点至少为 min_periods_for_std + + # 对每只股票进行分组,然后计算未来 N 天的夏普/索提诺 + # 这仍然涉及到对每个时间点获取未来N天的收益序列,Pandas 的 rolling 默认是向后看的 + # 为了实现向后看 N_days (即从当前日期 t 预测 t+1 到 t+N_days),我们需要一些技巧 + + # 最直接且通常高效的方法是: + # 1. 计算日收益率。 + # 2. 对每个股票,对日收益率进行反向滚动,然后计算指标。 + # 或者更简单地,使用 shift(-N_days) 创建“未来的”日收益率列,然后进行滚动。 + + # 为了简化且保持效率,我们可以这样做: + # 1. 计算每个股票的每日收益率。 + # 2. 对于每个 (ts_code, trade_date) 行,我们将查看其未来的 N_days 每日收益率。 + # 这在 Pandas 中不直接通过 .rolling() 实现,因为 rolling 是“当前及之前”的窗口。 + # 我们可以用 groupby().apply() 配合自定义函数来模拟这个“未来窗口”的行为。 + + def _apply_metrics_per_stock(stock_df_group): + """ + 对单只股票的数据帧进行处理,计算其每个日期的未来 N 日夏普/索提诺比率。 + """ + sharpe_labels = [np.nan] * len(stock_df_group) + sortino_labels = [np.nan] * len(stock_df_group) + + # 遍历当前股票的每个日期,获取未来的 N_days 收益率序列 + for i in range(len(stock_df_group) - N_days): + # 获取未来 N_days 的每日收益率序列 + # 从当前日期 t 的下一天 (t+1) 开始,到 t+N_days + future_pct_chgs = stock_df_group['pct_chg'].iloc[i+1 : i+1+N_days].dropna() + + # 计算夏普和索提诺 + sharpe, sortino = _calculate_metrics_for_window(future_pct_chgs) + + # 赋值到对应日期 + sharpe_labels[i] = sharpe + sortino_labels[i] = sortino + + stock_df_group['sharpe_ratio_label'] = sharpe_labels + stock_df_group['sortino_ratio_label'] = sortino_labels + return stock_df_group + + # 对每个股票分组应用这个函数 + df_result = df_copy.groupby('ts_code', group_keys=False).apply(_apply_metrics_per_stock) + + # # 清理不再需要的中间列 + # df_result = df_result.drop(columns=['pct_chg']) + + return df_result diff --git a/predictions_test.tsv b/predictions_test.tsv index cdc0bd4..6ab0f48 100644 --- a/predictions_test.tsv +++ b/predictions_test.tsv @@ -1,51 +1,51 @@ trade_date,score,ts_code -2023-01-03,0.04264513757161395,002247.SZ +2023-01-03,0.04264513757161396,002247.SZ 2023-01-03,0.047473879793379845,002513.SZ -2023-01-03,0.05543341870580454,002629.SZ +2023-01-03,0.055433418705804545,002629.SZ 2023-01-03,0.061053204232209037,603030.SH 2023-01-03,0.06834946223279599,000691.SZ 2023-01-04,0.04944180779763693,002652.SZ 2023-01-04,0.05101764675472167,000702.SZ 2023-01-04,0.052308519226764674,002247.SZ 2023-01-04,0.054430293533857546,600250.SH -2023-01-04,0.06296916608880651,002629.SZ +2023-01-04,0.06296916608880652,002629.SZ 2023-01-05,0.049799080682322444,603021.SH -2023-01-05,0.0544454175141359,603030.SH +2023-01-05,0.05444541751413591,603030.SH 2023-01-05,0.05640454658386936,600250.SH -2023-01-05,0.061364223956451906,002247.SZ +2023-01-05,0.06136422395645191,002247.SZ 2023-01-05,0.06186702549189658,002629.SZ -2023-01-06,0.048999956171680015,002629.SZ -2023-01-06,0.05358670281112123,002247.SZ -2023-01-06,0.057203477217011765,603021.SH +2023-01-06,0.04899995617168002,002629.SZ +2023-01-06,0.05358670281112124,002247.SZ +2023-01-06,0.05720347721701177,603021.SH 2023-01-06,0.06199820984701511,002652.SZ -2023-01-06,0.0724404044174652,603030.SH -2023-01-09,0.05244685056196679,002629.SZ +2023-01-06,0.07244040441746522,603030.SH +2023-01-09,0.052446850561966796,002629.SZ 2023-01-09,0.05568827403393317,600250.SH 2023-01-09,0.05795124819985819,603030.SH 2023-01-09,0.05842796373007265,603021.SH -2023-01-09,0.062250458078583544,002247.SZ +2023-01-09,0.06225045807858355,002247.SZ 2023-01-10,0.04956641692162102,600250.SH 2023-01-10,0.05416621073860915,002620.SZ 2023-01-10,0.05421082871972414,002513.SZ 2023-01-10,0.06016640270372842,603021.SH -2023-01-10,0.06094741214326171,002629.SZ -2023-01-11,0.04484704680100515,002629.SZ +2023-01-10,0.060947412143261714,002629.SZ +2023-01-11,0.04484704680100516,002629.SZ 2023-01-11,0.0462047496065822,002663.SZ 2023-01-11,0.06160223401528153,002513.SZ 2023-01-11,0.06386304735439895,002247.SZ -2023-01-11,0.06539045541890232,603021.SH +2023-01-11,0.06539045541890233,603021.SH 2023-01-12,0.050717553670052366,002663.SZ 2023-01-12,0.05188664861800753,600889.SH 2023-01-12,0.0530997141388225,002629.SZ 2023-01-12,0.0574694706126226,603021.SH -2023-01-12,0.06667637473470707,002513.SZ +2023-01-12,0.06667637473470708,002513.SZ 2023-01-13,0.047435387719658904,002571.SZ 2023-01-13,0.04934164641603143,603021.SH 2023-01-13,0.05165412498687684,002513.SZ -2023-01-13,0.0520976941508744,002629.SZ +2023-01-13,0.05209769415087441,002629.SZ 2023-01-13,0.058278158774065364,002620.SZ 2023-01-16,0.046561838060479,002207.SZ -2023-01-16,0.04849633882432156,002629.SZ +2023-01-16,0.04849633882432157,002629.SZ 2023-01-16,0.04904907249803364,002571.SZ 2023-01-16,0.04953635797493052,603021.SH 2023-01-16,0.0648569858189875,000702.SZ @@ -55,105 +55,105 @@ trade_date,score,ts_code 2023-01-17,0.054415370215465116,002660.SZ 2023-01-17,0.0560995897360317,603021.SH 2023-01-18,0.0408635713924239,000586.SZ -2023-01-18,0.04210622980775887,002620.SZ +2023-01-18,0.042106229807758876,002620.SZ 2023-01-18,0.055694953336546164,002247.SZ -2023-01-18,0.05625426973692878,002513.SZ +2023-01-18,0.056254269736928784,002513.SZ 2023-01-18,0.05729444275529857,603021.SH -2023-01-19,0.04492469230567692,002173.SZ -2023-01-19,0.04502391567802497,000586.SZ -2023-01-19,0.046564549526430826,002660.SZ -2023-01-19,0.050968903426642634,600355.SH -2023-01-19,0.05514664838924892,002513.SZ +2023-01-19,0.04492469230567693,002173.SZ +2023-01-19,0.045023915678024974,000586.SZ +2023-01-19,0.04656454952643082,002660.SZ +2023-01-19,0.05096890342664264,600355.SH +2023-01-19,0.055146648389248924,002513.SZ 2023-01-20,0.05055920803829244,002247.SZ 2023-01-20,0.05307394243821632,600355.SH 2023-01-20,0.055297497612008556,002652.SZ -2023-01-20,0.055738603185935306,603021.SH +2023-01-20,0.05573860318593531,603021.SH 2023-01-20,0.06174766927721104,002513.SZ -2023-01-30,0.041771348117859715,603021.SH +2023-01-30,0.04177134811785972,603021.SH 2023-01-30,0.044530994966345265,002629.SZ 2023-01-30,0.047935952750786846,000702.SZ -2023-01-30,0.05025612172590264,002660.SZ +2023-01-30,0.05025612172590263,002660.SZ 2023-01-30,0.05378880116172613,002652.SZ 2023-01-31,0.04999480687861859,603021.SH 2023-01-31,0.05465004088305856,000702.SZ 2023-01-31,0.05617413905685271,002247.SZ -2023-01-31,0.05645109869996786,002620.SZ +2023-01-31,0.05645109869996787,002620.SZ 2023-01-31,0.06097605017060088,002652.SZ 2023-02-01,0.0512156528590303,603828.SH -2023-02-01,0.05536232114200196,603021.SH -2023-02-01,0.057095884881694134,002629.SZ -2023-02-01,0.05849593879221137,002247.SZ +2023-02-01,0.055362321142001965,603021.SH +2023-02-01,0.05709588488169414,002629.SZ +2023-02-01,0.05849593879221138,002247.SZ 2023-02-01,0.07110641715304261,002620.SZ 2023-02-02,0.05837322771925943,002652.SZ 2023-02-02,0.058408901360184194,002629.SZ 2023-02-02,0.06088665913640544,002247.SZ 2023-02-02,0.06290146472075636,002775.SZ 2023-02-02,0.0632866363354719,002620.SZ -2023-02-03,0.056758613724144195,002629.SZ +2023-02-03,0.0567586137241442,002629.SZ 2023-02-03,0.05699306238759353,603021.SH 2023-02-03,0.06088665913640544,002247.SZ -2023-02-03,0.060934076541829287,002620.SZ +2023-02-03,0.06093407654182929,002620.SZ 2023-02-03,0.0654754837666029,002513.SZ -2023-02-06,0.06075392628764216,002629.SZ +2023-02-06,0.06075392628764217,002629.SZ 2023-02-06,0.06416280200374293,603030.SH 2023-02-06,0.06601901071597704,002620.SZ -2023-02-06,0.0676635977964893,600689.SH +2023-02-06,0.06766359779648931,600689.SH 2023-02-06,0.07606412782182433,002513.SZ -2023-02-07,0.05824166930648732,600561.SH -2023-02-07,0.05857676039915045,002620.SZ -2023-02-07,0.05937408701085855,002775.SZ -2023-02-07,0.06156651466710432,002513.SZ +2023-02-07,0.058241669306487324,600561.SH +2023-02-07,0.058576760399150454,002620.SZ +2023-02-07,0.059374087010858535,002775.SZ +2023-02-07,0.061566514667104326,002513.SZ 2023-02-07,0.07292171152378452,002629.SZ -2023-02-08,0.05804802903012867,603559.SH -2023-02-08,0.05857676039915045,002620.SZ +2023-02-08,0.05804802903012868,603559.SH +2023-02-08,0.058576760399150454,002620.SZ 2023-02-08,0.061336152992163336,603030.SH 2023-02-08,0.0615246235931781,600561.SH 2023-02-08,0.06173748519620736,002652.SZ -2023-02-09,0.06212532350645805,600689.SH +2023-02-09,0.06212532350645806,600689.SH 2023-02-09,0.06370710981613487,002652.SZ 2023-02-09,0.06495910944602075,600561.SH 2023-02-09,0.06816968385192665,002513.SZ -2023-02-09,0.07794605156127347,000691.SZ +2023-02-09,0.07794605156127349,000691.SZ 2023-02-10,0.06509429963101292,002513.SZ -2023-02-10,0.06661096055455584,603559.SH +2023-02-10,0.06661096055455586,603559.SH 2023-02-10,0.06830403397857686,600561.SH 2023-02-10,0.06836995018817245,000691.SZ 2023-02-10,0.06891908066512606,002247.SZ 2023-02-13,0.06715182613996035,603021.SH 2023-02-13,0.06798576406359091,002513.SZ -2023-02-13,0.0702613719449372,000691.SZ -2023-02-13,0.07403943248614486,002247.SZ +2023-02-13,0.07026137194493721,000691.SZ +2023-02-13,0.07403943248614488,002247.SZ 2023-02-13,0.07528888522776074,002652.SZ 2023-02-14,0.07023982850744284,002247.SZ 2023-02-14,0.07123281631043367,002513.SZ 2023-02-14,0.07255599550722729,002629.SZ 2023-02-14,0.07730094066931364,600561.SH -2023-02-14,0.07756420822872263,000691.SZ +2023-02-14,0.07756420822872265,000691.SZ 2023-02-15,0.06711108890997484,002620.SZ 2023-02-15,0.07123966014887462,603030.SH 2023-02-15,0.07242766932970054,002513.SZ -2023-02-15,0.07624127274156903,600561.SH -2023-02-15,0.08047698031350702,000691.SZ +2023-02-15,0.07624127274156904,600561.SH +2023-02-15,0.08047698031350703,000691.SZ 2023-02-16,0.06393913507338049,600561.SH -2023-02-16,0.06422092512877264,002620.SZ -2023-02-16,0.06433959452245494,000691.SZ +2023-02-16,0.06422092512877266,002620.SZ +2023-02-16,0.06433959452245495,000691.SZ 2023-02-16,0.0647341172307067,002652.SZ -2023-02-16,0.07038343026347987,002247.SZ -2023-02-17,0.06929610471096614,002620.SZ +2023-02-16,0.07038343026347989,002247.SZ +2023-02-17,0.06929610471096616,002620.SZ 2023-02-17,0.07518014133679977,002513.SZ 2023-02-17,0.07583967231731227,600561.SH -2023-02-17,0.07913751626888572,000691.SZ -2023-02-17,0.07980493433975645,002652.SZ +2023-02-17,0.07913751626888574,000691.SZ +2023-02-17,0.07980493433975647,002652.SZ 2023-02-20,0.06609711813405915,002620.SZ 2023-02-20,0.06664009228200883,603030.SH 2023-02-20,0.07179546626150034,600561.SH 2023-02-20,0.07688444647521289,002513.SZ 2023-02-20,0.07799416274064623,002652.SZ -2023-02-21,0.07239919453232362,600561.SH +2023-02-21,0.07239919453232363,600561.SH 2023-02-21,0.07567740314692595,002513.SZ 2023-02-21,0.07858712842868158,603030.SH -2023-02-21,0.07859789101146951,002652.SZ -2023-02-21,0.08093609755897588,000691.SZ +2023-02-21,0.07859789101146952,002652.SZ +2023-02-21,0.08093609755897589,000691.SZ 2023-02-22,0.06954659363834995,002620.SZ 2023-02-22,0.07019106676674747,000702.SZ 2023-02-22,0.07119499445764593,600561.SH @@ -161,14 +161,14 @@ trade_date,score,ts_code 2023-02-22,0.08144363824493701,002652.SZ 2023-02-23,0.0674463683814315,600689.SH 2023-02-23,0.0692127173727868,000702.SZ -2023-02-23,0.07187847865684104,002620.SZ +2023-02-23,0.07187847865684105,002620.SZ 2023-02-23,0.0723267136926143,600561.SH -2023-02-23,0.08005606302094297,002652.SZ +2023-02-23,0.08005606302094298,002652.SZ 2023-02-24,0.06412114056765673,000702.SZ -2023-02-24,0.06850204155886346,000691.SZ +2023-02-24,0.06850204155886347,000691.SZ 2023-02-24,0.07135455387892602,002247.SZ -2023-02-24,0.07385736654179707,600561.SH -2023-02-24,0.0844492628633141,002652.SZ +2023-02-24,0.07385736654179709,600561.SH +2023-02-24,0.08444926286331411,002652.SZ 2023-02-27,0.05899847229172572,000702.SZ 2023-02-27,0.06087322889940991,002513.SZ 2023-02-27,0.06535963751564641,600250.SH @@ -176,29 +176,29 @@ trade_date,score,ts_code 2023-02-27,0.07008424322039503,002620.SZ 2023-02-28,0.06356400841593483,600561.SH 2023-02-28,0.06373580442521587,000702.SZ -2023-02-28,0.06420038176694126,002620.SZ +2023-02-28,0.06420038176694128,002620.SZ 2023-02-28,0.06708922818866546,002513.SZ 2023-02-28,0.07541173449738532,002652.SZ 2023-03-01,0.06220879286805757,002620.SZ 2023-03-01,0.06377559691449575,600250.SH 2023-03-01,0.06568370425272939,002652.SZ -2023-03-01,0.07021898767522258,000691.SZ +2023-03-01,0.0702189876752226,000691.SZ 2023-03-01,0.07541173449738532,600561.SH 2023-03-02,0.06633557288347124,000890.SZ 2023-03-02,0.06859567440602136,000691.SZ 2023-03-02,0.07054006913769632,600250.SH 2023-03-02,0.07061400130898757,600561.SH -2023-03-02,0.07568994127357598,002652.SZ +2023-03-02,0.07568994127357599,002652.SZ 2023-03-03,0.06458080681520159,002247.SZ 2023-03-03,0.06477852369523922,002620.SZ 2023-03-03,0.06607838102986675,000691.SZ 2023-03-03,0.07061400130898757,600561.SH -2023-03-03,0.07980493433975645,002652.SZ -2023-03-06,0.06574183024465093,002629.SZ +2023-03-03,0.07980493433975647,002652.SZ +2023-03-06,0.06574183024465094,002629.SZ 2023-03-06,0.06685954827323952,002513.SZ 2023-03-06,0.06826072413001336,600561.SH 2023-03-06,0.06987195283496665,000691.SZ -2023-03-06,0.07679930972137936,002652.SZ +2023-03-06,0.07679930972137937,002652.SZ 2023-03-07,0.05348372011513591,600689.SH 2023-03-07,0.0548313709885044,002775.SZ 2023-03-07,0.06432823003133806,000691.SZ @@ -210,116 +210,116 @@ trade_date,score,ts_code 2023-03-08,0.06826626992469383,002629.SZ 2023-03-08,0.07695132786377036,600561.SH 2023-03-09,0.059070668415798944,002629.SZ -2023-03-09,0.0636708501045388,600250.SH +2023-03-09,0.06367085010453881,600250.SH 2023-03-09,0.06375596368526426,002247.SZ 2023-03-09,0.06732575868059083,603030.SH 2023-03-09,0.0757564748445035,600561.SH 2023-03-10,0.05690963577947678,000702.SZ 2023-03-10,0.06443166286081625,002652.SZ 2023-03-10,0.0676362902481909,002247.SZ -2023-03-10,0.06913737033868994,002629.SZ +2023-03-10,0.06913737033868995,002629.SZ 2023-03-10,0.0757564748445035,600561.SH -2023-03-13,0.05814662267233301,002513.SZ +2023-03-13,0.058146622672333025,002513.SZ 2023-03-13,0.061604462977820185,002247.SZ -2023-03-13,0.06327183995975198,600250.SH +2023-03-13,0.063271839959752,600250.SH 2023-03-13,0.06823477757251786,002652.SZ 2023-03-13,0.0757564748445035,600561.SH 2023-03-14,0.05473280281232688,600689.SH 2023-03-14,0.06577323292777704,600250.SH -2023-03-14,0.07051411084456109,002247.SZ -2023-03-14,0.07375227939789328,600561.SH -2023-03-14,0.07627164261708577,002652.SZ -2023-03-15,0.06394609759323472,600689.SH +2023-03-14,0.0705141108445611,002247.SZ +2023-03-14,0.07375227939789329,600561.SH +2023-03-14,0.07627164261708579,002652.SZ +2023-03-15,0.06394609759323473,600689.SH 2023-03-15,0.06683317911198176,002247.SZ 2023-03-15,0.06817184793667165,600250.SH -2023-03-15,0.07553716424582901,002652.SZ +2023-03-15,0.07553716424582903,002652.SZ 2023-03-15,0.07890971896904858,600561.SH -2023-03-16,0.0683291708733313,600689.SH -2023-03-16,0.07094128590881614,000820.SZ -2023-03-16,0.07192817813247969,600561.SH -2023-03-16,0.07257532008559263,600250.SH -2023-03-16,0.07318958914416412,002652.SZ -2023-03-17,0.05548202405265812,002247.SZ +2023-03-16,0.06832917087333132,600689.SH +2023-03-16,0.07094128590881615,000820.SZ +2023-03-16,0.0719281781324797,600561.SH +2023-03-16,0.07257532008559264,600250.SH +2023-03-16,0.07318958914416414,002652.SZ +2023-03-17,0.055482024052658126,002247.SZ 2023-03-17,0.05594474849580339,600250.SH 2023-03-17,0.06019462869202885,600889.SH 2023-03-17,0.06320731389050523,002199.SZ 2023-03-17,0.07498837590340543,600561.SH -2023-03-20,0.054639953080806415,603030.SH +2023-03-20,0.05463995308080642,603030.SH 2023-03-20,0.055121433660040235,600561.SH 2023-03-20,0.058175051923095994,002247.SZ 2023-03-20,0.07132043171222864,002199.SZ 2023-03-20,0.07411440138963289,002652.SZ -2023-03-21,0.05729811301722107,002247.SZ -2023-03-21,0.0585170026465719,000691.SZ +2023-03-21,0.057298113017221076,002247.SZ +2023-03-21,0.058517002646571906,000691.SZ 2023-03-21,0.0694094471449115,002199.SZ 2023-03-21,0.07204799640222587,600689.SH 2023-03-21,0.07731274821273716,600561.SH 2023-03-22,0.057392150903227634,600689.SH -2023-03-22,0.05895931234241279,002247.SZ -2023-03-22,0.05898999817721231,000691.SZ -2023-03-22,0.06080097441308602,600250.SH +2023-03-22,0.0589593123424128,002247.SZ +2023-03-22,0.058989998177212316,000691.SZ +2023-03-22,0.060800974413086024,600250.SH 2023-03-22,0.06141783909313495,600561.SH -2023-03-23,0.06590102196321139,002199.SZ +2023-03-23,0.06590102196321138,002199.SZ 2023-03-23,0.06788632174177578,002247.SZ 2023-03-23,0.0695543570019702,600250.SH 2023-03-23,0.0706861139136643,600561.SH -2023-03-23,0.07139677476072409,600689.SH -2023-03-24,0.06227277829173769,000691.SZ +2023-03-23,0.0713967747607241,600689.SH +2023-03-24,0.0622727782917377,000691.SZ 2023-03-24,0.06402777625234507,600561.SH -2023-03-24,0.06406501835035557,600250.SH -2023-03-24,0.07194439621524192,600689.SH +2023-03-24,0.06406501835035558,600250.SH +2023-03-24,0.07194439621524193,600689.SH 2023-03-24,0.07258406118954594,002247.SZ 2023-03-27,0.0673690922075145,002247.SZ -2023-03-27,0.06880942135273553,600250.SH -2023-03-27,0.06916519874371009,002199.SZ +2023-03-27,0.06880942135273554,600250.SH +2023-03-27,0.06916519874371008,002199.SZ 2023-03-27,0.0704099828441342,600889.SH 2023-03-27,0.0758453188502384,000691.SZ 2023-03-28,0.05593892176642336,000691.SZ 2023-03-28,0.062359272142527185,002247.SZ 2023-03-28,0.06280144851536318,002199.SZ -2023-03-28,0.06803797000859631,600250.SH -2023-03-28,0.07141907576847932,600689.SH +2023-03-28,0.06803797000859632,600250.SH +2023-03-28,0.07141907576847933,600689.SH 2023-03-29,0.05058459763039553,600355.SH 2023-03-29,0.05128589869925918,603030.SH 2023-03-29,0.05918890483154863,002199.SZ 2023-03-29,0.06699513513172045,600250.SH 2023-03-29,0.0677802508259075,002247.SZ 2023-03-30,0.05375556111870778,600355.SH -2023-03-30,0.05537194977539582,002495.SZ +2023-03-30,0.055371949775395835,002495.SZ 2023-03-30,0.06198531506673313,600250.SH -2023-03-30,0.0666535166370872,002247.SZ -2023-03-30,0.07747231666616201,603030.SH -2023-03-31,0.042937201676518134,002199.SZ +2023-03-30,0.06665351663708721,002247.SZ +2023-03-30,0.07747231666616203,603030.SH +2023-03-31,0.04293720167651814,002199.SZ 2023-03-31,0.04679102582529564,600355.SH 2023-03-31,0.06468901200836916,002247.SZ 2023-03-31,0.06699513513172045,600250.SH 2023-03-31,0.06783823339179906,603030.SH 2023-04-03,0.028931462956934672,600257.SH -2023-04-03,0.04072695494633112,600355.SH +2023-04-03,0.04072695494633113,600355.SH 2023-04-03,0.05273552382367705,002247.SZ 2023-04-03,0.05441398850151352,600689.SH 2023-04-03,0.06817654329863118,600250.SH -2023-04-04,0.05021008103068585,002494.SZ +2023-04-04,0.05021008103068586,002494.SZ 2023-04-04,0.05080874461856185,600355.SH -2023-04-04,0.06042259705342588,600889.SH -2023-04-04,0.062079626082698236,600689.SH +2023-04-04,0.0604225970534259,600889.SH +2023-04-04,0.06207962608269825,600689.SH 2023-04-04,0.06842372147638577,600250.SH 2023-04-06,0.03608681413226294,002495.SZ 2023-04-06,0.056253760028976314,600355.SH 2023-04-06,0.06335533351000736,600250.SH 2023-04-06,0.06523834194049655,002494.SZ -2023-04-06,0.06659854586993769,600689.SH -2023-04-07,0.03829344814911222,002247.SZ -2023-04-07,0.0411107752799028,002671.SZ +2023-04-06,0.0665985458699377,600689.SH +2023-04-07,0.03829344814911223,002247.SZ +2023-04-07,0.04111077527990279,002671.SZ 2023-04-07,0.04810117343428198,600355.SH 2023-04-07,0.05875257485092418,002494.SZ 2023-04-07,0.06517940270880622,600689.SH 2023-04-10,0.03449972682544694,002247.SZ 2023-04-10,0.03740275547222727,603030.SH 2023-04-10,0.05217744364556274,002652.SZ -2023-04-10,0.06027414661069868,002494.SZ -2023-04-10,0.06082269736346715,600689.SH -2023-04-11,0.039230602068320096,600243.SH +2023-04-10,0.06027414661069869,002494.SZ +2023-04-10,0.060822697363467154,600689.SH +2023-04-11,0.0392306020683201,600243.SH 2023-04-11,0.043964892303151204,600448.SH 2023-04-11,0.05310978475153235,600689.SH 2023-04-11,0.056406968804366964,002671.SZ @@ -329,51 +329,51 @@ trade_date,score,ts_code 2023-04-12,0.05401005415466271,600448.SH 2023-04-12,0.05681052598067632,002652.SZ 2023-04-12,0.07423400442589283,002494.SZ -2023-04-13,0.04526366638855588,600243.SH +2023-04-13,0.04526366638855589,600243.SH 2023-04-13,0.04721552044057541,600250.SH 2023-04-13,0.050117918813916834,600448.SH 2023-04-13,0.06242356315915176,002652.SZ 2023-04-13,0.06722752608787617,002494.SZ -2023-04-14,0.03546691571274977,600322.SH -2023-04-14,0.041857194855318886,002247.SZ +2023-04-14,0.03546691571274978,600322.SH +2023-04-14,0.04185719485531889,002247.SZ 2023-04-14,0.04479514262585236,000908.SZ 2023-04-14,0.06476505373331665,002629.SZ 2023-04-14,0.07502405108180721,002652.SZ 2023-04-17,0.025995559024715415,603616.SH -2023-04-17,0.03958598700940169,600322.SH +2023-04-17,0.0395859870094017,600322.SH 2023-04-17,0.047808581925745684,002247.SZ 2023-04-17,0.048709203172127576,002629.SZ 2023-04-17,0.06103598793515772,002652.SZ -2023-04-18,0.03636104380383554,600243.SH -2023-04-18,0.039505094299400766,002495.SZ +2023-04-18,0.03636104380383555,600243.SH +2023-04-18,0.03950509429940077,002495.SZ 2023-04-18,0.050860795117789064,002629.SZ 2023-04-18,0.05572165191472314,002247.SZ 2023-04-18,0.06103598793515772,002652.SZ 2023-04-19,0.0375283262752998,600889.SH -2023-04-19,0.04105864883690499,603828.SH +2023-04-19,0.041058648836904986,603828.SH 2023-04-19,0.04131762307923537,600322.SH 2023-04-19,0.06737032348328607,002629.SZ 2023-04-19,0.07214541529367192,002652.SZ 2023-04-20,0.038574008782411025,600889.SH 2023-04-20,0.040656444802960795,600448.SH 2023-04-20,0.04395465071895495,002629.SZ -2023-04-20,0.05283085148900924,603828.SH +2023-04-20,0.052830851489009234,603828.SH 2023-04-20,0.05548619239985584,002652.SZ -2023-04-21,0.044319914329346496,002513.SZ +2023-04-21,0.0443199143293465,002513.SZ 2023-04-21,0.05494756982609649,000017.SZ 2023-04-21,0.056574765621073685,002629.SZ -2023-04-21,0.06047258826304524,603828.SH +2023-04-21,0.06047258826304523,603828.SH 2023-04-21,0.07541346476788299,002652.SZ 2023-04-24,0.052427738391312956,603828.SH -2023-04-24,0.05384355804923849,002247.SZ -2023-04-24,0.05387363778761728,002629.SZ +2023-04-24,0.053843558049238495,002247.SZ +2023-04-24,0.053873637787617286,002629.SZ 2023-04-24,0.05524563679469133,002775.SZ 2023-04-24,0.08698372700494034,002652.SZ -2023-04-25,0.06067883535672813,600250.SH +2023-04-25,0.060678835356728134,600250.SH 2023-04-25,0.06358516621055792,600561.SH 2023-04-25,0.0645988214039533,002591.SZ 2023-04-25,0.06838486403662346,002652.SZ -2023-04-25,0.07523626622969828,002629.SZ +2023-04-25,0.0752362662296983,002629.SZ 2023-04-26,0.05906845031641825,002775.SZ 2023-04-26,0.06130747187621377,002591.SZ 2023-04-26,0.06908160955485754,600250.SH @@ -383,7 +383,7 @@ trade_date,score,ts_code 2023-04-27,0.0648188453899482,002494.SZ 2023-04-27,0.06740962933234293,600889.SH 2023-04-27,0.07588642034226821,002591.SZ -2023-04-27,0.07917006986217774,600561.SH +2023-04-27,0.07917006986217776,600561.SH 2023-04-28,0.06376006282176157,600250.SH 2023-04-28,0.06514776718696116,002775.SZ 2023-04-28,0.06635455493569573,603725.SH @@ -392,13 +392,13 @@ trade_date,score,ts_code 2023-05-04,0.06177690806329035,002494.SZ 2023-05-04,0.06536705274749859,000820.SZ 2023-05-04,0.07267716028933945,002591.SZ -2023-05-04,0.0832281126464811,002629.SZ -2023-05-04,0.08451368473359207,600561.SH -2023-05-05,0.06957878101054704,002591.SZ +2023-05-04,0.08322811264648111,002629.SZ +2023-05-04,0.08451368473359208,600561.SH +2023-05-05,0.06957878101054706,002591.SZ 2023-05-05,0.0696896799865044,603536.SH 2023-05-05,0.07502155254356148,002775.SZ 2023-05-05,0.07580518492418084,002629.SZ -2023-05-05,0.08150806011521497,600561.SH +2023-05-05,0.08150806011521498,600561.SH 2023-05-08,0.07117303521503879,002775.SZ 2023-05-08,0.07408298015543094,002620.SZ 2023-05-08,0.07580518492418084,600561.SH @@ -407,12 +407,12 @@ trade_date,score,ts_code 2023-05-09,0.0728773403534519,002775.SZ 2023-05-09,0.07408298015543094,002620.SZ 2023-05-09,0.0772516473966822,002652.SZ -2023-05-09,0.08214909833696618,600561.SH -2023-05-09,0.08652622259845148,002629.SZ +2023-05-09,0.0821490983369662,600561.SH +2023-05-09,0.0865262225984515,002629.SZ 2023-05-10,0.06049066497261356,002494.SZ 2023-05-10,0.06797232004522821,002652.SZ 2023-05-10,0.06849974206628409,002620.SZ -2023-05-10,0.06857320332812215,002775.SZ +2023-05-10,0.06857320332812214,002775.SZ 2023-05-10,0.07399858840578825,600561.SH 2023-05-11,0.06653405404323237,002591.SZ 2023-05-11,0.06849974206628409,002620.SZ @@ -420,12 +420,12 @@ trade_date,score,ts_code 2023-05-11,0.0734097883512578,002629.SZ 2023-05-11,0.07399858840578825,600561.SH 2023-05-12,0.059104402432322324,000702.SZ -2023-05-12,0.06211630895499993,002591.SZ +2023-05-12,0.062116308954999935,002591.SZ 2023-05-12,0.06433601014592737,002620.SZ -2023-05-12,0.06698417850209534,002652.SZ +2023-05-12,0.06698417850209536,002652.SZ 2023-05-12,0.07399858840578825,600561.SH -2023-05-15,0.06028760174565339,002591.SZ -2023-05-15,0.061616455605917116,002620.SZ +2023-05-15,0.060287601745653396,002591.SZ +2023-05-15,0.06161645560591712,002620.SZ 2023-05-15,0.06477255374801298,000638.SZ 2023-05-15,0.07003332638334406,600561.SH 2023-05-15,0.07377373839046755,000702.SZ @@ -434,18 +434,18 @@ trade_date,score,ts_code 2023-05-16,0.060923472904146216,002620.SZ 2023-05-16,0.06529415982066711,000702.SZ 2023-05-16,0.07003332638334406,600561.SH -2023-05-17,0.06091252871133244,000820.SZ -2023-05-17,0.06577695174149785,002620.SZ +2023-05-17,0.060912528711332445,000820.SZ +2023-05-17,0.06577695174149786,002620.SZ 2023-05-17,0.06615299982041743,600561.SH 2023-05-17,0.07136183329825489,000691.SZ 2023-05-17,0.07459553371770021,000702.SZ 2023-05-18,0.05858975674351729,002652.SZ -2023-05-18,0.06229032471125561,002620.SZ +2023-05-18,0.06229032471125562,002620.SZ 2023-05-18,0.06288382974882935,002494.SZ 2023-05-18,0.06983275083363302,000691.SZ 2023-05-18,0.07003332638334406,600561.SH 2023-05-19,0.06458746767067831,002652.SZ -2023-05-19,0.06488711984185797,600561.SH +2023-05-19,0.06488711984185798,600561.SH 2023-05-19,0.06632841516210178,002620.SZ 2023-05-19,0.06991029420649594,000702.SZ 2023-05-19,0.07244409188086909,002629.SZ @@ -453,24 +453,24 @@ trade_date,score,ts_code 2023-05-22,0.06641231670264831,600561.SH 2023-05-22,0.0671919720130438,002620.SZ 2023-05-22,0.07108971873062368,000702.SZ -2023-05-22,0.07266818650373204,002629.SZ -2023-05-23,0.06649898931127289,002620.SZ +2023-05-22,0.07266818650373205,002629.SZ +2023-05-23,0.0664989893112729,002620.SZ 2023-05-23,0.06720596011861966,000691.SZ 2023-05-23,0.07053265684777921,002652.SZ 2023-05-23,0.07165479874733964,600355.SH 2023-05-23,0.07214155042687785,000702.SZ -2023-05-24,0.06497020919026902,002247.SZ +2023-05-24,0.06497020919026904,002247.SZ 2023-05-24,0.06650414572471451,600250.SH 2023-05-24,0.06955644898235745,000702.SZ 2023-05-24,0.07120153390816869,002188.SZ -2023-05-24,0.08138133728565064,002629.SZ +2023-05-24,0.08138133728565065,002629.SZ 2023-05-25,0.0635449635684174,600561.SH 2023-05-25,0.0675036975949769,600250.SH 2023-05-25,0.07135580328680989,000702.SZ 2023-05-25,0.07385546822278194,002629.SZ 2023-05-25,0.07461501807016889,600355.SH -2023-05-26,0.059741036421874574,002207.SZ -2023-05-26,0.06114058539080114,600561.SH +2023-05-26,0.05974103642187457,002207.SZ +2023-05-26,0.061140585390801146,600561.SH 2023-05-26,0.06240344430706624,603536.SH 2023-05-26,0.07371734386363188,600250.SH 2023-05-26,0.07471223229093932,002188.SZ @@ -479,46 +479,46 @@ trade_date,score,ts_code 2023-05-29,0.06735349881886672,002494.SZ 2023-05-29,0.07105950336210193,000017.SZ 2023-05-29,0.07397609553394947,600250.SH -2023-05-30,0.07053775592894815,002207.SZ +2023-05-30,0.07053775592894813,002207.SZ 2023-05-30,0.07093148287789176,002828.SZ 2023-05-30,0.07217460949315459,600250.SH 2023-05-30,0.07377352075953095,000017.SZ 2023-05-30,0.074042036054306,002652.SZ 2023-05-31,0.060562316896129884,600250.SH 2023-05-31,0.06294925394391972,002629.SZ -2023-05-31,0.06437133532719265,002207.SZ +2023-05-31,0.06437133532719266,002207.SZ 2023-05-31,0.07105950336210193,000017.SZ -2023-05-31,0.07965952867611618,002652.SZ +2023-05-31,0.0796595286761162,002652.SZ 2023-06-01,0.06489784950666942,603725.SH 2023-06-01,0.06597162129711798,600250.SH 2023-06-01,0.066121303955808,002828.SZ 2023-06-01,0.06700955605395674,000017.SZ -2023-06-01,0.08515733942151257,002652.SZ +2023-06-01,0.08515733942151259,002652.SZ 2023-06-02,0.05588116021770234,603536.SH 2023-06-02,0.06156463909412396,002828.SZ -2023-06-02,0.0650897934777236,002652.SZ +2023-06-02,0.06508979347772362,002652.SZ 2023-06-02,0.06827907535717669,000702.SZ 2023-06-02,0.07745868467539321,000017.SZ 2023-06-05,0.06194227343533629,000702.SZ -2023-06-05,0.0637721163092585,600561.SH +2023-06-05,0.06377211630925851,600561.SH 2023-06-05,0.06498318990949332,600355.SH 2023-06-05,0.06663606834298873,002247.SZ 2023-06-05,0.07729892413331926,002652.SZ -2023-06-06,0.057280743862787066,603828.SH +2023-06-06,0.05728074386278706,603828.SH 2023-06-06,0.06056175868917302,600689.SH 2023-06-06,0.06274742311519664,002828.SZ -2023-06-06,0.06735969145766144,002652.SZ +2023-06-06,0.06735969145766145,002652.SZ 2023-06-06,0.06949556142221638,600355.SH 2023-06-07,0.05046183987937562,000702.SZ -2023-06-07,0.05373807020675787,002207.SZ +2023-06-07,0.053738070206757874,002207.SZ 2023-06-07,0.05607086172510028,002494.SZ 2023-06-07,0.05674186121296912,000017.SZ -2023-06-07,0.06287479128880384,600355.SH +2023-06-07,0.06287479128880386,600355.SH 2023-06-08,0.057519143561928714,603828.SH 2023-06-08,0.061940981717337876,000691.SZ 2023-06-08,0.06307147412756976,002494.SZ 2023-06-08,0.06785114952122873,000017.SZ -2023-06-08,0.07339183297336627,600355.SH +2023-06-08,0.07339183297336628,600355.SH 2023-06-09,0.05604921776341199,603725.SH 2023-06-09,0.0584234949031464,600561.SH 2023-06-09,0.06268383140104873,000702.SZ @@ -529,7 +529,7 @@ trade_date,score,ts_code 2023-06-12,0.06242085524091033,600689.SH 2023-06-12,0.06368533726958374,000702.SZ 2023-06-12,0.0693737291078877,002494.SZ -2023-06-13,0.05942007809692282,600448.SH +2023-06-13,0.05942007809692281,600448.SH 2023-06-13,0.06344476547109719,002494.SZ 2023-06-13,0.06562614563320014,000691.SZ 2023-06-13,0.06634176520973235,600689.SH @@ -545,47 +545,47 @@ trade_date,score,ts_code 2023-06-15,0.06561771506452703,000017.SZ 2023-06-15,0.0693737291078877,002494.SZ 2023-06-16,0.05874227474353723,600678.SH -2023-06-16,0.06033449182786196,000638.SZ +2023-06-16,0.06033449182786195,000638.SZ 2023-06-16,0.0695266802016066,000702.SZ 2023-06-16,0.07117475049724079,000691.SZ 2023-06-16,0.07562751649296028,600355.SH 2023-06-19,0.04433403214048923,002495.SZ 2023-06-19,0.04910680953346722,000017.SZ 2023-06-19,0.050028481934135574,603725.SH -2023-06-19,0.05516141907531858,600689.SH +2023-06-19,0.05516141907531859,600689.SH 2023-06-19,0.06072618079441497,000702.SZ 2023-06-20,0.04699012658937013,603725.SH 2023-06-20,0.04812888847905715,000702.SZ -2023-06-20,0.059208621019749004,600689.SH +2023-06-20,0.05920862101974901,600689.SH 2023-06-20,0.06183195641192798,600355.SH 2023-06-20,0.06670216605801102,000017.SZ -2023-06-21,0.054413656508634084,000638.SZ +2023-06-21,0.05441365650863408,000638.SZ 2023-06-21,0.05529676570585194,000702.SZ -2023-06-21,0.05536464275201502,000908.SZ +2023-06-21,0.055364642752015025,000908.SZ 2023-06-21,0.058720494786198216,002494.SZ 2023-06-21,0.07633690488729165,600355.SH -2023-06-26,0.06340281950164406,000638.SZ +2023-06-26,0.06340281950164407,000638.SZ 2023-06-26,0.06572530766353148,002494.SZ -2023-06-26,0.07109805515685336,600355.SH +2023-06-26,0.07109805515685337,600355.SH 2023-06-26,0.07139060957831492,002652.SZ -2023-06-26,0.08071391921477991,002629.SZ -2023-06-27,0.05935875844774947,000638.SZ +2023-06-26,0.08071391921477993,002629.SZ +2023-06-27,0.05935875844774946,000638.SZ 2023-06-27,0.0604135765659752,600689.SH 2023-06-27,0.06642851108921399,600448.SH 2023-06-27,0.06774007961266072,600355.SH -2023-06-27,0.06989270695755981,002629.SZ -2023-06-28,0.061619858658783645,603828.SH +2023-06-27,0.06989270695755982,002629.SZ +2023-06-28,0.06161985865878364,603828.SH 2023-06-28,0.06216408413848684,000017.SZ 2023-06-28,0.06407889277271497,600355.SH -2023-06-28,0.0651343621902688,002629.SZ +2023-06-28,0.06513436219026882,002629.SZ 2023-06-28,0.06826067729094601,002652.SZ 2023-06-29,0.05885643326896184,002652.SZ 2023-06-29,0.06373088412651211,002629.SZ 2023-06-29,0.06642135233947946,000638.SZ 2023-06-29,0.0675921076102027,603828.SH -2023-06-29,0.06862603943275525,600448.SH -2023-06-30,0.0567813402895775,600448.SH -2023-06-30,0.06085042295704437,002652.SZ +2023-06-29,0.06862603943275523,600448.SH +2023-06-30,0.056781340289577494,600448.SH +2023-06-30,0.060850422957044376,002652.SZ 2023-06-30,0.06370073833833445,000638.SZ 2023-06-30,0.06775920349101977,000702.SZ 2023-06-30,0.0733730531074548,603828.SH @@ -593,52 +593,52 @@ trade_date,score,ts_code 2023-07-03,0.06354465774535303,002207.SZ 2023-07-03,0.0652035398010426,002828.SZ 2023-07-03,0.06964021995222608,002652.SZ -2023-07-03,0.07204462704093981,603828.SH +2023-07-03,0.0720446270409398,603828.SH 2023-07-04,0.061831825612954416,000638.SZ 2023-07-04,0.06522402407787312,002828.SZ 2023-07-04,0.06529521528768925,603536.SH 2023-07-04,0.06728410679659493,600448.SH 2023-07-04,0.07107713449520933,002629.SZ 2023-07-05,0.06542603089867537,002494.SZ -2023-07-05,0.06939254033109643,002652.SZ +2023-07-05,0.06939254033109644,002652.SZ 2023-07-05,0.06986489705850653,000017.SZ -2023-07-05,0.07324171988364075,002629.SZ +2023-07-05,0.07324171988364077,002629.SZ 2023-07-05,0.07472895408898082,603536.SH 2023-07-06,0.06568104407261452,603536.SH 2023-07-06,0.0659232821200614,000017.SZ 2023-07-06,0.06834472823776931,000890.SZ -2023-07-06,0.06971455201724659,000638.SZ +2023-07-06,0.0697145520172466,000638.SZ 2023-07-06,0.07718599393952126,603828.SH 2023-07-07,0.06343441772382914,002629.SZ -2023-07-07,0.06454680402199671,000638.SZ -2023-07-07,0.06695616569947932,000890.SZ +2023-07-07,0.0645468040219967,000638.SZ +2023-07-07,0.06695616569947933,000890.SZ 2023-07-07,0.06966763614338757,603828.SH -2023-07-07,0.07144986240719356,002652.SZ +2023-07-07,0.07144986240719357,002652.SZ 2023-07-10,0.06844273116248376,002207.SZ 2023-07-10,0.0686281575771522,002652.SZ -2023-07-10,0.07114539270037139,000638.SZ +2023-07-10,0.07114539270037137,000638.SZ 2023-07-10,0.07758224024131134,603536.SH 2023-07-10,0.0796739653612335,603828.SH -2023-07-11,0.06557350850564582,002671.SZ +2023-07-11,0.06557350850564583,002671.SZ 2023-07-11,0.06567811237599248,002629.SZ 2023-07-11,0.06608791147701173,002494.SZ 2023-07-11,0.0663486637392004,002652.SZ 2023-07-11,0.07509059773963962,603536.SH -2023-07-12,0.06005964547349801,002495.SZ +2023-07-12,0.06005964547349802,002495.SZ 2023-07-12,0.06117920124767437,603828.SH -2023-07-12,0.062335653526774254,000638.SZ +2023-07-12,0.06233565352677425,000638.SZ 2023-07-12,0.07046127128781017,000890.SZ 2023-07-12,0.07280244920514695,002652.SZ -2023-07-13,0.062284936366586455,002207.SZ +2023-07-13,0.06228493636658646,002207.SZ 2023-07-13,0.06325803143328151,603536.SH -2023-07-13,0.06533076656581403,000638.SZ +2023-07-13,0.06533076656581402,000638.SZ 2023-07-13,0.06681418937695148,002495.SZ 2023-07-13,0.06886708920571298,002652.SZ 2023-07-14,0.05927189227369902,002629.SZ 2023-07-14,0.059291946883230875,002652.SZ 2023-07-14,0.06150142751010989,600448.SH -2023-07-14,0.0680631332155238,002620.SZ -2023-07-14,0.07345650681687428,000890.SZ +2023-07-14,0.06806313321552382,002620.SZ +2023-07-14,0.0734565068168743,000890.SZ 2023-07-17,0.05891905930033093,002494.SZ 2023-07-17,0.06122095697977213,002207.SZ 2023-07-17,0.06201165768421353,002629.SZ @@ -646,41 +646,41 @@ trade_date,score,ts_code 2023-07-17,0.07017798842040442,000890.SZ 2023-07-18,0.06473869695282886,002629.SZ 2023-07-18,0.06827524689426809,603828.SH -2023-07-18,0.06935858291690467,002494.SZ +2023-07-18,0.06935858291690468,002494.SZ 2023-07-18,0.07039438777209749,002652.SZ -2023-07-18,0.07479597086149557,000890.SZ +2023-07-18,0.07479597086149559,000890.SZ 2023-07-19,0.0679505051426791,603536.SH 2023-07-19,0.06859495896174257,002591.SZ 2023-07-19,0.07039438777209749,002629.SZ -2023-07-19,0.07495390440449587,002620.SZ +2023-07-19,0.07495390440449588,002620.SZ 2023-07-19,0.07709593888912479,002652.SZ 2023-07-20,0.06461318875017112,002620.SZ 2023-07-20,0.07235593695030114,603536.SH 2023-07-20,0.07421638483950098,002494.SZ -2023-07-20,0.07701332973731144,000890.SZ +2023-07-20,0.07701332973731145,000890.SZ 2023-07-20,0.07709593888912479,002652.SZ 2023-07-21,0.06583297844067203,002207.SZ -2023-07-21,0.06612722803577119,002591.SZ +2023-07-21,0.0661272280357712,002591.SZ 2023-07-21,0.0704522975336165,002494.SZ 2023-07-21,0.07143722264897336,000890.SZ 2023-07-21,0.07709593888912479,002652.SZ -2023-07-24,0.0693585560765433,600889.SH -2023-07-24,0.07099361377670384,002620.SZ +2023-07-24,0.06935855607654332,600889.SH +2023-07-24,0.07099361377670385,002620.SZ 2023-07-24,0.07421638483950098,002494.SZ -2023-07-24,0.07616747050460378,000890.SZ +2023-07-24,0.07616747050460379,000890.SZ 2023-07-24,0.07709593888912479,002652.SZ 2023-07-25,0.06756410070399892,603536.SH 2023-07-25,0.06902569490380533,002494.SZ 2023-07-25,0.06970242742647444,002629.SZ 2023-07-25,0.07103819052301656,002207.SZ 2023-07-25,0.07840090496130549,000890.SZ -2023-07-26,0.05889897237709236,002652.SZ -2023-07-26,0.062087156185469734,002278.SZ -2023-07-26,0.06400031693334053,002494.SZ +2023-07-26,0.05889897237709237,002652.SZ +2023-07-26,0.06208715618546975,002278.SZ +2023-07-26,0.06400031693334055,002494.SZ 2023-07-26,0.06470802787035995,603536.SH 2023-07-26,0.07051509114608924,000622.SZ 2023-07-27,0.060552630173400686,002591.SZ -2023-07-27,0.062087156185469734,002278.SZ +2023-07-27,0.06208715618546975,002278.SZ 2023-07-27,0.06591687756975777,603536.SH 2023-07-27,0.06760990304704799,002207.SZ 2023-07-27,0.07741608996384214,002652.SZ @@ -696,36 +696,36 @@ trade_date,score,ts_code 2023-07-31,0.07373481134084157,600561.SH 2023-08-01,0.0704877395577827,000622.SZ 2023-08-01,0.07251497400473726,600561.SH -2023-08-01,0.07417286752476701,600156.SH +2023-08-01,0.074172867524767,600156.SH 2023-08-01,0.07541549604778532,002629.SZ 2023-08-01,0.07722200945787809,002494.SZ 2023-08-02,0.06491049613448267,600250.SH 2023-08-02,0.0649455715403721,600889.SH 2023-08-02,0.07006572300586515,000622.SZ 2023-08-02,0.07182322006328519,002494.SZ -2023-08-02,0.08114439838437774,600561.SH +2023-08-02,0.08114439838437776,600561.SH 2023-08-03,0.06491049613448267,600250.SH -2023-08-03,0.06935858291690467,002494.SZ +2023-08-03,0.06935858291690468,002494.SZ 2023-08-03,0.07072096390889783,000017.SZ 2023-08-03,0.0707452623033503,000622.SZ -2023-08-03,0.08114439838437774,600561.SH +2023-08-03,0.08114439838437776,600561.SH 2023-08-04,0.06491049613448267,600250.SH 2023-08-04,0.06582990211544767,000622.SZ 2023-08-04,0.06693951986966172,600889.SH 2023-08-04,0.06984926204365628,002494.SZ -2023-08-04,0.07813877376600065,600561.SH +2023-08-04,0.07813877376600066,600561.SH 2023-08-07,0.06469260736148713,000622.SZ 2023-08-07,0.06574466685039485,600889.SH 2023-08-07,0.0686544090243894,002494.SZ -2023-08-07,0.06866584993836486,600156.SH -2023-08-07,0.07813877376600065,600561.SH +2023-08-07,0.06866584993836485,600156.SH +2023-08-07,0.07813877376600066,600561.SH 2023-08-08,0.05951473785648454,002620.SZ 2023-08-08,0.060258926194714485,600302.SH -2023-08-08,0.06064292442128204,600250.SH +2023-08-08,0.06064292442128205,600250.SH 2023-08-08,0.06726683380039537,002494.SZ 2023-08-08,0.07675119854200661,600561.SH 2023-08-09,0.06266452277046015,600156.SH -2023-08-09,0.06445810063275724,002207.SZ +2023-08-09,0.06445810063275725,002207.SZ 2023-08-09,0.06854412140514593,000622.SZ 2023-08-09,0.06935866707401915,000017.SZ 2023-08-09,0.07632783994802672,600561.SH @@ -738,7 +738,7 @@ trade_date,score,ts_code 2023-08-11,0.051430280945614144,000702.SZ 2023-08-11,0.056661976454857224,002494.SZ 2023-08-11,0.05911230194157515,600889.SH -2023-08-11,0.06739263985689699,600561.SH +2023-08-11,0.067392639856897,600561.SH 2023-08-14,0.05917639148727093,000856.SZ 2023-08-14,0.05978324514744961,000953.SZ 2023-08-14,0.06109626726365894,000622.SZ @@ -746,7 +746,7 @@ trade_date,score,ts_code 2023-08-14,0.0679763360578828,600561.SH 2023-08-15,0.056055296620406606,000017.SZ 2023-08-15,0.05794923944021139,600561.SH -2023-08-15,0.059015167531851064,000691.SZ +2023-08-15,0.05901516753185107,000691.SZ 2023-08-15,0.0629327686736714,002620.SZ 2023-08-15,0.06608414120870902,000622.SZ 2023-08-16,0.06307723387131882,000691.SZ @@ -756,19 +756,19 @@ trade_date,score,ts_code 2023-08-16,0.0679763360578828,600561.SH 2023-08-17,0.0641827642527829,600561.SH 2023-08-17,0.06473949063031623,002494.SZ -2023-08-17,0.0654302216769155,600889.SH +2023-08-17,0.06543022167691549,600889.SH 2023-08-17,0.0702645844047795,000622.SZ 2023-08-17,0.07513122365062223,000691.SZ 2023-08-18,0.06017079360998181,000691.SZ 2023-08-18,0.06503955836120215,000017.SZ -2023-08-18,0.0654302216769155,600889.SH +2023-08-18,0.06543022167691549,600889.SH 2023-08-18,0.06830777768260345,002494.SZ -2023-08-18,0.07566616626219477,600561.SH +2023-08-18,0.07566616626219479,600561.SH 2023-08-21,0.05387686396813307,600250.SH 2023-08-21,0.06336347185296959,000017.SZ 2023-08-21,0.06685997961968067,002494.SZ -2023-08-21,0.07068666003796148,000691.SZ -2023-08-21,0.0709844551355851,600561.SH +2023-08-21,0.0706866600379615,000691.SZ +2023-08-21,0.07098445513558511,600561.SH 2023-08-22,0.06410595443593459,000691.SZ 2023-08-22,0.06506354480809977,000017.SZ 2023-08-22,0.06676352217823665,002620.SZ @@ -777,28 +777,28 @@ trade_date,score,ts_code 2023-08-23,0.06567683997297415,000691.SZ 2023-08-23,0.06651527426726034,000017.SZ 2023-08-23,0.06669956093227762,000622.SZ -2023-08-23,0.0709844551355851,600561.SH +2023-08-23,0.07098445513558511,600561.SH 2023-08-23,0.07213146700172303,002494.SZ 2023-08-24,0.05907753596625362,000622.SZ -2023-08-24,0.060249688723843814,600889.SH -2023-08-24,0.06167342638302267,002775.SZ +2023-08-24,0.0602496887238438,600889.SH +2023-08-24,0.06167342638302266,002775.SZ 2023-08-24,0.07011371903151237,002494.SZ 2023-08-24,0.07080437689931875,600561.SH 2023-08-25,0.06036056311130449,002207.SZ -2023-08-25,0.06957637602523822,002620.SZ +2023-08-25,0.06957637602523824,002620.SZ 2023-08-25,0.07269475961607492,000691.SZ -2023-08-25,0.0731202222628225,600561.SH +2023-08-25,0.07312022226282251,600561.SH 2023-08-25,0.07601758219049881,002494.SZ 2023-08-28,0.05747871391123706,002207.SZ 2023-08-28,0.060395502168617526,600889.SH -2023-08-28,0.061440315714427714,603021.SH +2023-08-28,0.06144031571442773,603021.SH 2023-08-28,0.06524076613519923,000691.SZ 2023-08-28,0.06595409475880562,000017.SZ 2023-08-29,0.05859660015791081,600889.SH 2023-08-29,0.06058889563261092,000691.SZ 2023-08-29,0.06272925851660989,000017.SZ 2023-08-29,0.06637625935081867,600302.SH -2023-08-29,0.07750077813673284,600561.SH +2023-08-29,0.07750077813673285,600561.SH 2023-08-30,0.0661033655727259,600302.SH 2023-08-30,0.06737610534562655,603021.SH 2023-08-30,0.06785913370127986,000691.SZ @@ -811,55 +811,55 @@ trade_date,score,ts_code 2023-08-31,0.07093112886290634,000017.SZ 2023-09-01,0.06267325577607098,002629.SZ 2023-09-01,0.06477213313677209,603725.SH -2023-09-01,0.06723633882719575,600889.SH +2023-09-01,0.06723633882719576,600889.SH 2023-09-01,0.06938864321048598,603021.SH -2023-09-01,0.07167690336204946,002494.SZ +2023-09-01,0.07167690336204947,002494.SZ 2023-09-04,0.06500475970771047,600302.SH 2023-09-04,0.06690430830769956,000691.SZ 2023-09-04,0.06948705661903568,600561.SH 2023-09-04,0.06979749040199791,603725.SH 2023-09-04,0.07266716160695584,603021.SH -2023-09-05,0.06124318378074041,603021.SH +2023-09-05,0.061243183780740416,603021.SH 2023-09-05,0.06297868345114749,603725.SH 2023-09-05,0.0647265529315198,600302.SH 2023-09-05,0.06948705661903568,600561.SH 2023-09-05,0.07129102790569557,002629.SZ -2023-09-06,0.05748699394239483,002494.SZ +2023-09-06,0.05748699394239484,002494.SZ 2023-09-06,0.05869735848909689,002620.SZ -2023-09-06,0.06280604440399883,603021.SH +2023-09-06,0.06280604440399884,603021.SH 2023-09-06,0.06737188329351862,603725.SH 2023-09-06,0.06948705661903568,600561.SH 2023-09-07,0.061743367913086704,603725.SH 2023-09-07,0.06527530094194642,603021.SH -2023-09-07,0.06528392326113391,000691.SZ -2023-09-07,0.06824208837847519,600561.SH +2023-09-07,0.06528392326113393,000691.SZ +2023-09-07,0.0682420883784752,600561.SH 2023-09-07,0.0715786799890541,002629.SZ 2023-09-08,0.06118231606170357,600678.SH 2023-09-08,0.06128656648978217,603021.SH 2023-09-08,0.062320443735017286,603725.SH 2023-09-08,0.06447723655404837,600561.SH -2023-09-08,0.06766113977701922,002620.SZ +2023-09-08,0.06766113977701924,002620.SZ 2023-09-11,0.06363551169561787,002629.SZ 2023-09-11,0.06508013829488206,603021.SH 2023-09-11,0.06528852046591138,000017.SZ 2023-09-11,0.06845968657072043,600889.SH 2023-09-11,0.07345231864147989,600561.SH -2023-09-12,0.0599156880157915,002620.SZ -2023-09-12,0.06375413516868295,600889.SH +2023-09-12,0.059915688015791516,002620.SZ +2023-09-12,0.06375413516868293,600889.SH 2023-09-12,0.0643555088815909,000017.SZ 2023-09-12,0.06458878301227101,600561.SH 2023-09-12,0.07846487404096579,002629.SZ 2023-09-13,0.06109510085239514,600678.SH 2023-09-13,0.061480820044838805,603725.SH 2023-09-13,0.0643555088815909,000017.SZ -2023-09-13,0.06450113218650923,603021.SH +2023-09-13,0.06450113218650924,603021.SH 2023-09-13,0.06732868428242365,002629.SZ -2023-09-14,0.059578962947283695,600561.SH +2023-09-14,0.05957896294728371,600561.SH 2023-09-14,0.059956118524095436,603725.SH -2023-09-14,0.06375413516868295,600889.SH +2023-09-14,0.06375413516868293,600889.SH 2023-09-14,0.06502292695246163,000017.SZ 2023-09-14,0.06844274712495435,603021.SH -2023-09-15,0.059578962947283695,600561.SH +2023-09-15,0.05957896294728371,600561.SH 2023-09-15,0.06604788889434528,600889.SH 2023-09-15,0.06750357442640105,000017.SZ 2023-09-15,0.06887915953232937,002629.SZ @@ -867,11 +867,11 @@ trade_date,score,ts_code 2023-09-18,0.05844544554557185,600302.SH 2023-09-18,0.06400966188857303,603725.SH 2023-09-18,0.06458878301227101,600561.SH -2023-09-18,0.06586837932612823,002629.SZ +2023-09-18,0.06586837932612824,002629.SZ 2023-09-18,0.0717171975988706,000691.SZ 2023-09-19,0.06253658599314814,603725.SH 2023-09-19,0.0632520571892587,603021.SH -2023-09-19,0.06331489139674244,000953.SZ +2023-09-19,0.06331489139674246,000953.SZ 2023-09-19,0.06467352630686136,002629.SZ 2023-09-19,0.0647604732296153,600561.SH 2023-09-20,0.05487962528018983,000017.SZ @@ -888,10 +888,10 @@ trade_date,score,ts_code 2023-09-22,0.057375016283124566,600156.SH 2023-09-22,0.05914854912103608,000017.SZ 2023-09-22,0.059833020769565884,600302.SH -2023-09-22,0.0709844551355851,600561.SH -2023-09-25,0.05585918233610504,600302.SH +2023-09-22,0.07098445513558511,600561.SH +2023-09-25,0.055859182336105054,600302.SH 2023-09-25,0.056531146063483945,002494.SZ -2023-09-25,0.057229945572692786,000953.SZ +2023-09-25,0.05722994557269279,000953.SZ 2023-09-25,0.06021403215785376,603725.SH 2023-09-25,0.0685540450347152,600561.SH 2023-09-26,0.05627163367910625,603021.SH @@ -902,45 +902,45 @@ trade_date,score,ts_code 2023-09-27,0.05861841998162547,000953.SZ 2023-09-27,0.060807033308813,603725.SH 2023-09-27,0.06302730725658157,002494.SZ -2023-09-27,0.06633474320991897,603021.SH +2023-09-27,0.06633474320991899,603021.SH 2023-09-27,0.0685540450347152,600561.SH 2023-09-28,0.06061090058141458,002494.SZ 2023-09-28,0.06203808707304566,600302.SH 2023-09-28,0.06250987751123314,000017.SZ -2023-09-28,0.06497013628929886,603021.SH +2023-09-28,0.06497013628929887,603021.SH 2023-09-28,0.06510467552826116,603725.SH 2023-10-09,0.05517878399396407,002494.SZ -2023-10-09,0.057534856810738805,002806.SZ +2023-10-09,0.05753485681073881,002806.SZ 2023-10-09,0.05899416285265051,600889.SH -2023-10-09,0.06338939619895868,000953.SZ +2023-10-09,0.0633893961989587,000953.SZ 2023-10-09,0.06498334676186711,600302.SH 2023-10-10,0.055026760648849427,600302.SH -2023-10-10,0.057534856810738805,002806.SZ -2023-10-10,0.057754365171595635,002494.SZ +2023-10-10,0.05753485681073881,002806.SZ +2023-10-10,0.05775436517159564,002494.SZ 2023-10-10,0.0638664142537086,600889.SH -2023-10-10,0.06846457578115218,000953.SZ -2023-10-11,0.056502104087568054,600302.SH +2023-10-10,0.0684645757811522,000953.SZ +2023-10-11,0.05650210408756806,600302.SH 2023-10-11,0.0611930398228756,002494.SZ 2023-10-11,0.06252360594070917,000953.SZ 2023-10-11,0.06261290648322076,603021.SH 2023-10-11,0.0638664142537086,600889.SH 2023-10-12,0.05100339818787161,002806.SZ -2023-10-12,0.05430100339583553,000953.SZ -2023-10-12,0.05430227247492227,002188.SZ +2023-10-12,0.05430100339583554,000953.SZ +2023-10-12,0.054302272474922274,002188.SZ 2023-10-12,0.058309291138472524,600889.SH 2023-10-12,0.06162187829606007,002494.SZ -2023-10-13,0.04676830309653156,600107.SH +2023-10-13,0.046768303096531565,600107.SH 2023-10-13,0.048170232413220736,600119.SH 2023-10-13,0.06233552061984563,603021.SH -2023-10-13,0.0644149334308984,000953.SZ +2023-10-13,0.06441493343089841,000953.SZ 2023-10-13,0.06506126727297547,600889.SH 2023-10-16,0.05581871958548051,600119.SH -2023-10-16,0.056038838704352584,600107.SH +2023-10-16,0.05603883870435259,600107.SH 2023-10-16,0.05748340072572909,600889.SH 2023-10-16,0.05784557645982244,002494.SZ -2023-10-16,0.06488320114005895,000953.SZ +2023-10-16,0.06488320114005897,000953.SZ 2023-10-17,0.05591852635560677,600119.SH -2023-10-17,0.05603341000406129,603021.SH +2023-10-17,0.056033410004061306,603021.SH 2023-10-17,0.060246880355234775,600889.SH 2023-10-17,0.06375191544600388,600107.SH 2023-10-17,0.07079646079964329,000953.SZ @@ -951,35 +951,35 @@ trade_date,score,ts_code 2023-10-18,0.06935584928507967,000953.SZ 2023-10-19,0.05703024275758852,000820.SZ 2023-10-19,0.057666439549447654,002806.SZ -2023-10-19,0.06049632127890721,000953.SZ +2023-10-19,0.06049632127890722,000953.SZ 2023-10-19,0.06051131230055627,002495.SZ -2023-10-19,0.06975385260951816,600889.SH -2023-10-20,0.05142437369057876,600538.SH +2023-10-19,0.06975385260951818,600889.SH +2023-10-20,0.05142437369057878,600538.SH 2023-10-20,0.05446489942812968,600302.SH 2023-10-20,0.05532062236486063,002495.SZ 2023-10-20,0.057015673594667915,000953.SZ 2023-10-20,0.05840942782535603,600889.SH -2023-10-23,0.055682555788062145,002806.SZ +2023-10-23,0.05568255578806216,002806.SZ 2023-10-23,0.058132441857527715,603021.SH 2023-10-23,0.062038804660153046,002494.SZ -2023-10-23,0.06318990746458313,002495.SZ +2023-10-23,0.06318990746458314,002495.SZ 2023-10-23,0.06545308393425923,002775.SZ 2023-10-24,0.04846716448791382,000702.SZ 2023-10-24,0.04932466712822287,002272.SZ 2023-10-24,0.0505698497936178,002775.SZ 2023-10-24,0.057991563746266794,600107.SH 2023-10-24,0.06144845394528795,600889.SH -2023-10-25,0.06211034722532772,600107.SH +2023-10-25,0.062110347225327725,600107.SH 2023-10-25,0.06499002179232855,000691.SZ -2023-10-25,0.06923464185718474,600156.SH +2023-10-25,0.06923464185718475,600156.SH 2023-10-25,0.0698286558341296,002775.SZ 2023-10-25,0.07418933706407305,000702.SZ 2023-10-26,0.06352030421052322,002620.SZ 2023-10-26,0.06647105270161156,002495.SZ 2023-10-26,0.06704216981213659,600678.SH -2023-10-26,0.06721697003988743,600107.SH +2023-10-26,0.06721697003988744,600107.SH 2023-10-26,0.07109463636574005,002775.SZ -2023-10-27,0.05814505602835319,600107.SH +2023-10-27,0.058145056028353195,600107.SH 2023-10-27,0.060732400432383565,600119.SH 2023-10-27,0.062263110997574006,600156.SH 2023-10-27,0.06482492407758837,002775.SZ @@ -990,10 +990,10 @@ trade_date,score,ts_code 2023-10-30,0.07072202546417387,600156.SH 2023-10-30,0.07656095813511969,000702.SZ 2023-10-31,0.06163990282220991,002571.SZ -2023-10-31,0.061919918251033906,002247.SZ -2023-10-31,0.06332166288127629,002494.SZ +2023-10-31,0.06191991825103391,002247.SZ +2023-10-31,0.0633216628812763,002494.SZ 2023-10-31,0.06359472390077876,000702.SZ -2023-10-31,0.06669546297320393,603021.SH +2023-10-31,0.06669546297320395,603021.SH 2023-11-01,0.06721441255940612,600889.SH 2023-11-01,0.06847266151284634,000702.SZ 2023-11-01,0.07014652762369618,000691.SZ @@ -1005,26 +1005,26 @@ trade_date,score,ts_code 2023-11-02,0.07032287037349096,603021.SH 2023-11-02,0.07395813568377824,000702.SZ 2023-11-03,0.06721441255940612,600889.SH -2023-11-03,0.06817562613293843,002495.SZ +2023-11-03,0.06817562613293844,002495.SZ 2023-11-03,0.07067961728730836,000702.SZ 2023-11-03,0.07201003365837733,600250.SH 2023-11-03,0.07226903696243707,002571.SZ -2023-11-06,0.06260069958584005,002836.SZ -2023-11-06,0.0634725439003264,600302.SH -2023-11-06,0.0655629465521148,600889.SH +2023-11-06,0.06260069958584007,002836.SZ +2023-11-06,0.06347254390032642,600302.SH +2023-11-06,0.06556294655211478,600889.SH 2023-11-06,0.06772477889417967,000702.SZ 2023-11-06,0.07997672772855212,002571.SZ 2023-11-07,0.056903598211467954,600107.SH -2023-11-07,0.05932218118937019,002836.SZ +2023-11-07,0.059322181189370195,002836.SZ 2023-11-07,0.05972381188989865,000017.SZ 2023-11-07,0.061914864342273855,000702.SZ 2023-11-07,0.06469689666195583,002571.SZ 2023-11-08,0.06080615335441947,000691.SZ -2023-11-08,0.06093037661848505,002495.SZ -2023-11-08,0.06255906933393622,002620.SZ +2023-11-08,0.060930376618485056,002495.SZ +2023-11-08,0.06255906933393623,002620.SZ 2023-11-08,0.06352966560109885,002494.SZ 2023-11-08,0.06592794226046937,600302.SH -2023-11-09,0.06407790855170951,002495.SZ +2023-11-09,0.06407790855170953,002495.SZ 2023-11-09,0.06418350106340501,002571.SZ 2023-11-09,0.06434940821959804,600156.SH 2023-11-09,0.06737626669246821,600889.SH @@ -1035,11 +1035,11 @@ trade_date,score,ts_code 2023-11-10,0.06872750051422306,603021.SH 2023-11-10,0.07101588995573314,600302.SH 2023-11-13,0.06020249603167674,600889.SH -2023-11-13,0.061959576183388834,600156.SH +2023-11-13,0.06195957618338884,600156.SH 2023-11-13,0.06304365045897646,002571.SZ 2023-11-13,0.07180165701327045,600302.SH 2023-11-13,0.07344630005660306,603021.SH -2023-11-14,0.06124217519225249,002620.SZ +2023-11-14,0.061242175192252495,002620.SZ 2023-11-14,0.06819176516894085,002495.SZ 2023-11-14,0.06925505195763851,000017.SZ 2023-11-14,0.07227143915880355,600302.SH @@ -1050,7 +1050,7 @@ trade_date,score,ts_code 2023-11-15,0.0661220522760976,600561.SH 2023-11-15,0.07419715882755552,603021.SH 2023-11-16,0.06628400361277981,002494.SZ -2023-11-16,0.0664719681184374,603021.SH +2023-11-16,0.06647196811843742,603021.SH 2023-11-16,0.06762172649750745,600107.SH 2023-11-16,0.06782226619978653,002571.SZ 2023-11-16,0.07185700773724418,600302.SH @@ -1059,11 +1059,11 @@ trade_date,score,ts_code 2023-11-17,0.07069208162696755,600561.SH 2023-11-17,0.07324682059527061,002247.SZ 2023-11-17,0.07668150746756543,000691.SZ -2023-11-20,0.05943261627192385,600107.SH +2023-11-20,0.05943261627192386,600107.SH 2023-11-20,0.0594472940589979,600678.SH 2023-11-20,0.06353362488387074,600561.SH 2023-11-20,0.06764572799062366,002495.SZ -2023-11-20,0.06920853204602377,000691.SZ +2023-11-20,0.06920853204602379,000691.SZ 2023-11-21,0.06247723014961022,600561.SH 2023-11-21,0.06272581245546777,600678.SH 2023-11-21,0.06397502433951571,002494.SZ @@ -1077,9 +1077,9 @@ trade_date,score,ts_code 2023-11-23,0.06512346241219934,600561.SH 2023-11-23,0.06682559165875816,000820.SZ 2023-11-23,0.06808105530707796,000691.SZ -2023-11-23,0.07025109629717044,000622.SZ +2023-11-23,0.07025109629717045,000622.SZ 2023-11-23,0.07034766243759062,002247.SZ -2023-11-24,0.06109631233594972,000890.SZ +2023-11-24,0.06109631233594973,000890.SZ 2023-11-24,0.062208306514927335,000691.SZ 2023-11-24,0.06647546947169963,002775.SZ 2023-11-24,0.07324682059527061,002247.SZ @@ -1089,13 +1089,13 @@ trade_date,score,ts_code 2023-11-27,0.07168208407452184,002652.SZ 2023-11-27,0.07309087537206527,000691.SZ 2023-11-27,0.07426380820485326,002629.SZ -2023-11-28,0.06702364872290106,002247.SZ +2023-11-28,0.06702364872290108,002247.SZ 2023-11-28,0.07069208162696755,600561.SH 2023-11-28,0.07301893168882304,000890.SZ -2023-11-28,0.07379441033476213,002652.SZ +2023-11-28,0.07379441033476214,002652.SZ 2023-11-28,0.07704092079164435,000622.SZ 2023-11-29,0.06729766829685452,600302.SH -2023-11-29,0.07116673414102509,002629.SZ +2023-11-29,0.0711667341410251,002629.SZ 2023-11-29,0.07295246679035126,002798.SZ 2023-11-29,0.07607731849796001,600561.SH 2023-11-29,0.07628659646178144,000622.SZ @@ -1110,24 +1110,24 @@ trade_date,score,ts_code 2023-12-01,0.07651171829106283,002652.SZ 2023-12-01,0.0786662087143968,000890.SZ 2023-12-04,0.07037003854709035,002798.SZ -2023-12-04,0.0704445416904039,600778.SH -2023-12-04,0.07101550376498768,000890.SZ +2023-12-04,0.07044454169040391,600778.SH +2023-12-04,0.07101550376498769,000890.SZ 2023-12-04,0.07195507227843767,002247.SZ -2023-12-04,0.07692198810609338,002629.SZ +2023-12-04,0.0769219881060934,002629.SZ 2023-12-05,0.06654318510636018,000691.SZ 2023-12-05,0.06686559210225122,002798.SZ -2023-12-05,0.07156081492653933,002247.SZ +2023-12-05,0.07156081492653935,002247.SZ 2023-12-05,0.07170843443270733,002775.SZ 2023-12-05,0.07435129973666675,002629.SZ -2023-12-06,0.06785916088296684,000622.SZ +2023-12-06,0.06785916088296685,000622.SZ 2023-12-06,0.07225597492213107,002652.SZ 2023-12-06,0.07309600965670136,002775.SZ 2023-12-06,0.07328097184340433,000890.SZ -2023-12-06,0.07454580970600308,002629.SZ +2023-12-06,0.0745458097060031,002629.SZ 2023-12-07,0.06579358126290075,002247.SZ 2023-12-07,0.06597127699172448,600149.SH 2023-12-07,0.0677668194942622,002775.SZ -2023-12-07,0.06805854431646093,000622.SZ +2023-12-07,0.06805854431646094,000622.SZ 2023-12-07,0.07037003854709035,002798.SZ 2023-12-08,0.06465276783110939,000017.SZ 2023-12-08,0.06689693113376921,002620.SZ @@ -1142,27 +1142,27 @@ trade_date,score,ts_code 2023-12-12,0.0632708010010307,002247.SZ 2023-12-12,0.06369691792093714,603828.SH 2023-12-12,0.06429634246317309,000856.SZ -2023-12-12,0.07509174344251457,000890.SZ -2023-12-12,0.0778072560796493,002620.SZ -2023-12-13,0.06280718520011895,600778.SH +2023-12-12,0.07509174344251458,000890.SZ +2023-12-12,0.07780725607964932,002620.SZ +2023-12-13,0.06280718520011896,600778.SH 2023-12-13,0.06689601576462507,603828.SH 2023-12-13,0.06817622869807306,000691.SZ 2023-12-13,0.0711426939499271,002620.SZ 2023-12-13,0.07294839015053338,002247.SZ 2023-12-14,0.059790122751105866,000953.SZ 2023-12-14,0.06286336180349009,000702.SZ -2023-12-14,0.06500342841110195,002620.SZ +2023-12-14,0.06500342841110196,002620.SZ 2023-12-14,0.06645171885140833,002775.SZ -2023-12-14,0.06681821703721678,000890.SZ -2023-12-15,0.06440030001847165,000890.SZ -2023-12-15,0.07086876084509425,002247.SZ +2023-12-14,0.0668182170372168,000890.SZ +2023-12-15,0.06440030001847166,000890.SZ +2023-12-15,0.07086876084509426,002247.SZ 2023-12-15,0.07186139261393532,000017.SZ 2023-12-15,0.07189039405464656,002775.SZ 2023-12-15,0.07309600965670136,002620.SZ 2023-12-18,0.062008767071003196,000953.SZ 2023-12-18,0.06433371134605613,000691.SZ 2023-12-18,0.06627317016747938,000890.SZ -2023-12-18,0.0670455491810121,002775.SZ +2023-12-18,0.06704554918101212,002775.SZ 2023-12-18,0.07062340215289549,002620.SZ 2023-12-19,0.05813162176969336,000953.SZ 2023-12-19,0.058433275504402395,000820.SZ @@ -1185,27 +1185,27 @@ trade_date,score,ts_code 2023-12-22,0.06448792801617577,000702.SZ 2023-12-22,0.06765559256879204,000691.SZ 2023-12-25,0.05897027201059846,000017.SZ -2023-12-25,0.06254560353699536,002247.SZ +2023-12-25,0.06254560353699537,002247.SZ 2023-12-25,0.06262489177914357,000820.SZ -2023-12-25,0.06292771804604815,002798.SZ +2023-12-25,0.06292771804604816,002798.SZ 2023-12-25,0.0676328151639478,000691.SZ 2023-12-26,0.06061997145485647,603828.SH 2023-12-26,0.06335926278302492,002620.SZ 2023-12-26,0.06464085672786467,603021.SH -2023-12-26,0.0671613553563793,000820.SZ -2023-12-26,0.06773865225755393,000691.SZ +2023-12-26,0.06716135535637931,000820.SZ +2023-12-26,0.06773865225755395,000691.SZ 2023-12-27,0.05919753162411889,002247.SZ 2023-12-27,0.06454475141761419,002620.SZ 2023-12-27,0.06562517789390215,002798.SZ 2023-12-27,0.07071827443170917,000017.SZ 2023-12-27,0.07724870894748957,000691.SZ -2023-12-28,0.06231059742351894,603828.SH +2023-12-28,0.06231059742351895,603828.SH 2023-12-28,0.062349560003298665,000820.SZ 2023-12-28,0.0626307798209753,002775.SZ 2023-12-28,0.07058745104295404,002652.SZ 2023-12-28,0.07808945723496066,000691.SZ 2023-12-29,0.05406870698125842,002652.SZ -2023-12-29,0.05529910884297889,600778.SH +2023-12-29,0.055299108842978895,600778.SH 2023-12-29,0.056619043102581895,002247.SZ 2023-12-29,0.058694630914956525,000638.SZ 2023-12-29,0.06499883296940273,000691.SZ @@ -1213,7 +1213,7 @@ trade_date,score,ts_code 2024-01-02,0.05997029961202535,002629.SZ 2024-01-02,0.06130511056229847,002247.SZ 2024-01-02,0.06605721533294792,002775.SZ -2024-01-02,0.07282682667640808,002620.SZ +2024-01-02,0.0728268266764081,002620.SZ 2024-01-03,0.05973723756089827,000702.SZ 2024-01-03,0.062498702858545925,002629.SZ 2024-01-03,0.06422033256738466,002247.SZ @@ -1223,10 +1223,10 @@ trade_date,score,ts_code 2024-01-04,0.06660469733718992,000702.SZ 2024-01-04,0.06824946643773096,002775.SZ 2024-01-04,0.06899057192694348,000622.SZ -2024-01-04,0.07057599040283699,002620.SZ +2024-01-04,0.070575990402837,002620.SZ 2024-01-05,0.06578048468643378,002775.SZ -2024-01-05,0.0667296174969888,002620.SZ -2024-01-05,0.06690728265721384,002652.SZ +2024-01-05,0.06672961749698882,002620.SZ +2024-01-05,0.06690728265721385,002652.SZ 2024-01-05,0.067326470424539,000017.SZ 2024-01-05,0.06886839694954144,002629.SZ 2024-01-08,0.05863999876354357,002211.SZ @@ -1244,15 +1244,15 @@ trade_date,score,ts_code 2024-01-10,0.06455773937256762,002247.SZ 2024-01-10,0.06542611137532753,002207.SZ 2024-01-10,0.07027412921782028,002629.SZ -2024-01-11,0.061309958888706786,002207.SZ +2024-01-11,0.06130995888870679,002207.SZ 2024-01-11,0.06324258204016618,000702.SZ 2024-01-11,0.0635537899985218,002629.SZ 2024-01-11,0.06709715889229263,000622.SZ 2024-01-11,0.06724915437474548,002775.SZ -2024-01-12,0.05636614072512049,002211.SZ +2024-01-12,0.0563661407251205,002211.SZ 2024-01-12,0.05956070742715542,002652.SZ 2024-01-12,0.06185500681617215,000702.SZ -2024-01-12,0.06315859149037958,002247.SZ +2024-01-12,0.0631585914903796,002247.SZ 2024-01-12,0.06397063597827561,002775.SZ 2024-01-15,0.056713001328645304,002278.SZ 2024-01-15,0.05744860713833524,600889.SH @@ -1270,7 +1270,7 @@ trade_date,score,ts_code 2024-01-17,0.0737312903328404,002629.SZ 2024-01-17,0.07452179020169405,002775.SZ 2024-01-18,0.0589932613918438,600778.SH -2024-01-18,0.059869937991094455,002652.SZ +2024-01-18,0.05986993799109447,002652.SZ 2024-01-18,0.06189752549414071,002775.SZ 2024-01-18,0.06386690660855181,002798.SZ 2024-01-18,0.07136957478058116,000702.SZ @@ -1279,7 +1279,7 @@ trade_date,score,ts_code 2024-01-19,0.0634875233106185,002188.SZ 2024-01-19,0.06377341619519751,603616.SH 2024-01-19,0.06685730040972497,002798.SZ -2024-01-22,0.05393574367940027,002798.SZ +2024-01-22,0.05393574367940028,002798.SZ 2024-01-22,0.061185399582619225,002188.SZ 2024-01-22,0.06566018366020179,002207.SZ 2024-01-22,0.06617888484488552,000702.SZ @@ -1287,13 +1287,13 @@ trade_date,score,ts_code 2024-01-23,0.03954674874875075,002316.SZ 2024-01-23,0.04155765412640684,600165.SH 2024-01-23,0.047398872795605305,603616.SH -2024-01-23,0.04847570731592256,002629.SZ -2024-01-23,0.05158598610198261,002247.SZ +2024-01-23,0.048475707315922566,002629.SZ +2024-01-23,0.05158598610198262,002247.SZ 2024-01-24,0.04365960958571633,002231.SZ 2024-01-24,0.0440728980035465,000702.SZ 2024-01-24,0.05011367870618935,002629.SZ -2024-01-24,0.05122545294715373,600165.SH -2024-01-24,0.06025597298093062,603616.SH +2024-01-24,0.05122545294715372,600165.SH +2024-01-24,0.060255972980930626,603616.SH 2024-01-25,0.05055527630676037,002231.SZ 2024-01-25,0.051747469589929464,000702.SZ 2024-01-25,0.05748127246511613,002629.SZ @@ -1309,12 +1309,12 @@ trade_date,score,ts_code 2024-01-29,0.05652476062255281,002629.SZ 2024-01-29,0.06577846336138206,603616.SH 2024-01-29,0.06798807062925943,000702.SZ -2024-01-30,0.05253296181140802,002798.SZ +2024-01-30,0.05253296181140803,002798.SZ 2024-01-30,0.05614793259979282,002775.SZ 2024-01-30,0.05674808660871359,002629.SZ 2024-01-30,0.06364150735471182,000702.SZ -2024-01-30,0.06378400357511925,603616.SH -2024-01-31,0.05128539764852083,000622.SZ +2024-01-30,0.06378400357511926,603616.SH +2024-01-31,0.05128539764852084,000622.SZ 2024-01-31,0.05453456943579941,002316.SZ 2024-01-31,0.05478352377349949,002231.SZ 2024-01-31,0.06224172968954655,002775.SZ @@ -1324,12 +1324,12 @@ trade_date,score,ts_code 2024-02-01,0.040514977091995016,600165.SH 2024-02-01,0.059802261927798375,603616.SH 2024-02-01,0.06152181135746391,002231.SZ -2024-02-02,0.04273600692012099,600358.SH +2024-02-02,0.042736006920121,600358.SH 2024-02-02,0.044112160204543845,600165.SH 2024-02-02,0.05163156720741695,002316.SZ 2024-02-02,0.055586995806150834,603616.SH 2024-02-02,0.06308497648716287,000622.SZ -2024-02-05,0.04903740278229959,603616.SH +2024-02-05,0.049037402782299594,603616.SH 2024-02-05,0.049322561174311864,002316.SZ 2024-02-05,0.054338440294559524,600165.SH 2024-02-05,0.05601816303464323,002247.SZ @@ -1337,25 +1337,25 @@ trade_date,score,ts_code 2024-02-06,0.035876553428957486,002248.SZ 2024-02-06,0.04081793091467875,000856.SZ 2024-02-06,0.05344712898713794,000953.SZ -2024-02-06,0.054089396090830695,600165.SH +2024-02-06,0.0540893960908307,600165.SH 2024-02-06,0.05559592386159882,002775.SZ -2024-02-07,0.038235655681231856,002248.SZ +2024-02-07,0.03823565568123186,002248.SZ 2024-02-07,0.038461366215389876,002247.SZ 2024-02-07,0.04206037241401842,002775.SZ -2024-02-07,0.04421980999834755,600165.SH +2024-02-07,0.044219809998347556,600165.SH 2024-02-07,0.057145453780770725,603021.SH 2024-02-08,0.029946672707522725,600235.SH 2024-02-08,0.031342937537522715,600228.SH 2024-02-08,0.0329042453568178,002248.SZ -2024-02-08,0.034130597340273405,002207.SZ -2024-02-08,0.04977938797000745,002278.SZ +2024-02-08,0.0341305973402734,002207.SZ +2024-02-08,0.04977938797000746,002278.SZ 2024-02-19,0.05014399821907444,600107.SH 2024-02-19,0.05277047928371702,002278.SZ 2024-02-19,0.05373536593962759,002207.SZ 2024-02-19,0.056284390739086254,600302.SH -2024-02-19,0.059285735723175394,603616.SH +2024-02-19,0.0592857357231754,603616.SH 2024-02-20,0.04244581711186451,002278.SZ -2024-02-20,0.054952516454295046,600107.SH +2024-02-20,0.05495251645429505,600107.SH 2024-02-20,0.05675007202292831,002207.SZ 2024-02-20,0.06238577054124382,002798.SZ 2024-02-20,0.06519405827950253,600302.SH @@ -1363,48 +1363,48 @@ trade_date,score,ts_code 2024-02-21,0.04311323518273523,002278.SZ 2024-02-21,0.046032554380963084,600149.SH 2024-02-21,0.04636513850352445,600235.SH -2024-02-21,0.0518112941334177,002248.SZ +2024-02-21,0.05181129413341771,002248.SZ 2024-02-22,0.03991456290842865,603616.SH 2024-02-22,0.042107341956417875,002278.SZ 2024-02-22,0.04259962355358091,603838.SH -2024-02-22,0.0463110626567777,002164.SZ -2024-02-22,0.0552390421994677,002248.SZ -2024-02-23,0.04054409862213939,600235.SH +2024-02-22,0.04631106265677771,002164.SZ +2024-02-22,0.05523904219946771,002248.SZ +2024-02-23,0.040544098622139396,600235.SH 2024-02-23,0.04109110956873596,600149.SH 2024-02-23,0.04606674451311101,600302.SH 2024-02-23,0.047380007570769794,002798.SZ 2024-02-23,0.051764586057399656,002278.SZ 2024-02-26,0.040596181559822975,603616.SH -2024-02-26,0.04210354632312272,002620.SZ -2024-02-26,0.04382261701860926,600235.SH -2024-02-26,0.05018016942447176,002278.SZ +2024-02-26,0.04210354632312273,002620.SZ +2024-02-26,0.04382261701860927,600235.SH +2024-02-26,0.05018016942447177,002278.SZ 2024-02-26,0.05332545190690359,002798.SZ -2024-02-27,0.04684337522338276,603188.SH +2024-02-27,0.04684337522338277,603188.SH 2024-02-27,0.047725968371551096,002798.SZ -2024-02-27,0.048462246160141956,002620.SZ -2024-02-27,0.05066039639341365,002278.SZ +2024-02-27,0.04846224616014196,002620.SZ +2024-02-27,0.05066039639341366,002278.SZ 2024-02-27,0.051168471750530534,600149.SH 2024-02-28,0.041590857684768154,603616.SH -2024-02-28,0.042089137665004384,600235.SH -2024-02-28,0.04337126303493354,603188.SH +2024-02-28,0.04208913766500439,600235.SH +2024-02-28,0.04337126303493355,603188.SH 2024-02-28,0.04499137471138628,002798.SZ 2024-02-28,0.06293110512971578,600149.SH 2024-02-29,0.040932632838042896,600235.SH 2024-02-29,0.041787067768892704,603188.SH -2024-02-29,0.044314997665457156,603838.SH -2024-02-29,0.047032649418062816,002278.SZ -2024-02-29,0.06090860416119924,600149.SH -2024-03-01,0.04089472705858992,002278.SZ -2024-03-01,0.043796129901826804,002495.SZ +2024-02-29,0.04431499766545716,603838.SH +2024-02-29,0.04703264941806282,002278.SZ +2024-02-29,0.060908604161199247,600149.SH +2024-03-01,0.04089472705858993,002278.SZ +2024-03-01,0.04379612990182681,002495.SZ 2024-03-01,0.047994740966307396,600802.SH 2024-03-01,0.049842644156266484,002798.SZ -2024-03-01,0.05928022463451638,600149.SH -2024-03-04,0.03856915190044717,002798.SZ +2024-03-01,0.05928022463451639,600149.SH +2024-03-04,0.03856915190044718,002798.SZ 2024-03-04,0.03930936063099181,002370.SZ 2024-03-04,0.039896290927365186,600235.SH 2024-03-04,0.04655104770931766,002278.SZ 2024-03-04,0.061771202286244054,600149.SH -2024-03-05,0.041447139304430614,603188.SH +2024-03-05,0.04144713930443062,603188.SH 2024-03-05,0.04345869667272187,002798.SZ 2024-03-05,0.0437411533030817,002370.SZ 2024-03-05,0.050167782045791795,600235.SH @@ -1412,18 +1412,18 @@ trade_date,score,ts_code 2024-03-06,0.041984291332658984,600235.SH 2024-03-06,0.04252218815049097,002696.SZ 2024-03-06,0.044040862599736094,002370.SZ -2024-03-06,0.04529647187480521,002798.SZ -2024-03-06,0.04698174997270257,600844.SH -2024-03-07,0.04338274456664552,002798.SZ +2024-03-06,0.04529647187480522,002798.SZ +2024-03-06,0.046981749972702574,600844.SH +2024-03-07,0.04338274456664553,002798.SZ 2024-03-07,0.04548910197675221,002495.SZ 2024-03-07,0.04556361238965578,002278.SZ 2024-03-07,0.04982208033045451,603616.SH 2024-03-07,0.050341346376766814,002370.SZ -2024-03-08,0.041908393658313725,002397.SZ +2024-03-08,0.04190839365831373,002397.SZ 2024-03-08,0.0422306805331468,000573.SZ -2024-03-08,0.04400630017861498,002798.SZ +2024-03-08,0.04400630017861499,002798.SZ 2024-03-08,0.04618898574902054,002370.SZ -2024-03-08,0.0496955173056191,002278.SZ +2024-03-08,0.04969551730561911,002278.SZ 2024-03-11,0.0430283757883009,002495.SZ 2024-03-11,0.04439048294411703,600807.SH 2024-03-11,0.04548548204923844,600235.SH @@ -1435,69 +1435,69 @@ trade_date,score,ts_code 2024-03-12,0.048685757727703595,600844.SH 2024-03-12,0.050412246842468283,002798.SZ 2024-03-13,0.044683414886097846,603828.SH -2024-03-13,0.04692500705465447,600235.SH -2024-03-13,0.048401874061536586,002495.SZ -2024-03-13,0.05065090568968552,002798.SZ -2024-03-13,0.050898414662562355,002370.SZ +2024-03-13,0.046925007054654466,600235.SH +2024-03-13,0.04840187406153659,002495.SZ +2024-03-13,0.05065090568968553,002798.SZ +2024-03-13,0.05089841466256235,002370.SZ 2024-03-14,0.054024656345125835,002495.SZ -2024-03-14,0.05429837021088814,002231.SZ -2024-03-14,0.0543216762775485,600322.SH -2024-03-14,0.05824493395614511,603828.SH -2024-03-14,0.06024885605029105,600448.SH +2024-03-14,0.054298370210888146,002231.SZ +2024-03-14,0.054321676277548504,600322.SH +2024-03-14,0.05824493395614512,603828.SH +2024-03-14,0.06024885605029106,600448.SH 2024-03-15,0.04512816487396793,600844.SH -2024-03-15,0.04606944473184592,002798.SZ -2024-03-15,0.0490126723643405,600802.SH -2024-03-15,0.04961044793230816,603616.SH +2024-03-15,0.046069444731845925,002798.SZ +2024-03-15,0.04901267236434051,600802.SH +2024-03-15,0.04961044793230817,603616.SH 2024-03-15,0.05498304525337986,600561.SH 2024-03-18,0.05649183747318614,002513.SZ 2024-03-18,0.057981786126963065,002495.SZ 2024-03-18,0.05803021416145077,600561.SH 2024-03-18,0.06392794852644608,600448.SH 2024-03-18,0.06626464210309772,002798.SZ -2024-03-19,0.05376970233952622,002513.SZ +2024-03-19,0.05376970233952623,002513.SZ 2024-03-19,0.05473610764600219,002629.SZ 2024-03-19,0.054785178762977026,600561.SH 2024-03-19,0.05551144805141198,002495.SZ -2024-03-19,0.060284169234183574,600448.SH -2024-03-20,0.04962107019013101,000679.SZ +2024-03-19,0.06028416923418358,600448.SH +2024-03-20,0.04962107019013102,000679.SZ 2024-03-20,0.058597646997460305,600802.SH 2024-03-20,0.06392794852644608,600448.SH -2024-03-20,0.06458337353089764,002513.SZ +2024-03-20,0.06458337353089766,002513.SZ 2024-03-20,0.0669381784984857,600561.SH -2024-03-21,0.056273729438331706,002207.SZ +2024-03-21,0.05627372943833171,002207.SZ 2024-03-21,0.05761736780441935,600802.SH -2024-03-21,0.05899740340677231,002513.SZ -2024-03-21,0.061340836948489505,600448.SH +2024-03-21,0.058997403406772314,002513.SZ +2024-03-21,0.06134083694848951,600448.SH 2024-03-21,0.06212840027268222,600561.SH -2024-03-22,0.05488365692835014,600149.SH -2024-03-22,0.05838233207110091,002629.SZ -2024-03-22,0.06062407720693806,002495.SZ +2024-03-22,0.05488365692835015,600149.SH +2024-03-22,0.05838233207110092,002629.SZ +2024-03-22,0.06062407720693807,002495.SZ 2024-03-22,0.06276735612215843,600448.SH 2024-03-22,0.06847894006092271,002513.SZ -2024-03-25,0.053563870765444034,603616.SH +2024-03-25,0.05356387076544404,603616.SH 2024-03-25,0.05424220494682749,600448.SH -2024-03-25,0.05949458370487738,002495.SZ +2024-03-25,0.05949458370487739,002495.SZ 2024-03-25,0.06814289119853412,600561.SH -2024-03-25,0.06877142471011956,002513.SZ +2024-03-25,0.06877142471011957,002513.SZ 2024-03-26,0.056871159984969506,002571.SZ -2024-03-26,0.05971297753538476,603616.SH +2024-03-26,0.059712977535384765,603616.SH 2024-03-26,0.06278426704805425,000679.SZ 2024-03-26,0.06898740450271201,603828.SH 2024-03-26,0.07530326025155651,600561.SH 2024-03-27,0.05994946830314231,002571.SZ 2024-03-27,0.07172335692411416,603828.SH -2024-03-27,0.07315424960015536,000679.SZ -2024-03-27,0.07492053148006028,002513.SZ +2024-03-27,0.07315424960015537,000679.SZ +2024-03-27,0.0749205314800603,002513.SZ 2024-03-27,0.07764082838377208,600561.SH -2024-03-28,0.05971297753538476,603616.SH +2024-03-28,0.059712977535384765,603616.SH 2024-03-28,0.06893337381799497,000679.SZ 2024-03-28,0.07104020491713367,002513.SZ 2024-03-28,0.07687620618423924,603828.SH 2024-03-28,0.07764082838377208,600561.SH 2024-03-29,0.07075954735518848,000953.SZ 2024-03-29,0.07472952676062906,600561.SH -2024-03-29,0.07492053148006028,002513.SZ -2024-03-29,0.07810892884045931,000679.SZ +2024-03-29,0.0749205314800603,002513.SZ +2024-03-29,0.07810892884045932,000679.SZ 2024-03-29,0.0824892433627147,603828.SH 2024-04-01,0.07123536756419803,002513.SZ 2024-04-01,0.07244091184744571,600561.SH @@ -1514,72 +1514,72 @@ trade_date,score,ts_code 2024-04-03,0.06713222936533664,002620.SZ 2024-04-03,0.06882734435648286,000953.SZ 2024-04-03,0.07125072739562645,600561.SH -2024-04-08,0.06575720190857481,603616.SH +2024-04-08,0.06575720190857483,603616.SH 2024-04-08,0.06813497914182894,002494.SZ 2024-04-08,0.06886364435491418,000953.SZ 2024-04-08,0.07318085321486884,002571.SZ -2024-04-08,0.07539540409206012,603828.SH -2024-04-09,0.06688012424024367,002494.SZ +2024-04-08,0.07539540409206014,603828.SH +2024-04-09,0.06688012424024369,002494.SZ 2024-04-09,0.06779561634387639,002571.SZ 2024-04-09,0.0688678765381971,000953.SZ 2024-04-09,0.07318535773164797,600802.SH -2024-04-09,0.07539540409206012,603828.SH +2024-04-09,0.07539540409206014,603828.SH 2024-04-10,0.0602554613664339,603828.SH -2024-04-10,0.06124497302722002,000953.SZ -2024-04-10,0.07016481469883704,002571.SZ +2024-04-10,0.061244973027220026,000953.SZ +2024-04-10,0.07016481469883705,002571.SZ 2024-04-10,0.07192549638118476,002494.SZ -2024-04-10,0.07913941677786676,600561.SH -2024-04-11,0.06810207613336541,603828.SH -2024-04-11,0.07073985012486593,002494.SZ +2024-04-10,0.07913941677786678,600561.SH +2024-04-11,0.06810207613336543,603828.SH +2024-04-11,0.07073985012486594,002494.SZ 2024-04-11,0.07317411686061501,002495.SZ -2024-04-11,0.07822345176143984,002571.SZ -2024-04-11,0.07913941677786676,600561.SH +2024-04-11,0.07822345176143986,002571.SZ +2024-04-11,0.07913941677786678,600561.SH 2024-04-12,0.0602554613664339,603828.SH -2024-04-12,0.061075134840943984,600561.SH +2024-04-12,0.06107513484094399,600561.SH 2024-04-12,0.06472791722625697,000679.SZ -2024-04-12,0.06713999727767449,002495.SZ -2024-04-12,0.07555005156982948,002571.SZ +2024-04-12,0.0671399972776745,002495.SZ +2024-04-12,0.0755500515698295,002571.SZ 2024-04-15,0.028533170200040453,600082.SH -2024-04-15,0.02882712468059859,002622.SZ +2024-04-15,0.028827124680598597,002622.SZ 2024-04-15,0.03234437107401141,600802.SH -2024-04-15,0.03285633043721123,600107.SH -2024-04-15,0.044468135150468976,600561.SH -2024-04-16,0.03841694991076311,002278.SZ +2024-04-15,0.032856330437211236,600107.SH +2024-04-15,0.04446813515046898,600561.SH +2024-04-16,0.03841694991076312,002278.SZ 2024-04-16,0.04086664759437599,002247.SZ 2024-04-16,0.04932979571002355,603828.SH -2024-04-16,0.0515941940710175,002622.SZ -2024-04-16,0.05928877775545772,002571.SZ +2024-04-16,0.05159419407101751,002622.SZ +2024-04-16,0.05928877775545773,002571.SZ 2024-04-17,0.03531466519814479,600802.SH 2024-04-17,0.03832154129069051,600082.SH 2024-04-17,0.042918502887778105,600561.SH 2024-04-17,0.0460356393635376,600235.SH 2024-04-17,0.0478820129349816,002397.SZ 2024-04-18,0.039347900393117925,002495.SZ -2024-04-18,0.03976982567645844,600802.SH -2024-04-18,0.04285463208701486,002397.SZ +2024-04-18,0.039769825676458447,600802.SH +2024-04-18,0.042854632087014864,002397.SZ 2024-04-18,0.04582910416408972,002571.SZ 2024-04-18,0.04856807021557903,002622.SZ 2024-04-19,0.04439151180602918,603616.SH 2024-04-19,0.04466018773296844,002909.SZ -2024-04-19,0.05067761248393323,603828.SH +2024-04-19,0.05067761248393324,603828.SH 2024-04-19,0.05909650614739436,002622.SZ 2024-04-19,0.06350599713783925,002571.SZ 2024-04-22,0.04522628326666409,002571.SZ -2024-04-22,0.04594826126034702,002397.SZ +2024-04-22,0.045948261260347026,002397.SZ 2024-04-22,0.04674412644232729,600802.SH 2024-04-22,0.04703056356503477,002622.SZ 2024-04-22,0.05871172150869355,000010.SZ -2024-04-23,0.043480307133741125,002188.SZ +2024-04-23,0.04348030713374113,002188.SZ 2024-04-23,0.04455517609348042,600561.SH 2024-04-23,0.047299824173637955,002094.SZ 2024-04-23,0.05238626813003252,002571.SZ 2024-04-23,0.05324351015906945,000573.SZ -2024-04-24,0.05213009325662627,002622.SZ +2024-04-24,0.05213009325662628,002622.SZ 2024-04-24,0.05361902367745927,000573.SZ 2024-04-24,0.053841290946610436,002571.SZ 2024-04-24,0.05487897454282911,002713.SZ 2024-04-24,0.06737844925377706,600561.SH -2024-04-25,0.04845659849245645,000632.SZ +2024-04-25,0.048456598492456454,000632.SZ 2024-04-25,0.04955259769334179,002620.SZ 2024-04-25,0.06000986275955458,600561.SH 2024-04-25,0.06391773601848895,002571.SZ @@ -1589,45 +1589,45 @@ trade_date,score,ts_code 2024-04-26,0.05303493698590511,002571.SZ 2024-04-26,0.05977604017707324,000632.SZ 2024-04-26,0.06795406307377466,002713.SZ -2024-04-29,0.043751011712511056,600235.SH -2024-04-29,0.04736704725800031,600355.SH +2024-04-29,0.04375101171251106,600235.SH +2024-04-29,0.04736704725800032,600355.SH 2024-04-29,0.05126088772543229,002713.SZ 2024-04-29,0.05413323738816507,000632.SZ 2024-04-29,0.06162031526185683,600561.SH 2024-04-30,0.04722919441236804,002713.SZ -2024-04-30,0.05061908709526863,000632.SZ -2024-04-30,0.050694579775050395,600355.SH +2024-04-30,0.05061908709526864,000632.SZ +2024-04-30,0.0506945797750504,600355.SH 2024-04-30,0.06162031526185683,600561.SH 2024-04-30,0.06190667423194363,002571.SZ -2024-05-06,0.048598028274967425,600355.SH +2024-05-06,0.04859802827496743,600355.SH 2024-05-06,0.05508322811543588,600561.SH 2024-05-06,0.05647991651062292,002571.SZ 2024-05-06,0.05886197950903678,000632.SZ -2024-05-06,0.06917902233094633,002713.SZ -2024-05-07,0.05693948081689876,600355.SH +2024-05-06,0.06917902233094635,002713.SZ +2024-05-07,0.056939480816898765,600355.SH 2024-05-07,0.05809796984144187,002571.SZ -2024-05-07,0.06157975173296859,002370.SZ +2024-05-07,0.0615797517329686,002370.SZ 2024-05-07,0.0636819878954075,600778.SH 2024-05-07,0.06417189598164487,600561.SH 2024-05-08,0.04874446994814334,000632.SZ 2024-05-08,0.051695412920943054,002247.SZ -2024-05-08,0.053128165570498716,600358.SH +2024-05-08,0.05312816557049872,600358.SH 2024-05-08,0.054475077719805455,002713.SZ 2024-05-08,0.058607203422617916,600561.SH 2024-05-09,0.05922180140260837,002571.SZ 2024-05-09,0.0595624143329905,002370.SZ -2024-05-09,0.060619393219372396,002247.SZ +2024-05-09,0.0606193932193724,002247.SZ 2024-05-09,0.06495621976680252,600561.SH 2024-05-09,0.07576547700530714,002713.SZ 2024-05-10,0.046946009425503275,603725.SH 2024-05-10,0.04719359653056686,600778.SH 2024-05-10,0.04828988293532174,002397.SZ -2024-05-10,0.05317364114087237,000632.SZ +2024-05-10,0.05317364114087238,000632.SZ 2024-05-10,0.06043417039691747,600561.SH -2024-05-13,0.05411551683164333,002652.SZ -2024-05-13,0.05476545769245526,002247.SZ +2024-05-13,0.05411551683164334,002652.SZ +2024-05-13,0.05476545769245527,002247.SZ 2024-05-13,0.057150547898549786,002571.SZ -2024-05-13,0.0578807672075592,000632.SZ +2024-05-13,0.057880767207559206,000632.SZ 2024-05-13,0.06074717987902927,002775.SZ 2024-05-14,0.04879947716522115,002652.SZ 2024-05-14,0.04966850157969204,600802.SH @@ -1640,7 +1640,7 @@ trade_date,score,ts_code 2024-05-15,0.05970395365881306,000632.SZ 2024-05-15,0.0678035957896557,600778.SH 2024-05-16,0.05167712396757235,002696.SZ -2024-05-16,0.05375443254725258,600448.SH +2024-05-16,0.05375443254725259,600448.SH 2024-05-16,0.057415783381802026,000953.SZ 2024-05-16,0.058547414642102384,600561.SH 2024-05-16,0.0719385167457452,600358.SH @@ -1654,14 +1654,14 @@ trade_date,score,ts_code 2024-05-20,0.05912844676647941,000953.SZ 2024-05-20,0.06033847991614114,600802.SH 2024-05-20,0.06534349068224862,002775.SZ -2024-05-21,0.05370324074971171,000892.SZ +2024-05-21,0.053703240749711716,000892.SZ 2024-05-21,0.05484531211350165,000953.SZ 2024-05-21,0.06091058547012501,600149.SH -2024-05-21,0.06593422747176436,002486.SZ +2024-05-21,0.06593422747176438,002486.SZ 2024-05-21,0.06626462949510648,600802.SH 2024-05-22,0.055614845269264905,000632.SZ 2024-05-22,0.057904960851747914,600149.SH -2024-05-22,0.05804784908596556,600689.SH +2024-05-22,0.05804784908596557,600689.SH 2024-05-22,0.05855265678131122,002486.SZ 2024-05-22,0.06401811789270533,600802.SH 2024-05-23,0.05040587253071525,000820.SZ @@ -1669,12 +1669,12 @@ trade_date,score,ts_code 2024-05-23,0.0604002658514682,002775.SZ 2024-05-23,0.062362195296758724,000632.SZ 2024-05-23,0.06635009670372426,002719.SZ -2024-05-24,0.051595670647614576,002094.SZ +2024-05-24,0.05159567064761458,002094.SZ 2024-05-24,0.052519446871378744,000820.SZ 2024-05-24,0.05653524120605415,600802.SH 2024-05-24,0.0604002658514682,002775.SZ 2024-05-24,0.06545280772632421,600778.SH -2024-05-27,0.05405455858252606,600156.SH +2024-05-27,0.054054558582526065,600156.SH 2024-05-27,0.05741308059139727,000632.SZ 2024-05-27,0.05916052005073108,600802.SH 2024-05-27,0.059941367986284196,002571.SZ @@ -1682,51 +1682,51 @@ trade_date,score,ts_code 2024-05-28,0.04619689638491542,002495.SZ 2024-05-28,0.04809125469583721,600778.SH 2024-05-28,0.05202660212756254,600802.SH -2024-05-28,0.05461565390102649,000632.SZ +2024-05-28,0.0546156539010265,000632.SZ 2024-05-28,0.058183071822609574,002696.SZ 2024-05-29,0.04887262967750919,600232.SH 2024-05-29,0.05214451727268773,600778.SH 2024-05-29,0.05277075283898645,002798.SZ 2024-05-29,0.058448942135788336,002696.SZ 2024-05-29,0.06422749794242315,000632.SZ -2024-05-30,0.04805891417999064,000953.SZ +2024-05-30,0.04805891417999065,000953.SZ 2024-05-30,0.04898261021356629,002775.SZ 2024-05-30,0.05069061843954397,000757.SZ 2024-05-30,0.0564204768456065,002571.SZ 2024-05-30,0.06051073174998905,000632.SZ -2024-05-31,0.05213713333747361,000632.SZ +2024-05-31,0.052137133337473614,000632.SZ 2024-05-31,0.05220651963414105,002696.SZ -2024-05-31,0.05283155177133192,002494.SZ +2024-05-31,0.052831551771331926,002494.SZ 2024-05-31,0.0546277253757986,002571.SZ 2024-05-31,0.05718764759270946,000757.SZ 2024-06-03,0.04611413483925442,000573.SZ 2024-06-03,0.048439363145195924,002397.SZ -2024-06-03,0.048886675247083795,000953.SZ -2024-06-03,0.049130073112360666,000632.SZ +2024-06-03,0.0488866752470838,000953.SZ +2024-06-03,0.04913007311236067,000632.SZ 2024-06-03,0.060990490925916865,002571.SZ -2024-06-04,0.04294088136742652,002494.SZ +2024-06-04,0.04294088136742653,002494.SZ 2024-06-04,0.04664736200309994,600778.SH 2024-06-04,0.04805782094281939,600232.SH 2024-06-04,0.050740229376861484,002571.SZ 2024-06-04,0.06346074953170698,000632.SZ -2024-06-05,0.04264946754047467,000892.SZ +2024-06-05,0.042649467540474675,000892.SZ 2024-06-05,0.043109190111866647,002137.SZ 2024-06-05,0.04572990113415972,600232.SH 2024-06-05,0.04746700677591625,002486.SZ 2024-06-05,0.05670679796864499,002495.SZ 2024-06-06,0.027069552933064484,002713.SZ -2024-06-06,0.0311437364797695,603188.SH +2024-06-06,0.031143736479769507,603188.SH 2024-06-06,0.039845394467802275,600778.SH -2024-06-06,0.04508443530665207,002094.SZ +2024-06-06,0.04508443530665208,002094.SZ 2024-06-06,0.05077419695522791,002629.SZ -2024-06-07,0.034922912333227744,000803.SZ -2024-06-07,0.038532101366708045,600235.SH +2024-06-07,0.03492291233322775,000803.SZ +2024-06-07,0.03853210136670804,600235.SH 2024-06-07,0.04330719964733574,600156.SH 2024-06-07,0.04507774621367549,002629.SZ 2024-06-07,0.052830436336068355,600778.SH 2024-06-11,0.04074851531952806,002486.SZ -2024-06-11,0.044004588503020095,002551.SZ -2024-06-11,0.04433524779357511,002495.SZ +2024-06-11,0.0440045885030201,002551.SZ +2024-06-11,0.04433524779357512,002495.SZ 2024-06-11,0.046748531628646096,600156.SH 2024-06-11,0.06048552316616885,600778.SH 2024-06-12,0.040449570968747524,002495.SZ @@ -1736,38 +1736,38 @@ trade_date,score,ts_code 2024-06-12,0.05460907915832154,600778.SH 2024-06-13,0.03797171290220681,002629.SZ 2024-06-13,0.03866705154908446,600235.SH -2024-06-13,0.04308482300539484,002486.SZ -2024-06-13,0.04493164981886961,002495.SZ +2024-06-13,0.043084823005394846,002486.SZ +2024-06-13,0.044931649818869615,002495.SZ 2024-06-13,0.04774709585256932,002551.SZ 2024-06-14,0.03785762053243739,600358.SH 2024-06-14,0.04305904099200838,002137.SZ 2024-06-14,0.04564240892273613,002551.SZ 2024-06-14,0.053340402697483046,002486.SZ 2024-06-14,0.05342572844238663,600778.SH -2024-06-17,0.03800161728598923,002551.SZ +2024-06-17,0.038001617285989234,002551.SZ 2024-06-17,0.03882349981927645,002798.SZ -2024-06-17,0.04254522729999965,002486.SZ +2024-06-17,0.042545227299999655,002486.SZ 2024-06-17,0.05277518284969674,002094.SZ -2024-06-17,0.057945283366174535,002596.SZ -2024-06-18,0.03426223604336006,600193.SH +2024-06-17,0.05794528336617454,002596.SZ +2024-06-18,0.03426223604336007,600193.SH 2024-06-18,0.03709004575463525,000890.SZ -2024-06-18,0.03851843920760702,002495.SZ -2024-06-18,0.04020290973288813,002798.SZ +2024-06-18,0.03851843920760703,002495.SZ +2024-06-18,0.040202909732888134,002798.SZ 2024-06-18,0.044032820597352515,002486.SZ 2024-06-19,0.045986304236173774,600302.SH -2024-06-19,0.049298284587023,002596.SZ +2024-06-19,0.049298284587023004,002596.SZ 2024-06-19,0.05255006233840364,600156.SH -2024-06-19,0.05302411211446309,002486.SZ -2024-06-19,0.058180809115937,002798.SZ +2024-06-19,0.0530241121144631,002486.SZ +2024-06-19,0.05818080911593701,002798.SZ 2024-06-20,0.042218807386984455,002551.SZ -2024-06-20,0.0486480110815446,002798.SZ +2024-06-20,0.04864801108154461,002798.SZ 2024-06-20,0.04911804337790056,000890.SZ 2024-06-20,0.049834325562589335,002596.SZ 2024-06-20,0.05518518087418722,600156.SH 2024-06-21,0.043671607549233084,600302.SH 2024-06-21,0.04513266897293925,600156.SH 2024-06-21,0.0504067514496789,002316.SZ -2024-06-21,0.05436004620247653,000691.SZ +2024-06-21,0.05436004620247654,000691.SZ 2024-06-21,0.058010247878902764,002798.SZ 2024-06-24,0.04816697670399888,600302.SH 2024-06-24,0.05130784990466444,002370.SZ @@ -1778,9 +1778,9 @@ trade_date,score,ts_code 2024-06-25,0.04526910685581534,600302.SH 2024-06-25,0.0492840782217084,002316.SZ 2024-06-25,0.05307205064346427,000890.SZ -2024-06-25,0.05562228703407922,002370.SZ +2024-06-25,0.05562228703407921,002370.SZ 2024-06-26,0.04622168947018562,600156.SH -2024-06-26,0.047485968267099894,002513.SZ +2024-06-26,0.0474859682670999,002513.SZ 2024-06-26,0.04770933525468617,600302.SH 2024-06-26,0.04921108218122103,600802.SH 2024-06-26,0.06097529306996036,002798.SZ @@ -1790,13 +1790,13 @@ trade_date,score,ts_code 2024-06-27,0.057141560307302885,002094.SZ 2024-06-27,0.0600560462148551,600156.SH 2024-06-28,0.04273770570335824,600302.SH -2024-06-28,0.04722344200941195,600193.SH +2024-06-28,0.047223442009411955,600193.SH 2024-06-28,0.04839745323593241,000691.SZ -2024-06-28,0.05936793501954825,002094.SZ -2024-06-28,0.059458975074298245,600149.SH +2024-06-28,0.059367935019548256,002094.SZ +2024-06-28,0.05945897507429825,600149.SH 2024-07-01,0.04627086692784703,002622.SZ 2024-07-01,0.04627620095663744,000691.SZ -2024-07-01,0.051565702460721785,600149.SH +2024-07-01,0.05156570246072179,600149.SH 2024-07-01,0.05401493453589304,002094.SZ 2024-07-01,0.05592648851625833,600802.SH 2024-07-02,0.04031531085030498,002513.SZ @@ -1804,8 +1804,8 @@ trade_date,score,ts_code 2024-07-02,0.04577831664772983,600302.SH 2024-07-02,0.053489432009245746,002798.SZ 2024-07-02,0.05989446116954465,600149.SH -2024-07-03,0.04675220695723066,002513.SZ -2024-07-03,0.0532077879445765,002551.SZ +2024-07-03,0.04675220695723067,002513.SZ +2024-07-03,0.05320778794457651,002551.SZ 2024-07-03,0.057208651304108814,600802.SH 2024-07-03,0.05868012194494139,002798.SZ 2024-07-03,0.06497713431845839,600149.SH @@ -1817,96 +1817,96 @@ trade_date,score,ts_code 2024-07-05,0.04916375603305257,600302.SH 2024-07-05,0.051395513645296584,000955.SZ 2024-07-05,0.05244571120674203,002775.SZ -2024-07-05,0.05508209698624872,600689.SH +2024-07-05,0.055082096986248726,600689.SH 2024-07-05,0.06429217851498456,600149.SH -2024-07-08,0.04780840768220737,002551.SZ +2024-07-08,0.04780840768220738,002551.SZ 2024-07-08,0.05452577035190284,002591.SZ 2024-07-08,0.057069222137936484,002798.SZ -2024-07-08,0.05832242445967654,600689.SH +2024-07-08,0.058322424459676545,600689.SH 2024-07-08,0.06373573563604376,600156.SH 2024-07-09,0.05273831953841441,600448.SH 2024-07-09,0.05319157382638577,002591.SZ -2024-07-09,0.05811689682101966,002370.SZ +2024-07-09,0.058116896821019656,002370.SZ 2024-07-09,0.05967043024440048,600802.SH 2024-07-09,0.07220766455890675,600156.SH 2024-07-10,0.05176651971579897,002370.SZ 2024-07-10,0.05343394883361408,002620.SZ -2024-07-10,0.05677525079530873,000955.SZ +2024-07-10,0.056775250795308735,000955.SZ 2024-07-10,0.0636906238064769,600156.SH 2024-07-10,0.0712793394212001,002591.SZ 2024-07-11,0.0526849911873897,002620.SZ 2024-07-11,0.054475000037988414,600156.SH -2024-07-11,0.05604700195666247,002591.SZ +2024-07-11,0.05604700195666248,002591.SZ 2024-07-11,0.06166997741695262,600802.SH -2024-07-11,0.06366214185347573,600149.SH +2024-07-11,0.06366214185347574,600149.SH 2024-07-12,0.058385923021447815,002775.SZ 2024-07-12,0.058391459020482754,600802.SH -2024-07-12,0.058730548824444596,002494.SZ -2024-07-12,0.06109531763429048,600689.SH +2024-07-12,0.0587305488244446,002494.SZ +2024-07-12,0.061095317634290484,600689.SH 2024-07-12,0.06274199954857664,600156.SH 2024-07-15,0.05938027325420151,600156.SH -2024-07-15,0.06118556746384822,600149.SH +2024-07-15,0.06118556746384823,600149.SH 2024-07-15,0.06650593383184403,002316.SZ 2024-07-15,0.06745430045862755,002775.SZ -2024-07-15,0.06760086784386843,600448.SH +2024-07-15,0.06760086784386844,600448.SH 2024-07-16,0.05197344537210382,002798.SZ 2024-07-16,0.05432683571953998,600448.SH -2024-07-16,0.05529214607689566,002494.SZ +2024-07-16,0.055292146076895664,002494.SZ 2024-07-16,0.06096916054305935,600802.SH 2024-07-16,0.06573222052535153,600156.SH -2024-07-17,0.04484339251504093,002719.SZ +2024-07-17,0.044843392515040936,002719.SZ 2024-07-17,0.04876985408510326,002620.SZ 2024-07-17,0.055251963768573685,002798.SZ 2024-07-17,0.059096839111615646,600802.SH 2024-07-17,0.06395305633110103,002775.SZ -2024-07-18,0.052683114550196086,002103.SZ -2024-07-18,0.05405437260458306,002798.SZ +2024-07-18,0.05268311455019608,002103.SZ +2024-07-18,0.05405437260458307,002798.SZ 2024-07-18,0.05619048386606678,002377.SZ 2024-07-18,0.05861068728373614,600802.SH 2024-07-18,0.0715232567703681,600156.SH 2024-07-19,0.05016035892780038,002596.SZ 2024-07-19,0.05366873925407803,002909.SZ -2024-07-19,0.055099420764458965,002103.SZ -2024-07-19,0.05818648229187867,002316.SZ +2024-07-19,0.05509942076445896,002103.SZ +2024-07-19,0.05818648229187868,002316.SZ 2024-07-19,0.05848929704798777,002798.SZ 2024-07-22,0.05114135128976663,002909.SZ -2024-07-22,0.05315448104573377,002620.SZ +2024-07-22,0.053154481045733774,002620.SZ 2024-07-22,0.053461675213761314,002798.SZ 2024-07-22,0.05513109494767928,600778.SH 2024-07-22,0.06305876631118269,600802.SH -2024-07-23,0.05220902285049876,002596.SZ -2024-07-23,0.05278002695697225,600156.SH +2024-07-23,0.05220902285049877,002596.SZ +2024-07-23,0.05278002695697226,600156.SH 2024-07-23,0.0562485455895456,000691.SZ 2024-07-23,0.059671455871536626,002775.SZ 2024-07-23,0.06423757381669026,600802.SH -2024-07-24,0.058947282757516706,600448.SH +2024-07-24,0.05894728275751671,600448.SH 2024-07-24,0.061414064910485525,002205.SZ 2024-07-24,0.06402952678816912,002494.SZ 2024-07-24,0.06417578206215768,002775.SZ -2024-07-24,0.07480177516683796,600156.SH -2024-07-25,0.054075190123460966,002798.SZ +2024-07-24,0.07480177516683797,600156.SH +2024-07-25,0.05407519012346097,002798.SZ 2024-07-25,0.05480494220808873,600302.SH 2024-07-25,0.06295860259277254,600802.SH 2024-07-25,0.06591021959189264,600156.SH 2024-07-25,0.06702154011839981,002205.SZ 2024-07-26,0.057650062807577104,002316.SZ -2024-07-26,0.05766142926299581,600156.SH +2024-07-26,0.05766142926299582,600156.SH 2024-07-26,0.060601879143712394,600302.SH -2024-07-26,0.061645018115329776,002596.SZ +2024-07-26,0.06164501811532978,002596.SZ 2024-07-26,0.06323149637086531,600802.SH 2024-07-29,0.05754878751056079,002513.SZ 2024-07-29,0.057903565872321226,002397.SZ 2024-07-29,0.06042199930869166,002596.SZ 2024-07-29,0.06354688508472292,002775.SZ -2024-07-29,0.06902026033845851,600156.SH +2024-07-29,0.06902026033845853,600156.SH 2024-07-30,0.0548260926237995,600802.SH 2024-07-30,0.059168639755878286,000691.SZ 2024-07-30,0.05981620117657097,600302.SH -2024-07-30,0.06239812499129315,002316.SZ +2024-07-30,0.06239812499129316,002316.SZ 2024-07-30,0.06604123186367007,600156.SH 2024-07-31,0.05197841522040942,000573.SZ -2024-07-31,0.05512587747157421,002205.SZ -2024-07-31,0.056444018943201245,600358.SH +2024-07-31,0.055125877471574214,002205.SZ +2024-07-31,0.05644401894320125,600358.SH 2024-07-31,0.06323424937510347,600802.SH 2024-07-31,0.0642687202548424,600302.SH 2024-08-01,0.05694563135340634,002207.SZ @@ -1914,27 +1914,27 @@ trade_date,score,ts_code 2024-08-01,0.06014474312406751,000573.SZ 2024-08-01,0.06282978908053682,600302.SH 2024-08-01,0.06290492574820347,600802.SH -2024-08-02,0.053804293168771354,002494.SZ -2024-08-02,0.05759442086730984,002571.SZ -2024-08-02,0.057820682525851305,600149.SH +2024-08-02,0.05380429316877136,002494.SZ +2024-08-02,0.05759442086730985,002571.SZ +2024-08-02,0.05782068252585131,600149.SH 2024-08-02,0.06556618256118343,600358.SH 2024-08-02,0.06763196672054338,600802.SH 2024-08-05,0.060649677321572816,002397.SZ 2024-08-05,0.06185505817224405,002571.SZ 2024-08-05,0.062573126557247,600156.SH 2024-08-05,0.06353602595464306,603616.SH -2024-08-05,0.06815804294653054,600543.SH +2024-08-05,0.06815804294653055,600543.SH 2024-08-06,0.059828236351214606,002571.SZ 2024-08-06,0.06102580732227706,000632.SZ -2024-08-06,0.0686086782799878,600156.SH +2024-08-06,0.06860867827998782,600156.SH 2024-08-06,0.07015512926113891,600149.SH 2024-08-06,0.07203836950945716,600543.SH -2024-08-07,0.057986650688961264,002397.SZ +2024-08-07,0.05798665068896127,002397.SZ 2024-08-07,0.06051241561212164,000632.SZ 2024-08-07,0.06789166857479406,600156.SH 2024-08-07,0.06940946485965035,002571.SZ -2024-08-07,0.0729208352378591,600543.SH -2024-08-08,0.06486310151503732,600543.SH +2024-08-07,0.07292083523785911,600543.SH +2024-08-08,0.06486310151503734,600543.SH 2024-08-08,0.06613094646318049,002571.SZ 2024-08-08,0.06616880216669702,002798.SZ 2024-08-08,0.07078423524189241,600358.SH @@ -1945,84 +1945,84 @@ trade_date,score,ts_code 2024-08-09,0.0680267048197003,600156.SH 2024-08-09,0.06940946485965035,002571.SZ 2024-08-12,0.06480012488066572,002571.SZ -2024-08-12,0.06490480240045028,002798.SZ +2024-08-12,0.0649048024004503,002798.SZ 2024-08-12,0.06789829799681786,002591.SZ -2024-08-12,0.0685437109763738,600149.SH +2024-08-12,0.06854371097637381,600149.SH 2024-08-12,0.07307285015507577,600358.SH 2024-08-13,0.06168463407098868,002388.SZ -2024-08-13,0.062394859570713515,002486.SZ +2024-08-13,0.06239485957071352,002486.SZ 2024-08-13,0.06364626003608981,600302.SH 2024-08-13,0.06688155967382152,600358.SH -2024-08-13,0.0685437109763738,600149.SH -2024-08-14,0.06444487175436948,002795.SZ +2024-08-13,0.06854371097637381,600149.SH +2024-08-14,0.0644448717543695,002795.SZ 2024-08-14,0.06692477843255967,600302.SH 2024-08-14,0.0690532921963136,000632.SZ 2024-08-14,0.06965242196422819,600149.SH 2024-08-14,0.07102487576951906,600358.SH -2024-08-15,0.05854601761598661,000955.SZ +2024-08-15,0.058546017615986615,000955.SZ 2024-08-15,0.05867301122710747,600543.SH -2024-08-15,0.06293067379789834,600149.SH +2024-08-15,0.06293067379789835,600149.SH 2024-08-15,0.06364626003608981,600302.SH 2024-08-15,0.06408860825806803,002798.SZ 2024-08-16,0.06333393140980996,002571.SZ 2024-08-16,0.06563093889158941,600149.SH 2024-08-16,0.06640711098040711,600358.SH -2024-08-16,0.0685437109763738,600543.SH +2024-08-16,0.06854371097637381,600543.SH 2024-08-16,0.07153274158800228,002494.SZ 2024-08-19,0.06306108942971432,600228.SH 2024-08-19,0.06350503595789482,600358.SH 2024-08-19,0.06379711960451089,603880.SH -2024-08-19,0.0685437109763738,600149.SH +2024-08-19,0.06854371097637381,600149.SH 2024-08-19,0.07092752711053399,000691.SZ -2024-08-20,0.055150735692525064,603021.SH -2024-08-20,0.057224615171429474,603880.SH -2024-08-20,0.059778177177095125,002798.SZ +2024-08-20,0.05515073569252507,603021.SH +2024-08-20,0.05722461517142948,603880.SH +2024-08-20,0.05977817717709513,002798.SZ 2024-08-20,0.06572558623927112,000691.SZ 2024-08-20,0.07351113180358271,002494.SZ -2024-08-21,0.056700277724648473,600156.SH +2024-08-21,0.05670027772464848,600156.SH 2024-08-21,0.057598502861662314,002798.SZ 2024-08-21,0.057912734803004316,603880.SH 2024-08-21,0.06062385070562272,000691.SZ -2024-08-21,0.06805293909168002,002494.SZ +2024-08-21,0.06805293909168003,002494.SZ 2024-08-22,0.05875895878501403,600156.SH 2024-08-22,0.06054659963661854,600228.SH 2024-08-22,0.06124471302140929,600543.SH 2024-08-22,0.06520981573379851,600302.SH -2024-08-22,0.07396591917762727,600149.SH +2024-08-22,0.07396591917762728,600149.SH 2024-08-23,0.06522652105304252,002798.SZ -2024-08-23,0.06549108798366893,603021.SH +2024-08-23,0.06549108798366894,603021.SH 2024-08-23,0.06617227170055129,600543.SH 2024-08-23,0.06647871443801207,600156.SH 2024-08-23,0.07010743009825345,000691.SZ 2024-08-26,0.05758642036699106,002571.SZ -2024-08-26,0.06183368011541295,603880.SH +2024-08-26,0.06183368011541296,603880.SH 2024-08-26,0.06211593795070505,603616.SH 2024-08-26,0.06437199596348948,600156.SH 2024-08-26,0.07407774541617541,600543.SH -2024-08-27,0.061077401986133775,600156.SH +2024-08-27,0.06107740198613378,600156.SH 2024-08-27,0.06285877493244725,002795.SZ -2024-08-27,0.06697490426667149,002798.SZ +2024-08-27,0.0669749042666715,002798.SZ 2024-08-27,0.06844016656237775,600543.SH 2024-08-27,0.06915527657734019,600802.SH -2024-08-28,0.060733128881749095,002571.SZ -2024-08-28,0.06270790501406939,600448.SH +2024-08-28,0.0607331288817491,002571.SZ +2024-08-28,0.0627079050140694,600448.SH 2024-08-28,0.06381981336811705,002798.SZ -2024-08-28,0.06826885246832588,600302.SH +2024-08-28,0.0682688524683259,600302.SH 2024-08-28,0.07151986297396608,600802.SH 2024-08-29,0.05839570063909266,002798.SZ 2024-08-29,0.059452058574419056,002795.SZ -2024-08-29,0.05972696164089037,603880.SH +2024-08-29,0.05972696164089038,603880.SH 2024-08-29,0.06915527657734019,600802.SH 2024-08-29,0.0693495069026143,002571.SZ -2024-08-30,0.059650730369104434,002571.SZ +2024-08-30,0.05965073036910444,002571.SZ 2024-08-30,0.0607015436784601,002798.SZ -2024-08-30,0.062001654902363215,000638.SZ +2024-08-30,0.06200165490236322,000638.SZ 2024-08-30,0.06293569149470249,600302.SH 2024-08-30,0.06302436406147474,600448.SH -2024-09-02,0.06117643199481583,000691.SZ +2024-09-02,0.06117643199481584,000691.SZ 2024-09-02,0.06565969743831078,600802.SH 2024-09-02,0.06633017619466658,002571.SZ -2024-09-02,0.06697839310056347,600448.SH +2024-09-02,0.06697839310056349,600448.SH 2024-09-02,0.06969039537440358,603616.SH 2024-09-03,0.063830769680295,002795.SZ 2024-09-03,0.06480338660909032,002513.SZ @@ -2030,28 +2030,28 @@ trade_date,score,ts_code 2024-09-03,0.07050394273663824,600302.SH 2024-09-03,0.07218514751914432,002571.SZ 2024-09-04,0.06355156562936526,600802.SH -2024-09-04,0.06400657222159878,600448.SH -2024-09-04,0.06414284874428765,002513.SZ +2024-09-04,0.06400657222159879,600448.SH +2024-09-04,0.06414284874428766,002513.SZ 2024-09-04,0.0646455800892395,002571.SZ 2024-09-04,0.06777274849150702,600302.SH 2024-09-05,0.05559764503513091,603021.SH -2024-09-05,0.05594724845637204,600448.SH +2024-09-05,0.05594724845637205,600448.SH 2024-09-05,0.0642482379074959,600149.SH 2024-09-05,0.06877264106812078,600302.SH -2024-09-05,0.0689706659489441,600802.SH -2024-09-06,0.05497216509681443,002058.SZ +2024-09-05,0.06897066594894412,600802.SH +2024-09-06,0.054972165096814435,002058.SZ 2024-09-06,0.060789652476286045,600448.SH -2024-09-06,0.06197304133567217,002513.SZ +2024-09-06,0.06197304133567218,002513.SZ 2024-09-06,0.06529719553203243,603616.SH 2024-09-06,0.06613244980583118,002795.SZ -2024-09-09,0.06153886635176001,600802.SH -2024-09-09,0.0635480336129598,000757.SZ +2024-09-09,0.061538866351760015,600802.SH +2024-09-09,0.06354803361295981,000757.SZ 2024-09-09,0.06679476574389395,600448.SH 2024-09-09,0.06969039537440358,603616.SH 2024-09-09,0.07132399504552574,000691.SZ -2024-09-10,0.05752166949032493,603616.SH -2024-09-10,0.058435244358667385,002853.SZ -2024-09-10,0.06086433034781778,002513.SZ +2024-09-10,0.05752166949032494,603616.SH +2024-09-10,0.05843524435866739,002853.SZ +2024-09-10,0.06086433034781779,002513.SZ 2024-09-10,0.06333492863362304,000691.SZ 2024-09-10,0.0661805030873993,002795.SZ 2024-09-11,0.05903617883008926,000856.SZ @@ -2059,80 +2059,80 @@ trade_date,score,ts_code 2024-09-11,0.0616247411659367,002513.SZ 2024-09-11,0.06413076902408392,600302.SH 2024-09-11,0.06529719553203243,603616.SH -2024-09-12,0.0580401925550379,002842.SZ -2024-09-12,0.05805017081207648,002795.SZ +2024-09-12,0.05804019255503791,002842.SZ +2024-09-12,0.05805017081207649,002795.SZ 2024-09-12,0.058253301685840864,000691.SZ 2024-09-12,0.06161994637644603,600149.SH 2024-09-12,0.0729528381899876,603616.SH 2024-09-13,0.057825483674807644,002494.SZ -2024-09-13,0.05894063660690863,002842.SZ +2024-09-13,0.05894063660690864,002842.SZ 2024-09-13,0.05895230830091318,600802.SH 2024-09-13,0.05954050834522312,002795.SZ 2024-09-13,0.06318133829497359,000691.SZ -2024-09-18,0.058752264427906764,600202.SH +2024-09-18,0.05875226442790677,600202.SH 2024-09-18,0.0597156870852692,002494.SZ 2024-09-18,0.06058936714511097,000691.SZ 2024-09-18,0.06491960563892263,603616.SH -2024-09-18,0.07405329079862022,002795.SZ +2024-09-18,0.07405329079862023,002795.SZ 2024-09-19,0.059067538130940817,603616.SH -2024-09-19,0.0605642155816214,600302.SH -2024-09-19,0.061219159277440184,000890.SZ +2024-09-19,0.06056421558162141,600302.SH +2024-09-19,0.06121915927744019,000890.SZ 2024-09-19,0.0626959077333338,002795.SZ 2024-09-19,0.06713192961014594,000691.SZ 2024-09-20,0.06008252020664256,002247.SZ -2024-09-20,0.06166769380746729,000890.SZ +2024-09-20,0.061667693807467304,000890.SZ 2024-09-20,0.06298602864205131,600302.SH 2024-09-20,0.06468057530941626,603616.SH 2024-09-20,0.06703067205914659,600802.SH 2024-09-23,0.06114842261100084,000691.SZ 2024-09-23,0.06116987692664563,603616.SH -2024-09-23,0.0616496561894419,600802.SH +2024-09-23,0.061649656189441904,600802.SH 2024-09-23,0.06517968976788958,002247.SZ -2024-09-23,0.06608630750421558,002795.SZ -2024-09-24,0.05246081198421899,002795.SZ +2024-09-23,0.0660863075042156,002795.SZ +2024-09-24,0.052460811984218994,002795.SZ 2024-09-24,0.05474940560587084,000691.SZ -2024-09-24,0.05543967575033693,603021.SH +2024-09-24,0.05543967575033694,603021.SH 2024-09-24,0.055674570802184215,002842.SZ 2024-09-24,0.059587462657613416,002247.SZ 2024-09-25,0.0534896628646333,000691.SZ -2024-09-25,0.05425588193153274,002842.SZ +2024-09-25,0.054255881931532746,002842.SZ 2024-09-25,0.05506157029291455,600302.SH -2024-09-25,0.055575249644219116,002696.SZ +2024-09-25,0.05557524964421912,002696.SZ 2024-09-25,0.05822389758228074,603021.SH -2024-09-26,0.05746748459333523,002494.SZ +2024-09-26,0.057467484593335234,002494.SZ 2024-09-26,0.05766354435868862,000691.SZ -2024-09-26,0.05773008550898457,000757.SZ +2024-09-26,0.05773008550898458,000757.SZ 2024-09-26,0.05841839043064937,600302.SH 2024-09-26,0.05973385818001958,603616.SH 2024-09-27,0.050000210550116025,600448.SH -2024-09-27,0.05238706978465784,603880.SH -2024-09-27,0.05331881656435052,603021.SH -2024-09-27,0.0545850636516873,603616.SH -2024-09-27,0.06568240104808319,600302.SH +2024-09-27,0.05238706978465785,603880.SH +2024-09-27,0.05331881656435054,603021.SH +2024-09-27,0.054585063651687304,603616.SH +2024-09-27,0.0656824010480832,600302.SH 2024-09-30,0.016367845689762593,002634.SZ -2024-09-30,0.01756390892931722,600149.SH +2024-09-30,0.017563908929317213,600149.SH 2024-09-30,0.018196363994950927,000679.SZ -2024-09-30,0.02669272123383377,603616.SH -2024-09-30,0.03648853061449224,002193.SZ -2024-10-08,0.025072150535470294,002494.SZ -2024-10-08,0.02772625406803715,600753.SH -2024-10-08,0.0284340836731915,600149.SH -2024-10-08,0.03199206563999788,000757.SZ +2024-09-30,0.026692721233833774,603616.SH +2024-09-30,0.03648853061449225,002193.SZ +2024-10-08,0.025072150535470288,002494.SZ +2024-10-08,0.027726254068037144,600753.SH +2024-10-08,0.028434083673191494,600149.SH +2024-10-08,0.031992065639997874,000757.SZ 2024-10-08,0.03857870395766382,600421.SH 2024-10-09,0.058935703609874275,002571.SZ 2024-10-09,0.0621478713020026,603021.SH 2024-10-09,0.06262563824215814,603880.SH -2024-10-09,0.06267721553706443,600202.SH +2024-10-09,0.06267721553706444,600202.SH 2024-10-09,0.07254981356688615,600149.SH 2024-10-10,0.06607859198859659,600448.SH 2024-10-10,0.06670218677727499,603880.SH -2024-10-10,0.0698185026424581,002571.SZ +2024-10-10,0.06981850264245812,002571.SZ 2024-10-10,0.07088670672290064,002620.SZ 2024-10-10,0.07254981356688615,600149.SH 2024-10-11,0.06774498009439898,600149.SH 2024-10-11,0.06840691027130064,603880.SH 2024-10-11,0.06948204524881255,600202.SH -2024-10-11,0.0698185026424581,002571.SZ +2024-10-11,0.06981850264245812,002571.SZ 2024-10-11,0.0779321726575774,002798.SZ 2024-10-14,0.06778172901181453,603021.SH 2024-10-14,0.06895437119730673,000632.SZ @@ -2144,7 +2144,7 @@ trade_date,score,ts_code 2024-10-15,0.06855154714439071,002696.SZ 2024-10-15,0.07585426556196022,603880.SH 2024-10-15,0.0779321726575774,002798.SZ -2024-10-16,0.0673210655468634,002486.SZ +2024-10-16,0.06732106554686342,002486.SZ 2024-10-16,0.07002889284411021,002696.SZ 2024-10-16,0.07057666785753014,600202.SH 2024-10-16,0.0758529439074536,603021.SH @@ -2155,26 +2155,26 @@ trade_date,score,ts_code 2024-10-17,0.07154581631769903,603021.SH 2024-10-17,0.07396260925325293,600149.SH 2024-10-18,0.06095254755507156,002696.SZ -2024-10-18,0.061642726334959576,002620.SZ +2024-10-18,0.06164272633495958,002620.SZ 2024-10-18,0.0626423487514876,600149.SH 2024-10-18,0.06347375284209496,600202.SH -2024-10-18,0.06606529323348675,600561.SH -2024-10-21,0.057769417094346416,603880.SH -2024-10-21,0.058682841695511724,600149.SH +2024-10-18,0.06606529323348677,600561.SH +2024-10-21,0.05776941709434642,603880.SH +2024-10-21,0.05868284169551174,600149.SH 2024-10-21,0.06024023064391821,002696.SZ 2024-10-21,0.06270040829548985,600561.SH 2024-10-21,0.06374406597542938,600302.SH 2024-10-22,0.05721124729496889,600202.SH 2024-10-22,0.06440526025222632,002696.SZ -2024-10-22,0.06472693321189829,002494.SZ +2024-10-22,0.0647269332118983,002494.SZ 2024-10-22,0.06542530280008697,002571.SZ -2024-10-22,0.07750696714179003,600149.SH +2024-10-22,0.07750696714179005,600149.SH 2024-10-23,0.06165950274738459,002634.SZ 2024-10-23,0.0627607331416537,603880.SH 2024-10-23,0.06353509133289646,002494.SZ -2024-10-23,0.0719628745179812,600561.SH +2024-10-23,0.07196287451798121,600561.SH 2024-10-23,0.07456544079777302,600149.SH -2024-10-24,0.061730590281119976,002494.SZ +2024-10-24,0.06173059028111998,002494.SZ 2024-10-24,0.06636867015193638,002571.SZ 2024-10-24,0.06676725012313743,600561.SH 2024-10-24,0.0741386008524775,002798.SZ @@ -2186,7 +2186,7 @@ trade_date,score,ts_code 2024-10-25,0.07570085294908441,600149.SH 2024-10-28,0.05859562965577268,002524.SZ 2024-10-28,0.06652187228051729,600561.SH -2024-10-28,0.07239661143830525,600149.SH +2024-10-28,0.07239661143830527,600149.SH 2024-10-28,0.07257275725696809,603880.SH 2024-10-28,0.07456728771958049,002798.SZ 2024-10-29,0.06733540555880621,600561.SH @@ -2200,7 +2200,7 @@ trade_date,score,ts_code 2024-10-30,0.06501233091983392,603880.SH 2024-10-30,0.07531974404425791,002798.SZ 2024-10-31,0.055266217890183045,000663.SZ -2024-10-31,0.05752190050378312,600844.SH +2024-10-31,0.05752190050378313,600844.SH 2024-10-31,0.06164029451828106,002494.SZ 2024-10-31,0.07090937308372373,603880.SH 2024-10-31,0.0767167350669701,600561.SH @@ -2227,10 +2227,10 @@ trade_date,score,ts_code 2024-11-07,0.05905020681560198,002798.SZ 2024-11-07,0.06085905329958384,603880.SH 2024-11-07,0.06468711029849523,002278.SZ -2024-11-07,0.06587696246003855,002652.SZ +2024-11-07,0.06587696246003856,002652.SZ 2024-11-07,0.07463528073752165,600561.SH 2024-11-08,0.059889234865177526,603880.SH -2024-11-08,0.06269568950489057,002524.SZ +2024-11-08,0.06269568950489059,002524.SZ 2024-11-08,0.06524603623245032,002494.SZ 2024-11-08,0.07171399084076907,002798.SZ 2024-11-08,0.08025060176935252,600561.SH @@ -2240,46 +2240,46 @@ trade_date,score,ts_code 2024-11-11,0.07105984613427131,002798.SZ 2024-11-11,0.07118117299693631,002524.SZ 2024-11-12,0.06545714508736175,600561.SH -2024-11-12,0.0657772163651366,600448.SH +2024-11-12,0.06577721636513661,600448.SH 2024-11-12,0.06633678028598852,002486.SZ 2024-11-12,0.07688329974196662,002798.SZ -2024-11-12,0.08245411988754828,000691.SZ +2024-11-12,0.08245411988754829,000691.SZ 2024-11-13,0.0680603415807642,600448.SH 2024-11-13,0.07031320833625858,002494.SZ -2024-11-13,0.07517899460355348,002798.SZ +2024-11-13,0.0751789946035535,002798.SZ 2024-11-13,0.07857379332462167,000691.SZ 2024-11-13,0.08105575345529935,600561.SH 2024-11-14,0.06328763452593694,000573.SZ 2024-11-14,0.0678961959986985,600448.SH 2024-11-14,0.07066749064363866,002494.SZ -2024-11-14,0.07390709342468829,002798.SZ +2024-11-14,0.0739070934246883,002798.SZ 2024-11-14,0.08105575345529935,600561.SH 2024-11-15,0.06925691810431239,603725.SH 2024-11-15,0.07198874827715113,002486.SZ -2024-11-15,0.07257616306082723,002494.SZ +2024-11-15,0.07257616306082725,002494.SZ 2024-11-15,0.07882231899859765,600561.SH 2024-11-15,0.0793754858689859,002798.SZ 2024-11-18,0.06995816277580079,600302.SH 2024-11-18,0.0724495271482917,600561.SH 2024-11-18,0.07325041580469227,600448.SH -2024-11-18,0.07748390055405069,002494.SZ -2024-11-18,0.07928046517139901,002798.SZ -2024-11-19,0.06752238378866891,002798.SZ +2024-11-18,0.0774839005540507,002494.SZ +2024-11-18,0.07928046517139903,002798.SZ +2024-11-19,0.06752238378866893,002798.SZ 2024-11-19,0.06817125516673284,600302.SH -2024-11-19,0.07053215368924422,600448.SH +2024-11-19,0.07053215368924423,600448.SH 2024-11-19,0.08144999816604029,600561.SH 2024-11-19,0.08286913742504315,002494.SZ 2024-11-20,0.0726966155771561,600561.SH 2024-11-20,0.07527997670290852,002775.SZ -2024-11-20,0.07928046517139901,002193.SZ +2024-11-20,0.07928046517139903,002193.SZ 2024-11-20,0.08353655549591388,002494.SZ 2024-11-20,0.08353655549591388,002798.SZ -2024-11-21,0.06807303322962512,600448.SH +2024-11-21,0.06807303322962513,600448.SH 2024-11-21,0.0743732819086977,002775.SZ 2024-11-21,0.07918922952790586,002193.SZ 2024-11-21,0.08353655549591388,002494.SZ 2024-11-21,0.08353655549591388,002798.SZ -2024-11-22,0.07296756214151405,002486.SZ +2024-11-22,0.07296756214151406,002486.SZ 2024-11-22,0.07665609163975234,600561.SH 2024-11-22,0.07719145664239867,002775.SZ 2024-11-22,0.07969383659838594,002798.SZ @@ -2288,9 +2288,9 @@ trade_date,score,ts_code 2024-11-25,0.06970372813227645,002193.SZ 2024-11-25,0.07153183888689243,600156.SH 2024-11-25,0.07400349228355119,603616.SH -2024-11-25,0.08495444461087942,600561.SH -2024-11-26,0.06827646280703675,002193.SZ -2024-11-26,0.06860288589785504,600358.SH +2024-11-25,0.08495444461087943,600561.SH +2024-11-26,0.06827646280703677,002193.SZ +2024-11-26,0.06860288589785506,600358.SH 2024-11-26,0.07302086919003281,600561.SH 2024-11-26,0.07582064241154055,603616.SH 2024-11-26,0.08038074885532107,002494.SZ @@ -2300,7 +2300,7 @@ trade_date,score,ts_code 2024-11-27,0.0737110997333206,600561.SH 2024-11-27,0.07673735907243688,002494.SZ 2024-11-28,0.0722361137101369,600543.SH -2024-11-28,0.0724207032289842,002775.SZ +2024-11-28,0.07242070322898421,002775.SZ 2024-11-28,0.07255787625623089,600561.SH 2024-11-28,0.0725701899407457,000890.SZ 2024-11-28,0.08140628948055036,603616.SH @@ -2310,23 +2310,23 @@ trade_date,score,ts_code 2024-11-29,0.07751571180734496,002775.SZ 2024-11-29,0.08594739969039476,603616.SH 2024-12-02,0.07059543114590862,002620.SZ -2024-12-02,0.0722121617089825,002775.SZ +2024-12-02,0.07221216170898251,002775.SZ 2024-12-02,0.07560039844798176,603616.SH 2024-12-02,0.08160187335739733,600149.SH 2024-12-02,0.08319884411370874,600561.SH 2024-12-03,0.07645250221092482,002620.SZ 2024-12-03,0.07734759663195406,603616.SH -2024-12-03,0.08052660336240147,002775.SZ +2024-12-03,0.08052660336240149,002775.SZ 2024-12-03,0.0815169258048725,600149.SH -2024-12-03,0.08745894442241352,000691.SZ +2024-12-03,0.08745894442241353,000691.SZ 2024-12-04,0.0771501991560355,002188.SZ -2024-12-04,0.07748390055405069,002494.SZ -2024-12-04,0.08052660336240147,002775.SZ +2024-12-04,0.0774839005540507,002494.SZ +2024-12-04,0.08052660336240149,002775.SZ 2024-12-04,0.08160187335739733,600149.SH -2024-12-04,0.08305928260686651,600561.SH +2024-12-04,0.08305928260686653,600561.SH 2024-12-05,0.07748111473876944,600543.SH 2024-12-05,0.07805445807200127,002205.SZ -2024-12-05,0.07976265224492568,600561.SH +2024-12-05,0.0797626522449257,600561.SH 2024-12-05,0.08140628948055036,600802.SH 2024-12-05,0.08409405948441662,600149.SH 2024-12-06,0.06940788895188102,002634.SZ @@ -2337,7 +2337,7 @@ trade_date,score,ts_code 2024-12-09,0.07565155103953143,002620.SZ 2024-12-09,0.07587216192074774,002188.SZ 2024-12-09,0.07779035384881614,600358.SH -2024-12-09,0.08008672300539214,002494.SZ +2024-12-09,0.08008672300539216,002494.SZ 2024-12-09,0.08377378050655127,600802.SH 2024-12-10,0.07411901561605379,002494.SZ 2024-12-10,0.07744080373046935,002620.SZ @@ -2351,17 +2351,17 @@ trade_date,score,ts_code 2024-12-11,0.08377378050655127,600149.SH 2024-12-12,0.07068530132116901,600107.SH 2024-12-12,0.0750191535524838,600561.SH -2024-12-12,0.07677004089422364,000663.SZ -2024-12-12,0.08277015724660575,002571.SZ -2024-12-12,0.08366537261731362,600149.SH +2024-12-12,0.07677004089422365,000663.SZ +2024-12-12,0.08277015724660576,002571.SZ +2024-12-12,0.08366537261731363,600149.SH 2024-12-13,0.07817593865197112,600802.SH 2024-12-13,0.0788498233534181,000638.SZ 2024-12-13,0.08047715014461043,000691.SZ -2024-12-13,0.08305928260686651,002571.SZ +2024-12-13,0.08305928260686653,002571.SZ 2024-12-13,0.08522550996571182,600149.SH 2024-12-16,0.07880811881277268,000691.SZ 2024-12-16,0.08268340248877903,002652.SZ -2024-12-16,0.08305928260686651,002571.SZ +2024-12-16,0.08305928260686653,002571.SZ 2024-12-16,0.08422859359383429,600802.SH 2024-12-16,0.08522550996571182,600149.SH 2024-12-17,0.0581022209756965,603725.SH @@ -2369,16 +2369,16 @@ trade_date,score,ts_code 2024-12-17,0.05905325436264376,002571.SZ 2024-12-17,0.0629302205545665,600281.SH 2024-12-17,0.07742861921731241,600802.SH -2024-12-18,0.059394176619889535,600235.SH +2024-12-18,0.05939417661988954,600235.SH 2024-12-18,0.060078891252592,000663.SZ 2024-12-18,0.060232638948493414,600448.SH 2024-12-18,0.063720913115126,600202.SH -2024-12-18,0.08584965998158729,600802.SH +2024-12-18,0.0858496599815873,600802.SH 2024-12-19,0.05991076692531603,600202.SH -2024-12-19,0.06288955671469744,002494.SZ +2024-12-19,0.06288955671469745,002494.SZ 2024-12-19,0.06398587976562767,600358.SH 2024-12-19,0.06634605644530447,002620.SZ -2024-12-19,0.08022183873524066,600802.SH +2024-12-19,0.08022183873524068,600802.SH 2024-12-20,0.05863478689334259,000856.SZ 2024-12-20,0.059739465259042834,000633.SZ 2024-12-20,0.0599975476023589,600448.SH @@ -2388,8 +2388,8 @@ trade_date,score,ts_code 2024-12-23,0.042421594109913766,600423.SH 2024-12-23,0.0444743881413806,000637.SZ 2024-12-23,0.05533420490126539,002084.SZ -2024-12-23,0.056686460205795236,600107.SH -2024-12-24,0.038737266812244056,002188.SZ +2024-12-23,0.05668646020579524,600107.SH +2024-12-24,0.03873726681224406,002188.SZ 2024-12-24,0.04280126238667808,600107.SH 2024-12-24,0.04910878584369345,600561.SH 2024-12-24,0.052844532281038185,002696.SZ @@ -2400,27 +2400,27 @@ trade_date,score,ts_code 2024-12-25,0.04475722776780492,600561.SH 2024-12-25,0.04694607203822179,002798.SZ 2024-12-26,0.04049314114759624,600232.SH -2024-12-26,0.044946464508251446,600107.SH +2024-12-26,0.04494646450825145,600107.SH 2024-12-26,0.05139993773207367,600561.SH 2024-12-26,0.0533114803378996,002798.SZ 2024-12-26,0.06416780281593579,002620.SZ 2024-12-27,0.04650076587901999,002278.SZ -2024-12-27,0.04705698747753749,002494.SZ -2024-12-27,0.05863965131375893,002798.SZ +2024-12-27,0.0470569874775375,002494.SZ +2024-12-27,0.058639651313758936,002798.SZ 2024-12-27,0.0624434976264622,002620.SZ 2024-12-27,0.0636122120801895,600358.SH 2024-12-30,0.03960613538944225,603880.SH 2024-12-30,0.044758438613260454,002571.SZ 2024-12-30,0.04493629254175382,600232.SH 2024-12-30,0.045796539212867554,002084.SZ -2024-12-30,0.0545669142605643,002798.SZ +2024-12-30,0.05456691426056431,002798.SZ 2024-12-31,0.04753758297949495,600149.SH 2024-12-31,0.04814843854604856,002188.SZ 2024-12-31,0.04867340160991515,600202.SH 2024-12-31,0.049243505325310646,002551.SZ 2024-12-31,0.05724767772903999,600448.SH 2025-01-02,0.053114266937198756,002278.SZ -2025-01-02,0.05452269142318583,600149.SH +2025-01-02,0.05452269142318584,600149.SH 2025-01-02,0.05862002606688215,600802.SH 2025-01-02,0.06008082939332271,002571.SZ 2025-01-02,0.06460545068339545,600358.SH @@ -2428,33 +2428,33 @@ trade_date,score,ts_code 2025-01-03,0.05092783526477546,600802.SH 2025-01-03,0.058475115798973534,002696.SZ 2025-01-03,0.05945050823513974,603880.SH -2025-01-03,0.06152941643085061,002247.SZ -2025-01-06,0.0456162861994952,600232.SH -2025-01-06,0.046012510517003176,603188.SH +2025-01-03,0.061529416430850616,002247.SZ +2025-01-06,0.04561628619949518,600232.SH +2025-01-06,0.04601251051700318,603188.SH 2025-01-06,0.047812167948379926,600202.SH 2025-01-06,0.04939444007591362,002571.SZ 2025-01-06,0.05658785478089641,002188.SZ 2025-01-07,0.0426603444615672,002842.SZ 2025-01-07,0.04631589395790495,603880.SH -2025-01-07,0.046410815056927485,600232.SH +2025-01-07,0.04641081505692747,600232.SH 2025-01-07,0.046537653813158844,600844.SH 2025-01-07,0.04910307168243289,002571.SZ 2025-01-08,0.045863616618598044,002652.SZ -2025-01-08,0.04959970362091859,002247.SZ +2025-01-08,0.049599703620918596,002247.SZ 2025-01-08,0.049964986911990236,600202.SH -2025-01-08,0.05031175675941719,600448.SH -2025-01-08,0.05807516054215332,600543.SH +2025-01-08,0.050311756759417195,600448.SH +2025-01-08,0.05807516054215333,600543.SH 2025-01-09,0.0607139929145303,600543.SH -2025-01-09,0.06285913805137487,002247.SZ -2025-01-09,0.06406287379717446,600202.SH +2025-01-09,0.06285913805137489,002247.SZ +2025-01-09,0.06406287379717447,600202.SH 2025-01-09,0.06416368675527301,002652.SZ 2025-01-09,0.0704701235018488,600358.SH -2025-01-10,0.05848924540951598,600149.SH -2025-01-10,0.059509279305668746,002551.SZ -2025-01-10,0.0597163886821082,002278.SZ +2025-01-10,0.058489245409515986,600149.SH +2025-01-10,0.05950927930566875,002551.SZ +2025-01-10,0.05971638868210821,002278.SZ 2025-01-10,0.06061157386726942,600358.SH 2025-01-10,0.0739045864644508,600543.SH -2025-01-13,0.059199397890591456,002247.SZ +2025-01-13,0.05919939789059146,002247.SZ 2025-01-13,0.05995880539240343,002278.SZ 2025-01-13,0.07027813615708607,002652.SZ 2025-01-13,0.07059819969439468,600802.SH @@ -2473,7 +2473,7 @@ trade_date,score,ts_code 2025-01-16,0.062219181045966916,600802.SH 2025-01-16,0.06659796582844649,603880.SH 2025-01-16,0.07015251838523805,002652.SZ -2025-01-16,0.07109391532747417,600543.SH +2025-01-16,0.07109391532747418,600543.SH 2025-01-17,0.062408529644354956,002696.SZ 2025-01-17,0.06399709913395242,603778.SH 2025-01-17,0.06433010875126091,600543.SH @@ -2489,23 +2489,23 @@ trade_date,score,ts_code 2025-01-21,0.05527322488035435,600844.SH 2025-01-21,0.056384587263727116,002652.SZ 2025-01-21,0.0694783052486209,600149.SH -2025-01-22,0.056342340321509164,600844.SH +2025-01-22,0.05634234032150917,600844.SH 2025-01-22,0.05763484592640951,002696.SZ 2025-01-22,0.05974222403635379,600543.SH 2025-01-22,0.060367495158524645,002486.SZ 2025-01-22,0.061138340779642475,600448.SH 2025-01-23,0.05717043538519159,002114.SZ -2025-01-23,0.05970755231566793,002551.SZ +2025-01-23,0.05970755231566794,002551.SZ 2025-01-23,0.06313081781927633,002696.SZ 2025-01-23,0.06541728714730977,002652.SZ -2025-01-23,0.07027312826742889,600149.SH +2025-01-23,0.0702731282674289,600149.SH 2025-01-24,0.05989637122181074,603880.SH 2025-01-24,0.06106891485656146,603616.SH 2025-01-24,0.062496534604625675,002696.SZ -2025-01-24,0.07332254167647673,600149.SH +2025-01-24,0.07332254167647674,600149.SH 2025-01-24,0.07930531570172007,002652.SZ 2025-01-27,0.06626182400865141,600149.SH -2025-01-27,0.06720268616843583,002114.SZ +2025-01-27,0.06720268616843585,002114.SZ 2025-01-27,0.07076576923753744,603778.SH 2025-01-27,0.07178740160713316,002652.SZ 2025-01-27,0.07648691297854956,600561.SH @@ -2524,57 +2524,57 @@ trade_date,score,ts_code 2025-02-07,0.060655798762996406,600561.SH 2025-02-07,0.06705279868049044,002524.SZ 2025-02-07,0.07327048066842362,002652.SZ -2025-02-10,0.06165993367073042,600448.SH +2025-02-10,0.06165993367073043,600448.SH 2025-02-10,0.06287042555173596,000890.SZ 2025-02-10,0.06291670959396799,603616.SH 2025-02-10,0.06402486146442302,600543.SH 2025-02-10,0.06763119009742402,002513.SZ -2025-02-11,0.06215503008130609,002719.SZ +2025-02-11,0.062155030081306094,002719.SZ 2025-02-11,0.06718096548135598,002513.SZ 2025-02-11,0.06756393155881116,002652.SZ 2025-02-11,0.07092090675398822,000632.SZ 2025-02-11,0.08101809180879177,000953.SZ 2025-02-12,0.06640033056857625,603616.SH -2025-02-12,0.06729567674259616,002513.SZ +2025-02-12,0.06729567674259618,002513.SZ 2025-02-12,0.06853520130654843,002486.SZ 2025-02-12,0.07135641812817571,002231.SZ 2025-02-12,0.07509640192774245,000953.SZ -2025-02-13,0.06860200518186815,002486.SZ +2025-02-13,0.06860200518186817,002486.SZ 2025-02-13,0.06926266305123673,603616.SH 2025-02-13,0.0692754337232626,000638.SZ -2025-02-13,0.0749245884207826,002513.SZ +2025-02-13,0.07492458842078262,002513.SZ 2025-02-13,0.07964027141714777,002652.SZ 2025-02-14,0.06988526384309039,000638.SZ -2025-02-14,0.07322028328236949,002513.SZ +2025-02-14,0.0732202832823695,002513.SZ 2025-02-14,0.07359604704395772,002652.SZ 2025-02-14,0.07372886298910084,600448.SH 2025-02-14,0.07478008535749825,600149.SH 2025-02-17,0.07129788513321829,002652.SZ -2025-02-17,0.07322028328236949,002513.SZ -2025-02-17,0.07747637360688434,603616.SH -2025-02-17,0.08056946705837165,600149.SH +2025-02-17,0.0732202832823695,002513.SZ +2025-02-17,0.07747637360688435,603616.SH +2025-02-17,0.08056946705837166,600149.SH 2025-02-17,0.08393946061875686,000953.SZ 2025-02-18,0.06949086238224367,002652.SZ 2025-02-18,0.0717647917274491,600802.SH -2025-02-18,0.07322028328236949,002513.SZ +2025-02-18,0.0732202832823695,002513.SZ 2025-02-18,0.07331538948201254,603616.SH 2025-02-18,0.07454844670093903,002798.SZ -2025-02-19,0.06760724610389403,002513.SZ +2025-02-19,0.06760724610389404,002513.SZ 2025-02-19,0.0683150232479262,600561.SH -2025-02-19,0.06954662174394928,000638.SZ +2025-02-19,0.0695466217439493,000638.SZ 2025-02-19,0.07832990804437875,603616.SH -2025-02-19,0.08652622259845148,002652.SZ +2025-02-19,0.0865262225984515,002652.SZ 2025-02-20,0.0707142641370179,000017.SZ 2025-02-20,0.07215528192472323,002798.SZ 2025-02-20,0.07357600542306152,603616.SH -2025-02-20,0.0749245884207826,002513.SZ +2025-02-20,0.07492458842078262,002513.SZ 2025-02-20,0.07608532236975328,000638.SZ 2025-02-21,0.06925365468502938,002798.SZ 2025-02-21,0.06988201937815613,002696.SZ -2025-02-21,0.07622590790074658,002513.SZ -2025-02-21,0.07973312395074049,002652.SZ -2025-02-21,0.08147055924074573,000638.SZ -2025-02-24,0.0671628842031827,002652.SZ +2025-02-21,0.0762259079007466,002513.SZ +2025-02-21,0.0797331239507405,002652.SZ +2025-02-21,0.08147055924074574,000638.SZ +2025-02-24,0.06716288420318271,002652.SZ 2025-02-24,0.06906533421477531,600202.SH 2025-02-24,0.07110162739403272,002231.SZ 2025-02-24,0.07215528192472323,002798.SZ @@ -2582,16 +2582,16 @@ trade_date,score,ts_code 2025-02-25,0.06884405309971257,603616.SH 2025-02-25,0.07043668934154633,600202.SH 2025-02-25,0.07059288465393836,000953.SZ -2025-02-25,0.07160992893076783,002513.SZ +2025-02-25,0.07160992893076784,002513.SZ 2025-02-25,0.07825269619315374,002652.SZ 2025-02-26,0.06793004581822797,600202.SH 2025-02-26,0.07218656196301049,600543.SH 2025-02-26,0.07507774250125794,002652.SZ -2025-02-26,0.07628619599118662,002798.SZ -2025-02-26,0.08213302275608035,603616.SH +2025-02-26,0.07628619599118663,002798.SZ +2025-02-26,0.08213302275608036,603616.SH 2025-02-27,0.06979522601970196,600802.SH 2025-02-27,0.07357600542306152,603616.SH -2025-02-27,0.07672749933236339,002652.SZ +2025-02-27,0.0767274993323634,002652.SZ 2025-02-27,0.07841512811382977,002798.SZ 2025-02-27,0.07923217022850793,002207.SZ 2025-02-28,0.06939385446467046,600202.SH @@ -2604,7 +2604,7 @@ trade_date,score,ts_code 2025-03-03,0.07398685862372259,600561.SH 2025-03-03,0.07579756012360153,002798.SZ 2025-03-03,0.0835205979800744,603616.SH -2025-03-04,0.07752596291762373,600802.SH +2025-03-04,0.07752596291762374,600802.SH 2025-03-04,0.07803099458030323,002798.SZ 2025-03-04,0.07917754855941823,600561.SH 2025-03-04,0.08022396761813357,600149.SH @@ -2635,7 +2635,7 @@ trade_date,score,ts_code 2025-03-11,0.07775246688217004,600149.SH 2025-03-11,0.08154811253574563,603616.SH 2025-03-12,0.07249167437162102,000953.SZ -2025-03-12,0.07329582304253338,000632.SZ +2025-03-12,0.07329582304253339,000632.SZ 2025-03-12,0.07380384906322124,000890.SZ 2025-03-12,0.07521866328155002,000638.SZ 2025-03-12,0.08005204848585011,002798.SZ @@ -2643,39 +2643,39 @@ trade_date,score,ts_code 2025-03-13,0.0661628094602253,002231.SZ 2025-03-13,0.07370016580373014,000638.SZ 2025-03-13,0.07822670941046654,002798.SZ -2025-03-13,0.07891410335353105,000890.SZ +2025-03-13,0.07891410335353106,000890.SZ 2025-03-14,0.0749820123887084,600543.SH -2025-03-14,0.07589055087175761,000632.SZ +2025-03-14,0.07589055087175763,000632.SZ 2025-03-14,0.0776828345913968,000953.SZ -2025-03-14,0.07867604797149555,600408.SH +2025-03-14,0.07867604797149556,600408.SH 2025-03-14,0.07980948341830131,600561.SH 2025-03-17,0.0777211255646881,000890.SZ 2025-03-17,0.07953178446398777,603616.SH -2025-03-17,0.08170354299205611,600561.SH +2025-03-17,0.08170354299205612,600561.SH 2025-03-17,0.0835205979800744,600149.SH -2025-03-17,0.08652622259845148,600543.SH -2025-03-18,0.07490434656857911,600561.SH +2025-03-17,0.0865262225984515,600543.SH +2025-03-18,0.07490434656857912,600561.SH 2025-03-18,0.07961070785401,000953.SZ 2025-03-18,0.07984603927935054,002652.SZ 2025-03-18,0.08064301120196071,600543.SH 2025-03-18,0.08154811253574563,603616.SH 2025-03-19,0.08060782589529002,600543.SH 2025-03-19,0.08154811253574563,603616.SH -2025-03-19,0.08199454873561984,600561.SH +2025-03-19,0.08199454873561986,600561.SH 2025-03-19,0.08273094562967541,000890.SZ -2025-03-19,0.08745894442241352,600149.SH +2025-03-19,0.08745894442241353,600149.SH 2025-03-20,0.07374197270048256,002652.SZ 2025-03-20,0.07416346416919117,000638.SZ 2025-03-20,0.07828303469085718,600543.SH -2025-03-20,0.08149572690915781,600561.SH -2025-03-20,0.08745894442241352,600149.SH +2025-03-20,0.08149572690915782,600561.SH +2025-03-20,0.08745894442241353,600149.SH 2025-03-21,0.07231812007909742,002798.SZ 2025-03-21,0.07266792538003596,603778.SH -2025-03-21,0.07770215510405791,600561.SH +2025-03-21,0.07770215510405792,600561.SH 2025-03-21,0.08013180401687799,600543.SH -2025-03-21,0.08745894442241352,600149.SH -2025-03-24,0.0532168081517913,600408.SH -2025-03-24,0.0567981134497373,002798.SZ +2025-03-21,0.08745894442241353,600149.SH +2025-03-24,0.053216808151791306,600408.SH +2025-03-24,0.05679811344973731,002798.SZ 2025-03-24,0.06051151345183621,000663.SZ 2025-03-24,0.07334485605171823,600149.SH 2025-03-24,0.07376826952015021,600561.SH @@ -2683,7 +2683,7 @@ trade_date,score,ts_code 2025-03-25,0.067717159686755,000593.SZ 2025-03-25,0.06912082854554982,000663.SZ 2025-03-25,0.07701828952423896,600149.SH -2025-03-25,0.07942364097470071,600561.SH +2025-03-25,0.07942364097470073,600561.SH 2025-03-26,0.06602931169463445,600319.SH 2025-03-26,0.07025110050842943,600448.SH 2025-03-26,0.07157615869900048,000593.SZ @@ -2693,23 +2693,23 @@ trade_date,score,ts_code 2025-03-27,0.07033215791265776,002798.SZ 2025-03-27,0.07068124933232635,603725.SH 2025-03-27,0.07142766220043696,002620.SZ -2025-03-27,0.07721444374790164,600561.SH +2025-03-27,0.07721444374790165,600561.SH 2025-03-28,0.056147315898468074,600448.SH 2025-03-28,0.06603295537030436,000593.SZ 2025-03-28,0.06951534142396815,603725.SH 2025-03-28,0.07233360728516189,002798.SZ -2025-03-28,0.07759074767519561,600149.SH +2025-03-28,0.07759074767519562,600149.SH 2025-03-31,0.057094534876327305,002247.SZ 2025-03-31,0.05720509588924974,600561.SH -2025-03-31,0.06555007940152395,603725.SH +2025-03-31,0.06555007940152396,603725.SH 2025-03-31,0.07459822037943287,600149.SH 2025-03-31,0.07704192015185256,002798.SZ 2025-04-01,0.0674817918073703,000593.SZ 2025-04-01,0.06830569445937287,002798.SZ 2025-04-01,0.07118540919288391,000663.SZ -2025-04-01,0.07516398258762988,600561.SH -2025-04-01,0.08112403939786629,600149.SH -2025-04-02,0.06813625085570292,002798.SZ +2025-04-01,0.0751639825876299,600561.SH +2025-04-01,0.0811240393978663,600149.SH +2025-04-02,0.06813625085570293,002798.SZ 2025-04-02,0.06983226844169273,600149.SH 2025-04-02,0.06996240304771323,002620.SZ 2025-04-02,0.07271902407209979,603725.SH @@ -2728,13 +2728,13 @@ trade_date,score,ts_code 2025-04-08,0.06328659807390959,002798.SZ 2025-04-08,0.06547317667234993,600149.SH 2025-04-08,0.06803982152314689,000663.SZ -2025-04-08,0.06958538104500554,600802.SH +2025-04-08,0.06958538104500556,600802.SH 2025-04-09,0.04779137670885746,600543.SH 2025-04-09,0.05114208834033023,600149.SH 2025-04-09,0.05322345630882603,000663.SZ 2025-04-09,0.05742054170980656,603021.SH 2025-04-09,0.07598484413611609,600802.SH -2025-04-10,0.05524253516820138,000663.SZ +2025-04-10,0.055242535168201386,000663.SZ 2025-04-10,0.06143494391995101,600149.SH 2025-04-10,0.0656610698703062,000638.SZ 2025-04-10,0.07509393408634163,002798.SZ @@ -2753,36 +2753,36 @@ trade_date,score,ts_code 2025-04-15,0.07207296942082192,002188.SZ 2025-04-15,0.07388130487199845,002798.SZ 2025-04-15,0.0743008879487124,600802.SH -2025-04-15,0.07884781129523122,600149.SH +2025-04-15,0.07884781129523123,600149.SH 2025-04-16,0.06446773187909696,002188.SZ 2025-04-16,0.06820889992487857,600802.SH 2025-04-16,0.06847128714375508,600149.SH 2025-04-16,0.06924915098169765,000638.SZ 2025-04-16,0.07175425803889404,002798.SZ -2025-04-17,0.06410944701752545,600561.SH +2025-04-17,0.06410944701752547,600561.SH 2025-04-17,0.07219185906382933,002798.SZ 2025-04-17,0.07412162885536841,002513.SZ 2025-04-17,0.07518616485097553,002231.SZ -2025-04-17,0.07636104050575329,600802.SH +2025-04-17,0.07636104050575328,600802.SH 2025-04-18,0.062411552970689996,002513.SZ -2025-04-18,0.0664855500390746,600561.SH +2025-04-18,0.06648555003907461,600561.SH 2025-04-18,0.07147783730654816,600802.SH 2025-04-18,0.07155909539182968,002798.SZ -2025-04-18,0.07167278803649053,600149.SH +2025-04-18,0.07167278803649055,600149.SH 2025-04-21,0.06554295131894441,600561.SH 2025-04-21,0.06845762767695321,002798.SZ 2025-04-21,0.06853500442437094,002231.SZ 2025-04-21,0.07207809937096964,600149.SH -2025-04-21,0.07398328606156,600802.SH +2025-04-21,0.07398328606156002,600802.SH 2025-04-22,0.0728798194499104,600543.SH -2025-04-22,0.07345288225380132,600149.SH +2025-04-22,0.07345288225380134,600149.SH 2025-04-22,0.07388130487199845,002798.SZ 2025-04-22,0.07388948455138647,002591.SZ -2025-04-22,0.07398328606156,600802.SH -2025-04-23,0.0683360498805901,002798.SZ -2025-04-23,0.07345288225380132,600149.SH +2025-04-22,0.07398328606156002,600802.SH +2025-04-23,0.06833604988059011,002798.SZ +2025-04-23,0.07345288225380134,600149.SH 2025-04-23,0.07388948455138647,002591.SZ -2025-04-23,0.07727991642350084,600802.SH +2025-04-23,0.07727991642350085,600802.SH 2025-04-23,0.07961626442380308,600561.SH 2025-04-24,0.07133749703084998,002513.SZ 2025-04-24,0.07139228697817972,600791.SH @@ -2791,7 +2791,7 @@ trade_date,score,ts_code 2025-04-24,0.07605313710576586,000890.SZ 2025-04-25,0.06678844713784413,002652.SZ 2025-04-25,0.06804086666890916,002513.SZ -2025-04-25,0.06856231029241569,600802.SH +2025-04-25,0.0685623102924157,600802.SH 2025-04-25,0.06932735915174554,002798.SZ 2025-04-25,0.07605313710576586,000890.SZ 2025-04-28,0.06366374240742385,002513.SZ @@ -2801,13 +2801,13 @@ trade_date,score,ts_code 2025-04-28,0.07388928221695172,002652.SZ 2025-04-29,0.0618778482077996,002652.SZ 2025-04-29,0.06705674073603628,600561.SH -2025-04-29,0.06711987251626733,000593.SZ +2025-04-29,0.06711987251626735,000593.SZ 2025-04-29,0.07199011153321301,600791.SH -2025-04-29,0.07727991642350084,600802.SH +2025-04-29,0.07727991642350085,600802.SH 2025-04-30,0.07358077587913955,600302.SH -2025-04-30,0.07364107578190426,000663.SZ -2025-04-30,0.07574919511098391,600561.SH -2025-04-30,0.0797257873623505,002524.SZ +2025-04-30,0.07364107578190428,000663.SZ +2025-04-30,0.07574919511098392,600561.SH +2025-04-30,0.07972578736235052,002524.SZ 2025-04-30,0.08076646946913416,603778.SH 2025-05-06,0.07320616514669426,600791.SH 2025-05-06,0.07655689698343256,603778.SH @@ -2829,37 +2829,37 @@ trade_date,score,ts_code 2025-05-09,0.07344429789502946,600408.SH 2025-05-09,0.07809651937383462,603778.SH 2025-05-09,0.0789917347445425,002652.SZ -2025-05-12,0.07104837974021559,600561.SH +2025-05-12,0.0710483797402156,600561.SH 2025-05-12,0.07294751037135244,600543.SH 2025-05-12,0.07401654441841828,002652.SZ 2025-05-12,0.0745952752463081,603778.SH -2025-05-12,0.07863498783072509,600408.SH +2025-05-12,0.0786349878307251,600408.SH 2025-05-13,0.061064002034489494,600408.SH -2025-05-13,0.06201439753882464,600791.SH +2025-05-13,0.062014397538824644,600791.SH 2025-05-13,0.07205994097010995,002798.SZ 2025-05-13,0.07213296125407131,002652.SZ 2025-05-13,0.07334047998067142,600561.SH 2025-05-14,0.07055882899551491,600408.SH 2025-05-14,0.0712073908350696,600807.SH 2025-05-14,0.07419920166453371,002798.SZ -2025-05-14,0.07520122802439513,603778.SH +2025-05-14,0.07520122802439515,603778.SH 2025-05-14,0.07866608276449538,600561.SH 2025-05-15,0.06759013072900111,002652.SZ 2025-05-15,0.06846578087843982,002207.SZ 2025-05-15,0.06870310393069752,002798.SZ 2025-05-15,0.0726325337642689,600802.SH 2025-05-15,0.07840644190345003,600561.SH -2025-05-16,0.0714601948087763,000663.SZ +2025-05-16,0.07146019480877631,000663.SZ 2025-05-16,0.07226802650188485,600543.SH -2025-05-16,0.0741818611123374,603778.SH +2025-05-16,0.07418186111233742,603778.SH 2025-05-16,0.07435303155304111,002798.SZ 2025-05-16,0.07917754855941823,600561.SH 2025-05-19,0.0658908197043336,603725.SH -2025-05-19,0.07025602168237843,600802.SH +2025-05-19,0.07025602168237845,600802.SH 2025-05-19,0.07430066656413799,002524.SZ -2025-05-19,0.07569536405586767,600408.SH +2025-05-19,0.07569536405586769,600408.SH 2025-05-19,0.08021104808938245,603778.SH -2025-05-20,0.06824014950406244,000663.SZ +2025-05-20,0.06824014950406246,000663.SZ 2025-05-20,0.0737789363403541,002775.SZ 2025-05-20,0.07419259932786178,002652.SZ 2025-05-20,0.07493976888217371,600561.SH @@ -2867,21 +2867,21 @@ trade_date,score,ts_code 2025-05-21,0.07322928346749563,600802.SH 2025-05-21,0.07352703790577474,002591.SZ 2025-05-21,0.07393459437049911,002652.SZ -2025-05-21,0.07613051823593214,600561.SH +2025-05-21,0.07613051823593216,600561.SH 2025-05-21,0.07828657497629327,600543.SH 2025-05-22,0.0719661294032135,002494.SZ -2025-05-22,0.07939437251297182,002524.SZ +2025-05-22,0.07939437251297184,002524.SZ 2025-05-22,0.08173640746681499,600543.SH 2025-05-22,0.08296910898872806,002775.SZ 2025-05-22,0.08318575871695842,002652.SZ 2025-05-23,0.07551404595004521,002524.SZ 2025-05-23,0.07761399286170953,600561.SH 2025-05-23,0.07795928892374074,002775.SZ -2025-05-23,0.07822373361408906,603778.SH +2025-05-23,0.07822373361408907,603778.SH 2025-05-23,0.08173640746681499,600543.SH 2025-05-26,0.07269952703801015,002524.SZ 2025-05-26,0.0741407164676424,002494.SZ -2025-05-26,0.07672163551449661,600408.SH +2025-05-26,0.07672163551449662,600408.SH 2025-05-26,0.07872672590771557,600543.SH 2025-05-26,0.080176077157859,002652.SZ 2025-05-27,0.0751662570928717,002652.SZ @@ -2898,9 +2898,9 @@ trade_date,score,ts_code 2025-05-29,0.06962285220516948,600802.SH 2025-05-29,0.07017267799782732,600543.SH 2025-05-29,0.07339068759623589,002524.SZ -2025-05-29,0.07530525455143723,600561.SH +2025-05-29,0.07530525455143725,600561.SH 2025-05-30,0.06425071305167528,002524.SZ -2025-05-30,0.06451694033366435,002084.SZ -2025-05-30,0.0650296678839968,600159.SH +2025-05-30,0.06451694033366437,002084.SZ +2025-05-30,0.06502966788399682,600159.SH 2025-05-30,0.06884845595244969,002775.SZ 2025-05-30,0.07478011981142736,600408.SH