From 7862b9739a3ee8bb49fa4157b7dcb226c0222389 Mon Sep 17 00:00:00 2001
From: liaozhaorun <1300336796@qq.com>
Date: Tue, 14 Oct 2025 09:44:46 +0800
Subject: [PATCH] =?UTF-8?q?factor=E4=BC=98=E5=8C=96=EF=BC=88=E6=9A=82?=
=?UTF-8?q?=E5=AD=98=E7=89=88=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 3 +-
main/factor/money_factor.py | 3 +-
main/factor/operator_base.py | 196 --
main/factor/operator_framework.py | 302 +--
main/factor/polars_momentum_factors.py | 340 ++--
main/train/Classify/Classify2.ipynb | 2387 +-----------------------
main/train/Classify2.ipynb | 182 +-
main/train/Classify2_load_model.ipynb | 110 +-
predictions_test.tsv | 1708 ++++-------------
9 files changed, 804 insertions(+), 4427 deletions(-)
delete mode 100644 main/factor/operator_base.py
diff --git a/.gitignore b/.gitignore
index b587b99..0d27d41 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,5 @@ model
**/.*
!.gitignore
-!.git
\ No newline at end of file
+!.git
+!.env
\ No newline at end of file
diff --git a/main/factor/money_factor.py b/main/factor/money_factor.py
index d3dec15..4b1982f 100644
--- a/main/factor/money_factor.py
+++ b/main/factor/money_factor.py
@@ -33,7 +33,7 @@ def holder_trade_factors(all_data_df: pd.DataFrame,
# 或者如果 'in_de' 已经是 1 和 -1 (或类似数值),则可以跳过映射,但要确保类型正确
stk_trade_processed_df['_direction'] = stk_trade_processed_df['in_de'].map(in_de_map)
# 如果 _direction 列在映射后可能产生NaN (因为in_de中有未覆盖的值),需要处理
- if stk_trade_processed_df['_direction'].isnull().any():
+ if stk_trade_processed_df['_direction'].is_null().any():
print("警告: 'in_de' 列中存在未映射的值,可能导致 _direction 列出现NaN。")
# 可以选择填充NaN,例如用0填充,或者移除这些行
# stk_trade_processed_df['_direction'].fillna(0, inplace=True)
@@ -109,4 +109,3 @@ def holder_trade_factors(all_data_df: pd.DataFrame,
print("股东增减持因子计算完成。")
return df_merged
-
diff --git a/main/factor/operator_base.py b/main/factor/operator_base.py
deleted file mode 100644
index 1b14b5a..0000000
--- a/main/factor/operator_base.py
+++ /dev/null
@@ -1,196 +0,0 @@
-"""
-因子算子基础框架 - 简化版本
-提供股票截面和日期截面两个基础函数
-"""
-
-import polars as pl
-from typing import Callable, Any, Optional, Union
-import logging
-
-logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
-
-
-def apply_stockwise(
- df: pl.DataFrame,
- operator_func: Callable[[pl.DataFrame, Any], pl.DataFrame],
- *args,
- **kwargs
-) -> pl.DataFrame:
- """
- 在股票截面上应用算子函数
-
- Args:
- df: 输入的polars DataFrame,必须包含ts_code和trade_date列
- operator_func: 算子函数,接收单个股票的数据和参数,返回处理后的DataFrame
- *args, **kwargs: 传递给算子函数的额外参数
-
- Returns:
- 处理后的完整DataFrame
- """
- # 验证必需列
- required_cols = ['ts_code', 'trade_date']
- missing_cols = [col for col in required_cols if col not in df.columns]
- if missing_cols:
- raise ValueError(f"缺少必需列: {missing_cols}")
-
- # 获取股票列表
- stock_list = df['ts_code'].unique().to_list()
- results = []
-
- # 按股票分组处理
- for ts_code in stock_list:
- try:
- # 获取单个股票的数据并按日期排序
- stock_df = df.filter(pl.col('ts_code') == ts_code).sort('trade_date')
-
- # 应用算子函数
- result_df = operator_func(stock_df, *args, **kwargs)
- results.append(result_df)
-
- except Exception as e:
- logger.error(f"股票 {ts_code} 处理失败: {e}")
- # 失败时返回原始数据
- stock_df = df.filter(pl.col('ts_code') == ts_code).sort('trade_date')
- results.append(stock_df)
-
- # 合并结果并排序
- if results:
- return pl.concat(results).sort(['ts_code', 'trade_date'])
- else:
- return df
-
-
-def apply_datewise(
- df: pl.DataFrame,
- operator_func: Callable[[pl.DataFrame, Any], pl.DataFrame],
- *args,
- **kwargs
-) -> pl.DataFrame:
- """
- 在日期截面上应用算子函数
-
- Args:
- df: 输入的polars DataFrame,必须包含ts_code和trade_date列
- operator_func: 算子函数,接收单个日期的数据和参数,返回处理后的DataFrame
- *args, **kwargs: 传递给算子函数的额外参数
-
- Returns:
- 处理后的完整DataFrame
- """
- # 验证必需列
- required_cols = ['ts_code', 'trade_date']
- missing_cols = [col for col in required_cols if col not in df.columns]
- if missing_cols:
- raise ValueError(f"缺少必需列: {missing_cols}")
-
- # 获取日期列表
- date_list = df['trade_date'].unique().to_list()
- results = []
-
- # 按日期分组处理
- for trade_date in date_list:
- try:
- # 获取单个日期的数据
- date_df = df.filter(pl.col('trade_date') == trade_date)
-
- # 应用算子函数
- result_df = operator_func(date_df, *args, **kwargs)
- results.append(result_df)
-
- except Exception as e:
- logger.error(f"日期 {trade_date} 处理失败: {e}")
- # 失败时返回原始数据
- date_df = df.filter(pl.col('trade_date') == trade_date)
- results.append(date_df)
-
- # 合并结果并排序
- if results:
- return pl.concat(results).sort(['ts_code', 'trade_date'])
- else:
- return df
-
-
-# 常用算子函数示例
-def rolling_mean_operator(df: pl.DataFrame, column: str, window: int, output_col: str = None) -> pl.DataFrame:
- """
- 滚动均值算子 - 股票截面
-
- Args:
- df: 单个股票的数据
- column: 要计算均值的列
- window: 窗口大小
- output_col: 输出列名,默认为f'{column}_mean_{window}'
-
- Returns:
- 添加均值列的DataFrame
- """
- if output_col is None:
- output_col = f'{column}_mean_{window}'
-
- return df.with_columns(
- pl.col(column).rolling_mean(window_size=window).alias(output_col)
- )
-
-
-def rolling_std_operator(df: pl.DataFrame, column: str, window: int, output_col: str = None) -> pl.DataFrame:
- """
- 滚动标准差算子 - 股票截面
-
- Args:
- df: 单个股票的数据
- column: 要计算标准差的列
- window: 窗口大小
- output_col: 输出列名,默认为f'{column}_std_{window}'
-
- Returns:
- 添加标准差列的DataFrame
- """
- if output_col is None:
- output_col = f'{column}_std_{window}'
-
- return df.with_columns(
- pl.col(column).rolling_std(window_size=window).alias(output_col)
- )
-
-
-def rank_operator(df: pl.DataFrame, column: str, ascending: bool = True, output_col: str = None) -> pl.DataFrame:
- """
- 排名算子 - 日期截面
-
- Args:
- df: 单个日期的数据
- column: 要排名的列
- ascending: 是否升序
- output_col: 输出列名,默认为f'{column}_rank'
-
- Returns:
- 添加排名列的DataFrame
- """
- if output_col is None:
- output_col = f'{column}_rank'
-
- return df.with_columns(
- pl.col(column).rank(method='dense', descending=not ascending).alias(output_col)
- )
-
-
-def pct_change_operator(df: pl.DataFrame, column: str, periods: int = 1, output_col: str = None) -> pl.DataFrame:
- """
- 百分比变化算子 - 股票截面
-
- Args:
- df: 单个股票的数据
- column: 要计算变化的列
- periods: 期数
- output_col: 输出列名,默认为f'{column}_pct_change_{periods}'
-
- Returns:
- 添加变化率列的DataFrame
- """
- if output_col is None:
- output_col = f'{column}_pct_change_{periods}'
-
- return df.with_columns(
- ((pl.col(column) / pl.col(column).shift(periods)) - 1).alias(output_col)
- )
diff --git a/main/factor/operator_framework.py b/main/factor/operator_framework.py
index eaca01e..37bde4f 100644
--- a/main/factor/operator_framework.py
+++ b/main/factor/operator_framework.py
@@ -1,18 +1,14 @@
"""
-因子算子框架 - 使用Polars实现统一的因子计算
-避免数据泄露,支持切面计算
+因子算子框架 - Polars 实现
+支持:截面滚动 → 拼回长表 → 按列名合并
+返回形式可选:完整 DataFrame(默认)或单列 Series
"""
-import polars as pl
-import numpy as np
-from typing import Dict, List, Callable, Optional, Union, Any
from abc import ABC, abstractmethod
from dataclasses import dataclass
-import logging
+from typing import List, Literal
-# 配置日志
-logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
+import polars as pl
@dataclass
@@ -22,229 +18,107 @@ class OperatorConfig:
description: str
required_columns: List[str]
output_columns: List[str]
- parameters: Dict[str, Any]
-
-
-class DataSlice:
- """数据切面基类"""
-
- def __init__(self, df: pl.DataFrame):
- self.df = df
- self.validate_data()
-
- def validate_data(self):
- """验证数据格式"""
- required_cols = ['ts_code', 'trade_date']
- missing_cols = [col for col in required_cols if col not in self.df.columns]
- if missing_cols:
- raise ValueError(f"缺少必需列: {missing_cols}")
-
- def get_stock_slice(self, ts_code: str) -> pl.DataFrame:
- """获取单个股票的数据切面"""
- return self.df.filter(pl.col('ts_code') == ts_code).sort('trade_date')
-
- def get_date_slice(self, trade_date: str) -> pl.DataFrame:
- """获取单个日期的数据切面"""
- return self.df.filter(pl.col('trade_date') == trade_date)
-
- def get_stock_list(self) -> List[str]:
- """获取股票列表"""
- return self.df['ts_code'].unique().to_list()
-
- def get_date_list(self) -> List[str]:
- """获取日期列表"""
- return self.df['trade_date'].unique().to_list()
+ parameters: dict
class BaseOperator(ABC):
"""算子基类"""
-
+
def __init__(self, config: OperatorConfig):
self.config = config
self.name = config.name
self.required_columns = config.required_columns
self.output_columns = config.output_columns
-
- def validate_input(self, df: pl.DataFrame) -> bool:
- """验证输入数据"""
- missing_cols = [col for col in self.required_columns if col not in df.columns]
- if missing_cols:
- logger.warning(f"算子 {self.name} 缺少必需列: {missing_cols}")
- return False
- return True
-
+
+ # ---------- 子类必须实现 ----------
@abstractmethod
- def apply(self, df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """应用算子"""
+ def get_factor_name(self) -> str:
+ """返回因子列名(用于合并)"""
pass
-
- def __call__(self, df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """调用算子"""
+
+ @abstractmethod
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ """
+ 真正的截面计算逻辑。
+ 参数:按 ts_code 或 trade_date 分组后的子表
+ 返回:与 group_df 行数一一对应的因子 Series(含正确索引)
+ """
+ pass
+
+ # ---------- 公共接口 ----------
+ def apply(self,
+ df: pl.DataFrame,
+ return_type: Literal['df', 'series'] = 'df',
+ **kwargs) -> pl.DataFrame | pl.Series:
+ """入口:截面滚动 → 拼回长表 → 合并/返回"""
if not self.validate_input(df):
- # 返回原始数据,添加NaN列
- for col in self.output_columns:
- df = df.with_columns(pl.lit(None).alias(col))
- return df
-
- try:
- return self.apply(df, **kwargs)
- except Exception as e:
- logger.error(f"算子 {self.name} 应用失败: {e}")
- # 返回原始数据,添加NaN列
- for col in self.output_columns:
- df = df.with_columns(pl.lit(None).alias(col))
- return df
+ raise ValueError(f"缺少必需列:{self.required_columns}")
+
+ long_table = self._sectional_roll(df, **kwargs) # ① 滚动
+ merged = self._merge_factor(df, long_table) # ② 合并
+ return merged if return_type == 'df' else merged[self.get_factor_name()]
+
+ # ---------- 内部流程 ----------
+ def validate_input(self, df: pl.DataFrame) -> bool:
+ return all(col in df.columns for col in self.required_columns)
+
+ @abstractmethod
+ def _sectional_roll(self, df: pl.DataFrame, **kwargs) -> pl.DataFrame:
+ """
+ 截面滚动模板:group → calc_factor → 拼回长表
+ 返回:含【trade_date, ts_code, factor】的长表
+ """
+ pass
+
+ def _merge_factor(self, original: pl.DataFrame, factor_table: pl.DataFrame) -> pl.DataFrame:
+ """按 [ts_code, trade_date] 左联,原地追加因子列"""
+ factor_name = self.get_factor_name()
+ return original.join(factor_table.select(['ts_code', 'trade_date', factor_name]),
+ on=['ts_code', 'trade_date'],
+ how='left')
+# -------------------- 股票截面:按 ts_code 分组 --------------------
class StockWiseOperator(BaseOperator):
- """股票切面算子 - 按股票分组计算"""
-
- def apply(self, df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """按股票分组应用算子"""
- stock_list = df['ts_code'].unique().to_list()
- results = []
-
- for ts_code in stock_list:
- stock_df = df.filter(pl.col('ts_code') == ts_code).sort('trade_date')
- try:
- result_df = self.apply_stock(stock_df, **kwargs)
- results.append(result_df)
- except Exception as e:
- logger.error(f"股票 {ts_code} 算子应用失败: {e}")
- # 为失败的股票添加NaN列
- for col in self.output_columns:
- stock_df = stock_df.with_columns(pl.lit(None).alias(col))
- results.append(stock_df)
-
- return pl.concat(results).sort(['ts_code', 'trade_date'])
-
- @abstractmethod
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """应用到单个股票数据"""
- pass
+ """股票切面算子抽象类:按 ts_code 分组,对每个股票的时间序列计算因子"""
+ def _sectional_roll(self, df: pl.DataFrame, **kwargs) -> pl.DataFrame:
+ factor_name = self.get_factor_name()
+
+ # 确保排序(时间顺序对 shift 等操作至关重要)
+ df_sorted = df.sort(['ts_code', 'trade_date'])
+
+ # 使用 map_groups:对每个 ts_code 分组,传入完整子 DataFrame
+ result = (
+ df_sorted
+ .group_by('ts_code', maintain_order=True)
+ .map_groups(
+ lambda group_df: group_df.with_columns(
+ self.calc_factor(group_df, **kwargs)
+ )
+ )
+ .select(['ts_code', 'trade_date', factor_name])
+ )
+ return result
+# -------------------- 日期截面:按 trade_date 分组 --------------------
class DateWiseOperator(BaseOperator):
- """日期切面算子 - 按日期分组计算"""
-
- def apply(self, df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """按日期分组应用算子"""
- date_list = df['trade_date'].unique().to_list()
- results = []
+ """日期切面算子抽象类:按 trade_date 分组,对每个截面计算因子"""
+
+ def _sectional_roll(self, df: pl.DataFrame, **kwargs) -> pl.DataFrame:
+ factor_name = self.get_factor_name()
- for trade_date in date_list:
- date_df = df.filter(pl.col('trade_date') == trade_date)
- try:
- result_df = self.apply_date(date_df, **kwargs)
- results.append(result_df)
- except Exception as e:
- logger.error(f"日期 {trade_date} 算子应用失败: {e}")
- # 为失败的日期添加NaN列
- for col in self.output_columns:
- date_df = date_df.with_columns(pl.lit(None).alias(col))
- results.append(date_df)
+ df_sorted = df.sort(['trade_date', 'ts_code'])
- return pl.concat(results).sort(['ts_code', 'trade_date'])
-
- @abstractmethod
- def apply_date(self, date_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """应用到单个日期数据"""
- pass
-
-
-class RollingOperator(StockWiseOperator):
- """滚动窗口算子基类"""
-
- def __init__(self, config: OperatorConfig, window: int, min_periods: Optional[int] = None):
- super().__init__(config)
- self.window = window
- self.min_periods = min_periods or max(1, window // 2)
-
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """应用滚动窗口计算"""
- return self.apply_rolling(stock_df, **kwargs)
-
- @abstractmethod
- def apply_rolling(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """滚动窗口计算逻辑"""
- pass
-
-
-# 基础算子实现
-class ReturnOperator(RollingOperator):
- """收益率算子"""
-
- def __init__(self, periods: int = 1):
- config = OperatorConfig(
- name=f"return_{periods}",
- description=f"{periods}期收益率",
- required_columns=['close'],
- output_columns=[f'return_{periods}'],
- parameters={'periods': periods}
+ result = (
+ df_sorted
+ .group_by('trade_date', maintain_order=True)
+ .map_groups(
+ lambda group_df: group_df.with_columns(
+ self.calc_factor(group_df, **kwargs)
+ )
+ )
+ .select(['ts_code', 'trade_date', factor_name])
)
- super().__init__(config, window=periods + 1)
- self.periods = periods
-
- def apply_rolling(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算收益率"""
- return stock_df.with_columns(
- (pl.col('close') / pl.col('close').shift(self.periods) - 1).alias(f'return_{self.periods}')
- )
-
-
-class VolatilityOperator(RollingOperator):
- """波动率算子"""
-
- def __init__(self, window: int = 20):
- config = OperatorConfig(
- name=f"volatility_{window}",
- description=f"{window}日波动率",
- required_columns=['pct_chg'],
- output_columns=[f'volatility_{window}'],
- parameters={'window': window}
- )
- super().__init__(config, window=window)
-
- def apply_rolling(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算波动率"""
- return stock_df.with_columns(
- pl.col('pct_chg').rolling_std(window=self.window).alias(f'volatility_{self.window}')
- )
-
-
-class MeanOperator(RollingOperator):
- """均值算子"""
-
- def __init__(self, column: str, window: int):
- config = OperatorConfig(
- name=f"mean_{column}_{window}",
- description=f"{column}的{window}日均值",
- required_columns=[column],
- output_columns=[f'mean_{column}_{window}'],
- parameters={'column': column, 'window': window}
- )
- super().__init__(config, window=window)
- self.column = column
-
- def apply_rolling(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算均值"""
- return stock_df.with_columns(
- pl.col(self.column).rolling_mean(window=self.window).alias(f'mean_{self.column}_{self.window}')
- )
-
-
-class RankOperator(DateWiseOperator):
- """排名算子"""
-
- def __init__(self, column: str, ascending: bool = True):
- config = OperatorConfig(
- name=f"rank_{column}",
- description=f"{column}的排名",
- required_columns=[column],
- output_columns=[f'rank_{column}'],
- parameters={'column': column, 'ascending': ascending}
- )
- super().__init__(config)
- self.column = column
- self.ascending = ascending
-
+ return result
+
\ No newline at end of file
diff --git a/main/factor/polars_momentum_factors.py b/main/factor/polars_momentum_factors.py
index a2d7179..a1f2a67 100644
--- a/main/factor/polars_momentum_factors.py
+++ b/main/factor/polars_momentum_factors.py
@@ -6,7 +6,9 @@
import polars as pl
import numpy as np
from typing import Dict, List, Optional, Any
-from operator_framework import StockWiseOperator, OperatorConfig
+
+from tqdm import tqdm
+from main.factor.operator_framework import StockWiseOperator, OperatorConfig
from scipy.stats import linregress
@@ -14,6 +16,8 @@ class PriceMinusDeductionPriceOperator(StockWiseOperator):
"""价格减抵扣价算子"""
def __init__(self, n: int = 10):
+ if n <= 0:
+ raise ValueError("n must be positive")
config = OperatorConfig(
name=f"price_minus_deduction_price_{n}",
description=f"{n}日价格减抵扣价",
@@ -24,21 +28,22 @@ class PriceMinusDeductionPriceOperator(StockWiseOperator):
super().__init__(config)
self.n = n
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算价格减抵扣价"""
- # 抵扣价是n-1周期前的价格
- deduction_price = pl.col('close').shift(self.n - 1)
-
- # 计算差值
- price_diff = pl.col('close') - deduction_price
-
- return stock_df.with_columns(price_diff.alias(f'price_minus_deduction_price_{self.n}'))
+ def get_factor_name(self) -> str:
+ return f'price_minus_deduction_price_{self.n}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ # 抵扣价是 n 日前的价格(更合理),若坚持 n-1 则保留
+ deduction_price = group_df['close'].shift(self.n) # 建议用 n,不是 n-1
+ price_diff = group_df['close'] - deduction_price
+ return price_diff.alias(self.get_factor_name())
class PriceDeductionPriceDiffRatioToSMAOperator(StockWiseOperator):
"""价格抵扣价差值相对SMA比率算子"""
def __init__(self, n: int = 10):
+ if n <= 0:
+ raise ValueError("n must be positive")
config = OperatorConfig(
name=f"price_deduction_price_diff_ratio_to_sma_{n}",
description=f"{n}日价格抵扣价差值相对SMA比率",
@@ -49,27 +54,23 @@ class PriceDeductionPriceDiffRatioToSMAOperator(StockWiseOperator):
super().__init__(config)
self.n = n
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算价格抵扣价差值相对SMA比率"""
- # 计算n日SMA
- sma = pl.col('close').rolling_mean(window=self.n)
-
- # 抵扣价
- deduction_price = pl.col('close').shift(self.n - 1)
-
- # 计算差值
- diff = pl.col('close') - deduction_price
-
- # 计算比率 (处理除零)
+ def get_factor_name(self) -> str:
+ return f'price_deduction_price_diff_ratio_to_sma_{self.n}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ sma = group_df['close'].rolling_mean(window_size=self.n)
+ deduction_price = group_df['close'].shift(self.n)
+ diff = group_df['close'] - deduction_price
ratio = diff / (sma + 1e-8)
-
- return stock_df.with_columns(ratio.alias(f'price_deduction_price_diff_ratio_to_sma_{self.n}'))
+ return ratio.alias(self.get_factor_name())
class CatPriceVsSmaVsDeductionPriceOperator(StockWiseOperator):
"""价格vsSMAvs抵扣价分类算子"""
def __init__(self, n: int = 10):
+ if n <= 0:
+ raise ValueError("n must be positive")
config = OperatorConfig(
name=f"cat_price_vs_sma_vs_deduction_price_{n}",
description=f"{n}日价格vsSMAvs抵扣价分类",
@@ -80,40 +81,35 @@ class CatPriceVsSmaVsDeductionPriceOperator(StockWiseOperator):
super().__init__(config)
self.n = n
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算价格vsSMAvs抵扣价分类"""
- # 计算n日SMA
- sma = pl.col('close').rolling_mean(window=self.n)
+ def get_factor_name(self) -> str:
+ return f'cat_price_vs_sma_vs_deduction_price_{self.n}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ sma = group_df['close'].rolling_mean(window_size=self.n)
+ deduction_price = group_df['close'].shift(self.n)
- # 抵扣价
- deduction_price = pl.col('close').shift(self.n - 1)
+ cond1 = (group_df['close'] > sma) & (deduction_price > sma)
+ cond2 = (group_df['close'] < sma) & (deduction_price < sma)
+ cond3 = (group_df['close'] > sma) & (deduction_price <= sma)
+ cond4 = (group_df['close'] <= sma) & (deduction_price > sma)
- # 定义条件
- conditions = [
- # 1: 当前价 > SMA 且 抵扣价 > SMA
- (pl.col('close') > sma) & (deduction_price > sma),
- # 2: 当前价 < SMA 且 抵扣价 < SMA
- (pl.col('close') < sma) & (deduction_price < sma),
- # 3: 当前价 > SMA 且 抵扣价 <= SMA
- (pl.col('close') > sma) & (deduction_price <= sma),
- # 4: 当前价 <= SMA 且 抵扣价 > SMA
- (pl.col('close') <= sma) & (deduction_price > sma),
- ]
-
- choices = [1, 2, 3, 4]
-
- # 使用select函数进行分类
- classification = pl.select(conditions=conditions, choices=choices, default=0)
-
- return stock_df.with_columns(
- classification.alias(f'cat_price_vs_sma_vs_deduction_price_{self.n}')
+ classification = (
+ pl.when(cond1).then(1)
+ .when(cond2).then(2)
+ .when(cond3).then(3)
+ .when(cond4).then(4)
+ .otherwise(0)
)
+ return classification.alias(self.get_factor_name())
+# ✅ 修复:使用 rolling_map
class VolatilitySlopeOperator(StockWiseOperator):
"""波动率斜率算子"""
def __init__(self, long_window: int = 20, short_window: int = 5):
+ if long_window <= 0 or short_window <= 0:
+ raise ValueError("Windows must be positive")
config = OperatorConfig(
name=f"volatility_slope_{long_window}_{short_window}",
description=f"{long_window}日波动率{short_window}日斜率",
@@ -125,34 +121,40 @@ class VolatilitySlopeOperator(StockWiseOperator):
self.long_window = long_window
self.short_window = short_window
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算波动率斜率"""
- # 计算长期波动率
- long_vol = pl.col('pct_chg').rolling_std(window=self.long_window)
+ def get_factor_name(self) -> str:
+ return f'volatility_slope_{self.long_window}_{self.short_window}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ # 先计算长期波动率(标准差)
+ long_vol = group_df['pct_chg'].rolling_std(window_size=self.long_window)
- # 计算斜率函数
- def calculate_slope(series):
- if len(series) < 2:
- return 0
- x = np.arange(len(series))
- slope, _, _, _, _ = linregress(x, series)
- return slope
+ # 定义斜率函数(输入是 numpy array)
+ def slope_func(window_vals: np.ndarray) -> float:
+ if len(window_vals) < 2 or pl.Series(window_vals).is_null().any():
+ return 0.0
+ x = np.arange(len(window_vals))
+ try:
+ slope, _, _, _, _ = linregress(x, window_vals)
+ return slope if np.isfinite(slope) else 0.0
+ except:
+ return 0.0
- # 计算斜率
- volatility_slope = long_vol.rolling_apply(
- function=calculate_slope,
- window_size=self.short_window
- )
-
- return stock_df.with_columns(
- volatility_slope.alias(f'volatility_slope_{self.long_window}_{self.short_window}')
+ # 对波动率序列应用 rolling_map
+ volatility_slope = long_vol.rolling_map(
+ function=slope_func,
+ window_size=self.short_window,
+ min_periods=2 # 至少2点才能算斜率
)
+ return volatility_slope.alias(self.get_factor_name())
+# ✅ 修复:使用 rolling_map
class TurnoverRateTrendStrengthOperator(StockWiseOperator):
"""换手率趋势强度算子"""
def __init__(self, window: int = 5):
+ if window <= 0:
+ raise ValueError("Window must be positive")
config = OperatorConfig(
name=f"turnover_trend_strength_{window}",
description=f"{window}日换手率趋势强度",
@@ -163,31 +165,34 @@ class TurnoverRateTrendStrengthOperator(StockWiseOperator):
super().__init__(config)
self.window = window
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算换手率趋势强度"""
- # 计算斜率函数
- def calculate_slope(series):
- if len(series) < 2:
- return 0
- x = np.arange(len(series))
- slope, _, _, _, _ = linregress(x, series)
- return slope
+ def get_factor_name(self) -> str:
+ return f'turnover_trend_strength_{self.window}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ def slope_func(window_vals: np.ndarray) -> float:
+ if len(window_vals) < 2 or pl.Series(window_vals).is_null().any():
+ return 0.0
+ x = np.arange(len(window_vals))
+ try:
+ slope, _, _, _, _ = linregress(x, window_vals)
+ return slope if np.isfinite(slope) else 0.0
+ except:
+ return 0.0
- # 计算换手率斜率
- trend_strength = pl.col('turnover_rate').rolling_apply(
- function=calculate_slope,
- window_size=self.window
- )
-
- return stock_df.with_columns(
- trend_strength.alias(f'turnover_trend_strength_{self.window}')
+ trend_strength = group_df['turnover_rate'].rolling_map(
+ function=slope_func,
+ window_size=self.window,
+ min_periods=2
)
+ return trend_strength.alias(self.get_factor_name())
class FreeFloatTurnoverSurgeOperator(StockWiseOperator):
"""自由流通股换手率激增算子"""
def __init__(self, window: int = 10):
+ if window <= 0:
+ raise ValueError("Window must be positive")
config = OperatorConfig(
name=f"ff_turnover_surge_{window}",
description=f"{window}日自由流通股换手率激增",
@@ -198,21 +203,21 @@ class FreeFloatTurnoverSurgeOperator(StockWiseOperator):
super().__init__(config)
self.window = window
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算自由流通股换手率激增"""
- # 计算均值
- avg_turnover = pl.col('turnover_rate').rolling_mean(window=self.window)
-
- # 计算激增比率
- surge_ratio = pl.col('turnover_rate') / (avg_turnover + 1e-8)
-
- return stock_df.with_columns(surge_ratio.alias(f'ff_turnover_surge_{self.window}'))
+ def get_factor_name(self) -> str:
+ return f'ff_turnover_surge_{self.window}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ avg_turnover = group_df['turnover_rate'].rolling_mean(window_size=self.window)
+ surge_ratio = group_df['turnover_rate'] / (avg_turnover + 1e-8)
+ return surge_ratio.alias(self.get_factor_name())
class PriceVolumeTrendCoherenceOperator(StockWiseOperator):
"""价量趋势一致性算子"""
def __init__(self, price_window: int = 5, volume_window: int = 20):
+ if price_window <= 0 or volume_window <= 0:
+ raise ValueError("Windows must be positive")
config = OperatorConfig(
name=f"price_volume_coherence_{price_window}_{volume_window}",
description=f"{price_window}日价格{volume_window}日成交量趋势一致性",
@@ -224,25 +229,19 @@ class PriceVolumeTrendCoherenceOperator(StockWiseOperator):
self.price_window = price_window
self.volume_window = volume_window
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算价量趋势一致性"""
- # 计算价格上涨占比
- def price_up_ratio(series):
- return (series.diff() > 0).rolling_mean(window=self.price_window)
+ def get_factor_name(self) -> str:
+ return f'price_volume_coherence_{self.price_window}_{self.volume_window}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ price_up = (group_df['close'].diff() > 0).cast(pl.Int8)
+ price_up_ratio = price_up.rolling_mean(window_size=self.price_window)
- price_up = pl.col('close').apply(price_up_ratio)
+ vol_avg = group_df['vol'].rolling_mean(window_size=self.volume_window)
+ vol_above = (group_df['vol'] > vol_avg).cast(pl.Int8)
+ vol_above_ratio = vol_above.rolling_mean(window_size=self.price_window)
- # 计算成交量高于均值占比
- vol_avg = pl.col('vol').rolling_mean(window=self.volume_window)
- vol_above_avg = pl.col('vol') > vol_avg
- vol_above_ratio = vol_above_avg.cast(int).rolling_mean(window=self.price_window)
-
- # 计算一致性
- coherence = price_up * vol_above_ratio
-
- return stock_df.with_columns(
- coherence.alias(f'price_volume_coherence_{self.price_window}_{self.volume_window}')
- )
+ coherence = price_up_ratio * vol_above_ratio
+ return coherence.alias(self.get_factor_name())
class FreeFloatToTotalTurnoverRatioOperator(StockWiseOperator):
@@ -258,19 +257,21 @@ class FreeFloatToTotalTurnoverRatioOperator(StockWiseOperator):
)
super().__init__(config)
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算自由流通股对总换手率比率"""
- # 假设turnover_rate是自由流通股换手率
- # 计算比率 (简化处理)
- ratio = pl.col('turnover_rate') / (pl.col('turnover_rate') + 1e-8)
-
- return stock_df.with_columns(ratio.alias('ff_to_total_turnover_ratio'))
+ def get_factor_name(self) -> str:
+ return 'ff_to_total_turnover_ratio'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ # 实际业务中可能需要 total_turnover_rate,这里简化
+ ratio = pl.lit(1.0) # 或根据实际逻辑修改
+ return ratio.alias('ff_to_total_turnover_ratio')
class VarianceOperator(StockWiseOperator):
"""方差算子"""
def __init__(self, window: int):
+ if window <= 0:
+ raise ValueError("Window must be positive")
config = OperatorConfig(
name=f"variance_{window}",
description=f"{window}日方差",
@@ -281,12 +282,12 @@ class VarianceOperator(StockWiseOperator):
super().__init__(config)
self.window = window
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算方差"""
- # 计算方差
- variance = pl.col('pct_chg').rolling_var(window=self.window)
-
- return stock_df.with_columns(variance.alias(f'variance_{self.window}'))
+ def get_factor_name(self) -> str:
+ return f'variance_{self.window}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ variance = group_df['pct_chg'].rolling_var(window_size=self.window)
+ return variance.alias(self.get_factor_name())
class LimitUpDownOperator(StockWiseOperator):
@@ -302,26 +303,12 @@ class LimitUpDownOperator(StockWiseOperator):
)
super().__init__(config)
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算涨跌停因子"""
- # 判断是否涨停
- up_limit = pl.col('close') == pl.col('up_limit')
-
- # 判断是否跌停
- down_limit = pl.col('close') == pl.col('down_limit')
-
- # 计算10日涨停计数
- up_count_10d = up_limit.cast(int).rolling_sum(window=10)
-
- # 计算10日跌停计数
- down_count_10d = down_limit.cast(int).rolling_sum(window=10)
-
- return stock_df.with_columns([
- up_limit.alias('cat_up_limit'),
- down_limit.alias('cat_down_limit'),
- up_count_10d.alias('up_limit_count_10d'),
- down_count_10d.alias('down_limit_count_10d')
- ])
+ def get_factor_name(self) -> str:
+ return 'cat_up_limit'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ up_limit = (group_df['close'] == group_df['up_limit']).cast(pl.Int8)
+ return up_limit.alias('cat_up_limit')
class ConsecutiveUpLimitOperator(StockWiseOperator):
@@ -337,19 +324,21 @@ class ConsecutiveUpLimitOperator(StockWiseOperator):
)
super().__init__(config)
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算连续涨停天数"""
- # 计算连续涨停
- # 简化处理,实际应用中需要更复杂的逻辑
- consecutive = pl.col('cat_up_limit').cast(int)
-
- return stock_df.with_columns(consecutive.alias('consecutive_up_limit'))
+ def get_factor_name(self) -> str:
+ return 'consecutive_up_limit'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ # 简化版:实际连续计数需用 cumsum + groupby trick
+ # 这里先返回原始值,后续可优化
+ return group_df['cat_up_limit'].alias('consecutive_up_limit')
class MomentumFactorOperator(StockWiseOperator):
"""动量因子算子"""
def __init__(self, alpha: float = 0.5):
+ if not (0 <= alpha <= 1):
+ raise ValueError("alpha should be between 0 and 1")
config = OperatorConfig(
name=f"momentum_factor_{alpha}",
description=f"动量因子(alpha={alpha})",
@@ -360,12 +349,12 @@ class MomentumFactorOperator(StockWiseOperator):
super().__init__(config)
self.alpha = alpha
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算动量因子"""
- # 计算动量因子
- momentum = pl.col('volume_change_rate') + self.alpha * pl.col('turnover_deviation')
-
- return stock_df.with_columns(momentum.alias(f'momentum_factor_{self.alpha}'))
+ def get_factor_name(self) -> str:
+ return f'momentum_factor_{self.alpha}'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ momentum = group_df['volume_change_rate'] + self.alpha * group_df['turnover_deviation']
+ return momentum.alias(self.get_factor_name())
class ResonanceFactorOperator(StockWiseOperator):
@@ -381,28 +370,28 @@ class ResonanceFactorOperator(StockWiseOperator):
)
super().__init__(config)
- def apply_stock(self, stock_df: pl.DataFrame, **kwargs) -> pl.DataFrame:
- """计算共振因子"""
- # 计算共振因子
- resonance = pl.col('volume_ratio') * pl.col('pct_chg')
-
- return stock_df.with_columns(resonance.alias('resonance_factor'))
+ def get_factor_name(self) -> str:
+ return 'resonance_factor'
+
+ def calc_factor(self, group_df: pl.DataFrame, **kwargs) -> pl.Series:
+ resonance = group_df['volume_ratio'] * group_df['pct_chg']
+ return resonance.alias('resonance_factor')
# 动量因子集合
MOMENTUM_OPERATORS = [
- PriceMinusDeductionPriceOperator(),
- PriceDeductionPriceDiffRatioToSMAOperator(),
- CatPriceVsSmaVsDeductionPriceOperator(),
- VolatilitySlopeOperator(),
- TurnoverRateTrendStrengthOperator(5),
+ PriceMinusDeductionPriceOperator(10),
+ PriceDeductionPriceDiffRatioToSMAOperator(10),
+ CatPriceVsSmaVsDeductionPriceOperator(10),
+ # VolatilitySlopeOperator(20, 5),
+ # TurnoverRateTrendStrengthOperator(5),
FreeFloatTurnoverSurgeOperator(10),
- PriceVolumeTrendCoherenceOperator(),
+ PriceVolumeTrendCoherenceOperator(5, 20),
FreeFloatToTotalTurnoverRatioOperator(),
VarianceOperator(20),
LimitUpDownOperator(),
ConsecutiveUpLimitOperator(),
- MomentumFactorOperator(),
+ # MomentumFactorOperator(0.5),
ResonanceFactorOperator(),
]
@@ -410,19 +399,12 @@ MOMENTUM_OPERATORS = [
def apply_momentum_factors(df: pl.DataFrame, operators: List = None) -> pl.DataFrame:
"""
应用所有动量因子
-
- Args:
- df: 输入的Polars DataFrame
- operators: 要应用的算子列表,如果为None则使用默认列表
-
- Returns:
- 添加了动量因子的DataFrame
"""
if operators is None:
operators = MOMENTUM_OPERATORS
result_df = df
- for operator in operators:
- result_df = operator(result_df)
+ for operator in tqdm(operators, desc="Applying momentum factors"):
+ result_df = operator.apply(result_df)
return result_df
diff --git a/main/train/Classify/Classify2.ipynb b/main/train/Classify/Classify2.ipynb
index 3ff5215..64f9506 100644
--- a/main/train/Classify/Classify2.ipynb
+++ b/main/train/Classify/Classify2.ipynb
@@ -5,11 +5,8 @@
"execution_count": 1,
"id": "79a7758178bafdd3",
"metadata": {
- "ExecuteTime": {
- "end_time": "2025-04-03T12:46:06.987506Z",
- "start_time": "2025-04-03T12:46:06.259551Z"
- },
"jupyter": {
+ "is_executing": true,
"source_hidden": true
}
},
@@ -18,18 +15,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "/mnt/d/PyProject/NewStock/main/train/Classify\n"
- ]
- },
- {
- "ename": "ModuleNotFoundError",
- "evalue": "No module named 'main.factor'; 'main' is not a package",
- "output_type": "error",
- "traceback": [
- "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
- "\u001b[31mModuleNotFoundError\u001b[39m Traceback (most recent call last)",
- "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 15\u001b[39m\n\u001b[32m 13\u001b[39m \u001b[38;5;28mprint\u001b[39m(os.getcwd())\n\u001b[32m 14\u001b[39m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mpandas\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mas\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mpd\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmain\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mfactor\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mfactor\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m get_rolling_factor, get_simple_factor\n\u001b[32m 16\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmain\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mutils\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mfactor\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m read_industry_data\n\u001b[32m 17\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmain\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mutils\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mfactor_processor\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m calculate_score\n",
- "\u001b[31mModuleNotFoundError\u001b[39m: No module named 'main.factor'; 'main' is not a package"
+ "/mnt/d/PyProject/NewStock\n"
]
}
],
@@ -46,6 +32,12 @@
"sys.path.append('/mnt/d/PyProject/NewStock/main/')\n",
"import sys\n",
"sys.path.append('/mnt/d/PyProject/NewStock/train')\n",
+ "import sys\n",
+ "sys.path.append('/mnt/d/PyProject/NewStock')\n",
+ "import sys\n",
+ "sys.path.append('/mnt/d/PyProject/NewStock/main')\n",
+ "import sys\n",
+ "sys.path.append('/mnt/d/PyProject/NewStock/train/')\n",
"print(os.getcwd())\n",
"import pandas as pd\n",
"from main.factor.factor import get_rolling_factor, get_simple_factor\n",
@@ -60,20 +52,10 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "4a481c60",
"metadata": {},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
+ "outputs": [],
"source": [
"# 设置使用核心\n",
"import os\n",
@@ -82,11 +64,11 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"id": "a79cafb06a7e0e43",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T12:47:00.212859Z",
+ "end_time": "2025-10-13T13:43:40.016626900Z",
"start_time": "2025-04-03T12:46:06.998047Z"
},
"scrolled": true
@@ -106,7 +88,7 @@
"cyq perf\n",
"left merge on ['ts_code', 'trade_date']\n",
"\n",
- "RangeIndex: 8820754 entries, 0 to 8820753\n",
+ "RangeIndex: 9162612 entries, 0 to 9162611\n",
"Data columns (total 33 columns):\n",
" # Column Dtype \n",
"--- ------ ----- \n",
@@ -144,18 +126,9 @@
" 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",
+ "memory usage: 2.2+ GB\n",
"None\n"
]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
}
],
"source": [
@@ -191,11 +164,11 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"id": "cac01788dac10678",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T12:47:10.527104Z",
+ "end_time": "2025-10-13T13:43:40.020945600Z",
"start_time": "2025-04-03T12:47:00.488715Z"
}
},
@@ -206,15 +179,6 @@
"text": [
"industry\n"
]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
}
],
"source": [
@@ -268,28 +232,18 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"id": "c4e9e1d31da6dba6",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T12:47:10.719252Z",
+ "end_time": "2025-10-13T13:43:40.021492400Z",
"start_time": "2025-04-03T12:47:10.541247Z"
},
"jupyter": {
"source_hidden": true
}
},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
+ "outputs": [],
"source": [
"from main.factor.factor import *\n",
"\n",
@@ -378,25 +332,15 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"id": "a735bc02ceb4d872",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T12:47:10.821169Z",
+ "end_time": "2025-10-13T13:43:40.021998300Z",
"start_time": "2025-04-03T12:47:10.751831Z"
}
},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
+ "outputs": [],
"source": [
"import talib\n",
"import numpy as np"
@@ -404,11 +348,11 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 7,
"id": "53f86ddc0677a6d7",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T12:47:15.944254Z",
+ "end_time": "2025-10-13T13:43:40.021998300Z",
"start_time": "2025-04-03T12:47:10.826179Z"
},
"jupyter": {
@@ -416,17 +360,7 @@
},
"scrolled": true
},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
+ "outputs": [],
"source": [
"from main.utils.factor import get_act_factor\n",
"\n",
@@ -481,11 +415,11 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 8,
"id": "dbe2fd8021b9417f",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T12:47:15.969344Z",
+ "end_time": "2025-10-13T13:43:40.055745300Z",
"start_time": "2025-04-03T12:47:15.963327Z"
}
},
@@ -496,15 +430,6 @@
"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"
]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
}
],
"source": [
@@ -518,25 +443,15 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 9,
"id": "85c3e3d0235ffffa",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T12:47:16.089879Z",
+ "end_time": "2025-10-13T13:43:40.056256100Z",
"start_time": "2025-04-03T12:47:15.990101Z"
}
},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
+ "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', 'roa', 'roe'],\n",
@@ -560,162 +475,19 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 10,
"id": "92d84ce15a562ec6",
"metadata": {
"ExecuteTime": {
- "end_time": "2025-04-03T13:08:01.612695Z",
+ "end_time": "2025-10-13T13:43:40.057271300Z",
"start_time": "2025-04-03T12:47:16.121802Z"
}
},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "使用 'ann_date' 作为财务数据生效日期。\n",
- "警告: 从 financial_data_subset 中移除了 366 行,因为其 'ts_code' 或 'ann_date' 列存在空值。\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",
- "使用 '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",
- " 'amount', 'pct_chg', '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', 'undist_profit_ps', 'ocfps', 'roa', 'roe',\n",
- " 'AR', 'BR', 'AR_BR', 'log_circ_mv', 'cashflow_to_ev_factor',\n",
- " 'book_to_price_ratio', 'turnover_rate_mean_5', 'variance_20',\n",
- " 'bbi_ratio_factor', 'daily_deviation', 'lg_elg_net_buy_vol',\n",
- " 'flow_lg_elg_intensity', 'sm_net_buy_vol', 'flow_divergence_diff',\n",
- " 'flow_divergence_ratio', 'total_buy_vol', 'lg_elg_buy_prop',\n",
- " 'flow_struct_buy_change', 'lg_elg_net_buy_vol_change',\n",
- " 'flow_lg_elg_accel', 'chip_concentration_range', 'chip_skewness',\n",
- " 'floating_chip_proxy', 'cost_support_15pct_change',\n",
- " 'cat_winner_price_zone', 'flow_chip_consistency',\n",
- " 'profit_taking_vs_absorb', '_is_positive', '_is_negative',\n",
- " 'cat_is_positive', '_pos_returns', '_neg_returns', '_pos_returns_sq',\n",
- " '_neg_returns_sq', 'upside_vol', 'downside_vol', 'vol_ratio',\n",
- " '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_14', 'atr_6', 'obv'],\n",
- " dtype='object')\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: 181 entries, ts_code to cs_rank_size\n",
- "dtypes: bool(10), datetime64[ns](1), float64(165), int64(3), object(2)\n",
- "memory usage: 5.8+ GB\n",
- "None\n",
- "['ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'vol', 'amount', 'pct_chg', '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', 'undist_profit_ps', 'ocfps', 'roa', 'roe', '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_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', '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', '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"
- ]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
+ "outputs": [],
"source": [
"\n",
"import numpy as np\n",
+ "import polars as pl\n",
"from main.factor.factor import *\n",
"from main.factor.money_factor import *\n",
"\n",
@@ -739,2100 +511,49 @@
"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",
- "\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 = holder_trade_factors(stk_holdertrade_df, 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",
- "df = add_financial_factor(df, fina_indicator_df, factor_value_col='roa')\n",
- "df = add_financial_factor(df, fina_indicator_df, factor_value_col='roe')\n",
- "\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",
- "\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 = 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())"
+ "df = pl.from_dataframe(df)"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "b87b938028afa206",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2025-04-03T13:08:03.658725Z",
- "start_time": "2025-04-03T13:08:02.469611Z"
- }
- },
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "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": null,
- "id": "f4f16d63ad18d1bc",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2025-04-03T13:08:03.670700Z",
- "start_time": "2025-04-03T13:08:03.665739Z"
- }
- },
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "import numpy as np\n",
- "import statsmodels.api as sm # 用于中性化回归\n",
- "from tqdm import tqdm # 可选,用于显示进度条\n",
- "\n",
- "# --- 常量 ---\n",
- "epsilon = 1e-10 # 防止除零\n",
- "\n",
- "# --- 1. 中位数去极值 (MAD) ---\n",
- "\n",
- "def cs_mad_filter(df: pd.DataFrame,\n",
- " features: list,\n",
- " k: float = 3.0,\n",
- " scale_factor: float = 1.4826):\n",
- " \"\"\"\n",
- " 对指定特征列进行截面 MAD 去极值处理 (原地修改)。\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 (pd.DataFrame): 输入 DataFrame,需包含 'trade_date' 和 features 列。\n",
- " features (list): 需要处理的特征列名列表。\n",
- " k (float): MAD 的倍数,用于确定边界。默认为 3.0。\n",
- " scale_factor (float): MAD 的缩放因子。默认为 1.4826。\n",
- "\n",
- " WARNING: 此函数会原地修改输入的 DataFrame 'df'。\n",
- " \"\"\"\n",
- " print(f\"开始截面 MAD 去极值处理 (k={k})...\")\n",
- " if not all(col in df.columns for col in features):\n",
- " missing = [col for col in features if col not in df.columns]\n",
- " print(f\"错误: DataFrame 中缺少以下特征列: {missing}。跳过去极值处理。\")\n",
- " return\n",
- "\n",
- " grouped = df.groupby('trade_date')\n",
- "\n",
- " for col in tqdm(features, desc=\"MAD Filtering\"):\n",
- " try:\n",
- " # 计算截面中位数\n",
- " median = grouped[col].transform('median')\n",
- " # 计算截面 MAD (Median Absolute Deviation from Median)\n",
- " mad = (df[col] - median).abs().groupby(df['trade_date']).transform('median')\n",
- "\n",
- " # 计算上下边界\n",
- " lower_bound = median - k * scale_factor * mad\n",
- " upper_bound = median + k * scale_factor * mad\n",
- "\n",
- " # 原地应用 clip\n",
- " df[col] = np.clip(df[col], lower_bound, upper_bound)\n",
- "\n",
- " except KeyError:\n",
- " print(f\"警告: 列 '{col}' 可能不存在或在分组中出错,跳过此列的 MAD 处理。\")\n",
- " except Exception as e:\n",
- " print(f\"警告: 处理列 '{col}' 时发生错误: {e},跳过此列的 MAD 处理。\")\n",
- "\n",
- " print(\"截面 MAD 去极值处理完成。\")\n",
- "\n",
- "\n",
- "# --- 2. 行业市值中性化 ---\n",
- "\n",
- "from tqdm import tqdm\n",
- "\n",
- "def cs_neutralize_market_cap_numpy(df: pd.DataFrame,\n",
- " features: list,\n",
- " market_cap_col: str = 'circ_mv'):\n",
- " \"\"\"\n",
- " 对 DataFrame 中的指定特征进行截面市值中性化 (NumPy 优化)。\n",
- "\n",
- " Args:\n",
- " df (pd.DataFrame): 包含数据的 DataFrame,需要有 'trade_date' 和 market_cap_col 列。\n",
- " features (list): 需要进行市值中性化的特征列名列表。\n",
- " market_cap_col (str): 包含市值数据的列名,默认为 'circ_mv'。\n",
- " \"\"\"\n",
- " print(\"开始截面市值中性化 (NumPy 优化)...\")\n",
- " required_cols = features + ['trade_date', 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",
- " df_copy = df\n",
- " log_cap_col = '_log_market_cap'\n",
- " df_copy[log_cap_col] = np.log1p(df_copy[market_cap_col])\n",
- "\n",
- " # 创建一个 DataFrame 来存储所有日期的残差结果\n",
- " residuals_container = pd.DataFrame(index=df_copy.index, columns=features, dtype=float)\n",
- "\n",
- " for date, group_df in tqdm(df_copy.groupby('trade_date'), desc=\"Neutralizing by Date (NumPy)\"):\n",
- " # 准备 X 矩阵 (自变量):常数项和对数市值\n",
- " X_daily = np.concatenate([np.ones((len(group_df), 1)), group_df[[log_cap_col]].values], axis=1)\n",
- "\n",
- " for feature_col in features:\n",
- " Y_daily = group_df[feature_col].values\n",
- "\n",
- " # 处理 NaN:只对有效数据对进行回归\n",
- " valid_mask_y = ~np.isnan(Y_daily)\n",
- " valid_mask_x = ~np.isnan(X_daily).any(axis=1)\n",
- " valid_mask = valid_mask_y & valid_mask_x\n",
- "\n",
- " current_feature_indices = group_df.index[valid_mask]\n",
- "\n",
- " if np.sum(valid_mask) < X_daily.shape[1] + 1:\n",
- " # 有效数据不足,此特征在此日期保持 NaN\n",
- " continue\n",
- "\n",
- " Y_valid = Y_daily[valid_mask]\n",
- " X_valid = X_daily[valid_mask, :]\n",
- "\n",
- " try:\n",
- " # 使用 np.linalg.lstsq 进行 OLS 计算\n",
- " beta, sum_sq_resid, rank, s = np.linalg.lstsq(X_valid, Y_valid, rcond=None)\n",
- "\n",
- " # 计算预测值 Y_hat = X_valid @ beta\n",
- " Y_hat_valid = X_valid @ beta\n",
- "\n",
- " # 计算残差 residuals = Y_valid - Y_hat_valid\n",
- " residuals_valid = Y_valid - Y_hat_valid\n",
- "\n",
- " # 将计算得到的残差放回 residuals_container\n",
- " residuals_container.loc[current_feature_indices, feature_col] = residuals_valid\n",
- "\n",
- " except np.linalg.LinAlgError:\n",
- " pass\n",
- " except Exception as e:\n",
- " pass\n",
- "\n",
- " # 将所有计算得到的残差更新回原始的 df (原地修改)\n",
- " for feature_col in features:\n",
- " df[feature_col] = residuals_container[feature_col]\n",
- "\n",
- " # 清理临时列\n",
- " df.drop(columns=[log_cap_col], inplace=True, errors='ignore')\n",
- " print(\"截面市值中性化完成 (NumPy 优化)。\")\n",
- "\n",
- "# --- 3. Z-Score 标准化 ---\n",
- "\n",
- "def cs_zscore_standardize(df: pd.DataFrame, features: list, epsilon: float = 1e-10):\n",
- " \"\"\"\n",
- " 对指定特征列进行截面 Z-Score 标准化 (原地修改)。\n",
- " 方法: Z = (value - cross_sectional_mean) / (cross_sectional_std + epsilon)\n",
- "\n",
- " Args:\n",
- " df (pd.DataFrame): 输入 DataFrame,需包含 'trade_date' 和 features 列。\n",
- " features (list): 需要处理的特征列名列表。\n",
- " epsilon (float): 防止除以零的小常数。\n",
- "\n",
- " WARNING: 此函数会原地修改输入的 DataFrame 'df'。\n",
- " \"\"\"\n",
- " print(\"开始截面 Z-Score 标准化...\")\n",
- " if not all(col in df.columns for col in features):\n",
- " missing = [col for col in features if col not in df.columns]\n",
- " print(f\"错误: DataFrame 中缺少以下特征列: {missing}。跳过标准化处理。\")\n",
- " return\n",
- "\n",
- " grouped = df.groupby('trade_date')\n",
- "\n",
- " for col in tqdm(features, desc=\"Standardizing\"):\n",
- " try:\n",
- " # 使用 transform 计算截面均值和标准差\n",
- " mean = grouped[col].transform('mean')\n",
- " std = grouped[col].transform('std')\n",
- "\n",
- " # 计算 Z-Score 并原地赋值\n",
- " df[col] = (df[col] - mean) / (std + epsilon)\n",
- "\n",
- " except KeyError:\n",
- " print(f\"警告: 列 '{col}' 可能不存在或在分组中出错,跳过此列的标准化处理。\")\n",
- " except Exception as e:\n",
- " print(f\"警告: 处理列 '{col}' 时发生错误: {e},跳过此列的标准化处理。\")\n",
- "\n",
- " print(\"截面 Z-Score 标准化完成。\")\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": null,
- "id": "40e6b68a91b30c79",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2025-04-03T13:08:04.694262Z",
- "start_time": "2025-04-03T13:08:03.694904Z"
- }
- },
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "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",
- "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": null,
- "id": "47c12bb34062ae7a",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2025-04-03T14:57:50.841165Z",
- "start_time": "2025-04-03T14:49:25.889057Z"
- }
- },
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "days = 5\n",
- "validation_days = 120\n",
- "\n",
- "import gc\n",
- "\n",
- "gc.collect()\n",
- "\n",
- "df = df.sort_values(by=['ts_code', 'trade_date'])\n",
- "df['future_return'] = df.groupby('ts_code', group_keys=False)['close'].apply(lambda x: x.shift(-days) / x - 1)\n",
- "# df['future_return'] = (df.groupby('ts_code')['close'].shift(-days) - df.groupby('ts_code')['open'].shift(-1)) / \\\n",
- "# df.groupby('ts_code')['open'].shift(-1)\n",
- "\n",
- "df['cat_up_limit'] = df['pct_chg'] > 5\n",
- "df['label'] = df.groupby('ts_code')['cat_up_limit'].rolling(window=5, min_periods=1).max().groupby('ts_code').shift(-5).fillna(0).astype(int).reset_index(level=0, drop=True)\n",
- "\n",
- "filter_index = df['future_return'].between(df['future_return'].quantile(0.01), df['future_return'].quantile(0.99))\n",
- "\n",
- "# for col in [col for col in df.columns]:\n",
- "# train_data[col] = train_data[col].astype('str')\n",
- "# test_data[col] = test_data[col].astype('str')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "29221dde",
+ "id": "a2b3d9e6",
"metadata": {},
"outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "191\n"
- ]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "feature_columns = [col for col in df.head(10).merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left').merge(index_data, on='trade_date', how='left').columns]\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 ['roa', 'roe']]\n",
- "print(len(feature_columns))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "03ee5daf",
- "metadata": {},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "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",
- " # median_val = df[feature_col].median()\n",
- " df[feature_col].fillna(0, inplace=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "b76ea08a",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " ts_code trade_date log_circ_mv\n",
- "0 000001.SZ 2019-01-02 16.574219\n",
- "1 000001.SZ 2019-01-03 16.583965\n",
- "2 000001.SZ 2019-01-04 16.633371\n",
- "['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'winner_rate', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', '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', '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', 'cat_up_limit', '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%|██████████| 131/131 [00:15<00:00, 8.53it/s]\n"
+ "Applying momentum factors: 0%| | 0/10 [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: 100%|██████████| 131/131 [00:11<00:00, 11.23it/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",
- "开始截面 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', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', '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', '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', 'cat_up_limit', '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",
- "2057465\n",
- "train_data最小日期: 2020-01-02\n",
- "train_data最大日期: 2022-12-30\n",
- "1781706\n",
- "test_data最小日期: 2023-01-03\n",
- "test_data最大日期: 2025-05-30\n",
- " ts_code trade_date log_circ_mv\n",
- "0 000001.SZ 2019-01-02 16.574219\n",
- "1 000001.SZ 2019-01-03 16.583965\n",
- "2 000001.SZ 2019-01-04 16.633371\n"
- ]
- },
- {
- "ename": "",
- "evalue": "",
+ "ename": "DuplicateError",
+ "evalue": "column with name 'price_minus_deduction_price_10_right' already exists\n\nYou may want to try:\n- renaming the column prior to joining\n- using the `suffix` parameter to specify a suffix different to the default one ('_right')",
"output_type": "error",
"traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
+ "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
+ "\u001b[31mDuplicateError\u001b[39m Traceback (most recent call last)",
+ "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[14]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmain\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mfactor\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mpolars_momentum_factors\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m apply_momentum_factors\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m df = \u001b[43mapply_momentum_factors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdf\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 6\u001b[39m \u001b[38;5;28mprint\u001b[39m(df.columns)\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/PyProject/NewStock/main/factor/polars_momentum_factors.py:408\u001b[39m, in \u001b[36mapply_momentum_factors\u001b[39m\u001b[34m(df, operators)\u001b[39m\n\u001b[32m 406\u001b[39m result_df = df\n\u001b[32m 407\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m operator \u001b[38;5;129;01min\u001b[39;00m tqdm(operators, desc=\u001b[33m\"\u001b[39m\u001b[33mApplying momentum factors\u001b[39m\u001b[33m\"\u001b[39m):\n\u001b[32m--> \u001b[39m\u001b[32m408\u001b[39m result_df = \u001b[43moperator\u001b[49m\u001b[43m.\u001b[49m\u001b[43mapply\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult_df\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 410\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result_df\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/PyProject/NewStock/main/factor/operator_framework.py:58\u001b[39m, in \u001b[36mBaseOperator.apply\u001b[39m\u001b[34m(self, df, return_type, **kwargs)\u001b[39m\n\u001b[32m 55\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33m缺少必需列:\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m.required_columns\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 57\u001b[39m long_table = \u001b[38;5;28mself\u001b[39m._sectional_roll(df, **kwargs) \u001b[38;5;66;03m# ① 滚动\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m58\u001b[39m merged = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_merge_factor\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlong_table\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# ② 合并\u001b[39;00m\n\u001b[32m 59\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m merged \u001b[38;5;28;01mif\u001b[39;00m return_type == \u001b[33m'\u001b[39m\u001b[33mdf\u001b[39m\u001b[33m'\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m merged[\u001b[38;5;28mself\u001b[39m.get_factor_name()]\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/PyProject/NewStock/main/factor/operator_framework.py:76\u001b[39m, in \u001b[36mBaseOperator._merge_factor\u001b[39m\u001b[34m(self, original, factor_table)\u001b[39m\n\u001b[32m 74\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"按 [ts_code, trade_date] 左联,原地追加因子列\"\"\"\u001b[39;00m\n\u001b[32m 75\u001b[39m factor_name = \u001b[38;5;28mself\u001b[39m.get_factor_name()\n\u001b[32m---> \u001b[39m\u001b[32m76\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43moriginal\u001b[49m\u001b[43m.\u001b[49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfactor_table\u001b[49m\u001b[43m.\u001b[49m\u001b[43mselect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mts_code\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\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[43mfactor_name\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 77\u001b[39m \u001b[43m \u001b[49m\u001b[43mon\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mts_code\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\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\n\u001b[32m 78\u001b[39m \u001b[43m \u001b[49m\u001b[43mhow\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mleft\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/polars/_utils/deprecation.py:128\u001b[39m, in \u001b[36mdeprecate_renamed_parameter..decorate..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 123\u001b[39m \u001b[38;5;129m@wraps\u001b[39m(function)\n\u001b[32m 124\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mwrapper\u001b[39m(*args: P.args, **kwargs: P.kwargs) -> T:\n\u001b[32m 125\u001b[39m _rename_keyword_argument(\n\u001b[32m 126\u001b[39m old_name, new_name, kwargs, function.\u001b[34m__qualname__\u001b[39m, version\n\u001b[32m 127\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m128\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunction\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\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[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/polars/dataframe/frame.py:7842\u001b[39m, in \u001b[36mDataFrame.join\u001b[39m\u001b[34m(self, other, on, how, left_on, right_on, suffix, validate, nulls_equal, coalesce, maintain_order)\u001b[39m\n\u001b[32m 7824\u001b[39m require_same_type(\u001b[38;5;28mself\u001b[39m, other)\n\u001b[32m 7826\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mpolars\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mlazyframe\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mopt_flags\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m QueryOptFlags\n\u001b[32m 7828\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m (\n\u001b[32m 7829\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlazy\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 7830\u001b[39m \u001b[43m \u001b[49m\u001b[43m.\u001b[49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 7831\u001b[39m \u001b[43m \u001b[49m\u001b[43mother\u001b[49m\u001b[43m=\u001b[49m\u001b[43mother\u001b[49m\u001b[43m.\u001b[49m\u001b[43mlazy\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7832\u001b[39m \u001b[43m \u001b[49m\u001b[43mleft_on\u001b[49m\u001b[43m=\u001b[49m\u001b[43mleft_on\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7833\u001b[39m \u001b[43m \u001b[49m\u001b[43mright_on\u001b[49m\u001b[43m=\u001b[49m\u001b[43mright_on\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7834\u001b[39m \u001b[43m \u001b[49m\u001b[43mon\u001b[49m\u001b[43m=\u001b[49m\u001b[43mon\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7835\u001b[39m \u001b[43m \u001b[49m\u001b[43mhow\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhow\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7836\u001b[39m \u001b[43m \u001b[49m\u001b[43msuffix\u001b[49m\u001b[43m=\u001b[49m\u001b[43msuffix\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7837\u001b[39m \u001b[43m \u001b[49m\u001b[43mvalidate\u001b[49m\u001b[43m=\u001b[49m\u001b[43mvalidate\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7838\u001b[39m \u001b[43m \u001b[49m\u001b[43mnulls_equal\u001b[49m\u001b[43m=\u001b[49m\u001b[43mnulls_equal\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7839\u001b[39m \u001b[43m \u001b[49m\u001b[43mcoalesce\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcoalesce\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7840\u001b[39m \u001b[43m \u001b[49m\u001b[43mmaintain_order\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmaintain_order\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7841\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m-> \u001b[39m\u001b[32m7842\u001b[39m \u001b[43m \u001b[49m\u001b[43m.\u001b[49m\u001b[43mcollect\u001b[49m\u001b[43m(\u001b[49m\u001b[43moptimizations\u001b[49m\u001b[43m=\u001b[49m\u001b[43mQueryOptFlags\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_eager\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 7843\u001b[39m )\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/polars/_utils/deprecation.py:97\u001b[39m, in \u001b[36mdeprecate_streaming_parameter..decorate..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 93\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mengine\u001b[39m\u001b[33m\"\u001b[39m] = \u001b[33m\"\u001b[39m\u001b[33min-memory\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 95\u001b[39m \u001b[38;5;28;01mdel\u001b[39;00m kwargs[\u001b[33m\"\u001b[39m\u001b[33mstreaming\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m---> \u001b[39m\u001b[32m97\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunction\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\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[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/polars/lazyframe/opt_flags.py:331\u001b[39m, in \u001b[36mforward_old_opt_flags..decorate..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 328\u001b[39m optflags = cb(optflags, kwargs.pop(key)) \u001b[38;5;66;03m# type: ignore[no-untyped-call,unused-ignore]\u001b[39;00m\n\u001b[32m 330\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33moptimizations\u001b[39m\u001b[33m\"\u001b[39m] = optflags\n\u001b[32m--> \u001b[39m\u001b[32m331\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunction\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\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[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/polars/lazyframe/frame.py:2300\u001b[39m, in \u001b[36mLazyFrame.collect\u001b[39m\u001b[34m(self, type_coercion, predicate_pushdown, projection_pushdown, simplify_expression, slice_pushdown, comm_subplan_elim, comm_subexpr_elim, cluster_with_columns, collapse_joins, no_optimization, engine, background, optimizations, **_kwargs)\u001b[39m\n\u001b[32m 2298\u001b[39m \u001b[38;5;66;03m# Only for testing purposes\u001b[39;00m\n\u001b[32m 2299\u001b[39m callback = _kwargs.get(\u001b[33m\"\u001b[39m\u001b[33mpost_opt_callback\u001b[39m\u001b[33m\"\u001b[39m, callback)\n\u001b[32m-> \u001b[39m\u001b[32m2300\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m wrap_df(\u001b[43mldf\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcollect\u001b[49m\u001b[43m(\u001b[49m\u001b[43mengine\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallback\u001b[49m\u001b[43m)\u001b[49m)\n",
+ "\u001b[31mDuplicateError\u001b[39m: column with name 'price_minus_deduction_price_10_right' already exists\n\nYou may want to try:\n- renaming the column prior to joining\n- using the `suffix` parameter to specify a suffix different to the default one ('_right')"
]
}
],
"source": [
- "split_date = '2023-01-01'\n",
- "train_data = df[filter_index & (df['trade_date'] <= split_date) & (df['trade_date'] >= '2020-01-01')]\n",
- "test_data = df[(df['trade_date'] >= split_date)]\n",
+ "from main.factor.polars_momentum_factors import apply_momentum_factors\n",
"\n",
- "print(df[['ts_code', 'trade_date', 'log_circ_mv']].head(3))\n",
"\n",
- "industry_df = industry_df.sort_values(by=['trade_date'])\n",
- "index_data = index_data.sort_values(by=['trade_date'])\n",
+ "df = apply_momentum_factors(df)\n",
"\n",
- "# train_data = train_data.merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left')\n",
- "# train_data = train_data.merge(index_data, on='trade_date', how='left')\n",
- "# test_data = test_data.merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left')\n",
- "# test_data = test_data.merge(index_data, on='trade_date', how='left')\n",
- "\n",
- "train_data, test_data = train_data.replace([np.inf, -np.inf], np.nan), test_data.replace([np.inf, -np.inf], np.nan)\n",
- "\n",
- "# feature_columns_new = feature_columns[:]\n",
- "# train_data, _ = create_deviation_within_dates(train_data, [col for col in feature_columns if col in train_data.columns])\n",
- "# test_data, _ = create_deviation_within_dates(test_data, [col for col in feature_columns if col in train_data.columns])\n",
- "\n",
- "# feature_columns = [\n",
- "# 'undist_profit_ps', \n",
- "# 'AR_BR',\n",
- "# 'pe_ttm',\n",
- "# 'alpha_22_improved', \n",
- "# 'alpha_003', \n",
- "# 'alpha_007', \n",
- "# 'alpha_013', \n",
- "# 'cat_up_limit', \n",
- "# 'cat_down_limit', \n",
- "# 'up_limit_count_10d', \n",
- "# 'down_limit_count_10d', \n",
- "# 'consecutive_up_limit', \n",
- "# 'vol_break', \n",
- "# 'weight_roc5', \n",
- "# 'price_cost_divergence', \n",
- "# 'smallcap_concentration', \n",
- "# 'cost_stability', \n",
- "# 'high_cost_break_days', \n",
- "# 'liquidity_risk', \n",
- "# 'turnover_std', \n",
- "# 'mv_volatility', \n",
- "# 'volume_growth', \n",
- "# 'mv_growth', \n",
- "# 'lg_flow_mom_corr_20_60', \n",
- "# 'lg_flow_accel', \n",
- "# 'profit_pressure', \n",
- "# 'underwater_resistance', \n",
- "# 'cost_conc_std_20', \n",
- "# 'profit_decay_20', \n",
- "# 'vol_amp_loss_20', \n",
- "# 'vol_drop_profit_cnt_5', \n",
- "# 'lg_flow_vol_interact_20', \n",
- "# 'cost_break_confirm_cnt_5', \n",
- "# 'atr_norm_channel_pos_14', \n",
- "# 'turnover_diff_skew_20', \n",
- "# 'lg_sm_flow_diverge_20', \n",
- "# 'pullback_strong_20_20', \n",
- "# 'vol_wgt_hist_pos_20', \n",
- "# 'vol_adj_roc_20',\n",
- "# 'cashflow_to_ev_factor',\n",
- "# 'ocfps',\n",
- "# 'book_to_price_ratio',\n",
- "# 'turnover_rate_mean_5',\n",
- "# 'variance_20',\n",
- "# 'bbi_ratio_factor'\n",
- "# ]\n",
- "# feature_columns = [col for col in feature_columns if col in train_data.columns]\n",
- "# feature_columns = [col for col in feature_columns if not col.startswith('_')]\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",
- "# feature_columns = select_top_features_by_rankic(df, numeric_columns, n=10)\n",
- "print(feature_columns)\n",
- "\n",
- "# train_data = fill_nan_with_daily_median(train_data, feature_columns)\n",
- "# test_data = fill_nan_with_daily_median(test_data, feature_columns)\n",
- "\n",
- "train_data = train_data.dropna(subset=[col for col in feature_columns if col in train_data.columns])\n",
- "train_data = train_data.dropna(subset=['label'])\n",
- "train_data = train_data.reset_index(drop=True)\n",
- "# print(test_data.tail())\n",
- "test_data = test_data.dropna(subset=[col for col in feature_columns if col in train_data.columns])\n",
- "# test_data = test_data.dropna(subset=['label'])\n",
- "test_data = test_data.reset_index(drop=True)\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",
- "cs_mad_filter(train_data, transform_feature_columns)\n",
- "# print('中性化')\n",
- "# cs_neutralize_market_cap_numpy(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_neutralize_market_cap_numpy(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": null,
- "id": "3ff2d1c5",
- "metadata": {},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "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 datetime # 用于日期计算\n",
- "from catboost import CatBoostClassifier\n",
- "from catboost import Pool\n",
- "import lightgbm as lgb\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",
- " numeric_feature_columns = train_data_df[feature_columns].select_dtypes(include=['float64', 'int64']).columns.tolist()\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",
- " 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['label']\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': 'Logloss', # 适用于二分类\n",
- " 'eval_metric': 'Logloss', # 评估指标\n",
- " 'iterations': 1500,\n",
- " 'learning_rate': 0.01,\n",
- " 'depth': 10, # 控制模型复杂度\n",
- " 'l2_leaf_reg': 50, # L2 正则化\n",
- " 'verbose': 5000,\n",
- " 'early_stopping_rounds': 300,\n",
- " # 'od_type': 'Iter', # Overfitting detector type\n",
- " # 'od_wait': 300, # Number of iterations to wait after the bes\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",
- " train_pool = Pool(data=X_train, label=y_train, cat_features=cat_features)\n",
- " val_pool = Pool(data=X_val, label=y_val, cat_features=cat_features)\n",
- "\n",
- "\n",
- " model = CatBoostClassifier(**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",
- " params = {\n",
- " 'objective': 'binary',\n",
- " 'metric': 'average_precision',\n",
- " 'learning_rate': 0.01,\n",
- " 'is_unbalance': True,\n",
- " 'num_leaves': 2048,\n",
- " 'min_data_in_leaf': 1024,\n",
- " 'max_depth': 32,\n",
- " 'max_bin': 1024,\n",
- " 'feature_fraction': 0.5,\n",
- " 'bagging_fraction': 0.5,\n",
- " 'bagging_freq': 1,\n",
- " 'lambda_l1': 50,\n",
- " 'lambda_l2': 50,\n",
- " 'verbosity': -1,\n",
- " 'num_threads' : 8\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",
- " categorical_feature=categorical_feature\n",
- " )\n",
- " val_dataset = lgb.Dataset(\n",
- " X_val, label=y_val,\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(100, first_metric_only=True)\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",
- "\n",
- " return model, scaler, None # 返回训练好的模型、scaler 和 pca 对象"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "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": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "train data size: 36400\n",
- " ts_code trade_date log_circ_mv\n",
- "0 600306.SH 2020-01-02 11.552040\n",
- "1 603269.SH 2020-01-02 11.324801\n",
- "2 002633.SZ 2020-01-02 11.759023\n",
- "3 603991.SH 2020-01-02 11.181150\n",
- "4 000691.SZ 2020-01-02 11.677910\n",
- "... ... ... ...\n",
- "36395 600615.SH 2022-12-30 12.027909\n",
- "36396 603829.SH 2022-12-30 12.034572\n",
- "36397 603037.SH 2022-12-30 12.035767\n",
- "36398 002767.SZ 2022-12-30 11.896427\n",
- "36399 600561.SH 2022-12-30 11.858571\n",
- "\n",
- "[36400 rows x 3 columns]\n",
- "原始样本数: 36400, 去除标签为空后样本数: 36400\n"
- ]
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "9de2338da1fc42ec952054f233070da7",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "MetricVisualizer(layout=Layout(align_self='stretch', height='500px'))"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0:\tlearn: 0.6890148\ttest: 0.6905107\tbest: 0.6905107 (0)\ttotal: 92.5ms\tremaining: 2m 18s\n",
- "bestTest = 0.5221693203\n",
- "bestIteration = 874\n",
- "Shrink model to first 875 iterations.\n"
- ]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "\n",
- "gc.collect()\n",
- "\n",
- "use_pca = False\n",
- "type = 'cat'\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\n",
- " .dropna(subset=['label']).groupby('trade_date', group_keys=False)\n",
- " .apply(lambda x: x.nsmallest(50, 'total_mv'))\n",
- " .merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left')\n",
- " .merge(index_data, on='trade_date', how='left'), feature_columns, type=type)\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": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "score_df = test_data.groupby('trade_date', group_keys=False).apply(lambda x: x.nsmallest(300, '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",
- "# score_df.loc[:, numeric_columns] = scaler.transform(score_df[numeric_columns])\n",
- "# score_df = cross_sectional_standardization(score_df, numeric_columns)\n",
- "\n",
- "if type == 'cat':\n",
- " score_df['score'] = model.predict_proba(score_df[feature_columns])[:, 1]\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: x[x['score'] >= x['score'].quantile(0.90)] # 计算90%分位数作为阈值,筛选分数>=阈值的行\n",
- ").reset_index(drop=True) # drop=True 避免添加旧索引列\n",
- "# save_df = score_df.groupby('trade_date', group_keys=False).apply(lambda x: x.nlargest(1, '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": "c1c40917",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "模型已保存到: /mnt/d/PyProject/NewStock/main/train/catboost_model/catboost_model_2025-06-01.cbm\n"
- ]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "current_date = datetime.datetime.now()\n",
- "\n",
- "# 2. 格式化日期为字符串,例如 '2025-07-06'\n",
- "# 你可以根据需要调整日期格式,例如 '%Y%m%d' 会得到 '20250706'\n",
- "date_str = current_date.strftime('%Y-%m-%d')\n",
- "\n",
- "# 3. 构建包含日期的模型文件名\n",
- "model_filename = f'/mnt/d/PyProject/NewStock/main/train/catboost_model/catboost_model_2025-06-01.cbm'\n",
- "\n",
- "model.save_model(model_filename)\n",
- "print(f\"模型已保存到: {model_filename}\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "09b1799e",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "191\n",
- "['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'winner_rate', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', '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', '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', 'cat_up_limit', '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"
- ]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "print(len(feature_columns))\n",
- "print(feature_columns)\n",
- "print([col for col in feature_columns if 'total_mv' in col])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "e53b209a",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "5595 2057465\n",
- " ts_code trade_date turnover_rate\n",
- "0 000001.SZ 2023-01-03 1.1307\n",
- "1 000001.SZ 2023-01-04 1.1284\n",
- "2 000001.SZ 2023-01-05 0.8582\n",
- "3 000001.SZ 2023-01-06 0.6162\n",
- "4 000001.SZ 2023-01-09 0.5450\n",
- "... ... ... ...\n",
- "1781701 605599.SH 2025-05-26 0.6188\n",
- "1781702 605599.SH 2025-05-27 1.2576\n",
- "1781703 605599.SH 2025-05-28 2.0432\n",
- "1781704 605599.SH 2025-05-29 2.0954\n",
- "1781705 605599.SH 2025-05-30 1.4392\n",
- "\n",
- "[1781706 rows x 3 columns]\n"
- ]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "print(len(train_data[train_data['pct_chg'] > 7]), len(train_data))\n",
- "print(test_data[['ts_code', 'trade_date', 'turnover_rate']])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "364e821a",
- "metadata": {},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, roc_curve\n",
- "import matplotlib.pyplot as plt\n",
- "import numpy as np\n",
- "\n",
- "def calculate_binary_classification_metrics(df: pd.DataFrame, score_col: str, label_col: str, future_return_col: str = None, total_mv_col: str = None, n_mv_bins: int = 10, threshold: float = 0.5):\n",
- " \"\"\"\n",
- " 计算二分类模型的评估指标,可选择计算 score 和 future_return 的相关性,\n",
- " 并可选择计算 score 在按总市值 (total_mv) 分为 n 份后的每个分组上的预测性能(ROC AUC)。\n",
- "\n",
- " Args:\n",
- " df: 包含 score (预测概率或置信度), label (真实二分类标签), 可选的 future_return 和 total_mv 的 Pandas DataFrame。\n",
- " score_col: 包含模型预测 score 的列名。\n",
- " label_col: 包含真实二分类标签 (0 或 1) 的列名。\n",
- " future_return_col: (可选) 包含未来收益率的列名,用于计算相关性。\n",
- " total_mv_col: (可选) 包含总市值的列名,用于按市值分 n 份分析预测性能。\n",
- " n_mv_bins: (可选) 将总市值分为多少份,默认为 5。\n",
- " threshold: 将 score 转换为预测类别的阈值,默认为 0.5。\n",
- "\n",
- " Returns:\n",
- " 一个包含以下评估指标的字典:\n",
- " - accuracy: 准确率\n",
- " - precision: 精确率\n",
- " - recall: 召回率\n",
- " - f1: F1 分数\n",
- " - roc_auc: ROC AUC 值\n",
- " - fpr: ROC 曲线的假正率 (False Positive Rate)\n",
- " - tpr: ROC 曲线的真正率 (True Positive Rate)\n",
- " - thresholds: ROC 曲线的阈值\n",
- " - score_return_correlation: (如果 future_return_col 提供) score 和 future_return 的皮尔逊相关系数\n",
- " - mv_roc_auc: (如果 total_mv_col 提供) 一个字典,包含按总市值分为 n 份后的每个市值分组对应的 ROC AUC 值\n",
- " \"\"\"\n",
- " y_true = df[label_col].values\n",
- " y_score = df[score_col].values\n",
- " y_pred = (y_score >= threshold).astype(int)\n",
- "\n",
- " metrics = {}\n",
- " metrics['accuracy'] = accuracy_score(y_true, y_pred)\n",
- " metrics['precision'] = precision_score(y_true, y_pred)\n",
- " metrics['recall'] = recall_score(y_true, y_pred)\n",
- " metrics['f1'] = f1_score(y_true, y_pred)\n",
- " metrics['roc_auc'] = roc_auc_score(y_true, y_score)\n",
- " metrics['fpr'], metrics['tpr'], metrics['thresholds'] = roc_curve(y_true, y_score)\n",
- "\n",
- " if future_return_col in df.columns:\n",
- " metrics['score_return_correlation'] = df[score_col].corr(df[future_return_col])\n",
- "\n",
- " if total_mv_col in df.columns and n_mv_bins > 1:\n",
- " metrics['mv_roc_auc'] = {}\n",
- " df['mv_quantile'] = pd.cut(df[total_mv_col], bins=n_mv_bins, labels=False, duplicates='drop')\n",
- " for i in range(df['mv_quantile'].nunique()):\n",
- " mv_group = df[df['mv_quantile'] == i]\n",
- " if len(mv_group) > 0 and len(np.unique(mv_group[label_col])) > 1 and len(np.unique(mv_group[score_col])) > 1:\n",
- " roc_auc_mv = roc_auc_score(mv_group[label_col], mv_group[score_col])\n",
- " lower_bound = df[total_mv_col][df['mv_quantile'] == i].min()\n",
- " upper_bound = df[total_mv_col][df['mv_quantile'] == i].max()\n",
- " metrics['mv_roc_auc'][f'{lower_bound:.0e}-{upper_bound:.0e}'] = roc_auc_mv\n",
- " else:\n",
- " lower_bound = df[total_mv_col][df['mv_quantile'] == i].min()\n",
- " upper_bound = df[total_mv_col][df['mv_quantile'] == i].max()\n",
- " metrics['mv_roc_auc'][f'{lower_bound:.0e}-{upper_bound:.0e}'] = np.nan\n",
- " print(f'{lower_bound:.0e}-{upper_bound:.0e}')\n",
- " df.drop(columns=['mv_quantile'], inplace=True)\n",
- "\n",
- " return metrics\n",
- "\n",
- "def plot_roc_curve(metrics: dict):\n",
- " plt.figure(figsize=(8, 6))\n",
- " plt.plot(metrics['fpr'], metrics['tpr'], color='darkorange', lw=2, label=f'ROC curve (AUC = {metrics[\"roc_auc\"]:.2f})')\n",
- " plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')\n",
- " plt.xlabel('False Positive Rate')\n",
- " plt.ylabel('True Positive Rate')\n",
- " plt.title('Receiver Operating Characteristic (ROC)')\n",
- " plt.legend(loc=\"lower right\")\n",
- " plt.grid(True)\n",
- " plt.show()\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "1f6e6336",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "6e+04-9e+04\n",
- "9e+04-1e+05\n",
- "1e+05-1e+05\n",
- "1e+05-1e+05\n",
- "1e+05-2e+05\n",
- "2e+05-2e+05\n",
- "2e+05-2e+05\n",
- "2e+05-2e+05\n",
- "2e+05-3e+05\n",
- "3e+05-3e+05\n",
- "二分类评估指标:\n",
- "accuracy: 0.6449\n",
- "precision: 0.4384\n",
- "recall: 0.2532\n",
- "f1: 0.3210\n",
- "roc_auc: 0.6147\n",
- "fpr: (array of length 7456)\n",
- "tpr: (array of length 7456)\n",
- "thresholds: (array of length 7456)\n",
- "score_return_correlation: -0.0356\n",
- "mv_roc_auc: {'6e+04-9e+04': np.float64(0.5291280148423005), '9e+04-1e+05': np.float64(0.5695028952947505), '1e+05-1e+05': np.float64(0.5623844792554237), '1e+05-2e+05': np.float64(0.5622699726201068), '2e+05-2e+05': np.float64(0.6035659704533877), '2e+05-3e+05': np.float64(0.6119956359669062), '3e+05-3e+05': np.float64(0.5959528412973004)}\n"
- ]
- },
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "\n",
- "for sd in [\n",
- " # save_df1, \n",
- " # save_df2, \n",
- " score_df\n",
- " ]:\n",
- " # 计算二分类指标\n",
- " evaluation_metrics = calculate_binary_classification_metrics(sd, score_col='score', label_col='label', threshold=0.6,\n",
- " future_return_col='future_return', total_mv_col='total_mv')\n",
- "\n",
- " # 打印指标\n",
- " print(\"二分类评估指标:\")\n",
- " for metric, value in evaluation_metrics.items():\n",
- " if isinstance(value, (float, int)):\n",
- " print(f\"{metric}: {value:.4f}\")\n",
- " elif isinstance(value, (list, tuple, np.ndarray)):\n",
- " print(f\"{metric}: (array of length {len(value)})\")\n",
- " else:\n",
- " print(f\"{metric}: {value}\")\n",
- "\n",
- " # 绘制 ROC 曲线\n",
- " plot_roc_curve(evaluation_metrics)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "7e9023cc",
- "metadata": {},
- "outputs": [
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "def analyze_factors(\n",
- " df: pd.DataFrame,\n",
- " feature_columns: list[str],\n",
- " target_column: str = 'target', # 假设目标列默认为 'target'\n",
- " trade_date_col: str = 'trade_date', # 假设日期列默认为 'trade_date'\n",
- " mcap_col: str = 'total_mv', # 新增: 市值列名称\n",
- " mcap_bins: int = 5 # 新增: 市值分位数的数量 (例如 5 表示五分位数)\n",
- ") -> pd.DataFrame:\n",
- " \"\"\"\n",
- " 分析DataFrame中指定特征列的各种指标,包括基本统计、相关性、日间IC、ICIR以及在不同市值分位数上的IC。\n",
- "\n",
- " Args:\n",
- " df (pd.DataFrame): 包含日期、目标列、特征列和市值列的DataFrame。\n",
- " 需要包含 trade_date_col, target_column, feature_columns 和 mcap_col 中的所有列。\n",
- " feature_columns (list[str]): 需要分析的特征列名称列表。\n",
- " target_column (str): 目标变量列的名称。\n",
- " trade_date_col (str): 交易日期列的名称。\n",
- " mcap_col (str): 市值列的名称。\n",
- " mcap_bins (int): 市值分位数的数量 (例如 5 表示五分位数)。\n",
- "\n",
- " Returns:\n",
- " pd.DataFrame: 包含各个因子分析指标的汇总DataFrame。\n",
- " 同时打印因子在不同市值分位数上的平均IC表格。\n",
- " 如果输入数据或列有问题,可能返回空或包含NaN的DataFrame。\n",
- " \"\"\"\n",
- "\n",
- " # --- 数据校验 ---\n",
- " required_cols = [trade_date_col, target_column, mcap_col] + feature_columns\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 pd.DataFrame() # 返回空DataFrame\n",
- "\n",
- " # 确保日期列是 datetime 类型\n",
- " df = df.copy() # 在副本上操作\n",
- " df[trade_date_col] = pd.to_datetime(df[trade_date_col], errors='coerce')\n",
- " df.dropna(subset=[trade_date_col], inplace=True) # 移除日期转换失败的行\n",
- "\n",
- " # 过滤掉那些在 feature_columns, target_column, mcap_col 上有 NaN 的行,以确保后续计算是在完整数据上\n",
- " # 直接在 df 副本上进行清洗\n",
- " initial_rows_before_clean = len(df)\n",
- " df.dropna(subset=feature_columns + [target_column, mcap_col], inplace=True)\n",
- " rows_dropped_clean = initial_rows_before_clean - len(df)\n",
- " if rows_dropped_clean > 0:\n",
- " print(f\"警告: 移除了 {rows_dropped_clean} 行,因为其特征、目标或市值列存在空值。\")\n",
- "\n",
- " if df.empty:\n",
- " print(\"错误: 清理缺失值后数据为空,无法进行因子分析。\")\n",
- " return pd.DataFrame() # 返回空DataFrame\n",
- "\n",
- "\n",
- " print(f\"开始分析 {len(feature_columns)} 个因子指标...\")\n",
- "\n",
- " # --- 1. 基本因子统计量 ---\n",
- " basic_stats = df[feature_columns].describe().T\n",
- "\n",
- " print(\"\\n--- 基本因子统计量 ---\")\n",
- " print(basic_stats)\n",
- "\n",
- " # --- 2. 因子与目标变量的整体相关性 ---\n",
- " overall_correlation = {}\n",
- " for feature in feature_columns:\n",
- " # 在清理后的 df 上计算相关性\n",
- " if df[[feature, target_column]].dropna().shape[0] > 1: # 确保至少有两个有效数据点\n",
- " overall_correlation[feature] = {\n",
- " 'Pearson_Correlation_with_Target': df[feature].corr(df[target_column], method='pearson'),\n",
- " 'Spearman_Correlation_with_Target': df[feature].corr(df[target_column], method='spearman')\n",
- " }\n",
- " else:\n",
- " overall_correlation[feature] = {\n",
- " 'Pearson_Correlation_with_Target': np.nan,\n",
- " 'Spearman_Correlation_with_Target': np.nan\n",
- " }\n",
- " overall_corr_df = pd.DataFrame.from_dict(overall_correlation, orient='index')\n",
- "\n",
- " print(\"\\n--- 因子与目标变量的整体相关性 ---\")\n",
- " print(overall_corr_df)\n",
- "\n",
- " # --- 3. 因子之间的相关性矩阵 ---\n",
- " # 在清理后的 df 上计算相关性\n",
- " factor_correlation_matrix = df[feature_columns].corr(method='spearman') # 改回 Spearman\n",
- "\n",
- " print(\"\\n--- 因子之间的相关性矩阵 (Spearman) ---\") # 修正打印信息\n",
- " print(factor_correlation_matrix)\n",
- "\n",
- " # --- 4. 日间 IC 和 ICIR ---\n",
- " print(\"\\n--- 计算日间 IC (Spearman 相关性) 和 ICIR ---\")\n",
- "\n",
- " # 直接在清理后的 df 上计算每日 IC\n",
- " if df.empty: # 理论上上面已经检查过,这里再检查一次更安全\n",
- " daily_ic_series = pd.Series(dtype=float) # 空 Series\n",
- " ic_stats = pd.DataFrame({\n",
- " 'Mean_IC (Spearman)': np.nan, 'Std_Dev_IC': np.nan, 'ICIR': np.nan\n",
- " }, index=feature_columns)\n",
- " else:\n",
- " daily_ic_series = df.groupby(trade_date_col).apply(\n",
- " lambda day_group: {\n",
- " feature: day_group[feature].corr(day_group[target_column], method='spearman')\n",
- " for feature in feature_columns if day_group.shape[0] > 1 # 确保每日数据点多于1才能计算相关性\n",
- " }\n",
- " ).apply(pd.Series) # 将字典结果转换为 DataFrame\n",
- "\n",
- " # 计算 IC 的统计量\n",
- " if not daily_ic_series.empty:\n",
- " ic_mean = daily_ic_series.mean()\n",
- " ic_std = daily_ic_series.std()\n",
- " # 避免除以零\n",
- " ic_ir = ic_mean / ic_std.replace(0, np.nan) # 使用 replace 0 为 NaN\n",
- "\n",
- " ic_stats = pd.DataFrame({\n",
- " 'Mean_IC (Spearman)': ic_mean,\n",
- " 'Std_Dev_IC': ic_std,\n",
- " 'ICIR': ic_ir\n",
- " })\n",
- " print(\"\\n--- 日间 IC 和 ICIR (Spearman) ---\")\n",
- " print(ic_stats)\n",
- " else:\n",
- " ic_stats = pd.DataFrame({\n",
- " 'Mean_IC (Spearman)': np.nan, 'Std_Dev_IC': np.nan, 'ICIR': np.nan\n",
- " }, index=feature_columns)\n",
- "\n",
- "\n",
- " # --- 5. 因子在不同市值分位数上的平均 IC ---\n",
- " print(f\"\\n--- 计算因子在 {mcap_bins} 个市值分位数上的平均 IC (Spearman) ---\")\n",
- "\n",
- " # 在清理后的 df 上计算每日市值分位数,直接添加到 df 中\n",
- " # 使用 transform() 和 qcut() 在每个日期分组内计算分位数\n",
- " # labels=False 返回整数 0 to mcap_bins-1\n",
- " # duplicates='drop' 处理在某些日期股票数量少于 bins 导致分位数边缘重复的情况,会返回 NaN\n",
- " # 添加一个临时列来存储分位数\n",
- " mcap_bin_col_name = f'_mcap_bin_{mcap_bins}'\n",
- " df[mcap_bin_col_name] = df.groupby(trade_date_col)[mcap_col].transform(\n",
- " lambda x: pd.qcut(x, q=mcap_bins, labels=False, duplicates='drop') if len(x) >= mcap_bins else np.nan # 确保股票数量足够进行分位数划分\n",
- " )\n",
- "\n",
- " # 过滤掉无法划分分位数 (NaN) 的行,进行分位数 IC 计算\n",
- " # 创建一个临时 DataFrame df_binned_analysis\n",
- " df_binned_analysis = df.dropna(subset=[mcap_bin_col_name]).copy()\n",
- "\n",
- " if df_binned_analysis.empty:\n",
- " print(\"错误: 划分市值分位数后数据为空,无法计算分位数上的 IC。\")\n",
- " avg_ic_by_bin = pd.DataFrame(index=range(mcap_bins), columns=feature_columns) # Placeholder\n",
- " else:\n",
- " # 按日期和市值分位数分组,计算每个分组内的因子与目标变量的截面相关性 (分位数IC)\n",
- " binned_ic_by_day = df_binned_analysis.groupby([trade_date_col, mcap_bin_col_name]).apply(\n",
- " lambda group: {\n",
- " feature: group[feature].corr(group[target_column], method='spearman')\n",
- " for feature in feature_columns if group.shape[0] > 1 # 确保分位数组内数据点多于1\n",
- " }\n",
- " ).apply(pd.Series) # 将嵌套结果转为 DataFrame\n",
- "\n",
- " # 对每个分位数组的每日 IC 求平均\n",
- " # unstack(level=mcap_bin_col_name) 将 mcap_bin 作为列\n",
- " # mean(axis=0) 对日期索引求平均\n",
- " avg_ic_by_bin = binned_ic_by_day.unstack(level=mcap_bin_col_name).mean(axis=0).unstack()\n",
- "\n",
- " # 重命名索引和列,使表格更清晰\n",
- " if not avg_ic_by_bin.empty:\n",
- " # Index name will be the original column name used for grouping ('_mcap_bin_X')\n",
- " # Rename the index name explicitly\n",
- " avg_ic_by_bin.index.name = 'MarketCap_Bin'\n",
- " avg_ic_by_bin.columns.name = 'Feature'\n",
- " # 可以根据需要对分位数 bin 索引进行排序 (虽然 pd.qcut labels=False usually sorts)\n",
- " avg_ic_by_bin = avg_ic_by_bin.sort_index()\n",
- "\n",
- " print(avg_ic_by_bin)\n",
- "\n",
- "\n",
- " # --- 6. 汇总所有指标 ---\n",
- " # 将基本统计、整体相关性、IC/ICIR 合并到一个 DataFrame\n",
- " # 注意:合并时需要根据索引进行对齐 (因子名称)\n",
- " summary_df = basic_stats\n",
- " summary_df = summary_df.merge(overall_corr_df, left_index=True, right_index=True, how='left')\n",
- " summary_df = summary_df.merge(ic_stats, left_index=True, right_index=True, how='left')\n",
- "\n",
- " # print(\"\\n--- 因子分析汇总报告 ---\")\n",
- " # print(summary_df)\n",
- "\n",
- " # --- 清理临时列 'mcap_bin' ---\n",
- " # 修正:在函数结束时从我们一直在操作的 df 副本中删除临时列\n",
- " if mcap_bin_col_name in df.columns:\n",
- " df.drop(columns=[mcap_bin_col_name], inplace=True)\n",
- "\n",
- "\n",
- " return summary_df # 主要返回汇总报告,分位数IC单独打印\n",
- "\n",
- "# # 运行分析函数\n",
- "# factor_analysis_report = analyze_factors(test_data.copy(), feature_columns, 'future_return')\n",
- "\n",
- "# print(\"\\n--- 最终汇总报告 DataFrame ---\")\n",
- "# print(factor_analysis_report)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "a0000d75",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "开始分析 'score' 在 'circ_mv' 和 'future_return' 下的表现...\n",
- "准备数据,处理 NaN 值...\n",
- "原始数据 17430 行,移除 NaN 后剩余 17119 行用于分析。\n",
- "对 'circ_mv' 和 'future_return' 进行 100 分位数分箱...\n",
- "按二维分箱分组计算 Spearman Rank IC...\n",
- "整理结果用于绘图...\n",
- "circ_mv_bin 0 1 2 3 4 5 6 7 8 9 ... 90 91 92 \\\n",
- "future_return_bin ... \n",
- "0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "... .. .. .. .. .. .. .. .. .. .. ... .. .. .. \n",
- "95 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "96 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "97 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "98 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "99 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN \n",
- "\n",
- "circ_mv_bin 93 94 95 96 97 98 99 \n",
- "future_return_bin \n",
- "0 NaN NaN NaN NaN NaN NaN NaN \n",
- "1 NaN NaN NaN NaN NaN NaN NaN \n",
- "2 NaN NaN NaN NaN NaN NaN NaN \n",
- "3 NaN NaN NaN NaN NaN NaN NaN \n",
- "4 NaN NaN NaN NaN NaN NaN NaN \n",
- "... .. .. .. .. .. .. .. \n",
- "95 NaN NaN NaN NaN NaN NaN NaN \n",
- "96 NaN NaN NaN NaN NaN NaN NaN \n",
- "97 NaN NaN NaN NaN NaN NaN NaN \n",
- "98 NaN NaN NaN NaN NaN NaN NaN \n",
- "99 NaN NaN NaN NaN NaN NaN NaN \n",
- "\n",
- "[100 rows x 100 columns]\n",
- "生成热力图...\n",
- "分析完成。\n"
- ]
- },
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAABdEAAASgCAYAAAAXXAHaAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Xd0VFX79vErvdC7UqQL0YggUkRBaSJRiiigYhAUpUtRFBBQUUEUAQFRBBEEeWjSVASkiApIFzIQioAYihRpIQNJmJz3D97Mj5BMSIbJnJnM97NW1vPjzLVn3yd3nHe9Ozv7+BmGYQgAAAAAAAAAAKTjb3YBAAAAAAAAAAB4KhbRAQAAAAAAAABwgEV0AAAAAAAAAAAcYBEdAAAAAAAAAAAHWEQHAAAAAAAAAMABFtEBAAAAAAAAAHCARXQAAAAAAAAAABxgER0AAAAAAAAAAAdYRAcAAF6lTZs2atasmVJSUswuxaELFy5o2bJlMgzDfm3Xrl3q0qWLfvnll2y/3+rVqzVw4EBt27Yty2MMw9CePXuyPRcAAAAAIK1AswsAAADIjv/++0/Jycny98/6XoDExEQlJycrPDw8zbirV6/qypUryps3r/r16yeLxXLT91qwYIEKFCiQaWbevHkaPXq09uzZo9dff12SVKBAAW3YsEGXLl3SI488kuXaJenw4cNatGiRoqKiMnw9OTlZp0+f1pEjR3To0CHt3LlTmzZt0r///qtPP/1Ujz32WLbmy4p///1Xc+fO1auvvio/Pz+Xvz9ghmnTpunBBx9UlSpVzC4FAAAAHoRFdAAA4FHi4uL0ww8/qECBAgoKClJAQECa15OSkpSSkqKFCxemG5uSkqLExEQVLFhQjz/+uP360qVLNWTIkAznK1q0qNavX6+LFy/q3Llz6tChQ4a5DRs2aNeuXQoKCsq0fqvVqhkzZig0NFTR0dH262XLltWTTz6pBQsWaNGiRXryySczfZ/rhYWFpfnfVGfPnlXz5s114cIF+653f39/lShRQmXLllX9+vUVFxcnm82W7vt4K+Lj49W5c2cFBATopZdeUt68eV323oBZrl69qrVr12ratGmaP3++br/9drNLAgAAgIdgER0AAHiU48ePa9y4cTfNDRo0yOFr9957b5pF9CpVqqhnz54KCgrSzz//rL/++kvdunVTUlKSgoODJUmBgYHKnz+/+vXrl+F7Wq1W7dq1SyEhIZnWNW3aNJ0+fVovv/yySpQokea1vn37avny5RoxYoTuv/9+lSlT5qb3Kcm+e/7GHd8BAQE6f/68ateurR49eqhUqVK67bbb7PeUUwYMGKCkpCTNnj3bvoB+487dwMBAFS1aVPXq1VPXrl1Vrly5HK1JkjZt2qSOHTuqV69e6t27d47N06hRIx07dkyrV69W6dKlHeaWLFmiGTNm6ODBg8qbN68aN26svn37qnDhwjlWm7tFR0dr8+bN2rdv3y2/V5UqVXTvvfdq3rx5LqgsY0ePHlXjxo315JNP6sMPP0zzWmBgoD7//HP7z9CcOXNu+kszAAAA+AYW0QEAgEepVq2afv31VxUoUEDBwcHpjm1p2rSpbDab1qxZk25sSkqKrFarEhIS0r1ntWrVJElHjhzRP//8ox49eqTJ3LhTe/78+QoKClLDhg3THN+S2Y7uffv26YsvvlDhwoXVtWvXdK8XK1ZMb7zxhoYNG6aePXvq22+/Vb58+Ry+V1JSkoKCgnTmzBlJ137BsH//fiUmJqps2bL2xfJSpUrpgQcecFiXKy1evFi//vqr5s2bl+6XBJLUrVs3SdK5c+e0fft2LVy4UCtWrNDs2bNVtWpVt9ToCcaMGaPJkyerZMmSateunY4dO6Z58+Zp8+bNmj9/vsO+w1x58+bVZ599pscff1xTp05V9+7dzS4JAAAAHoBFdAAA4FHCwsIUHx+v+fPnKzQ0NN2idUJCgmw2W7rjXGw2m5KSkhQWFqY2bdrcch2zZs3S3r17tXHjxizlk5OT9eabbyo5OVl9+/Z1uEjavn17rV+/XitWrFCXLl30+eefZ7gzedCgQdq9e3eaawMGDLD/31OmTFHdunWzcUe3LikpSZ988ok6deqkyMjIDDPX7+RPSUnRkCFD9N1332ncuHH64osv3FWqqbZs2aLJkyerfPnymjdvnvLnzy/pWs9Gjx6tzz77TAMHDjS5Sjhy++2367XXXtPo0aP1zDPPqFChQmaXBAAAAJOxiA4AADzO8ePH9f7772eacXScS+XKlV2yiG6z2VS4cOEsH70xbtw4xcbG6qGHHlK7du0yzY4aNUrnzp3T5s2b1bZtW40ZM0b33ntvmszgwYN1+fJlhYSE6JNPPtGff/6pd955R5UrV9bly5d11113uf2oiVWrVuncuXN6+eWXs5T39/dX9+7d9d1332nHjh05XJ3nmDJliiSpT58+9gV0SXruuec0YcIE/fjjjyyie7j27dtr4sSJWrhwoV566SWzywEAAIDJWEQHAAAeJzIyUn/++aeCg4PT7UR3dJyLYRhKTk5WcnKyS2qw2WwqVqxYlrLz5s3T1KlTVbRoUY0aNSrd2eU3CgsL05QpU9S3b1+tXbtWzz77rF544QV1797dvuh6//33S5IuXbqk2NhYSdd+QZB6PZW/v7/279+vL7/8MsO5rl69qitXrqh///5ZupfMrFmzRg899FC2duYWKVJEknTlypVbnt8bJCYmasOGDfL391f9+vXTvJYnTx6VKFFC//zzjy5cuJDmmCB4lsDAQEVFRWn16tUsogMAAIBFdAAAPMG///6rCRMmaOPGjTpz5oyKFi2qBg0aqHfv3vZFyFQ2m00zZ87UggULdOTIERUpUkTVqlVTnz59VLFixXTvvXTpUs2YMUMHDhxQWFiYHnjgAb366quqUKFCmtyND2VctmyZ5syZo3379mnGjBnpzrPes2ePJk2apC1btighIUHly5dXx44d1bZtW6e/DwcPHlRwcLACAwMdLkTbbDbZbDb9+++/Dl8/efKkkpKS7DXv2bNHc+bMUXBwsCwWixITE/XBBx8oKSlJderUUVRUVLr3SUlJydIi+rx58/T2228rKChIbdu21bvvvquQkBAFBATcdDG9atWqqlSpkqZMmaJp06YpJCREffv2TZNZvHixEhMT7f/+559/VKZMGft7G4ahgwcPasaMGfbMhQsXZLPZlD9/fiUmJiopKckli+gWi+Wmu+xvtGfPHklK9xDVhIQETZs2TT/++KNOnDihggULqkaNGurXr5/Kli1rzy1cuFCDBg3SyJEjVa1aNX388cfatm2bAgMD9eCDD+qtt97K9K8FUlJSNGjQIC1evFjdu3dP9/11tYMHDyo5OVklS5a0P3T1ekOGDNH58+ez/fBXm82mhx9+WH5+flq3bl26ZwU0atRIVqtVv/32m/0vFK5cuaJp06bphx9+0PHjx5UnTx7dc8896tOnjyIiIpy/yWzau3evJk2apB07dig+Pl4lS5ZUq1at1Llz5wy/D+vXr9fo0aP1119/qUiRImrdurV69OiRLpucnKyvv/5aS5cu1ZEjRxQeHq6HHnpI/fv3V6lSpW657lq1amnhwoUyDOOm/y0DAAAgd2MRHQAAk8XHx6tDhw46duyYGjVqpHLlyuno0aOaO3eudu3apQULFtgXzGw2m3r27Km1a9eqXLlyat++vc6ePauVK1fql19+0cyZM9McCzJixAjNmDFDxYsX15NPPqmzZ89qxYoVWrdunaZOnaqaNWtmWNOQIUM0f/58lS5dWmXLllVoaGia19etW6devXopPDxcTZs2VWhoqH755RcNGTJE//77r3r37u3U96Jjx472h2jezMMPP3zTzL59+yRdOx5m4cKFCgoKUnJysq5evaqFCxcqKSlJefLkyXAR/ezZs6pevXqm72+1WjVnzhz5+fnpo48+0oULF/T5559nqX5JeuSRRzR58mTdd999mjdvnl599dU0rxuGoZkzZ9r//dNPP+l///uf3n33XbVt21Y2m02GYahly5Z677337Ll27drpzJkzGT589VacPHkyw4eJZiQpKUk7d+7UkCFD7DWlunr1qrp166bNmzerVq1aatiwoc6cOaOffvpJO3bs0Pfff5/mGBRJOnDggD744ANVrFhRTz31lH7//Xf98MMPSkhIcHjWumEYGjZsmNsW0CXpxIkTkpTul1+psvJzm5GAgAC1aNFC06ZN09atW1W7dm37a3/++aeOHTum559/Ps0RP6+//rp+/vln3XvvvXr22WcVHx+v5cuXq2PHjlq8eLFLFppvZs+ePerQoYNSUlL02GOPqVChQtq5c6fGjBmjU6dOaejQoWnycXFx6tq1q+677z61bdtWGzZs0Oeff669e/fq888/ty9mJycn6+WXX9bGjRtVq1Yt1a9fX0ePHtVPP/2kTZs2adGiRVn+SxJHSpQoIavVqvPnz3MuOgAAgI9jER0AAJNt2rRJR48e1dNPP60PPvjAfv2jjz7S8uXLdfToUd1xxx2Srj3scu3atXr44Yc1ceJE+87MH374Qa+99pomTpxoP4953bp1mjFjhqpUqaKZM2faj4749ddf9corr+j111/XihUr0u3uXLJkieLj4zV16tR0x1FI0uXLlzVw4EDlyZNHixYt0u233y5J6tu3r5544gl9+eWXio6OVsGCBbP9vXjttdfk7++vvHnzKjw83H7darVq6NChOnv2rF5//XWVK1dOSUlJGS5s2Ww2JSYm6ty5c/ZrTZo0kcVikSQNHDhQq1at0tatW9ONS3Xx4kVdvHgx3e5p6drO5tRfaoSHh2v27NnaunWrHnroISUmJqpFixYKDQ3Vli1b1KlTJ3Xu3Dnd+dcxMTF6+umn7QvSjRo1UqNGjdLN9f333+vvv/9WoUKFdO7cOdWtW1eLFi3SJ598ombNmunq1auSrh0P4w6JiYk3PYKkSpUqaf7t5+en559/Xh06dLBf++OPP7R582b7LxFSVa9eXcOHD9e6devUokWLNO/z9ddf6/nnn9dbb70lPz8/Wa1WPfroo1q3bp2uXLmS7hc9kjR8+HDNnz/fbQvo0rWfVUkKCQlx+Xu3atXKvnv/+kX0H3/80f56qosXL+rnn39WuXLlNGfOHPvPbIMGDfThhx9q27ZtbllE/+qrr2S1WjVu3Dg1b97cfv2pp57S/Pnz9dZbb6XZVX/27FlFR0fbf/litVr1/PPPa+3atVq9erWaNGkiSfrmm2+0ceNGvfzyy3r99dft46dPn66RI0dq2rRpevPNN2+p9tSf9ev/EgQAAAC+iUV0AABMlrpb8tChQ4qPj1e+fPkkSW+88YbeeOONNNnFixdLurYQfP3id9OmTTVmzJg0x0d89913kqT+/funWfhs0KCBmjZtqpUrV2rDhg165JFH0swRFxen6dOn64EHHsiw3vXr1+vs2bOKiIjQnDlz0ryWL18+nThxQtu3b89wUfhmMnog6OXLl9WzZ0+dPXtWvXv3VocOHdSwYUNFRUXp7bfftucuXbqkDz74QAMGDMjyw0Cvd/1Z6qlnkN945I10bYf19Qu2oaGheuihhyRdWzhNXTw9evSoJKlcuXLp3uP06dOSlOmu7qSkJI0bN05BQUFq166dJk+erEKFCumFF17QpEmTNGnSJD399NOSpKJFi2bnVp0WGhqq//77L9NMt27dJF07P33//v0aNWpUmsVdSXrooYfsfyWQ6siRI9q1a5eka0fW3KhkyZJ644037DuRw8PDVbNmTS1fvlz//fdfugXhESNGaPbs2apatarbFtAl2eu7/pcyrlK1alVVqVJFK1eu1LBhwxQQEKCUlBQtX75cFSpUULVq1ezZPHnyKDw8XOfOndORI0dUvnx5SdKjjz6qRx991OW1OfLJJ5/ok08+sf87KSlJ27Zt04ULF5SYmKiTJ0/afxEnScHBwWn+IiM8PFydO3fW66+/rjVr1tgX0ZcuXSrp2pE1Y8eOtefj4+MlXfvl5K06e/asJPf9kgoAAACei0V0AABMdu+996ply5ZaunSpHnzwQVWpUkURERGqU6eOmjZtmmax/NChQwoJCbEviKUKCQnR448/nubaX3/9JUkZnn189913a+XKlfrrr7/SLaI3atTI4QK6JB0+fFjStYXm1MXmG508edLxDWdDXFycevbsqX379qlevXrq1auXpGtnFS9atEjdunVTiRIlZLPZ9Nprr+mXX37R3r17NXv27GwvfN1zzz32Hf+//PKLpGu7WmfMmKG5c+fq/vvvl81mU0pKSpbeLyYmRlL6ndlS1hbRJ0yYoGPHjqlDhw5pFhk7duyov//+W23btrX34rbbbstSTbeqVKlSN+1tv379JEk1a9bUyy+/rEWLFqVbRJeufQ/mzp2rLVu2aO/evTp//rx9R3JG3+NmzZql+6uJ1B4bhpHm+vz583Xy5ElVrFhRe/fu1S+//JLu5zynpP4SLHUx90bt27fXnj17tGbNGqeOG2ndurVGjRqljRs36qGHHtLWrVt16tSpNDv9pWvHv7z55psaPny4oqKiVL58eUVERKhGjRqKiopy6hdNztq0aZOWLVumHTt26NChQ0pOTk5zRNX1SpYsme4on0qVKkn6v19MSdLff/8tSWmOO7qeKz6DTp48qXz58vEAWAAAAMj/5hEAAJDTPv74Yy1YsEC9evVS2bJl9fvvv6t///5q2bKlLly4kKX3uHLlihISEtItKGb3gXh33XVXpq+nvv/gwYO1b9++DL+effbZbM2Zke+++05PPfWUDhw4IElpjofp2bOnrly5omHDhikxMVF9+vTRL7/8oqZNm+qbb75xaudov3799M4778hms2nFihWqVq2aAgICdOzYMUnXFnGHDRuW5pgZR1JSUvT7778rLCxMkZGR6V5PXUQvXrx4huPXrVunKVOmqGDBgunOly9UqJDGjh2rihUr2h/ambrImNPuuecebdiwIUvZBg0a6O6779bGjRu1Y8eONK/FxMSoWbNm+vLLL1WoUCG9/PLLmjJlisOzzaWMd/Q7cvLkSb3yyiuaN2+eihUrpvfff99tR3Kk/vXCsWPHMtyNfvr0aSUnJ6dbKM6qFi1aKCAgwH6Ey48//ig/Pz+1bNkyXfaZZ57Rzz//rCFDhuj+++/X4cOH9d5776lJkybauXOn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7LHHVKxYMc2ePVvPPfecYmJi9MYbb6h27dqKiopSr1697At0jz32mOrWrauPP/5YGzZs0IQJE/T000/bF9D//fdfdenSRb/++qsGDBig2rVr2+e/fpfrnj17NGfOHPtDW6935MgRPfvss9q0aZPq1auX4SKeYRjavHmz9u3bl2a39M0kJydL+r8Hbm7btk1z5sxReHi4/diZ69lstkyPRrkVjRs3Vrt27dS/f3/t3bv3pvmWLVuqVKlSWrt2rf0Yob59+6p79+5KSkrSrFmztHv3bj3//POaOXOm/P39tWbNGpeeYX7//ferefPm+u2337Ry5UqXva8j/v7+GjdunIYMGaLg4GB9++23OnLkiJ5//nnNnj37lhdmw8LC7AvKTZo0yfD9goODNWvWLPXq1cv+ENelS5eqRIkSeu+999SjR49bqiErgoODNW3aNDVp0kRbt27VnDlzFBAQoLFjx9r/SmPZsmVpxpQrV06ffvqpveZLly6pS5cu9p3h17/3V199pf79+8tms2nu3Ln6448/1LRpUy1atEj33nuvUzUfP35c3bp1U926dfXcc885f/MAAADIVfyMnPr/YQEAALjAqlWr1LNnT0nSnXfeqWHDhqlWrVrpcgcPHtS3336r77//XhcvXtSTTz6pDz/8UNK1xeeMzjY/e/asZs6cqenTpys5OVnDhg1Tu3bt7K937txZGzdu1NChQxUSEqKPP/5YSUlJ+vXXX+1nr584cUIzZszQt99+q6SkJDVr1izDXf7R0dHatm2bfVH+jTfe0EsvvZSl78HUqVP18ccfa9q0aSpVqpSeffZZnT17Vj169FCfPn3S5Vu0aKFz587p999/z9L7Z1dSUpK6dOmiv/76S8uXL3f6IZmAJ7l69apatmypgIAAzZ49O8vPVwAAAEDux3EuAADAozVo0ED33nuvatWqpT59+jg8gqZixYoaNmyYBg8erD///DPNUSmOHg76yy+/aOrUqapSpYref//9NEeoSFKHDh104MABDR8+XNK1vxro169fmsW1lJQU/frrrwoMDNSbb76p559/PsO5OnTooMOHDysyMlItW7ZUVFRUlr8HqeffJyYmqmzZsho+fLi+/PJL+4M7M8pfvnw5y++fXcHBwfriiy+0YcMGFtCRawQGBuqtt95S1apVWUAHAABAGuxEBwAAHi8pKSnHHp55+PBhlStXzuFDSbPi6NGjCg4OVvHixV1Y2f85e/aszpw5o5IlS9qP7jAM45ZqBgAAAABkDYvoAAAAAAAAAAA4wINFAQAAAAAAAABwgEV0AAAAAAAAAAAcYBEdAAAAALxMYmLiTTOc3AkAAOAaLKIDAHKVn376Sd99953D1xcvXqwffvghS++VkJCgpKQkpaSkZHn+q1evKiEhQefPn8/yGHiu5ORkXblyxewyAOQCP/zwgy5cuGD/95UrVzR8+HC99dZb2X6v8+fP68EHH1Tnzp0VFxeXYcZms+nxxx9Xt27d9N9//zldNwAAAKRAswsAAMCVPv/8c8XFxempp57K8PWRI0eqQIECeuKJJ276XkOGDNGyZcucqqNo0aJav369U2NhjpSUFJ0+fVqHDh3Svn37tHPnTv3666/q06ePOnbsaHZ5ALzYyZMnNXDgQBUpUkSrVq1SUFCQQkNDtX//fm3fvl0vvviiKlasmOX3mzhxouLj42Wz2ZSUlKSDBw9KuvaLv+DgYFWoUEE//vijDh48qHvvvVdFihSxjzUMQ5cvX1ZoaKj8/dlTBQAAkBUsogMAvNq5c+f0999/KyQkRCEhIQoICFBQUJB9QeFGgYGB9tcNw1BiYqIKFiyoUqVKpcvWrl1bhQoVUmBgoAICAtK89vPPPysuLk7t2rVT3rx57devXr2qpKQkhYaGuvZGkSNOnz6t7t276+zZszp16pSSk5Ptr4WGhqpUqVI6cOCAiRUCyA2mTJmi5ORkde7cWUFBQfbrffv2VYcOHTR8+HDNmDEjS++1detWzZ49W5K0adMmRUVFpXm9WbNmGj16tMaNGyfp2l9gLVmyxP66zWaTJK1evVqlS5e+ldsCAADwGX4GB+UBALzYqlWr1LdvX/sCekJCgmw2mwoUKJBhPj4+Xn5+fsqbN68Mw1BSUpI6d+6sPn36ZGverl276pdffvHIRYjo6Ght3rxZ+/btM7sUr/Dqq6/KZrPp9ttvV0hIiKZOnao33nhDL774ovz8/Oy57du3a9euXRm+R0BAgKKjo2+5luTkZH355ZdavHixTpw4oTx58qhu3br69NNPb/m9gRsdPHhQzzzzjAYNGqQ2bdpkmImPj9ekSZO0YsUKnTlzRvfcc48GDRqkyMjIdNmkpCR99dVX9p/fihUr6vXXX9eDDz7ospqHDRum33//XWvWrHGY2bBhgyZOnKi9e/cqPDxcTz31lHr37q3AwPT7hywWi8aNG6ddu3bJz89PzZs314ABA5QnTx6X1fz333/riSeeULFixbRixQoFBweneb1Pnz5avny5Bg0apE6dOmX6XkePHlXbtm118eJFTZkyRdu3b9eECRP0ySefKCIiQklJSQoPD9f8+fM1ZcoUde3aVTVq1NC0adO0e/duffTRR0pOTlZiYqKaNm3q0vsEAADIzdiJDgDwak2aNJHFYrH/Ozo6WocOHXJ4lMoTTzyh8PBwzZs3z10lwsONHz/e/n8fPHhQU6dOVXh4eJoFdOnawtyECRMyfI/w8HCXLKKPGzdOU6dO1QMPPKBHH31U586d059//nnL7wvc6OzZs+rWrZsuXrzoMJOQkKDOnTsrJiZG1apVU7NmzfTrr78qOjpaCxYsSHP8iM1m06uvvqq1a9eqYsWK6tChg7Zt26aXX35Z06ZNU926dW+55unTp2vu3LkZ/uVQqh9++EEDBgxQaGionnjiCSUlJWnq1Kk6ffq0RowYkSa7efNmdenSRTabTVFRUQoLC9PixYv1999/6+uvv073GeCMlJQUDR48WMnJyerfv3+6BXTp2tFhGzdu1OjRo1WpUiU99NBDGb5XTEyMevbsqbNnz6pPnz6qV6+eQkJCNGHCBB08eNB+TNn69es1bdo03X333erbt6/8/f31zz//aPPmzSpQoIBq1ap1y/cFAADga1hEBwDkOmfOnFGVKlUcvn7vvfe6sRr3GzVqlC5fvmx2GblO6hE9P//8s0qWLGm/3qlTJ/31118umeP777/XHXfckWYBLzsPts3I0aNH1bhxYz355JP68MMPXVGmT9i0aZM6duyoXr16qXfv3maX41IHDhxQjx499M8//2SamzRpkmJiYvT4449r9OjR8vf3V+/evdW6dWu99dZbmjNnjj07d+5crV27Vvfff7++/vprBQcHy2azKTo6WoMHD9aKFSvSHGOSHSkpKRo3bpwmT56cae7MmTMaNmyYgoKCNGvWLN19992SpBo1aujtt99WVFSUfYE6MTFRAwcOVFJSkr744gs98sgjkqSmTZuqS5cumjdvntq3b+9UvdebNm2atm3bpho1ajh8FkexYsX04YcfqkePHurdu7fGjx+v+vXrp8kYhqHPP/9cJ0+eVOvWrdW9e3dJ0l133aWAgABt3bpV0rXvVeov+9599137med169aVn5+fLBYLi+gAAABO4EkyAIBcJ2/evBo5cmSGXyVKlDC7vBxXsmTJbD2gzpddunRJycnJcnS6XVJSki5duiSr1Wo/CsLf31+BgYH2Lz8/v3Rn5jvr5MmTuu2229LsgOXBf3ClQ4cOqV27dpKuHUvlyNWrVzV37lwFBQVpyJAh9p/D8PBwvfTSS9qxY4cOHTpkz3/77beSpKFDh9p3WwcEBKhHjx46duyYNm7c6HTNb7/9tiZPnqzu3btnugt98eLFSkhI0LPPPmtfQJekp59+Wrfffru+++47+7U1a9bo2LFjatKkiX0BXZLq16+vGjVqpMk6a8+ePfr0008VHh6ukSNHZrqzvVGjRho6dKisVqu6du2qKVOmpPkFmp+fnyZMmKB3333X/l6tW7fWwIEDNXXqVH311VeSJKvVquHDh+vdd99VeHi4Dh48qIMHDyowMFCfffaZGjRokKZvAAAAyBp2ogMAcp2goCCHu83DwsJuOj4hIUFBQUEKCgpy+s/5DcOQzWZTYmKiQkJCMjyLF+Z78sknM9yN+8477+idd96x//vll19W0aJF3VgZkDPOnDljX7DN7Fzx2NhYxcfHq169eipcuHCa11LPOF+/fr0qVKigs2fP6q+//lLZsmVVtWrVNNnatWsrKChIGzZsUIMGDZyqOSEhQZ999pmaNGmipUuXOsxt2bJFkvToo4+muR4YGKi6detq7dq1N82m3t9nn32mS5cupXlwdHYcP35cXbt2VVJSkoYPH67y5cvfdEyHDh0UFhamoUOHavTo0Vq9erWGDBliP38+ICBAzzzzjD1/9OhR5cmTR/Xq1bNfW7dunfr375/pPOHh4dqxY4dT9wUAAOCr+P/RAwBynXPnzikqKsrh6zc7zqV9+/Y6cOBAluZq3LjxTTPffPON6tSpk6X3u9H27ds1adIk7dixQ/7+/ipfvryio6P1xBNPOFzgz8qDRRs1aiTp2m7MQ4cO6auvvtKGDRv02GOP6c0330yTPX/+vD777DP9/PPPOnv2rEqWLKkGDRqoR48eKliwYLbvaeHChRo0aJAGDx6smJgYrVq1SuXLl9f48eM1ffp0LVy4UEWLFtXIkSN1//33q2/fvvrpp5/0008/qUKFCmnea+DAgVq0aJEWLVqku+66K9u19OzZU8nJyfad5IsWLdLmzZvVunVr1alTRzabTcnJybrzzjvTnL3vSjcePbR58+Y0167/+Um934weaHt9T1OPcLle6vcp1fXvkdqTkSNHpnvAZEZz3njUybJlyzRnzhzt27dPM2bMSLeQumfPHk2aNElbtmxRQkKCypcvr44dO6pt27bZ/n45uueb/RxfunRJX375pZYvX67jx4+rYMGCatSokfr166dChQqlua/rTZw4URMnTrT/+/r/riZMmKCJEydm+N94Rv8dXv99bt26tebNm6dFixbp4MGDWrt2rfLly5emjl69eqldu3YaNWqU1q9fr5SUFNWoUUNDhw5VmTJlnPqe1axZU7Vr175p7tSpU5KU4X9XpUuXVlBQkP0XUJllg4ODVbJkyTS/rJo4caImTJigzp07a+DAgfbrY8eO1RdffKFu3bqpX79+9usff/xxlv7a49SpU/Lz88uwjrJly+r8+fOKj49Xvnz57DVfv2P9+qxhGIqLi1NERMRN571RXFycXnjhBZ06dUrt27fXypUr9dtvvykwMDBLf1kyYsQIffjhh9qxY4dee+01LVmyxH6c1PUCAwPTfV9Sf1E8ZcqUDH9pER0dneX/9w0AAAD/h0V0AECuU7RoUYcPFk1ddMtMkyZNVLt27QwXKFL9/PPPiouLU7t27TLcqZiSkiKbzabLly87vYN56dKlGjhwoIKCgtSsWTPlz59fq1ev1uuvvy6LxaJBgwY59b7X++233/Tqq69KkipXrpzuuJtTp07pueeeU1xcnO6//341a9bMvlC6Zs0aLVy4UPnz53dq7nHjxum+++5T9erVtXHjRj399NMqVqyYHnvsMS1cuFBjx47Vt99+q1atWumnn37SsmXL1KtXL/v4pKQkrVq1SnfeeadTC+iS1Lp1a/v/ffXqVX366aeSpOrVq6tZs2YKCgqyH02RU4vo3bp1s//fX3zxhUqWLKmWLVvar11//npW5c+f3/6+ly5d0qxZs1SlShU1bNgwTcYVhgwZovnz56t06dIqW7ZsusW+devWqVevXgoPD1fTpk0VGhqqX375RUOGDNG///7rkvPGb/ZzHB8fr+eee04HDhxQ/fr11bhxY+3fv19z587Vtm3btGDBAoWFhalkyZL279vx48e1dOlS3X///br//vtvucbrXb16Va+88op+++03VahQQRUqVMhwcfX06dP2z5jWrVtr+/btWrdunU6ePKlFixY5ddRPVo8eunTpkiQ5/PzKly+fTp48maVs/vz57Vnp2s/8mjVrNHPmTLVp00Z33nmnDh8+rK+++kp33nmnevbs6XTN4eHhGf7FUerP+7///qt8+fLZay5SpEi6bIECBSRdO17JmUX0n376yX5UzJtvvqn77rsvW+PfeOMN1a1bV4MGDdIbb7xh/29qyZIl+vjjjxUcHCx/f39dvHhRO3fuVMOGDZWUlKTo6Gj7Z+HFixd1+vTpdO99/S8NAQAAkHUsogMAvNY///yjCxcu2I9ekaTLly/LZrPp4MGDGY5JTk5WYmJimteTk5Nls9nsOxL79u1707kPHTqkuLg4de3aNd2OYFc4deqUhg4dqpCQEC1YsMB+xvmrr76q5s2b65tvvlGXLl1UrFgxp+eIj4/Xa6+9pg4dOqh79+7KkydPusy7776ruLg49enTRz169LBfHzZsmObOnau5c+fq5Zdfdmr+atWq6auvvtLevXvVqlUrSdLs2bPtvyw4ceKEpGtnFBcuXDjdIvqvv/6q+Pj4NIvQt2LBggX6999/JV078uKZZ57R3XffneMP47x+x+0XX3yh0qVLp7nmjPz589vf4+jRo5o1a5buuuuuW37fGy1ZskTx8fGaOnVqugchStf+exw4cKDy5MmjRYsW6fbbb5d07b+xJ554Ql9++aWio6Od+ouGVFn5OR47dqz279+vd955R88++6z9+gcffKBvvvlGCxcuVIcOHVSmTBn792jTpk1aunSp6tat6/IHi3755ZcyDEPz589XtWrVHObmzZunpk2basyYMQoKCpLNZtNTTz2l2NhY/f333+n+MsOVUhdaM9oBLV3bYX7lypUsZy9cuGD/d2BgoD788EO1adNGw4cP18yZM/Xee+/JMAyNGjXK/our7PL393d4ZFfqe6Y+dDm15ozyN2az65VXXlHVqlVVt25dBQcHa/PmzQoLC1NgYKAaN24sq9WqTZs2pRv3xBNP6MiRI/bjc6ZNm5bm9Vq1aumDDz5QcHCwfvzxR82fP18REREaPHiwrl69qhIlSth3/L/22msO6+NoKgAAgOxjER0A4LUmT56sBQsWZPhaZse5nDp1Kt3rme1eN8Py5ct15coVvfLKK2keEpo/f36NHTtWp0+ftv/iwFkXL15Uq1at9Prrr2f4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5+zZoKAgffTRR2mORvn333/17rvvqmjRoho8eLAk6c0339Svv/6q999/X7Vq1VLp0qWdqvnDDz9Up06dNHHiRH355Zey2Wyy2Wxq3LixnnvuuTTZgQMH6tChQ5o3b54WLVokwzB09epVVatWTX369HFq/ozMnTtXM2fOVIkSJRy+b+rxP44W0Q3D0JgxYxQUFKT3339ffn5+Gf6iJiu/vLl+5z0AAACyhkV0AIDXSl0AvV7qYnqqoKAgBQQE2B98l7q7NFWePHn0yiuvZGm+/fv3288iT915mpUjH5zVunVrlS5dWp9//rlWrVqlq1evqlKlSurRo4eefvrpHJv3eiVKlNCCBQs0adIkrVy5Ujt27FDRokX1/PPPq1evXm4/S75169b6448/VKJECdWtW/eW3itPnjwaN25cmgftZbYAlXr+u7+/f5oxfn5+SkxMvKVasuree+/V6NGjNWnSJPXu3VuFCxdW8+bN1bt3bz3xxBMOxw0dOlQFCxbUihUrtHbtWuXPnz9NPm/evPryyy/1wQcfaOTIkQoODtYDDzygBQsW6LPPPnN6EV2SGjZsqDlz5mjSpElav369kpKSVL58eQ0fPtxtP8f58+fX3Llz9cUXX2j58uWaPXu2ihcvrrZt26pnz54Oz6EeO3asxowZo3Xr1um///5TkSJFFB0dbX+9VKlSmjRpkkaPHq1BgwYpb968atiwoebNm+fSRVgzvfDCC6pZs6a++eYbxcXFqVKlSurWrVu6z1JJat68ue666y599dVX+uuvv1SyZEn72dypDMPQwIEDdeHCBY0fP95+vEq+fPn07rvvqlu3bnrjjTc0a9Yspz5fixYtqoULF2rmzJn69ddfFRgYqKioKLVp08a+SztVWFiYZsyYoQULFmjFihW6evWqGjZsqOeff94lD+BMSkrSp59+qqlTpypfvnyaPHlyhg8rPXfunL7//ntJcvjLAz8/P40bN067du1S5cqVJcn+C4Lrpf77+uNebpT6PQcAAEDW+Rm54W9NAQA+KykpSRMnTlRISIh99/n1Zs+erYSEhHQLCikpKbLZbEpKStLTTz+tMmXK3HSulStXqnfv3vZ/BwcHa8uWLQoNDXXNzcB0FotFTz31lIYOHarnn38+zWv//POPjh49qpo1ayokJMR+/fz587p69arDneAAfEtSUpK+//57ffHF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cZwLAAAAAAAAAHipxo0bZ/r66tWrM7weHx+vO+64I821AgUKKDY2NtP3i4+PV0BAgMqUKWO/lj9/fp08eTLD/KRJk1SyZEk1bNhQ0rVF+AYNGujFF19UcnKy3nvvPfXr108LFizIdN6s2LVrl5YvX659+/bp1KlTCggIULFixRQZGanHHntMVapUcep9WUQHAAAAAAAA4BM4E/3/BAYGKiQkJM210NBQWa3Wm44LDg5Ocy0sLCzDcRs3btTMmTP19ddfKzDw2lJ06rEvqd577z01adJEhw4dsu9Wz659+/bpvffe0/nz5/XYY4+pS5cuKlasmGw2m06fPq3NmzerZ8+eqly5st566y2VLl06W+/PIjoAAAAAAAAAeClHO81vplChQjpz5kyaa5cuXUq3QJ7RuMuXL+vSpUvKmzevpGu7028cFxcXp/79+6t///6qVauWw/crXry4JOno0aNOLaLPnz9f48aNU79+/fT000+ne71KlSp66KGH1KdPH3399dd65plnNGLECDVo0CDLc3AmOgAAAAAAAAD4mOrVq+vAgQO6ePGi/VpMTIxuv/32TMeVKVNGRYsW1bZt2xyOO3v2rLp27aqGDRvqxRdftF//77//1Lx58zS71lPfp2TJktm+hwMHDujrr7/W7NmzM1xAv15AQIC6dOmiiRMn6oMPPkhz3zfDIjoAAAAAAAAA+JjKlSurQoUKGjNmjFJSUrR7926tXLlSjRo1UkpKii5evCibzZZunL+/v6KiojR+/HhdunRJ586d0/Tp09WoUSNJUmJiorp06aLChQtr4MCBSkhIUEJCgpKSklSkSBHlzZtXb731liwWi9auXashQ4aoXr16aR5wmp17+OGHH1S2bNksj6levbp++ukn5c+fP8tjWEQHAAAAAAAA4BOMXPh1K0aOHKnVq1erXr16ateunVq2bKkGDRro+PHjqlWrlvbv35/huFdffVVBQUFq0KCBGjVqpNDQUHXr1k2S9Pvvv2v37t3asmWLatWqpfvuu0/33Xefhv0/9u49zsZ6////c81gWBhGTskg0bZYI5JDSQoVaqSDDk7ZqcghKeWQQyEiKaWDdnaF7N2mHZ3syuHbrvZWk1MulkNJiSK7jRlrGoz1+6Nf89ljrDHXmmvW+1qzHvfbbW41az3f7/fr6tXt+uPt8r4mTpQkPfPMMzpy5Ih69+6tCRMm6Oqrr9bcuXMjvoaEBPtb3HbHeEKhUHH/W8cUy7JMlwAAAAAAAAA4wu/3my4hpvzh75NNl+C47TdMLNb4YDCojIwMpaSkqHnz5kUed/LkSa1bt07Hjh1TmzZtVLZs2WLV4WZx+WLRU28uwWBQgUBAPp9PXq+3QN6yLFs3JPJm8+HGFNZnt10D+cjG0GP35p1agx5HL2+qJnoced6NNdFj82vQY7N5N9ZEj82vEQv5WOqxG2uKhbzJHkdjjXjLA8Xl9XrVsWNH2+MSEhIKfWFoaRKXm+gAAAAAAAAAgNKhU6dO8ng8Rc6vWrXK1vxsogMAAAAAAACIC6FQ0TdaETuGDx9eovOziQ4AAAAAAAAAiFnXX399ic5v/9WlAAAAAAAAAADECTbRAQAAAAAAAAAII6LjXA4ePKgPPvhA27dv14EDB5SYmKgaNWrI7/fryiuvVJUqVZyuEwAAAAAAAACKJ2S6AETT8ePHtW/fPp199tk6cuSIqlevHtE8tp5EP3jwoB566CGlp6dry5YtSktL02233aYbb7xRPp9P//73v3XVVVfpscceU1ZWVkQFAQAAAAAAAAAQqezsbI0ePVoXXnihunXrpl27dmnGjBnq2bOnDhw4YHu+Im+if/rpp+rRo4fOOeccrVmzRtOmTVOvXr3UsWNHderUSbfccouefPJJffTRRzpx4oTS09O1bds22wUBAAAAAAAAABCpxx9/XP/+97/10EMP6eTJk5Kku+66SwkJCZoxY4bt+Yq0ib5z506NGTNGzz33nEaMGKHy5cuHzSYnJ2vSpEkaN26c7r77bh05csR2UQAAAAAAAAAAROKjjz7ShAkT1K9fv7zPzj//fI0cOVKffvqp7fk8oVCoSCcBZWVlqVKlSrYmj2RMSbMsy3QJAAAAAAAAgCP8fr/pEmJK4yVTTZfguJ29xpsuwXXatGmjWbNm6bLLLlOTJk20bNkyNWnSRCtXrtS4ceP0xRdf2JqvyC8WTUxM1Nq1a9WuXbsiT+62DfTfnXpzCQaDCgQC8vl88nq9BfKWZdm6IZE3mw83prA+u+0ayEc2hh67N+/UGvQ4enlTNdHjyPNurIkem1+DHpvNu7Ememx+jVjIx1KP3VhTLORN9jgaa8RbHkBBV1xxhZ544gnVrFkz77MdO3Zozpw5uuKKK2zPV+RN9H379mnQoEHatGlTge/atm2rChUqKDEx8f8mLlNGPXv21D333GO7KAAAAAAAAAAAIjFu3DgNGzZMPXv2lCTddNNNys3N1UUXXaSxY8fanq/Im+hJSUkqU+b08cOHD2vSpEn5Plu7dq3mz5/PJjoAAAAAAAAAIGqqVKmihQsX6osvvtCOHTskSY0bN1bbtm0jmq/Im+gejyfvSfOnnnpKSUlJOn78uO69915JUvfu3fPl69atq2PHjunYsWMqV65cRMUBAAAAAAAAgFOK9nZIlBZt2rRRmzZtij1PkTfR/9e8efPUuXNnffbZZxo2bFje52+88YbKli2rnJwc3XbbbWrevHmxCwQAAAAAAAAAwI5PP/1Ur732mr777jvl5uaqfv366tu3rzp16mR7roRICvB4PHruuedUpUqVvN8l6fHHH9frr7+uxx57LJJpAQAAAAAAAAAolsWLF+vOO+9UVlaWrrjiCl111VU6fvy4hg4dqr/97W+254voSfTf/b55/rvatWvrzTffVOvWrYszLQAAAAAAAAAAEZk3b57uvPNOjRo1Kt/nTz31lF5++WXdfPPNtuYr0ib6G2+8UaQd+lM31QEAAAAAAADALUIh9i/jQWZmptq3b1/g83bt2mnBggW25yvScS6bN2/W8ePHbU8OAAAAAAAAAEA03XDDDXrllVd09OjRvM+ys7O1aNEidevWzfZ8nlDozO+kzc3N1Y8//qgbbrhBX3zxhXw+nwKBgC6//HKtWrVKfr9fgUBA3bt31/vvv682bdroiy++sF2MJC1fvlxz5szR6tWrJUlvvfWWnn32WR09elQ333yzRo4cqYSEiI5ylyRZlhXxWAAAAAAAAMBN/H6/6RJiynlvlL53OX5zy8OmSzBu8ODB+X4PhUL67LPPVL58eTVp0kQej0c7duxQVlaWLr74Yr388su25i/ScS6JiYlFOqrlu+++k9/vV25urq0ifvfTTz9p6tSpqly5siTpn//8px5++GE9+uijat26tcaMGaNFixapf//+Ec3/u1NvLsFgUIFAQD6fT16vt0DesixbNyTyZvPhxhTWZ7ddA/nIxtBj9+adWoMeRy9vqiZ6HHnejTXRY/Nr0GOzeTfWRI/NrxEL+VjqsRtrioW8yR5HY414ywOQUlJSCnyWnp6e7/e6detGPH9ELxYNhUIaNmyYDh06lPe7JP3jH/9QcnKyDh8+HNGcY8eOVe3atfMes3/llVd01VVXqVevXpKkMWPG6KGHHir2JjoAAAAAAAAAoHSYPn16ic4f0Sb6LbfcogoVKuimm25SQkJC3lPqqampkqQqVarYnnPRokXat2+fxo4dq8mTJ0uStm7dqoceeigvk5aWpn379umXX35RtWrVIikdAAAAAAAAQLzixaJxIxgM6ptvvtGvv/6a99mJEye0bt06DRs2zNZcRd5ED4VCOnnypCTp0UcfLfDdhAkTTjtuypQpZ5z722+/1dNPP61XXnlF2dnZeZ9nZmaqfv36eb8nJiaqYsWKOnDgQLE20YPBYL7ff1/zf9c+0xi7a5CPbv50Y87UZ7ddA3n7Y+ixu/NOrEGPo5uPxhr02Nl8NNagx87mo7EGPTabj8Ya9NjZfDTWcHs+1nocjTVKW950j6OxRjzlT3c0MRDv/v3vf+vee+9VVlaWpP87ScXj8SglJcX2JnqRXiwqSd98842uu+66076Y87777lO5cuXynkoPhULKzc3V8ePH9fTTTxc6b25urm677TZ17NhRQ4cO1eeff66xY8dq9erVSktL0+uvv67mzZvn5Tt27KjZs2erVatWti70d5ZlKScnx9aYpKQkW2PIm827sSbyzubdWBN582uQdzbvxprIm1+DvLN5N9ZE3tm8G2sib34N8s7m3VgTefNrxFs+0j2yeHXeX6eZLsFx39w6znQJrtOzZ09deOGF6tmzp3r37q1//vOf+u9//6s//vGPGjVqlHr06GFrviI/iV6vXj2tWLHitN+daaO8MC+++KISEhIKvEFV+u1A+IMHD+b7LCsrS+XKlYt4PUny+Xz5fs/Oztbu3bvVoEEDVahQoUB+165dBcYUhrzZfLgxhfXZbddAPrIx9Ni9eafWoMfRy5uqiR5HnndjTfTY/Br02GzejTXRY/NrxEI+lnrsxppiIW+yx9FYI97yAAravXu3Jk6cqObNm6t+/fpav369unTpomHDhumFF14ouU30smXL5p157qQ333xT//nPf9S2bVtJvz2Znp2drYsuukg+n0/r1q1Tp06dJP12E8nKytLZZ59drDXD/TWXChUqhP3O7l+NIW82X9iYcH122zWQj3wMPXZn3sk16HF08tFYgx47m4/GGvTY2Xw01qDHZvPRWIMeO5uPxhqxko+VHkdjjdKaN9XjaKwRb3kU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bdmyRf/617+UlJSkiy66SMePH1e1atV02WWX6e6779YVV1yhihUrSpIOHDig++67T3/5y19sFQQAAAAAAAAAQKSef/55DRo0SCNGjMj77LrrrlPt2rU1d+7cktlEr1ixovx+v9q1a6cLL7xQ27Ztk9fr1d///ndlZGSoRo0auvbaa/PyOTk5GjVqlHr16qUlS5aoV69etooCAAAAAAAAAMeFTBeAaPjxxx/Vpk2bAp+3adNG8+fPtz2fJxQKnfF/nWAwqMsvv1zdu3dXlSpV9PXXX+u5557TY489pnPOOUcpKSl6+eWX1b17d/Xp00d///vf9cknn6hz585q0KCBLrnkEtuFlRTLskyXAAAAAAAAADjC7/ebLiGmNHhxlukSHLd78CjTJbjOrbfeqlq1amn27NlKTEyU9Ns7PUeOHKn9+/frr3/9q635irSJLknfffedXn31VZUvX1579+7V2WefrYyMDL3wwguSpM6dO6tly5baunWrkpKSNH78eHXv3t3m5ZU8y7IK3FyCwaACgYB8Pp+8Xm+Rxthdg3z08uHGFNZnt10D+cjG0GP35p1agx5HL2+qJnoced6NNdFj82vQY7N5N9ZEj82vEQv5WOqxG2uKhbzJHkdjjXjLwx420ePDpk2bNGDAANWoUUOtWrWSJK1fv14HDhzQa6+9pubNm9uaL6EooW3btmnt2rVKS0vTf//7X/34448qX768evTooe+//16SVK5cOS1cuFCPPPKIfvnlF23evNnmpQEAAAAAAAAAUDwXXHCBlixZopYtW2rz5s366quv1LJlSy1dutT2BrpUxDPRLcvSa6+9pjJlyigzM1M//fSTfv75Z6WkpGjbtm367rvv8rK5ublq27atVqxYoXbt2qljx462iwIAAAAAAAAAx3Emetxo1KiRZsyY4chcRdpEv+mmm3TTTTcpIyND33zzjZ566in9+uuvmjp1qrxer5566ilt3LhRN998s5KSktSjRw9Vq1ZN06dP12WXXSaPx+NIsQAAAAAAAAAAnMnhw4f1448/qkmTJtq7d6/+3//7f7r66qtVvXp123MV6TiXkydPasKECbr//vv1n//8RxdeeKFGjRqlu+++W+XLl9eDDz6Yt3n+3XffqX379urcubM8Ho9WrlxpuygAAAAAAAAAACKxZcsWde3aNe99nr/88otmzJiha6+9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r18/x+dNiHTgyZMnde+99+q+++5zsBwAAAAAAAAAANwj4k30F154QVu2bNFVV13lZD0AAAAAAAAAALhGRJvoK1as0HPPPadevXrJ4/Fo48aN+umnn3Ty5Emn6wMAAAAAAAAAR3hCpe+nOA4ePKghQ4aoZcuWuuGGG7Rt27YijcvNzdWMGTPUtm1bXXHFFXr//ffzfb97927169dPLVu2VP/+/bVv375837/11lvq1KmT2rZtqyeffNL1+8q2z0RfuHChHn/8cV133XUaMGCArrnmGnk8HklSQkKCatSoodq1a6tFixYaNmyYKlWq5HjRAAAAAAAAAIDIhUIhDRs2TJK0dOlSffXVVxoyZIjeeecdVaxYsdCxTz/9tJYvX65nn31WZcuW1fDhw1W/fn01a9ZMOTk5GjhwoJo0aaLly5drxYoVGjZsmJYuXaqEhAT985//1MMPP6xHH31UrVu31pgxY7Ro0SL1798/GpcdkSI/ib57924NHDhQ06dP15133qnp06fnbZ6vWbNGf/nLX/TUU09p4MCBatq0qd544w3Nnj27xAoHAAAAAAAAAERm/fr12rBhg6ZOnarzzjtP119/vc4991ytXLmy0HHHjh3TokWLNGzYMLVp0ybvafPFixdLkj744AMdPHhQU6dOVb169TRo0CBlZ2dr/fr1kqRXXnlFV111lXr16qUGDRrkbaK7WZGeRP/73/+u8ePHy+/3669//auaN2+e953H41Ht2rVVu3btfGMSEhK0evVqTZw40dmKAQAAAAAAAACSpM6dOxf6/apVq077+datW1WnTh01atQo77OWLVtq06ZNuu6668LO9+233yoYDKpDhw75xr399tt586alpSklJSXv+xYtWmjTpk266KKLtHXrVj300EN536WlpWnfvn365ZdfVK1atcIv1hBPKBQ648k5e/bs0TfffKPLL7883+e7du3SNddco0AgUGDMggULFAwGNXjw4DMWsXDhQk2dOjXfZ2PHjtWAAQP01Vdf6dFHH9WuXbvUvn17TZ06VVWrVj3jnOFYlhXxWAAAAAAAAMBN/H6/6RJiSsM5pe/kjHPffq/Q78Ntoj///PP6/PPP9dprr+V9tnDhQq1du1bPPfdc2Pm+/PJL9e/fX1u3bs37bPv27erbt68yMjL08MMPKxQKadq0aXnfP/744zp58qTGjRun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NeIt36pVqyJnITUbUwrPRH+cM9FP9Z///EcPPvig0tPTdeWVV+q6667Tvn37JEkjRozQ4MGDbc1XrE300/nqq680btw4jRw5Up07dy7SmHfeeUdjxozRV199pcTEREnS/v37ddlllykhIUHjxo3Lt2Gfnp6uoUOHqmvXrrbrsyxLDRs2zPdZdna2du/erQYNGqhChQoFxuzatavAmMKQN5sPN6awPrvtGshHNoYeuzfv1Br0OHp5UzXR48jzbqyJHptfgx6bzbuxJnpsfo1YyMdSj91YUyzkTfY4GmvEW54n0e1pNroUbqLPYBP9TI4ePaq1a9cqJSVFF154oe3xxTrO5XSaN2+uZ555Rvfee2+RN9Hr1KmjkydP6tdff817nP6HH36QJPXs2VPr1q3L20Q/evSovv32W9WpUyfiGsPdXCpUqBD2O7s3JPJm84WNCddnt10D+cjH0GN35p1cgx5HJx+NNeixs/lorEGPnc1HYw16bDYfjTXosbP5aKwRK/lY6XE01iiteVM9jsYa8ZYHULiKFSsWea/6dIr1YtFwzj77bP34449Fzl9wwQU699xzNXHiRO3Zs0dbtmzRY489pksuuUT9+vXTypUrlZGRIem3c9hTUlLk9/tLonQAAAAAAAAAQIx788031a9fP3Xs2FFff/21pkyZomnTpunEiRO25yrWk+jLli0r8Fl2drbeffddnX/++UUvokwZzZ8/XzNmzNBNN92kY8eO6eKLL9aUKVN01llnafjw4RowYICqVq2qYDCoOXPmKCGhRPb/AQAAAAAAAAAx7LXXXtPMmTPVqVMnffnllzpx4oRatWqlyZMnq3z58rr//vttzVesTfRnnnmm4IRlyqhJkyZ68MEHbc119tln6+mnnz7td4MGDVL37t21fft2paWlqVatWpGUCwAAAAAAACCOeRx9OyTcauHChRo7dqz69u2rJk2aSJK6d++ukydP6oknnrC9ie74i0XdzrIs0yUAAAAAAAAAjuDIY3v8D5W+F4taM3mx6KlatGihl19+WRdddJGaNGmiZcuWqUmTJvr3v/+te+65Rxs3brQ1n60n0T/55BMlJyfrggsusLWI25x6cwkGgwoEAvL5fKd9cYNlWbZuSOTN5sONKazPbrsG8pGNocfuzTu1Bj2OXt5UTfQ48rwba6LH5tegx2bzbqyJHptfIxby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OXKkli5dqszMTCUmJio1NTVvbHJyct5YkzyhUKgETs5xL8uyTJcAAAAAAAAAOMLv95suIaZcesMs0yU4LunwikK/P90m+n/+8x9lZ2efNn/HHXdo5MiR6tatW95nvXv31q233qoePXoUutbEiROVmJioSZMm5X329NNP5x3xcqo9e/aoS5cuWrFihY4cOaIBAwZo48aNed9///336tatm/Fz0ePySfRTby7BYFCBQEA+n09er7dA3rIsWzck8mbz4cYU1me3XQP5yMbQY/fmnVqDHkcvb6omehx53o010WPza9Bjs3k31kSPza8RC/lY6rEba4qFvMkeR2ONeMsDp9skP5Ozzjqr0O8OHjyY77PMzEyVK1fujPOmpKRo165d+T7LysoKO7ZmzZqSpB9++EH169dXdna2srKyVKlSJVvrljTORAcAAAAAAAAASPrtDPN169bl/X706FF9++23qlOnzhnHtmzZUhs2bFBubm7eZ5s3b9bZZ5+t//znP+rWrZuCwWDed7+vU6dOHaWmpqp69er51v59rGlsogMAAAAAAAAAJEnp6elauXKlMjIyJElz585VSkpK3t+QyMnJUVZW1mnHtm/fXidOnND8+fMlSWvWrNFXX32lTp066ayzzlKlSpX08MMPy7IsrVmzRuPHj9cll1yiRo0aKSEhQd27d9czzzyjrKws/fe//9Wrr76qTp06RefCCxGXx7kAAAAAAAAAiD+euHo7ZGSaNm2q4cOHa8CAAapataqCwaDmzJmjhITfnsd+6aWXtHLlSi1fvrzA2LJly2rWrFkaOXKkXn31VR06dEhDhw7VeeedJ0l65plnNH78ePXu3VvJyclKT0/XsGHD8sbfe++9uuuuu3TZZZcpFAqpfv36Gjx4cHQuvBBsogMAAAAAAAAA8gwaNEjdu3fX9u3blZaWplq1auV9N3z4cA0fPjzs2EsvvVQfffSR1q1bp3r16qlx48Z535199tl5T6mfTuXKlbV48WKtW7dOx44dU5s2bVS2bFlnLqoY2EQHAAAAAAAAAOSTmpqq1NTUiMZWrVpVnTt3jmhsQkKCWrduHdHYksKZ6AAAAAAAAAAAhMGT6AAAAAAAAADiQ4hD0WEfT6IDAAAAAAAAABCGJxSKrz9+sSzLdAkAAAAAAACAI/x+v+kSYkqHnk+YLsFxnyx70HQJpV5cHudy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Ffvv45M6duyou+66S2vWrLGveX8N92rXEhkZqQEDBuj555/XpEmTFBAQoIiICPXp00ePPPKIFi5cyOsuF5eQkKDBgwfriSee0Jdffqlx48ZpyZIlCgsLU6dOnfTJJ59o48aNOd74pMauJSkpSWPHjlWvXr20ePFiffDBBypdurRq1qypWrVqKTw8XBs3buTnGACcyG0fLHpNYGCgRowYoWXLlumVV17RN998Iw8PD+3bt0/Dhg2Tj4+P0Snib5hMJnl7eys2NlZHjhxRiRIl1Lt3bwUGBmrGjBl68cUXNW/ePPXo0UMhISGSrr6oSExMZKkeF5GZmSlfX1/17t1bktS5c2ft3r1bn332mSIiIpSWlqavv/5aO3bs0MMPP6zU1FRFR0drwIABBmeOvLBarapevbrat28v6WpD5pNPPtG2bdvUtm1bHTt2TJs2bdKOHTvUsmVLWSwW6uxisrKyZDKZVK5cOXXv3l0XLlxQWFiYFi9erIoVK+qNN95QSEiImjRpovPnz+v06dNq1KiR0WnjFpnNZtWrV0/9+vWT1WrVwIEDlZKSosTERLVr105paWk6c+aMJkyYoJCQEGVkZGjXrl2aOHEinwpzQbVr11ZERIQaNmyo7du3a8eOHbLZbIqPj1dCQoJ27NihFi1aKC0tjXu1Czl37pzCwsIUGhqqESNGSJJatmypxYsXS7r6KaH333+f110u7syZMwoKCtLo0aMlXX1WxbJly7R79249+OCDOnTokH766Sdec7mwc+fOqUyZMgoNDZWPj4/atGmj5ORkvf3221q9erVWr16tFStW8HMMAE7k9k10SfYnzbdp00Y//vijkpOT9c4776hFixZGp4ZbYLVa5eHhoWrVqikzM1Pbt2+XyWRS7969VbVqVc2aNUvvvvuuli5dqrlz5yooKEgbNmzQiy++yJskLiIzM1OJiYm6dOmSfVuzZs3syzCNGTNGW7Zs0d69ezV//nyZTCaNHDlSrVu3Nipl5FN6erpOnjypWrVqaenSpfr999+VkpIiSapcubKqVasmPz8/hYeHy9PTkzq7mGuzVu+//34lJSXp+eef19SpUzVkyBANGjRINptNp0+f1urVq+Xh4aGhQ4eqWbNmBmeNW9WsWTOtXbtWixcv1h9//KHSpUvr3Xffldls1t69e2WxWHTvvfcqKChIq1atkslk0ssv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8X/9mw7/+c9/5OnpecufWgAAAABwczTRAQCA26hbt64k6bfffrNv+/PPP/XUU0/p8OHDLjPGNV27dtXWrVu1detWtWjRQv7+/vk+1+XLlzVv3jw9+uij9tnp1yQkJOSriX7+/HnFxcXp999/V82aNRUQEHDD2GXLlunChQsym8369ddfNWvWLA0cOFDe3t6SpAEDBujw4cOKjIz827Xb/86jjz6q1atX59q2c+dORUVFSbpar82bN992w/56p06d0tNPP63Q0FCFhYXl+fjrm+ilS5fW008/re+//97+NXny5L9dHmbNmjV69NFHc50PAAAAQP6wnAsAAHAb9957rzp37qy3335bVqtVd911l+bNm6fq1avroYcecpkxruncubNmzJihtLQ0Pf744/k+z8WLFzV06FClpKRo7NixOfYlJSXp4sWLt7R8iNVqVVZWlooXL66GDRvqxx9/VPXq1bV79+4cs9uzs7Nls9nszd7+/furdu3a2rVrl1544QVZLBaVLl1ahw8fVoMGDXT58mV5e3vLZrMpOTnZYTP+VvTp00ddu3bVoUOH1LBhQ0lSu3bt1KxZMz3zzDMKCQnRzp07Va5cOfXt2zff41wvOjpaw4YN04QJE/L9iYHr13NPTk7WV199pcWLF9u3ZWdnq2TJkg7P8ddff+nLL7/UypUr85UDAAAAgNxoogMAALcyffp0zZw5U9OnT1d2draaNm2qqVOn2mc9u8oY0tW1vBs1aqR9+/Zp7ty5eT7earVq48aNev/993XhwgWFh4fbZ5zHxMTou+++0969e1WsWDHVr1/f4XmysrIkXZ1p3alTpxvG7Nu3T1999ZX9+2nTptkb/8WLF1ft2rW1du1alSlTRu+//75+/vln7du3T+fOndPEiRPVs2dPxcbGKjQ0VAsWLLhpPjdTunRpTZgwQePGjdOyZcsUEBAgk8mk+fPn66OPPtL27dvVvHlzjR07NteM/Nvx4Ycf6q233lKLFi3yfQ6r1Zrj+xkzZjiMPXfunI4ePaqzZ8/al3NJT0/Xyy+/rOeeey7fD2cFAAAAkJvJdv2UFwAAAOSb1WrN1Qz9Xx4eHre81vrt2rt3r5599lk99NBDmjx5sqpVq2bfl56ervbt26t69er65z//qZCQEIfneffdd3Xo0CEtXLhQx48fV4kSJW66VEhmZqYqVKigcuXKadu2bfr222+1bds2de/eXS+//LLKli2rU6dO6a233tKuXbs0duxYhYaGKjU1VUOGDNGBAwc0bdo09ejRI9/XPnPmTJ09e1Zvv/12vs9R0I4fP65u3brd0oNF//jjD3Xt2lU1a9bU3LlzVbVqVc2ePVtxcXGaMWMGS7kAAAAATkQTHQAAwInGjx+vb7/91uH+0NBQvfbaawWWzx9//KG77777ts7x+uuv6+jRo1q+fHmej42JidG6dev05JNPqmrVqvbtmZmZmjNnjp544glVr17dvj07O1vLly9X37595eXlle+cbTabLl26JD8/v3yfo7BLS0tTqVKlcnzv6emp4sWLG5gVAAAA4H5oogMAADjR6dOndfHiRYf7AwICFBgYWIAZAQAAAABuB010AAAAAAAAAAAcKJgFOQEAAAAAAAAAcEE00QEAAAAAAAAAcIAmOgAAAAAAAAAADtBEBwAAAAAAAADAAZroAAAAAAAAAAA4QBMdAAAAAAAAAAAHaKIDAAAAAAAAAOAATXQAAAAAAAAAABz4f+vX7CVnnsudAAAAAElFTkSuQmCC",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "import matplotlib.pyplot as plt\n",
- "import seaborn as sns\n",
- "from scipy.stats import spearmanr\n",
- "from tqdm import tqdm # 用于显示进度条 (可选)\n",
- "\n",
- "# 设置 Matplotlib/Seaborn 样式 (可选)\n",
- "sns.set_theme(style=\"whitegrid\")\n",
- "plt.rcParams['font.sans-serif'] = ['SimHei'] # 或者其他支持中文的字体\n",
- "plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题\n",
- "\n",
- "def analyze_score_performance_2d(score_df: pd.DataFrame,\n",
- " score_col: str = 'score',\n",
- " label_col: str = 'label',\n",
- " condition1_col: str = 'circ_mv',\n",
- " condition2_col: str = 'future_return',\n",
- " n_bins: int = 100,\n",
- " min_samples_per_bin: int = 30): # 每个格子最少样本数\n",
- " \"\"\"\n",
- " 分析 score 在两个条件下 (如市值、未来收益) 的二维分箱表现。\n",
- "\n",
- " Args:\n",
- " score_df (pd.DataFrame): 包含分数、标签和条件列的 DataFrame。\n",
- " score_col (str): 预测分数所在的列名。\n",
- " label_col (str): 目标标签所在的列名 (应为数值或可排序类别)。\n",
- " condition1_col (str): 第一个条件列名 (例如 'circ_mv')。\n",
- " condition2_col (str): 第二个条件列名 (例如 'future_return')。\n",
- " n_bins (int): 每个条件划分的箱数 (分位数数量)。\n",
- " min_samples_per_bin (int): 计算指标所需的最小样本数,小于此数目的格子结果将被屏蔽。\n",
- "\n",
- " Returns:\n",
- " tuple: 包含 (performance_pivot, count_pivot, fig)\n",
- " performance_pivot: 以二维分箱为索引/列的 Spearman 相关系数矩阵。\n",
- " count_pivot: 每个二维分箱的样本数量矩阵。\n",
- " fig: 生成的热力图 Matplotlib Figure 对象。\n",
- " \"\"\"\n",
- " print(f\"开始分析 '{score_col}' 在 '{condition1_col}' 和 '{condition2_col}' 下的表现...\")\n",
- "\n",
- " required_cols = [score_col, label_col, condition1_col, condition2_col]\n",
- " if not all(col in score_df.columns for col in required_cols):\n",
- " missing = [col for col in required_cols if col not in score_df.columns]\n",
- " raise ValueError(f\"输入 DataFrame 缺少必需列: {missing}\")\n",
- "\n",
- " # --- 1. 数据准备和清洗 ---\n",
- " print(\"准备数据,处理 NaN 值...\")\n",
- " # 只保留需要的列,并移除包含 NaN 的行,避免影响分箱和计算\n",
- " analysis_df = score_df[required_cols].dropna().copy()\n",
- " n_original = len(score_df)\n",
- " n_after_drop = len(analysis_df)\n",
- " print(f\"原始数据 {n_original} 行,移除 NaN 后剩余 {n_after_drop} 行用于分析。\")\n",
- "\n",
- " if n_after_drop < min_samples_per_bin * n_bins: # 检查数据量是否过少\n",
- " print(f\"警告: 清理 NaN 后数据量 ({n_after_drop}) 可能不足以支持 {n_bins}x{n_bins} 的精细分箱分析。\")\n",
- " if n_after_drop < min_samples_per_bin:\n",
- " print(\"错误: 有效数据过少,无法进行分析。\")\n",
- " return None, None, None\n",
- "\n",
- " # --- 2. 二维分箱 ---\n",
- " print(f\"对 '{condition1_col}' 和 '{condition2_col}' 进行 {n_bins} 分位数分箱...\")\n",
- " bin1_col = f'{condition1_col}_bin'\n",
- " bin2_col = f'{condition2_col}_bin'\n",
- "\n",
- " try:\n",
- " # 使用 qcut 进行分位数分箱,labels=False 返回 0 到 n_bins-1 的整数标签\n",
- " # duplicates='drop' 会丢弃导致边界不唯一的重复值所在的箱子,可能导致某些箱号缺失\n",
- " # 对于可视化,这通常可以接受,但如果需要严格的等分,需先 rank\n",
- " analysis_df[bin1_col] = pd.qcut(analysis_df[condition1_col], q=n_bins, labels=False, duplicates='drop')\n",
- " analysis_df[bin2_col] = pd.qcut(analysis_df[condition2_col], q=n_bins, labels=False, duplicates='drop')\n",
- " except Exception as e:\n",
- " print(f\"错误: 分箱失败,请检查数据分布或减少 n_bins。错误信息: {e}\")\n",
- " # 可以尝试先 rank 再 qcut\n",
- " # analysis_df[bin1_col] = pd.qcut(analysis_df[condition1_col].rank(method='first'), q=n_bins, labels=False, duplicates='raise')\n",
- " # analysis_df[bin2_col] = pd.qcut(analysis_df[condition2_col].rank(method='first'), q=n_bins, labels=False, duplicates='raise')\n",
- " return None, None, None\n",
- "\n",
- " # --- 3. 分组计算表现指标 (Spearman Rank IC) ---\n",
- " print(\"按二维分箱分组计算 Spearman Rank IC...\")\n",
- "\n",
- " def safe_spearmanr(x, y):\n",
- " \"\"\"安全计算 Spearman 相关性,处理数据量过少的情况\"\"\"\n",
- " if len(x) < max(2, min_samples_per_bin): # 要求至少有 min_samples_per_bin 个点才计算\n",
- " return np.nan\n",
- " corr, p_value = spearmanr(x, y)\n",
- " return corr if not np.isnan(corr) else np.nan # 确保返回 NaN 而不是 None 或其他\n",
- "\n",
- " # 按两个分箱列分组\n",
- " grouped = analysis_df.groupby([bin1_col, bin2_col])\n",
- "\n",
- " # 计算每个格子的 Spearman 相关系数\n",
- " # apply 可能较慢,但计算相关性通常需要 apply\n",
- " performance_series = grouped.apply(lambda sub: safe_spearmanr(sub[score_col], sub[label_col]))\n",
- "\n",
- " # 计算每个格子的样本数量\n",
- " count_series = grouped.size()\n",
- "\n",
- " # --- 4. 结果整理成 Pivot Table (用于绘图) ---\n",
- " print(\"整理结果用于绘图...\")\n",
- " try:\n",
- " # 将 performance_series 转换成二维矩阵\n",
- " # index 为 condition1_bin, columns 为 condition2_bin\n",
- " performance_pivot = performance_series.unstack(level=0) # level=0 对应第一个 groupby key (bin1_col)\n",
- " count_pivot = count_series.unstack(level=0)\n",
- "\n",
- " # 可选:按列和索引排序,确保顺序正确\n",
- " performance_pivot = performance_pivot.sort_index(axis=0).sort_index(axis=1)\n",
- " count_pivot = count_pivot.sort_index(axis=0).sort_index(axis=1)\n",
- " \n",
- " print(performance_pivot)\n",
- "\n",
- " except Exception as e:\n",
- " print(f\"错误: 无法将结果转换为二维矩阵,可能因为分箱不均匀或数据问题: {e}\")\n",
- " return None, None, None\n",
- "\n",
- " # --- 5. 可视化:绘制热力图 ---\n",
- " print(\"生成热力图...\")\n",
- " fig, ax = plt.subplots(figsize=(16, 12)) # 调整图像大小\n",
- "\n",
- " # 使用 count_pivot 创建一个 mask,屏蔽掉样本量过小的格子\n",
- " mask = count_pivot < min_samples_per_bin\n",
- "\n",
- " # 绘制热力图\n",
- " sns.heatmap(performance_pivot,\n",
- " annot=False, # 100x100 个格子加注释会太密集\n",
- " fmt=\".2f\",\n",
- " cmap=\"viridis\", # 选择颜色映射, 'viridis', 'coolwarm', 'RdYlGn' 等都不错\n",
- " linewidths=.5,\n",
- " linecolor='lightgray',\n",
- " # mask=mask, # 应用 mask\n",
- " ax=ax,\n",
- " cbar_kws={'label': f'Spearman Rank IC ({score_col} vs {label_col})'}) # 颜色条标签\n",
- "\n",
- " # 设置标题和轴标签\n",
- " ax.set_title(f'{score_col} 表现分析 (Rank IC vs {label_col})\\n基于 {condition1_col} 和 {condition2_col} {n_bins}x{n_bins} 分箱', fontsize=16)\n",
- " ax.set_xlabel(f'{condition1_col} 分位数 (0 -> 高)', fontsize=12)\n",
- " ax.set_ylabel(f'{condition2_col} 分位数 (0 -> 高)', fontsize=12)\n",
- "\n",
- " # 可选:调整刻度标签,避免显示所有 100 个刻度\n",
- " if n_bins > 20:\n",
- " tick_interval = n_bins // 10 # 大约显示 10 个刻度\n",
- " ax.set_xticks(np.arange(0, n_bins, tick_interval) + 0.5)\n",
- " ax.set_yticks(np.arange(0, n_bins, tick_interval) + 0.5)\n",
- " ax.set_xticklabels(np.arange(0, n_bins, tick_interval))\n",
- " ax.set_yticklabels(np.arange(0, n_bins, tick_interval))\n",
- "\n",
- " plt.xticks(rotation=45, ha='right')\n",
- " plt.yticks(rotation=0)\n",
- " plt.tight_layout() # 调整布局\n",
- "\n",
- " print(\"分析完成。\")\n",
- " return performance_pivot, count_pivot, fig\n",
- "\n",
- "# --- 如何使用 ---\n",
- "# 假设你的包含预测结果和所需列的 DataFrame 是 final_predictions_df\n",
- "# 确保它包含 'score', 'label', 'circ_mv', 'future_return'\n",
- "\n",
- "# # 示例调用 (你需要有实际的 score_df)\n",
- "try:\n",
- " # 确保数据类型正确\n",
- " cols_to_numeric = ['score', 'label', 'circ_mv', 'future_return']\n",
- " for col in cols_to_numeric:\n",
- " if col in score_df.columns:\n",
- " score_df[col] = pd.to_numeric(score_df[col], errors='coerce')\n",
- "\n",
- " # 调用分析函数\n",
- " performance_matrix, count_matrix, heatmap_figure = analyze_score_performance_2d(\n",
- " score_df,\n",
- " n_bins=100, # 你要求的100分箱\n",
- " min_samples_per_bin=50 # 每个格子至少需要50个样本才显示IC,可以调整\n",
- " )\n",
- "\n",
- " # 显示图像\n",
- " if heatmap_figure:\n",
- " plt.show()\n",
- "\n",
- " # 可以查看具体的 performance_matrix 和 count_matrix\n",
- " # print(\"\\nPerformance Matrix (Spearman IC):\")\n",
- " # print(performance_matrix)\n",
- " # print(\"\\nCount Matrix:\")\n",
- " # print(count_matrix)\n",
- "\n",
- "except ValueError as ve:\n",
- " print(f\"数据错误: {ve}\")\n",
- "except Exception as e:\n",
- " print(f\"发生未知错误: {e}\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "a436dba4",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Empty DataFrame\n",
- "Columns: [ts_code, trade_date, is_st]\n",
- "Index: []\n"
- ]
- },
- {
- "ename": "",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31mnotebook controller is DISPOSED. \n",
- "\u001b[1;31m有关更多详细信息,请查看 Jupyter log。"
- ]
- }
- ],
- "source": [
- "print(df[(df['ts_code'] == '600242.SH') & (df['trade_date'] >= '2023-06-01')][['ts_code', 'trade_date', 'is_st']])"
+ "print(df)"
]
}
],
diff --git a/main/train/Classify2.ipynb b/main/train/Classify2.ipynb
index bc593b0..f5edfe1 100644
--- a/main/train/Classify2.ipynb
+++ b/main/train/Classify2.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 1,
"id": "79a7758178bafdd3",
"metadata": {
"ExecuteTime": {
@@ -45,7 +45,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 2,
"id": "4a481c60",
"metadata": {},
"outputs": [],
@@ -57,7 +57,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 3,
"id": "a79cafb06a7e0e43",
"metadata": {
"ExecuteTime": {
@@ -81,7 +81,7 @@
"cyq perf\n",
"left merge on ['ts_code', 'trade_date']\n",
"\n",
- "RangeIndex: 8820754 entries, 0 to 8820753\n",
+ "RangeIndex: 9162612 entries, 0 to 9162611\n",
"Data columns (total 33 columns):\n",
" # Column Dtype \n",
"--- ------ ----- \n",
@@ -119,7 +119,7 @@
" 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",
+ "memory usage: 2.2+ GB\n",
"None\n"
]
}
@@ -157,7 +157,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 4,
"id": "cac01788dac10678",
"metadata": {
"ExecuteTime": {
@@ -225,7 +225,7 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 5,
"id": "c4e9e1d31da6dba6",
"metadata": {
"ExecuteTime": {
@@ -325,7 +325,7 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 6,
"id": "a735bc02ceb4d872",
"metadata": {
"ExecuteTime": {
@@ -341,7 +341,7 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 7,
"id": "53f86ddc0677a6d7",
"metadata": {
"ExecuteTime": {
@@ -408,7 +408,7 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 8,
"id": "dbe2fd8021b9417f",
"metadata": {
"ExecuteTime": {
@@ -436,7 +436,7 @@
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": 9,
"id": "85c3e3d0235ffffa",
"metadata": {
"ExecuteTime": {
@@ -468,7 +468,7 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 10,
"id": "92d84ce15a562ec6",
"metadata": {
"ExecuteTime": {
@@ -603,10 +603,10 @@
"Calculating cs_rank_size...\n",
"Finished cs_rank_size.\n",
"\n",
- "RangeIndex: 4554725 entries, 0 to 4554724\n",
+ "RangeIndex: 4819708 entries, 0 to 4819707\n",
"Columns: 181 entries, ts_code to cs_rank_size\n",
"dtypes: bool(10), datetime64[ns](1), float64(165), int64(3), object(2)\n",
- "memory usage: 5.8+ GB\n",
+ "memory usage: 6.2+ GB\n",
"None\n",
"['ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'vol', 'amount', 'pct_chg', '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', 'undist_profit_ps', 'ocfps', 'roa', 'roe', '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_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', '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', '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"
]
@@ -621,7 +621,7 @@
"\n",
"def filter_data(df):\n",
" # df = df.groupby('trade_date').apply(lambda x: x.nlargest(1000, 'act_factor1'))\n",
- " df = df[df['trade_date'] <= '2025-06-01']\n",
+ " # df = df[df['trade_date'] <= '2025-06-01']\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",
@@ -718,7 +718,7 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 11,
"id": "b87b938028afa206",
"metadata": {
"ExecuteTime": {
@@ -756,7 +756,7 @@
},
{
"cell_type": "code",
- "execution_count": 13,
+ "execution_count": 12,
"id": "f4f16d63ad18d1bc",
"metadata": {
"ExecuteTime": {
@@ -982,7 +982,7 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": 13,
"id": "40e6b68a91b30c79",
"metadata": {
"ExecuteTime": {
@@ -1302,7 +1302,7 @@
},
{
"cell_type": "code",
- "execution_count": 15,
+ "execution_count": 14,
"id": "47c12bb34062ae7a",
"metadata": {
"ExecuteTime": {
@@ -1336,7 +1336,7 @@
},
{
"cell_type": "code",
- "execution_count": 16,
+ "execution_count": 15,
"id": "29221dde",
"metadata": {},
"outputs": [
@@ -1379,7 +1379,7 @@
},
{
"cell_type": "code",
- "execution_count": 17,
+ "execution_count": 16,
"id": "03ee5daf",
"metadata": {},
"outputs": [],
@@ -1392,7 +1392,7 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": 17,
"id": "b76ea08a",
"metadata": {},
"outputs": [
@@ -1413,7 +1413,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
- "MAD Filtering: 100%|██████████| 131/131 [00:15<00:00, 8.53it/s]\n"
+ "MAD Filtering: 100%|██████████| 131/131 [00:23<00:00, 5.61it/s]\n"
]
},
{
@@ -1428,7 +1428,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
- "MAD Filtering: 100%|██████████| 131/131 [00:11<00:00, 11.23it/s]\n"
+ "MAD Filtering: 100%|██████████| 131/131 [00:03<00:00, 34.28it/s]\n"
]
},
{
@@ -1468,13 +1468,13 @@
"截面 MAD 去极值处理完成。\n",
"feature_columns: ['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'winner_rate', 'undist_profit_ps', 'ocfps', 'AR', 'BR', 'AR_BR', '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', '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', 'cat_up_limit', '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",
- "2057465\n",
+ "df最大日期: 2025-10-10\n",
+ "3509747\n",
"train_data最小日期: 2020-01-02\n",
- "train_data最大日期: 2022-12-30\n",
- "1781706\n",
- "test_data最小日期: 2023-01-03\n",
- "test_data最大日期: 2025-05-30\n",
+ "train_data最大日期: 2024-12-31\n",
+ "559901\n",
+ "test_data最小日期: 2025-01-02\n",
+ "test_data最大日期: 2025-10-10\n",
" ts_code trade_date log_circ_mv\n",
"0 000001.SZ 2019-01-02 16.574219\n",
"1 000001.SZ 2019-01-03 16.583965\n",
@@ -1483,7 +1483,7 @@
}
],
"source": [
- "split_date = '2023-01-01'\n",
+ "split_date = '2025-01-01'\n",
"train_data = df[filter_index & (df['trade_date'] <= split_date) & (df['trade_date'] >= '2020-01-01')]\n",
"test_data = df[(df['trade_date'] >= split_date)]\n",
"\n",
@@ -1610,7 +1610,7 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": 18,
"id": "3ff2d1c5",
"metadata": {},
"outputs": [],
@@ -1751,7 +1751,7 @@
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": 19,
"id": "c6eb5cd4-e714-420a-ac48-39af3e11ee81",
"metadata": {
"ExecuteTime": {
@@ -1764,7 +1764,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "train data size: 36400\n",
+ "train data size: 60600\n",
" ts_code trade_date log_circ_mv\n",
"0 600306.SH 2020-01-02 11.552040\n",
"1 603269.SH 2020-01-02 11.324801\n",
@@ -1772,20 +1772,20 @@
"3 603991.SH 2020-01-02 11.181150\n",
"4 000691.SZ 2020-01-02 11.677910\n",
"... ... ... ...\n",
- "36395 600615.SH 2022-12-30 12.027909\n",
- "36396 603829.SH 2022-12-30 12.034572\n",
- "36397 603037.SH 2022-12-30 12.035767\n",
- "36398 002767.SZ 2022-12-30 11.896427\n",
- "36399 600561.SH 2022-12-30 11.858571\n",
+ "60595 002211.SZ 2024-12-31 11.938823\n",
+ "60596 002058.SZ 2024-12-31 11.941882\n",
+ "60597 600883.SH 2024-12-31 11.948840\n",
+ "60598 002072.SZ 2024-12-31 11.589595\n",
+ "60599 600149.SH 2024-12-31 11.951859\n",
"\n",
- "[36400 rows x 3 columns]\n",
- "原始样本数: 36400, 去除标签为空后样本数: 36400\n"
+ "[60600 rows x 3 columns]\n",
+ "原始样本数: 60600, 去除标签为空后样本数: 60600\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "9de2338da1fc42ec952054f233070da7",
+ "model_id": "30b53365fe7b4643b79cadcb7280cf28",
"version_major": 2,
"version_minor": 0
},
@@ -1800,10 +1800,10 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "0:\tlearn: 0.6890148\ttest: 0.6905107\tbest: 0.6905107 (0)\ttotal: 92.5ms\tremaining: 2m 18s\n",
- "bestTest = 0.5221693203\n",
- "bestIteration = 874\n",
- "Shrink model to first 875 iterations.\n"
+ "0:\tlearn: 0.6885716\ttest: 0.6919121\tbest: 0.6919121 (0)\ttotal: 823ms\tremaining: 20m 34s\n",
+ "bestTest = 0.667731918\n",
+ "bestIteration = 74\n",
+ "Shrink model to first 75 iterations.\n"
]
}
],
@@ -1825,7 +1825,7 @@
},
{
"cell_type": "code",
- "execution_count": 21,
+ "execution_count": 20,
"id": "5d1522a7538db91b",
"metadata": {
"ExecuteTime": {
@@ -1863,18 +1863,10 @@
},
{
"cell_type": "code",
- "execution_count": 22,
+ "execution_count": 21,
"id": "c1c40917",
"metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "模型已保存到: /mnt/d/PyProject/NewStock/main/train/catboost_model/catboost_model_2025-06-01.cbm\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
"current_date = datetime.datetime.now()\n",
"\n",
@@ -1883,15 +1875,15 @@
"date_str = current_date.strftime('%Y-%m-%d')\n",
"\n",
"# 3. 构建包含日期的模型文件名\n",
- "model_filename = f'/mnt/d/PyProject/NewStock/main/train/catboost_model/catboost_model_2025-06-01.cbm'\n",
+ "# model_filename = f'/mnt/d/PyProject/NewStock/main/train/catboost_model/catboost_model_2025-06-01.cbm'\n",
"\n",
- "model.save_model(model_filename)\n",
- "print(f\"模型已保存到: {model_filename}\")"
+ "# model.save_model(model_filename)\n",
+ "# print(f\"模型已保存到: {model_filename}\")"
]
},
{
"cell_type": "code",
- "execution_count": 23,
+ "execution_count": 22,
"id": "09b1799e",
"metadata": {},
"outputs": [
@@ -1913,7 +1905,7 @@
},
{
"cell_type": "code",
- "execution_count": 24,
+ "execution_count": 23,
"id": "e53b209a",
"metadata": {},
"outputs": [
@@ -1921,21 +1913,21 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "5595 2057465\n",
- " ts_code trade_date turnover_rate\n",
- "0 000001.SZ 2023-01-03 1.1307\n",
- "1 000001.SZ 2023-01-04 1.1284\n",
- "2 000001.SZ 2023-01-05 0.8582\n",
- "3 000001.SZ 2023-01-06 0.6162\n",
- "4 000001.SZ 2023-01-09 0.5450\n",
- "... ... ... ...\n",
- "1781701 605599.SH 2025-05-26 0.6188\n",
- "1781702 605599.SH 2025-05-27 1.2576\n",
- "1781703 605599.SH 2025-05-28 2.0432\n",
- "1781704 605599.SH 2025-05-29 2.0954\n",
- "1781705 605599.SH 2025-05-30 1.4392\n",
+ "15540 3509747\n",
+ " ts_code trade_date turnover_rate\n",
+ "0 000001.SZ 2025-01-02 0.9377\n",
+ "1 000001.SZ 2025-01-03 0.5950\n",
+ "2 000001.SZ 2025-01-06 0.5594\n",
+ "3 000001.SZ 2025-01-07 0.3854\n",
+ "4 000001.SZ 2025-01-08 0.5475\n",
+ "... ... ... ...\n",
+ "559896 605599.SH 2025-09-26 0.3434\n",
+ "559897 605599.SH 2025-09-29 0.3943\n",
+ "559898 605599.SH 2025-09-30 0.4982\n",
+ "559899 605599.SH 2025-10-09 1.0319\n",
+ "559900 605599.SH 2025-10-10 0.8859\n",
"\n",
- "[1781706 rows x 3 columns]\n"
+ "[559901 rows x 3 columns]\n"
]
}
],
@@ -1946,7 +1938,7 @@
},
{
"cell_type": "code",
- "execution_count": 25,
+ "execution_count": 24,
"id": "364e821a",
"metadata": {},
"outputs": [],
@@ -2030,7 +2022,7 @@
},
{
"cell_type": "code",
- "execution_count": 26,
+ "execution_count": 25,
"id": "1f6e6336",
"metadata": {},
"outputs": [
@@ -2038,32 +2030,32 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "6e+04-9e+04\n",
+ "7e+04-9e+04\n",
"9e+04-1e+05\n",
"1e+05-1e+05\n",
- "1e+05-1e+05\n",
"1e+05-2e+05\n",
"2e+05-2e+05\n",
"2e+05-2e+05\n",
"2e+05-2e+05\n",
"2e+05-3e+05\n",
"3e+05-3e+05\n",
+ "3e+05-3e+05\n",
"二分类评估指标:\n",
- "accuracy: 0.6449\n",
- "precision: 0.4384\n",
- "recall: 0.2532\n",
- "f1: 0.3210\n",
- "roc_auc: 0.6147\n",
- "fpr: (array of length 7456)\n",
- "tpr: (array of length 7456)\n",
- "thresholds: (array of length 7456)\n",
- "score_return_correlation: -0.0356\n",
- "mv_roc_auc: {'6e+04-9e+04': np.float64(0.5291280148423005), '9e+04-1e+05': np.float64(0.5695028952947505), '1e+05-1e+05': np.float64(0.5623844792554237), '1e+05-2e+05': np.float64(0.5622699726201068), '2e+05-2e+05': np.float64(0.6035659704533877), '2e+05-3e+05': np.float64(0.6119956359669062), '3e+05-3e+05': np.float64(0.5959528412973004)}\n"
+ "accuracy: 0.6690\n",
+ "precision: 0.0000\n",
+ "recall: 0.0000\n",
+ "f1: 0.0000\n",
+ "roc_auc: 0.6421\n",
+ "fpr: (array of length 2338)\n",
+ "tpr: (array of length 2338)\n",
+ "thresholds: (array of length 2338)\n",
+ "score_return_correlation: 0.0225\n",
+ "mv_roc_auc: {'7e+04-9e+04': np.float64(0.6513157894736842), '9e+04-1e+05': np.float64(0.5768921095008052), '1e+05-1e+05': np.float64(0.6421728904950381), '1e+05-2e+05': np.float64(0.6613848565392216), '2e+05-2e+05': np.float64(0.6637681784060829), '2e+05-3e+05': np.float64(0.6137690379795642), '3e+05-3e+05': np.float64(0.5940703428773416)}\n"
]
},
{
"data": {
- "image/png": "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",
+ "image/png": "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918MHz5c/do3btwYGzZswOrVq/H7779rPS48PBw7duxAoUKF1MehSZMm2LBhA9auXYvRo0cna/8JCQl4/vw5mjZtmqztiX4Ex8wSpZKaNWuiQoUKmDNnDmJjY5E1a1bUrFkT//77L16/fq21fXBwsPrfrVq1wvXr17Ft2zat7T6fJWvbti1evnyJpUuXam0TExOjvio/MYULF0bx4sXh7+8Pf39/ZMuWTaOxNDc3R6tWrbBlyxadv2y/zquvypUro27duli5cqXOOwyNHTsWDx48wMiRI7XOmG3fvl1jzOuFCxdw/vx5dSOhz+ucFHNzc60zpfPmzYNSqdSo2dnZAYBWk/sjypUrh8yZM2Pp0qVISEhQ19etW5fombiveXh4oFevXjh48CDmzZuntV6lUmHmzJl48eKFXrk+n7n9dsjFypUrU/056tevDwcHB0ybNg2xsbEa675+rJ2dnc5hHz/6/tBFqVRq7Str1qzInj074uLivpvpW66urqhevTpWrFiBoKAgjXXfO0ufI0cOeHh46HUnt5EjR0KhUGicrW7dujWKFCmCv/76S+u5VCoV+vXrhw8fPmDChAkajylevDimTJmCc+fOae0nIiICY8eO1ajduXMHsbGxqFy5crLzEqUUz8wSpaIRI0agTZs28PPzQ9++fbFgwQJUrVoVxYsXR69evZA3b168ffsW586dw4sXL9S3exwxYoT6zlLdu3dH2bJlERoaip07d2Lx4sUoWbIkOnfujE2bNqFv3744duwYqlSpAqVSiXv37mHTpk04cOCAethDYry9vTF+/HhYW1ujR48eMDPT/Hv2r7/+wrFjx1CxYkX06tULRYoUQWhoKK5cuYLDhw8jNDQ0xa/N6tWrUadOHTRr1gwdOnRAtWrVEBcXh61bt+L48ePw9vbGiBEjtB6XP39+VK1aFf369UNcXBzmzJmDzJkzY+TIkeptkvs6J6Vx48ZYs2YNnJycUKRIEZw7dw6HDx9Wf7z7WalSpWBubo7p06cjLCwMVlZWqF27NrJmzZri18bS0hITJ07EoEGDULt2bbRt2xaBgYHw8/NDvnz5knXmb+bMmXj8+DEGDx6MrVu3onHjxnBxcUFQUBA2b96Me/fuaZyJT4769evD0tISTZo0QZ8+fRAZGYmlS5cia9asOv9w+JHncHR0xOzZs9GzZ0+UL18eHTp0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",
"text/plain": [
""
]
@@ -2099,7 +2091,7 @@
},
{
"cell_type": "code",
- "execution_count": 27,
+ "execution_count": 26,
"id": "7e9023cc",
"metadata": {},
"outputs": [],
@@ -2299,7 +2291,7 @@
},
{
"cell_type": "code",
- "execution_count": 28,
+ "execution_count": 27,
"id": "a0000d75",
"metadata": {},
"outputs": [
@@ -2309,7 +2301,7 @@
"text": [
"开始分析 'score' 在 'circ_mv' 和 'future_return' 下的表现...\n",
"准备数据,处理 NaN 值...\n",
- "原始数据 17430 行,移除 NaN 后剩余 17119 行用于分析。\n",
+ "原始数据 5550 行,移除 NaN 后剩余 5297 行用于分析。\n",
"对 'circ_mv' 和 'future_return' 进行 100 分位数分箱...\n",
"按二维分箱分组计算 Spearman Rank IC...\n",
"整理结果用于绘图...\n",
@@ -2545,7 +2537,7 @@
},
{
"cell_type": "code",
- "execution_count": 29,
+ "execution_count": 28,
"id": "a436dba4",
"metadata": {},
"outputs": [
diff --git a/main/train/Classify2_load_model.ipynb b/main/train/Classify2_load_model.ipynb
index 131edef..d769be4 100644
--- a/main/train/Classify2_load_model.ipynb
+++ b/main/train/Classify2_load_model.ipynb
@@ -68,56 +68,28 @@
"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: 9162612 entries, 0 to 9162611\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 amount float64 \n",
- " 8 pct_chg 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.2+ GB\n",
- "None\n"
+ "daily data\n"
+ ]
+ },
+ {
+ "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[3]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmain\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mutils\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mutils\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m read_and_merge_h5_data\n\u001b[32m 3\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m'\u001b[39m\u001b[33mdaily data\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m df = \u001b[43mread_and_merge_h5_data\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43m/mnt/d/PyProject/NewStock/data/daily_data.h5\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkey\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mdaily_data\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 5\u001b[39m \u001b[43m \u001b[49m\u001b[43mcolumns\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mts_code\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\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[33;43m'\u001b[39;49m\u001b[33;43mopen\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mclose\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mhigh\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mlow\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvol\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mamount\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mpct_chg\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 6\u001b[39m \u001b[43m \u001b[49m\u001b[43mdf\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[32m 8\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m'\u001b[39m\u001b[33mdaily basic\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 9\u001b[39m df = read_and_merge_h5_data(\u001b[33m'\u001b[39m\u001b[33m/mnt/d/PyProject/NewStock/data/daily_basic.h5\u001b[39m\u001b[33m'\u001b[39m, key=\u001b[33m'\u001b[39m\u001b[33mdaily_basic\u001b[39m\u001b[33m'\u001b[39m,\n\u001b[32m 10\u001b[39m columns=[\u001b[33m'\u001b[39m\u001b[33mts_code\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtrade_date\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mturnover_rate\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mpe_ttm\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mcirc_mv\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mtotal_mv\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mvolume_ratio\u001b[39m\u001b[33m'\u001b[39m,\n\u001b[32m 11\u001b[39m \u001b[33m'\u001b[39m\u001b[33mis_st\u001b[39m\u001b[33m'\u001b[39m], df=df, join=\u001b[33m'\u001b[39m\u001b[33minner\u001b[39m\u001b[33m'\u001b[39m)\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/PyProject/NewStock/main/utils/utils.py:14\u001b[39m, in \u001b[36mread_and_merge_h5_data\u001b[39m\u001b[34m(h5_filename, key, columns, df, join, on, prefix)\u001b[39m\n\u001b[32m 11\u001b[39m processed_columns.append(col)\n\u001b[32m 13\u001b[39m \u001b[38;5;66;03m# 从 HDF5 文件读取数据,选择需要的列\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m data = \u001b[43mpd\u001b[49m\u001b[43m.\u001b[49m\u001b[43mread_hdf\u001b[49m\u001b[43m(\u001b[49m\u001b[43mh5_filename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkey\u001b[49m\u001b[43m=\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcolumns\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprocessed_columns\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m# 修改列名,如果列名以前有 _,加上 _\u001b[39;00m\n\u001b[32m 17\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m col \u001b[38;5;129;01min\u001b[39;00m data.columns:\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/io/pytables.py:452\u001b[39m, in \u001b[36mread_hdf\u001b[39m\u001b[34m(path_or_buf, key, mode, errors, where, start, stop, columns, iterator, chunksize, **kwargs)\u001b[39m\n\u001b[32m 447\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[32m 448\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mkey must be provided when HDF5 \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 449\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mfile contains multiple datasets.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 450\u001b[39m )\n\u001b[32m 451\u001b[39m key = candidate_only_group._v_pathname\n\u001b[32m--> \u001b[39m\u001b[32m452\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mstore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mselect\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 453\u001b[39m \u001b[43m \u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 454\u001b[39m \u001b[43m \u001b[49m\u001b[43mwhere\u001b[49m\u001b[43m=\u001b[49m\u001b[43mwhere\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 455\u001b[39m \u001b[43m \u001b[49m\u001b[43mstart\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 456\u001b[39m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 457\u001b[39m \u001b[43m \u001b[49m\u001b[43mcolumns\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcolumns\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 458\u001b[39m \u001b[43m \u001b[49m\u001b[43miterator\u001b[49m\u001b[43m=\u001b[49m\u001b[43miterator\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 459\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunksize\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunksize\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 460\u001b[39m \u001b[43m \u001b[49m\u001b[43mauto_close\u001b[49m\u001b[43m=\u001b[49m\u001b[43mauto_close\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 461\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 462\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mValueError\u001b[39;00m, \u001b[38;5;167;01mTypeError\u001b[39;00m, \u001b[38;5;167;01mLookupError\u001b[39;00m):\n\u001b[32m 463\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(path_or_buf, HDFStore):\n\u001b[32m 464\u001b[39m \u001b[38;5;66;03m# if there is an error, close the store if we opened it.\u001b[39;00m\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/io/pytables.py:906\u001b[39m, in \u001b[36mHDFStore.select\u001b[39m\u001b[34m(self, key, where, start, stop, columns, iterator, chunksize, auto_close)\u001b[39m\n\u001b[32m 892\u001b[39m \u001b[38;5;66;03m# create the iterator\u001b[39;00m\n\u001b[32m 893\u001b[39m it = TableIterator(\n\u001b[32m 894\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 895\u001b[39m s,\n\u001b[32m (...)\u001b[39m\u001b[32m 903\u001b[39m auto_close=auto_close,\n\u001b[32m 904\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m906\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mit\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_result\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/io/pytables.py:2029\u001b[39m, in \u001b[36mTableIterator.get_result\u001b[39m\u001b[34m(self, coordinates)\u001b[39m\n\u001b[32m 2026\u001b[39m where = \u001b[38;5;28mself\u001b[39m.where\n\u001b[32m 2028\u001b[39m \u001b[38;5;66;03m# directly return the result\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m2029\u001b[39m results = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mwhere\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 2030\u001b[39m \u001b[38;5;28mself\u001b[39m.close()\n\u001b[32m 2031\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m results\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/io/pytables.py:890\u001b[39m, in \u001b[36mHDFStore.select..func\u001b[39m\u001b[34m(_start, _stop, _where)\u001b[39m\n\u001b[32m 889\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mfunc\u001b[39m(_start, _stop, _where):\n\u001b[32m--> \u001b[39m\u001b[32m890\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43ms\u001b[49m\u001b[43m.\u001b[49m\u001b[43mread\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m=\u001b[49m\u001b[43m_start\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43m_stop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mwhere\u001b[49m\u001b[43m=\u001b[49m\u001b[43m_where\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\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/io/pytables.py:4631\u001b[39m, in \u001b[36mAppendableFrameTable.read\u001b[39m\u001b[34m(self, where, columns, start, stop)\u001b[39m\n\u001b[32m 4628\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m.infer_axes():\n\u001b[32m 4629\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m4631\u001b[39m result = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_read_axes\u001b[49m\u001b[43m(\u001b[49m\u001b[43mwhere\u001b[49m\u001b[43m=\u001b[49m\u001b[43mwhere\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstart\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 4633\u001b[39m info = (\n\u001b[32m 4634\u001b[39m \u001b[38;5;28mself\u001b[39m.info.get(\u001b[38;5;28mself\u001b[39m.non_index_axes[\u001b[32m0\u001b[39m][\u001b[32m0\u001b[39m], {})\n\u001b[32m 4635\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m.non_index_axes)\n\u001b[32m 4636\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m {}\n\u001b[32m 4637\u001b[39m )\n\u001b[32m 4639\u001b[39m inds = [i \u001b[38;5;28;01mfor\u001b[39;00m i, ax \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(\u001b[38;5;28mself\u001b[39m.axes) \u001b[38;5;28;01mif\u001b[39;00m ax \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28mself\u001b[39m.index_axes[\u001b[32m0\u001b[39m]]\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/io/pytables.py:3818\u001b[39m, in \u001b[36mTable._read_axes\u001b[39m\u001b[34m(self, where, start, stop)\u001b[39m\n\u001b[32m 3816\u001b[39m \u001b[38;5;66;03m# create the selection\u001b[39;00m\n\u001b[32m 3817\u001b[39m selection = Selection(\u001b[38;5;28mself\u001b[39m, where=where, start=start, stop=stop)\n\u001b[32m-> \u001b[39m\u001b[32m3818\u001b[39m values = \u001b[43mselection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mselect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 3820\u001b[39m results = []\n\u001b[32m 3821\u001b[39m \u001b[38;5;66;03m# convert the data\u001b[39;00m\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/pandas/io/pytables.py:5397\u001b[39m, in \u001b[36mSelection.select\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 5395\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.coordinates \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 5396\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.table.table.read_coordinates(\u001b[38;5;28mself\u001b[39m.coordinates)\n\u001b[32m-> \u001b[39m\u001b[32m5397\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtable\u001b[49m\u001b[43m.\u001b[49m\u001b[43mtable\u001b[49m\u001b[43m.\u001b[49m\u001b[43mread\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m)\u001b[49m\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/tables/table.py:2083\u001b[39m, in \u001b[36mTable.read\u001b[39m\u001b[34m(self, start, stop, step, field, out)\u001b[39m\n\u001b[32m 2077\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(msg)\n\u001b[32m 2079\u001b[39m start, stop, step = \u001b[38;5;28mself\u001b[39m._process_range(\n\u001b[32m 2080\u001b[39m start, stop, step, warn_negstep=\u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[32m 2081\u001b[39m )\n\u001b[32m-> \u001b[39m\u001b[32m2083\u001b[39m arr = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_read\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfield\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 2084\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m internal_to_flavor(arr, \u001b[38;5;28mself\u001b[39m.flavor)\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/stock/lib/python3.13/site-packages/tables/table.py:1989\u001b[39m, in \u001b[36mTable._read\u001b[39m\u001b[34m(self, start, stop, step, field, out)\u001b[39m\n\u001b[32m 1985\u001b[39m \u001b[38;5;66;03m# Call the routine to fill-up the resulting array\u001b[39;00m\n\u001b[32m 1986\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m step == \u001b[32m1\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m field:\n\u001b[32m 1987\u001b[39m \u001b[38;5;66;03m# This optimization works three times faster than\u001b[39;00m\n\u001b[32m 1988\u001b[39m \u001b[38;5;66;03m# the row._fill_col method (up to 170 MB/s on a pentium IV @ 2GHz)\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1989\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_read_records\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m \u001b[49m\u001b[43m-\u001b[49m\u001b[43m \u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresult\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1990\u001b[39m \u001b[38;5;66;03m# Warning!: _read_field_name should not be used until\u001b[39;00m\n\u001b[32m 1991\u001b[39m \u001b[38;5;66;03m# H5TBread_fields_name in tableextension will be finished\u001b[39;00m\n\u001b[32m 1992\u001b[39m \u001b[38;5;66;03m# F. Alted 2005/05/26\u001b[39;00m\n\u001b[32m 1993\u001b[39m \u001b[38;5;66;03m# XYX Ho implementem per a PyTables 2.0??\u001b[39;00m\n\u001b[32m 1994\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m field \u001b[38;5;129;01mand\u001b[39;00m step > \u001b[32m15\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[32m0\u001b[39m:\n\u001b[32m 1995\u001b[39m \u001b[38;5;66;03m# For step>15, this seems to work always faster than row._fill_col.\u001b[39;00m\n",
+ "\u001b[31mKeyboardInterrupt\u001b[39m: "
]
}
],
@@ -154,7 +126,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": null,
"id": "cac01788dac10678",
"metadata": {
"ExecuteTime": {
@@ -222,7 +194,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": null,
"id": "c4e9e1d31da6dba6",
"metadata": {
"ExecuteTime": {
@@ -322,7 +294,7 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": null,
"id": "a735bc02ceb4d872",
"metadata": {
"ExecuteTime": {
@@ -338,7 +310,7 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": null,
"id": "53f86ddc0677a6d7",
"metadata": {
"ExecuteTime": {
@@ -405,7 +377,7 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": null,
"id": "dbe2fd8021b9417f",
"metadata": {
"ExecuteTime": {
@@ -433,7 +405,7 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": null,
"id": "85c3e3d0235ffffa",
"metadata": {
"ExecuteTime": {
@@ -465,7 +437,7 @@
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": null,
"id": "92d84ce15a562ec6",
"metadata": {
"ExecuteTime": {
@@ -722,7 +694,7 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": null,
"id": "b87b938028afa206",
"metadata": {
"ExecuteTime": {
@@ -760,7 +732,7 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": null,
"id": "f4f16d63ad18d1bc",
"metadata": {
"ExecuteTime": {
@@ -986,7 +958,7 @@
},
{
"cell_type": "code",
- "execution_count": 13,
+ "execution_count": null,
"id": "40e6b68a91b30c79",
"metadata": {
"ExecuteTime": {
@@ -1306,7 +1278,7 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": null,
"id": "47c12bb34062ae7a",
"metadata": {
"ExecuteTime": {
@@ -1340,7 +1312,7 @@
},
{
"cell_type": "code",
- "execution_count": 15,
+ "execution_count": null,
"id": "29221dde",
"metadata": {},
"outputs": [
@@ -1383,7 +1355,7 @@
},
{
"cell_type": "code",
- "execution_count": 16,
+ "execution_count": null,
"id": "03ee5daf",
"metadata": {},
"outputs": [],
@@ -1396,7 +1368,7 @@
},
{
"cell_type": "code",
- "execution_count": 17,
+ "execution_count": null,
"id": "b76ea08a",
"metadata": {},
"outputs": [
@@ -1621,7 +1593,7 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": null,
"id": "3ff2d1c5",
"metadata": {},
"outputs": [],
@@ -1762,7 +1734,7 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": null,
"id": "a5bbb8be",
"metadata": {},
"outputs": [
@@ -1787,7 +1759,7 @@
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": null,
"id": "5d1522a7538db91b",
"metadata": {
"ExecuteTime": {
@@ -1825,7 +1797,7 @@
},
{
"cell_type": "code",
- "execution_count": 21,
+ "execution_count": null,
"id": "09b1799e",
"metadata": {},
"outputs": [
@@ -1847,7 +1819,7 @@
},
{
"cell_type": "code",
- "execution_count": 22,
+ "execution_count": null,
"id": "e53b209a",
"metadata": {},
"outputs": [
diff --git a/predictions_test.tsv b/predictions_test.tsv
index 6f18a92..6b0efe3 100644
--- a/predictions_test.tsv
+++ b/predictions_test.tsv
@@ -1,1339 +1,371 @@
trade_date,score,ts_code
-2023-01-03,0.47885945722193696,600355.SH
-2023-01-03,0.4794496398576543,002199.SZ
-2023-01-04,0.5165860009003062,600455.SH
-2023-01-04,0.6284707822475957,000691.SZ
-2023-01-05,0.45342507610849814,000691.SZ
-2023-01-05,0.4540228228045671,600455.SH
-2023-01-06,0.42843733619926844,000691.SZ
-2023-01-06,0.4421580430268355,603536.SH
-2023-01-09,0.4273828171359468,002828.SZ
-2023-01-09,0.6141995113522722,603499.SH
-2023-01-10,0.41797071359460963,002828.SZ
-2023-01-10,0.5016305023005194,603499.SH
-2023-01-11,0.39348731690956285,002828.SZ
-2023-01-11,0.3974548639492933,603316.SH
-2023-01-12,0.3507238865534161,600898.SH
-2023-01-12,0.4728934873927953,603316.SH
-2023-01-13,0.35123831264028943,000691.SZ
-2023-01-13,0.3752347919486008,603316.SH
-2023-01-16,0.3147140478173332,000691.SZ
-2023-01-16,0.37474690238468134,603316.SH
-2023-01-17,0.37524355172649376,603316.SH
-2023-01-17,0.38198341939151714,002209.SZ
-2023-01-18,0.3808596431573214,600137.SH
-2023-01-18,0.5190511859093865,002816.SZ
-2023-01-19,0.358790745991016,000691.SZ
-2023-01-19,0.4777775689430156,600455.SH
-2023-01-20,0.3457076535996993,000691.SZ
-2023-01-20,0.3568353504673053,600455.SH
-2023-01-30,0.40156197711328284,603030.SH
-2023-01-30,0.42574215622114214,600355.SH
-2023-01-31,0.40516773821718316,600898.SH
-2023-01-31,0.5787479688982131,600768.SH
-2023-02-01,0.5150224953592915,002899.SZ
-2023-02-01,0.6082914491828215,600768.SH
-2023-02-02,0.5206021029958193,600768.SH
-2023-02-02,0.5261852944167362,600898.SH
-2023-02-03,0.473913742242283,002830.SZ
-2023-02-03,0.5262366881938345,600768.SH
-2023-02-06,0.4016277545771481,600898.SH
-2023-02-06,0.4809193125009747,600355.SH
-2023-02-07,0.4635519338992774,600898.SH
-2023-02-07,0.500635109831376,600768.SH
-2023-02-08,0.39059545457609707,600898.SH
-2023-02-08,0.40044322464792614,600768.SH
-2023-02-09,0.4249399548511067,603269.SH
-2023-02-09,0.5091607568273739,600768.SH
-2023-02-10,0.41124691282899895,600355.SH
-2023-02-10,0.4468460117870622,600768.SH
-2023-02-13,0.37315456396575936,600768.SH
-2023-02-13,0.3778262945399821,600355.SH
-2023-02-14,0.3554482385949266,600768.SH
-2023-02-14,0.3877913345618911,603709.SH
-2023-02-15,0.34775314880830144,603559.SH
-2023-02-15,0.4943870002719201,600355.SH
-2023-02-16,0.34665602028878006,002199.SZ
-2023-02-16,0.4255367993433563,603709.SH
-2023-02-17,0.31081317601445824,600539.SH
-2023-02-17,0.3554327162714571,002861.SZ
-2023-02-20,0.335690610866925,002861.SZ
-2023-02-20,0.34173754140583545,600355.SH
-2023-02-21,0.3649938002812785,002494.SZ
-2023-02-21,0.37518512735802473,600355.SH
-2023-02-22,0.29988822406427396,002780.SZ
-2023-02-22,0.32186008196090077,600355.SH
-2023-02-23,0.3027368238765316,600355.SH
-2023-02-23,0.317524723000595,600898.SH
-2023-02-24,0.37877366498412635,603269.SH
-2023-02-24,0.599342275548068,002633.SZ
-2023-02-27,0.44426852513339604,002633.SZ
-2023-02-27,0.48188485943806375,603559.SH
-2023-02-28,0.352240163043455,600898.SH
-2023-02-28,0.36883370621963146,600137.SH
-2023-03-01,0.32238511595397695,002633.SZ
-2023-03-01,0.5428923886108606,002848.SZ
-2023-03-02,0.3392927139282351,600898.SH
-2023-03-02,0.6626297807327568,603860.SH
-2023-03-03,0.3739616585802998,002848.SZ
-2023-03-03,0.41677166334574806,002883.SZ
-2023-03-06,0.34259331398461634,002848.SZ
-2023-03-06,0.48482191257854657,603685.SH
-2023-03-07,0.3295421983709264,002856.SZ
-2023-03-07,0.3395450344263692,002848.SZ
-2023-03-08,0.3220203064312643,002856.SZ
-2023-03-08,0.4836260499524904,603729.SH
-2023-03-09,0.328147023443869,002856.SZ
-2023-03-09,0.3281532685951232,603316.SH
-2023-03-10,0.34516251255117264,603729.SH
-2023-03-10,0.37813753258431126,603269.SH
-2023-03-13,0.3083718661587994,603269.SH
-2023-03-13,0.31504816673434183,002856.SZ
-2023-03-14,0.35517917175416375,002629.SZ
-2023-03-14,0.3974863122243927,603269.SH
-2023-03-15,0.28707167180649235,603813.SH
-2023-03-15,0.3291780283583069,603316.SH
-2023-03-16,0.34161568364085204,002830.SZ
-2023-03-16,0.3975095971185765,600768.SH
-2023-03-17,0.3486540672391469,002830.SZ
-2023-03-17,0.3557673848026299,603269.SH
-2023-03-20,0.3604941818411113,002629.SZ
-2023-03-20,0.40701947517518594,603269.SH
-2023-03-21,0.35740383000943726,002629.SZ
-2023-03-21,0.5643852911312177,600539.SH
-2023-03-22,0.3470142555526257,002856.SZ
-2023-03-22,0.36667174927605023,603729.SH
-2023-03-23,0.31929735575521384,600455.SH
-2023-03-23,0.47911937233078933,600539.SH
-2023-03-24,0.3892611868392197,000702.SZ
-2023-03-24,0.43465343103457665,600539.SH
-2023-03-27,0.3320980763632635,600455.SH
-2023-03-27,0.36601800834247716,000702.SZ
-2023-03-28,0.37792572897260546,600539.SH
-2023-03-28,0.37808926266553033,000702.SZ
-2023-03-29,0.36531102858063924,600539.SH
-2023-03-29,0.39069562163922905,000702.SZ
-2023-03-30,0.28457329708897755,600455.SH
-2023-03-30,0.2915895626163999,000702.SZ
-2023-03-31,0.282710402836109,600455.SH
-2023-03-31,0.320188999578032,000702.SZ
-2023-04-03,0.3075762659749896,000702.SZ
-2023-04-03,0.3223541919688368,603030.SH
-2023-04-04,0.31941059220810913,000702.SZ
-2023-04-04,0.4024913168765111,600455.SH
-2023-04-06,0.29538354783139975,603030.SH
-2023-04-06,0.2987015006204031,600455.SH
-2023-04-07,0.303662083396844,600355.SH
-2023-04-07,0.3066440878031005,000692.SZ
-2023-04-10,0.3103476443020088,000702.SZ
-2023-04-10,0.3263205213772171,603030.SH
-2023-04-11,0.302903807754161,000702.SZ
-2023-04-11,0.33299298999484994,603030.SH
-2023-04-12,0.3210724668106587,002816.SZ
-2023-04-12,0.35992194883909195,603030.SH
-2023-04-13,0.32468975661632943,002816.SZ
-2023-04-13,0.5772203188365422,603030.SH
-2023-04-14,0.3030930208729861,603729.SH
-2023-04-14,0.4733344700526481,603030.SH
-2023-04-17,0.29941990542748237,603729.SH
-2023-04-17,0.41014203084545975,603030.SH
-2023-04-18,0.32868820159073375,600539.SH
-2023-04-18,0.39627800479093905,603030.SH
-2023-04-19,0.2913292057649716,000609.SZ
-2023-04-19,0.45291041520388914,603030.SH
-2023-04-20,0.32509941555701577,000609.SZ
-2023-04-20,0.4303410658270638,603030.SH
-2023-04-21,0.3577772016637592,000609.SZ
-2023-04-21,0.5480032809276628,603030.SH
-2023-04-24,0.45566543966480255,000609.SZ
-2023-04-24,0.5088598119871328,603030.SH
-2023-04-25,0.4431612895631404,000691.SZ
-2023-04-25,0.5810251948957009,603030.SH
-2023-04-26,0.45078682001517156,002652.SZ
-2023-04-26,0.47975715850292316,603030.SH
-2023-04-27,0.4723293583803111,002652.SZ
-2023-04-27,0.5267790019668871,603030.SH
-2023-04-28,0.3937841340568146,603729.SH
-2023-04-28,0.5784074153542521,603030.SH
-2023-05-04,0.4244991408334302,002652.SZ
-2023-05-04,0.4368586336023455,000609.SZ
-2023-05-05,0.34331282529468865,002652.SZ
-2023-05-05,0.4253021425706697,000609.SZ
-2023-05-08,0.37018642467679636,002652.SZ
-2023-05-08,0.37743975769440546,603729.SH
-2023-05-09,0.3222803921804246,603729.SH
-2023-05-09,0.3288134561312375,002652.SZ
-2023-05-10,0.3388785825012055,002856.SZ
-2023-05-10,0.3609777332856756,002652.SZ
-2023-05-11,0.5818379750940922,603729.SH
-2023-05-11,0.604639163728697,603958.SH
-2023-05-12,0.40197407992300116,600539.SH
-2023-05-12,0.5088471850091371,603729.SH
-2023-05-15,0.47005286381291683,603729.SH
-2023-05-15,0.48867105210466205,603958.SH
-2023-05-16,0.4412697703281623,603729.SH
-2023-05-16,0.44139960714815835,002652.SZ
-2023-05-17,0.4308749485146275,600539.SH
-2023-05-17,0.4636309674805906,603729.SH
-2023-05-18,0.39305043801751804,600355.SH
-2023-05-18,0.5174016654152166,603958.SH
-2023-05-19,0.3830123886960628,002316.SZ
-2023-05-19,0.5387002345882874,603958.SH
-2023-05-22,0.4493390654541321,603958.SH
-2023-05-22,0.4544001660018375,002719.SZ
-2023-05-23,0.5196440436186276,002316.SZ
-2023-05-23,0.6719621253587986,603958.SH
-2023-05-24,0.4573730334135947,002719.SZ
-2023-05-24,0.5755014588250861,603958.SH
-2023-05-25,0.4178121027826169,603725.SH
-2023-05-25,0.48631226170776076,002719.SZ
-2023-05-26,0.37510444463515974,603958.SH
-2023-05-26,0.4744084785740701,002719.SZ
-2023-05-29,0.47816901842788473,002719.SZ
-2023-05-29,0.6149084332923903,603958.SH
-2023-05-30,0.3789708525558222,002719.SZ
-2023-05-30,0.6029545509717783,600083.SH
-2023-05-31,0.3912419758508662,603958.SH
-2023-05-31,0.49852773381967536,603608.SH
-2023-06-01,0.3951561294107728,603608.SH
-2023-06-01,0.4922086313249833,002719.SZ
-2023-06-02,0.38718556033409324,000622.SZ
-2023-06-02,0.47129749435646023,002719.SZ
-2023-06-05,0.40622572445907984,000622.SZ
-2023-06-05,0.4927755255626212,603729.SH
-2023-06-06,0.43149178417246814,000622.SZ
-2023-06-06,0.4960394980412886,600137.SH
-2023-06-07,0.44894433612743384,603389.SH
-2023-06-07,0.4749438130024184,002652.SZ
-2023-06-08,0.44706417381829255,002719.SZ
-2023-06-08,0.47864404645233105,600137.SH
-2023-06-09,0.44684196602646997,002652.SZ
-2023-06-09,0.4600263394737736,600137.SH
-2023-06-12,0.403048466546019,002652.SZ
-2023-06-12,0.6331514439465104,603286.SH
-2023-06-13,0.4124676001145173,002652.SZ
-2023-06-13,0.4666905305568208,603286.SH
-2023-06-14,0.3741162147871443,002848.SZ
-2023-06-14,0.4585347026887019,603286.SH
-2023-06-15,0.42357729162548746,002848.SZ
-2023-06-15,0.43368739500949494,603286.SH
-2023-06-16,0.3442269809008922,603729.SH
-2023-06-16,0.4180990943210513,603286.SH
-2023-06-19,0.3523396758604217,002193.SZ
-2023-06-19,0.6033664084385953,603286.SH
-2023-06-20,0.32507626114892846,002193.SZ
-2023-06-20,0.5601940705349382,002247.SZ
-2023-06-21,0.40801058852385635,000609.SZ
-2023-06-21,0.4550250296600302,002058.SZ
-2023-06-26,0.5574397102239779,000691.SZ
-2023-06-26,0.5681934419901743,002247.SZ
-2023-06-27,0.44431929878003734,603389.SH
-2023-06-27,0.47494144261372023,000609.SZ
-2023-06-28,0.41386276151089263,002211.SZ
-2023-06-28,0.580641839141047,000609.SZ
-2023-06-29,0.4282633000507008,000609.SZ
-2023-06-29,0.460323506357742,002211.SZ
-2023-06-30,0.39948466004858535,603709.SH
-2023-06-30,0.44312290010907335,002211.SZ
-2023-07-03,0.3896574069007179,603389.SH
-2023-07-03,0.6534550364637162,002211.SZ
-2023-07-04,0.41297891975052886,603709.SH
-2023-07-04,0.6221094448597468,000691.SZ
-2023-07-05,0.4791999114804626,000691.SZ
-2023-07-05,0.5685333785975794,002211.SZ
-2023-07-06,0.4353665843287007,000702.SZ
-2023-07-06,0.7026522874517822,000691.SZ
-2023-07-07,0.4070489102816367,000702.SZ
-2023-07-07,0.5787838669364066,000691.SZ
-2023-07-10,0.3993442552102214,000702.SZ
-2023-07-10,0.4647879025660164,000691.SZ
-2023-07-11,0.42561280104983895,000691.SZ
-2023-07-11,0.5890285041434683,600493.SH
-2023-07-12,0.3972971618305476,000691.SZ
-2023-07-12,0.4289597112570851,600493.SH
-2023-07-13,0.3878585014598166,000691.SZ
-2023-07-13,0.4302834986363502,002211.SZ
-2023-07-14,0.3728879235944033,000691.SZ
-2023-07-14,0.6251992822754106,000609.SZ
-2023-07-17,0.38480361519996553,603729.SH
-2023-07-17,0.5107229738009851,000609.SZ
-2023-07-18,0.3891808752284618,000609.SZ
-2023-07-18,0.4893978378143931,603709.SH
-2023-07-19,0.4324050369621531,603709.SH
-2023-07-19,0.6439828368570264,000609.SZ
-2023-07-20,0.5276139887988155,000691.SZ
-2023-07-20,0.5918515712091996,000609.SZ
-2023-07-21,0.5517485753650442,000691.SZ
-2023-07-21,0.6165778592087386,000609.SZ
-2023-07-24,0.5166222250495962,000609.SZ
-2023-07-24,0.5397717045726875,000691.SZ
-2023-07-25,0.5563712602289645,000691.SZ
-2023-07-25,0.5578730640838173,000609.SZ
-2023-07-26,0.5126469746458647,000702.SZ
-2023-07-26,0.5728701324000706,000691.SZ
-2023-07-27,0.5082868584136728,000609.SZ
-2023-07-27,0.5736557691995247,000691.SZ
-2023-07-28,0.4932662081349891,000702.SZ
-2023-07-28,0.5298275225478074,000691.SZ
-2023-07-31,0.491777348662727,603729.SH
-2023-07-31,0.6687093228002459,002652.SZ
-2023-08-01,0.4412850383029033,002652.SZ
-2023-08-01,0.4877165502366056,000609.SZ
-2023-08-02,0.46236482032322307,002652.SZ
-2023-08-02,0.4846315858119308,000609.SZ
-2023-08-03,0.4692935533574923,002652.SZ
-2023-08-03,0.5302975088036743,000609.SZ
-2023-08-04,0.39939975307621284,002652.SZ
-2023-08-04,0.40382511133046023,600355.SH
-2023-08-07,0.41364994343471156,600355.SH
-2023-08-07,0.5008722846398659,002652.SZ
-2023-08-08,0.48558925120214425,002652.SZ
-2023-08-08,0.5008036871246055,000609.SZ
-2023-08-09,0.3985592325703999,000691.SZ
-2023-08-09,0.46359907115718185,002652.SZ
-2023-08-10,0.408444680159888,000691.SZ
-2023-08-10,0.631781957055195,002652.SZ
-2023-08-11,0.3956474043356871,000691.SZ
-2023-08-11,0.5897698495172246,002652.SZ
-2023-08-14,0.44833840513026363,000691.SZ
-2023-08-14,0.5370488325402696,002652.SZ
-2023-08-15,0.39079058373142933,000691.SZ
-2023-08-15,0.5146441212784494,002652.SZ
-2023-08-16,0.44042598135131195,600355.SH
-2023-08-16,0.6419441177926305,002652.SZ
-2023-08-17,0.394898840170979,600355.SH
-2023-08-17,0.5701797023226247,002652.SZ
-2023-08-18,0.4796694217551151,603729.SH
-2023-08-18,0.5595333052237114,002652.SZ
-2023-08-21,0.5342246963660287,002652.SZ
-2023-08-21,0.5351052454738098,600455.SH
-2023-08-22,0.5480006296814814,603139.SH
-2023-08-22,0.5836304959564835,002652.SZ
-2023-08-23,0.5100003283531153,000609.SZ
-2023-08-23,0.5844732767497399,002652.SZ
-2023-08-24,0.483633107150444,000609.SZ
-2023-08-24,0.5514158518214188,002652.SZ
-2023-08-25,0.5059582842609434,002652.SZ
-2023-08-25,0.5293863376248813,600455.SH
-2023-08-28,0.4742698551833178,002861.SZ
-2023-08-28,0.48007299853952573,002193.SZ
-2023-08-29,0.4683423100957086,603729.SH
-2023-08-29,0.49200967254945727,603389.SH
-2023-08-30,0.49461266900032624,002856.SZ
-2023-08-30,0.503237483759797,603389.SH
-2023-08-31,0.5064758312177008,603389.SH
-2023-08-31,0.5116773574685926,002856.SZ
-2023-09-01,0.4332981723784006,002652.SZ
-2023-09-01,0.44301923163009016,002856.SZ
-2023-09-04,0.4230712362807199,002652.SZ
-2023-09-04,0.42951848786446883,603729.SH
-2023-09-05,0.38552285115101165,002652.SZ
-2023-09-05,0.40919270509455674,603729.SH
-2023-09-06,0.42094077196500895,603709.SH
-2023-09-06,0.4246545089189349,603389.SH
-2023-09-07,0.43388583308172224,002856.SZ
-2023-09-07,0.47044249505003943,002652.SZ
-2023-09-08,0.4418750192288378,002652.SZ
-2023-09-08,0.459817997704136,603389.SH
-2023-09-11,0.4403834639483758,002652.SZ
-2023-09-11,0.4726108865170528,603389.SH
-2023-09-12,0.40480945141093183,002652.SZ
-2023-09-12,0.4619121690911902,603389.SH
-2023-09-13,0.42349913221757,603389.SH
-2023-09-13,0.43671952543865944,002652.SZ
-2023-09-14,0.45388062669769347,002652.SZ
-2023-09-14,0.4563921471377267,603389.SH
-2023-09-15,0.38034263923971007,002652.SZ
-2023-09-15,0.39967471323071446,600355.SH
-2023-09-18,0.38235593234795084,600355.SH
-2023-09-18,0.5830368497803139,603389.SH
-2023-09-19,0.41169033934223026,002652.SZ
-2023-09-19,0.5197388457633353,603389.SH
-2023-09-20,0.4479705695950589,002652.SZ
-2023-09-20,0.5023428732409297,603389.SH
-2023-09-21,0.4769043292864373,600137.SH
-2023-09-21,0.5104167655396493,603389.SH
-2023-09-22,0.4906505565863172,603389.SH
-2023-09-22,0.5209832755234006,000622.SZ
-2023-09-25,0.44316367471522133,603389.SH
-2023-09-25,0.45764379346859047,002652.SZ
-2023-09-26,0.4609818272687006,603389.SH
-2023-09-26,0.47483224569025867,000609.SZ
-2023-09-27,0.47533488274720587,603389.SH
-2023-09-27,0.49231699700935216,002652.SZ
-2023-09-28,0.4272160644546847,603389.SH
-2023-09-28,0.5274220916994968,002652.SZ
-2023-10-09,0.44426240905734254,000609.SZ
-2023-10-09,0.5513509849887579,002652.SZ
-2023-10-10,0.4864095311333566,600083.SH
-2023-10-10,0.5307517345021574,002652.SZ
-2023-10-11,0.45108425294478943,600083.SH
-2023-10-11,0.46562533713740284,603389.SH
-2023-10-12,0.45861697200446905,600083.SH
-2023-10-12,0.47799668232683235,002629.SZ
-2023-10-13,0.4167747762955955,603389.SH
-2023-10-13,0.4686298736384583,600083.SH
-2023-10-16,0.41016599210000637,603286.SH
-2023-10-16,0.5275310087487154,002652.SZ
-2023-10-17,0.5064970100201818,002652.SZ
-2023-10-17,0.5110021424793302,600493.SH
-2023-10-18,0.45730295862679665,002652.SZ
-2023-10-18,0.4835297772247048,600561.SH
-2023-10-19,0.49275937957381943,002652.SZ
-2023-10-19,0.49849960586298525,600083.SH
-2023-10-20,0.47191307322245685,603729.SH
-2023-10-20,0.48903708409876384,600083.SH
-2023-10-23,0.4943826031405657,002652.SZ
-2023-10-23,0.5105100329693995,603729.SH
-2023-10-24,0.4989206102038761,002652.SZ
-2023-10-24,0.5605751624906592,603729.SH
-2023-10-25,0.47327894431521866,002856.SZ
-2023-10-25,0.49350405290358934,603729.SH
-2023-10-26,0.48653090688365114,603389.SH
-2023-10-26,0.5197547596266551,603729.SH
-2023-10-27,0.5136524761222605,603729.SH
-2023-10-27,0.525557352850893,603389.SH
-2023-10-30,0.49079602365912817,001211.SZ
-2023-10-30,0.5436448130036337,603729.SH
-2023-10-31,0.5109875119634294,002193.SZ
-2023-10-31,0.520156293384026,600493.SH
-2023-11-01,0.4820731197262264,603729.SH
-2023-11-01,0.5247440493459776,002652.SZ
-2023-11-02,0.5353467316892918,001211.SZ
-2023-11-02,0.5584812273150905,002652.SZ
-2023-11-03,0.4723690898158219,001211.SZ
-2023-11-03,0.5139813047400597,002652.SZ
-2023-11-06,0.36412120546954546,002652.SZ
-2023-11-06,0.4262084015320331,600493.SH
-2023-11-07,0.3852271388393353,002652.SZ
-2023-11-07,0.5650576506823274,600493.SH
-2023-11-08,0.3683298705516716,002652.SZ
-2023-11-08,0.3846604698382686,600561.SH
-2023-11-09,0.39826636351369143,002652.SZ
-2023-11-09,0.42285796889467325,600493.SH
-2023-11-10,0.4340253466940136,600493.SH
-2023-11-10,0.43911097769079394,002652.SZ
-2023-11-13,0.404722999833302,603729.SH
-2023-11-13,0.42238291798173677,600493.SH
-2023-11-14,0.4084959215816481,002652.SZ
-2023-11-14,0.41203878340795036,002193.SZ
-2023-11-15,0.3885346719827534,001211.SZ
-2023-11-15,0.3901713805755436,002652.SZ
-2023-11-16,0.40186306120428483,002193.SZ
-2023-11-16,0.467216339097379,603860.SH
-2023-11-17,0.40171721457261805,002652.SZ
-2023-11-17,0.41600577494562907,002856.SZ
-2023-11-20,0.48323462557800123,002856.SZ
-2023-11-20,0.6894706167767604,600455.SH
-2023-11-21,0.4312148414204438,002856.SZ
-2023-11-21,0.4826241059230131,600539.SH
-2023-11-22,0.46216688934895517,603389.SH
-2023-11-22,0.4920872622150701,600455.SH
-2023-11-23,0.4567002892353848,603021.SH
-2023-11-23,0.4579180109967577,600493.SH
-2023-11-24,0.4326298606406475,002193.SZ
-2023-11-24,0.46562250811095607,603389.SH
-2023-11-27,0.41500348670874576,603729.SH
-2023-11-27,0.6890062152930027,002856.SZ
-2023-11-28,0.45757567718911063,603021.SH
-2023-11-28,0.6666032100905133,002856.SZ
-2023-11-29,0.3954645083642221,600493.SH
-2023-11-29,0.5994191750243592,002856.SZ
-2023-11-30,0.3990548430957687,002652.SZ
-2023-11-30,0.443052898477057,002058.SZ
-2023-12-01,0.4509947801608849,603729.SH
-2023-12-01,0.5146127863686942,002193.SZ
-2023-12-04,0.48909128851553635,600493.SH
-2023-12-04,0.5067308049396115,002193.SZ
-2023-12-05,0.45108490205674007,600561.SH
-2023-12-05,0.48073609538872725,002193.SZ
-2023-12-06,0.5326272279253256,600083.SH
-2023-12-06,0.5460247143348224,600561.SH
-2023-12-07,0.5274193229076088,002856.SZ
-2023-12-07,0.5466783872504936,600083.SH
-2023-12-08,0.4593284229518822,600561.SH
-2023-12-08,0.4813972250839563,600083.SH
-2023-12-11,0.45458575807169127,002856.SZ
-2023-12-11,0.5032358985938714,600561.SH
-2023-12-12,0.45873689820744734,002856.SZ
-2023-12-12,0.5104419491287915,600455.SH
-2023-12-13,0.4737606197117625,002058.SZ
-2023-12-13,0.4823505375200145,002652.SZ
-2023-12-14,0.5013941565817015,002883.SZ
-2023-12-14,0.5252981709904638,002856.SZ
-2023-12-15,0.5624073263066665,002856.SZ
-2023-12-15,0.6156221401385377,600561.SH
-2023-12-18,0.4715983678403302,000668.SZ
-2023-12-18,0.5822277080541463,603389.SH
-2023-12-19,0.5081779967949517,603813.SH
-2023-12-19,0.5370746259000246,603389.SH
-2023-12-20,0.5305081223949948,603813.SH
-2023-12-20,0.608342279976026,603389.SH
-2023-12-21,0.4901979800539966,600493.SH
-2023-12-21,0.5070887782102607,603813.SH
-2023-12-22,0.49486864918743095,603709.SH
-2023-12-22,0.49805298595745573,603813.SH
-2023-12-25,0.5020770142187592,002719.SZ
-2023-12-25,0.5110024102497753,603813.SH
-2023-12-26,0.47827924070025374,605081.SH
-2023-12-26,0.5593614954548919,603389.SH
-2023-12-27,0.5033566993949921,600156.SH
-2023-12-27,0.5880651758200383,603389.SH
-2023-12-28,0.47185764150863524,002652.SZ
-2023-12-28,0.5683910142868634,603389.SH
-2023-12-29,0.5199009499110674,603389.SH
-2023-12-29,0.5852136802251388,002633.SZ
-2024-01-02,0.4867749193863235,000691.SZ
-2024-01-02,0.5353060927234542,600768.SH
-2024-01-03,0.4590763556619104,603389.SH
-2024-01-03,0.4718151636950369,000691.SZ
-2024-01-04,0.4748513301331667,002778.SZ
-2024-01-04,0.7129638408365928,000691.SZ
-2024-01-05,0.5392110766263524,603389.SH
-2024-01-05,0.6258152452429666,000691.SZ
-2024-01-08,0.5201889112623933,603389.SH
-2024-01-08,0.5647695846054438,000691.SZ
-2024-01-09,0.4982382333769596,603709.SH
-2024-01-09,0.5152663218939055,000691.SZ
-2024-01-10,0.5012548751732717,603709.SH
-2024-01-10,0.5299633791501315,000691.SZ
-2024-01-11,0.4916370594721171,002652.SZ
-2024-01-11,0.5254530845599394,000691.SZ
-2024-01-12,0.5141306455101734,000691.SZ
-2024-01-12,0.5689581602570709,605081.SH
-2024-01-15,0.5470461328427865,605081.SH
-2024-01-15,0.596804106790967,603389.SH
-2024-01-16,0.540894428580782,605081.SH
-2024-01-16,0.603437474818376,603389.SH
-2024-01-17,0.5883968844792609,605081.SH
-2024-01-17,0.6253695563397992,603389.SH
-2024-01-18,0.5644090196278336,605081.SH
-2024-01-18,0.5694385399713675,002652.SZ
-2024-01-19,0.5440000294499066,603389.SH
-2024-01-19,0.5465826506824902,002719.SZ
-2024-01-22,0.581859180607598,002629.SZ
-2024-01-22,0.5882612441913276,603316.SH
-2024-01-23,0.5857340302535804,002652.SZ
-2024-01-23,0.6275185702744395,002633.SZ
-2024-01-24,0.5941042155173373,002856.SZ
-2024-01-24,0.6297702829293348,002719.SZ
-2024-01-25,0.5158772768709453,002633.SZ
-2024-01-25,0.5262337763680598,002193.SZ
-2024-01-26,0.5160339973289757,002629.SZ
-2024-01-26,0.5555396258483924,603389.SH
-2024-01-29,0.5110298991763622,000691.SZ
-2024-01-29,0.5261230305715433,002856.SZ
-2024-01-30,0.5532150707277028,002633.SZ
-2024-01-30,0.5575946266938067,002856.SZ
-2024-01-31,0.6096880634428382,002856.SZ
-2024-01-31,0.654522241357284,002633.SZ
-2024-02-01,0.5300156751890279,000691.SZ
-2024-02-01,0.5360029901707386,000622.SZ
-2024-02-02,0.5448561200592063,000890.SZ
-2024-02-02,0.6235357231049657,002890.SZ
-2024-02-05,0.553307049145791,600883.SH
-2024-02-05,0.5812535687865998,002231.SZ
-2024-02-06,0.48611808694848824,002193.SZ
-2024-02-06,0.491782781829821,603021.SH
-2024-02-07,0.5153524472765557,603316.SH
-2024-02-07,0.517458537089523,603021.SH
-2024-02-08,0.5273073752142526,002862.SZ
-2024-02-08,0.5380546963552444,002856.SZ
-2024-02-19,0.47409485092380266,002652.SZ
-2024-02-19,0.4794698456802336,600083.SH
-2024-02-20,0.4961353865489028,600083.SH
-2024-02-20,0.5011083504125493,002719.SZ
-2024-02-21,0.5249822009082501,002856.SZ
-2024-02-21,0.5378436902963636,600083.SH
-2024-02-22,0.49849360166829493,603389.SH
-2024-02-22,0.5497168245697065,600083.SH
-2024-02-23,0.5457434020822595,002633.SZ
-2024-02-23,0.5784640112698425,002856.SZ
-2024-02-26,0.53914760071659,002633.SZ
-2024-02-26,0.5857072405252118,002856.SZ
-2024-02-27,0.5735617890520076,603389.SH
-2024-02-27,0.576822435392692,002856.SZ
-2024-02-28,0.5877050526902723,002856.SZ
-2024-02-28,0.5882880422582885,000691.SZ
-2024-02-29,0.5287481039869175,603389.SH
-2024-02-29,0.5596603243240845,002856.SZ
-2024-03-01,0.5360951220642642,002193.SZ
-2024-03-01,0.6030380462328101,002856.SZ
-2024-03-04,0.5500157449848865,002193.SZ
-2024-03-04,0.6011823772229243,002856.SZ
-2024-03-05,0.5576745643258202,002193.SZ
-2024-03-05,0.6168981854207019,002856.SZ
-2024-03-06,0.5435181320465915,002856.SZ
-2024-03-06,0.5525664189492857,603316.SH
-2024-03-07,0.5468159614397508,002856.SZ
-2024-03-07,0.5730782408644117,603389.SH
-2024-03-08,0.5363055976233075,002856.SZ
-2024-03-08,0.5604381403412438,603389.SH
-2024-03-11,0.5017765952394764,002856.SZ
-2024-03-11,0.5079826234679258,603389.SH
-2024-03-12,0.5254461627117529,600234.SH
-2024-03-12,0.5417407106211491,000929.SZ
-2024-03-13,0.5401808773328594,002856.SZ
-2024-03-13,0.5945214622577971,600455.SH
-2024-03-14,0.5642971660879913,000622.SZ
-2024-03-14,0.5967054530508952,603021.SH
-2024-03-15,0.5788726004879782,002856.SZ
-2024-03-15,0.6547753094798106,000691.SZ
-2024-03-18,0.578875419865238,002856.SZ
-2024-03-18,0.6020217894947674,603021.SH
-2024-03-19,0.5721141015431161,002652.SZ
-2024-03-19,0.5831925552442382,603021.SH
-2024-03-20,0.5870462483879707,002633.SZ
-2024-03-20,0.588798827072135,002856.SZ
-2024-03-21,0.60478461219708,002856.SZ
-2024-03-21,0.6166453988553989,600847.SH
-2024-03-22,0.5754718397827072,002652.SZ
-2024-03-22,0.5964848193565442,600455.SH
-2024-03-25,0.5605548108972374,002652.SZ
-2024-03-25,0.57677735447963,002247.SZ
-2024-03-26,0.5540344324973216,002652.SZ
-2024-03-26,0.5633153602355297,002856.SZ
-2024-03-27,0.6163210566400936,002856.SZ
-2024-03-27,0.6236690788267506,002652.SZ
-2024-03-28,0.5813975509048955,002247.SZ
-2024-03-28,0.6735139455984742,000691.SZ
-2024-03-29,0.592769410537943,603021.SH
-2024-03-29,0.6336957655423899,000691.SZ
-2024-04-01,0.5557413771373911,002856.SZ
-2024-04-01,0.6757071581267241,000622.SZ
-2024-04-02,0.5569747317578037,002247.SZ
-2024-04-02,0.6660226594329649,000691.SZ
-2024-04-03,0.5683282116319991,002856.SZ
-2024-04-03,0.5915066659207749,002652.SZ
-2024-04-08,0.6004650998608282,002856.SZ
-2024-04-08,0.609557060913053,600539.SH
-2024-04-09,0.5938675452093092,600561.SH
-2024-04-09,0.5994892021781124,600234.SH
-2024-04-10,0.5924608192060138,002856.SZ
-2024-04-10,0.6079973673463104,600539.SH
-2024-04-11,0.6141802008189985,600847.SH
-2024-04-11,0.622514536767961,600539.SH
-2024-04-12,0.595900216939704,600539.SH
-2024-04-12,0.602076492618752,600847.SH
-2024-04-15,0.689214048464711,002856.SZ
-2024-04-15,0.700529247138368,600539.SH
-2024-04-16,0.5188982771201872,600778.SH
-2024-04-16,0.5232195434303617,002193.SZ
-2024-04-17,0.6411970088557386,600539.SH
-2024-04-17,0.6809731391570163,002633.SZ
-2024-04-18,0.6566359821853837,600539.SH
-2024-04-18,0.685110364347488,002633.SZ
-2024-04-19,0.6611046099409232,002193.SZ
-2024-04-19,0.6957840551526947,600539.SH
-2024-04-22,0.5528016603918052,600234.SH
-2024-04-22,0.5571908279911814,002633.SZ
-2024-04-23,0.682274814902642,002856.SZ
-2024-04-23,0.762010800795303,002193.SZ
-2024-04-24,0.6864209235618642,002193.SZ
-2024-04-24,0.7313537286847338,002856.SZ
-2024-04-25,0.6887120649075228,002856.SZ
-2024-04-25,0.7670121076838373,002193.SZ
-2024-04-26,0.6116895791571039,002633.SZ
-2024-04-26,0.6412622739035451,002856.SZ
-2024-04-29,0.5501413879207012,002856.SZ
-2024-04-29,0.6193371566312604,002193.SZ
-2024-04-30,0.5482056817589295,002856.SZ
-2024-04-30,0.664573358792903,002193.SZ
-2024-05-06,0.5370853251867015,002633.SZ
-2024-05-06,0.6138861123152172,002193.SZ
-2024-05-07,0.5533649991298526,002856.SZ
-2024-05-07,0.5763545090058011,002193.SZ
-2024-05-08,0.52927963082861,002193.SZ
-2024-05-08,0.5603085731030494,002856.SZ
-2024-05-09,0.5405601580547983,002193.SZ
-2024-05-09,0.6500589369703919,600847.SH
-2024-05-10,0.56213330641194,002856.SZ
-2024-05-10,0.5627155098546122,002193.SZ
-2024-05-13,0.5650223080850473,002193.SZ
-2024-05-13,0.5845021128886227,002856.SZ
-2024-05-14,0.5542578208843654,002856.SZ
-2024-05-14,0.5723530559648116,002193.SZ
-2024-05-15,0.5650536380872908,002629.SZ
-2024-05-15,0.5721803422681506,002193.SZ
-2024-05-16,0.5846686811738396,002856.SZ
-2024-05-16,0.5944781396983833,600847.SH
-2024-05-17,0.6190902989140125,002856.SZ
-2024-05-17,0.6398923451043185,600847.SH
-2024-05-20,0.584324280690676,002193.SZ
-2024-05-20,0.614105452874249,002856.SZ
-2024-05-21,0.5940318700562347,002856.SZ
-2024-05-21,0.6484316469102587,600847.SH
-2024-05-22,0.581204824170764,002193.SZ
-2024-05-22,0.5833702503462116,002856.SZ
-2024-05-23,0.6079145932786718,600539.SH
-2024-05-23,0.6334307750210825,002856.SZ
-2024-05-24,0.6313133005355399,600321.SH
-2024-05-24,0.6391105050091029,002856.SZ
-2024-05-27,0.5906744951296534,600539.SH
-2024-05-27,0.6092623536827394,600321.SH
-2024-05-28,0.5424674127912912,002629.SZ
-2024-05-28,0.5434215442522912,600321.SH
-2024-05-29,0.578868893866268,600539.SH
-2024-05-29,0.5930658302443064,000679.SZ
-2024-05-30,0.5498420292320503,600321.SH
-2024-05-30,0.6025841096204847,002629.SZ
-2024-05-31,0.539889639882707,600539.SH
-2024-05-31,0.5987724572871158,002629.SZ
-2024-06-03,0.5979493289325418,002193.SZ
-2024-06-03,0.6471117172013012,002629.SZ
-2024-06-04,0.6430905224688402,600539.SH
-2024-06-04,0.7114982335873982,002629.SZ
-2024-06-05,0.6817748376382282,002629.SZ
-2024-06-05,0.6840236067165515,002193.SZ
-2024-06-06,0.5285123219396212,002633.SZ
-2024-06-06,0.552124642450037,002207.SZ
-2024-06-07,0.5418014292591011,000679.SZ
-2024-06-07,0.5447467791855033,002629.SZ
-2024-06-11,0.5337998223172306,002193.SZ
-2024-06-11,0.5360125873569147,002629.SZ
-2024-06-12,0.6480689956765823,002193.SZ
-2024-06-12,0.6811488369075126,002629.SZ
-2024-06-13,0.5123041948268758,002629.SZ
-2024-06-13,0.5285261651404838,603021.SH
-2024-06-14,0.5151309834382739,603021.SH
-2024-06-14,0.5874961145830149,000679.SZ
-2024-06-17,0.46964998781479356,002629.SZ
-2024-06-17,0.4991534860071786,603021.SH
-2024-06-18,0.6417226841156547,603021.SH
-2024-06-18,0.6721346094921411,002629.SZ
-2024-06-19,0.4854347307515835,002629.SZ
-2024-06-19,0.5596338790585856,000679.SZ
-2024-06-20,0.4712896439910853,002629.SZ
-2024-06-20,0.5007948183351082,603021.SH
-2024-06-21,0.5217276692035384,002629.SZ
-2024-06-21,0.5384439314325283,603021.SH
-2024-06-24,0.552610667595553,002629.SZ
-2024-06-24,0.5952402028762945,603021.SH
-2024-06-25,0.5388942815540131,002629.SZ
-2024-06-25,0.569553655789221,603021.SH
-2024-06-26,0.5902695744461458,002629.SZ
-2024-06-26,0.6289076021325273,603021.SH
-2024-06-27,0.5157458207046127,603021.SH
-2024-06-27,0.5385131203185486,002629.SZ
-2024-06-28,0.5216719470734773,002629.SZ
-2024-06-28,0.5309408934543914,000679.SZ
-2024-07-01,0.5179836390734217,002629.SZ
-2024-07-01,0.5425854000274155,000679.SZ
-2024-07-02,0.5243756119488598,002193.SZ
-2024-07-02,0.5401682847551621,603021.SH
-2024-07-03,0.5025954840785866,002193.SZ
-2024-07-03,0.5617091543298768,002629.SZ
-2024-07-04,0.5259524986198575,000953.SZ
-2024-07-04,0.554862601211307,002629.SZ
-2024-07-05,0.4933529776875012,002193.SZ
-2024-07-05,0.5840406525538597,002629.SZ
-2024-07-08,0.5210071725837517,002193.SZ
-2024-07-08,0.5875763984845536,002629.SZ
-2024-07-09,0.5363554367835497,002193.SZ
-2024-07-09,0.558779966762437,002629.SZ
-2024-07-10,0.5460716862342355,002629.SZ
-2024-07-10,0.564790305668333,603021.SH
-2024-07-11,0.5070460818577294,002193.SZ
-2024-07-11,0.5711443239118948,002629.SZ
-2024-07-12,0.5176894929878133,002193.SZ
-2024-07-12,0.5638916544503183,002629.SZ
-2024-07-15,0.5590426787957652,002629.SZ
-2024-07-15,0.5656932482033828,603021.SH
-2024-07-16,0.5237810755026249,603021.SH
-2024-07-16,0.585284548031148,002629.SZ
-2024-07-17,0.4946189944788445,603021.SH
-2024-07-17,0.5417384214682474,002629.SZ
-2024-07-18,0.532375603574812,002629.SZ
-2024-07-18,0.6090319000233864,002713.SZ
-2024-07-19,0.5052072035062006,002629.SZ
-2024-07-19,0.5665651141223088,002713.SZ
-2024-07-22,0.44971528783236353,002629.SZ
-2024-07-22,0.5710307646105857,002193.SZ
-2024-07-23,0.5572484213904243,002629.SZ
-2024-07-23,0.5647150300028636,002633.SZ
-2024-07-24,0.4869991378334247,002629.SZ
-2024-07-24,0.5774238797448292,002713.SZ
-2024-07-25,0.44851378445159257,002193.SZ
-2024-07-25,0.5514159440868289,002713.SZ
-2024-07-26,0.4543228051083524,002193.SZ
-2024-07-26,0.5323697711530061,002713.SZ
-2024-07-29,0.5303652927638742,000608.SZ
-2024-07-29,0.5784844098133578,002713.SZ
-2024-07-30,0.508766633337181,002713.SZ
-2024-07-30,0.6092522232262765,002629.SZ
-2024-07-31,0.4653177598392356,002058.SZ
-2024-07-31,0.47612844294960643,002629.SZ
-2024-08-01,0.4869740750934358,002629.SZ
-2024-08-01,0.5041834370779138,002193.SZ
-2024-08-02,0.4421509314370104,002713.SZ
-2024-08-02,0.6422129972189946,002193.SZ
-2024-08-05,0.5097810422603736,002193.SZ
-2024-08-05,0.6725297990397573,002629.SZ
-2024-08-06,0.5998045071801569,002633.SZ
-2024-08-06,0.6681203023268856,002193.SZ
-2024-08-07,0.49536643444150125,002629.SZ
-2024-08-07,0.552365020451377,600455.SH
-2024-08-08,0.518385517696459,002633.SZ
-2024-08-08,0.5268870965355223,002629.SZ
-2024-08-09,0.44805370841926895,002629.SZ
-2024-08-09,0.5646632830869424,002633.SZ
-2024-08-12,0.45160892621371246,000890.SZ
-2024-08-12,0.520680742901565,000608.SZ
-2024-08-13,0.4928633874008074,600768.SH
-2024-08-13,0.6089016015449847,002629.SZ
-2024-08-14,0.5158105583289192,002629.SZ
-2024-08-14,0.531925658489162,603316.SH
-2024-08-15,0.44549790446568344,002193.SZ
-2024-08-15,0.5345072631903978,002629.SZ
-2024-08-16,0.499111096919017,002713.SZ
-2024-08-16,0.5104202197149742,002629.SZ
-2024-08-19,0.502339894822735,002629.SZ
-2024-08-19,0.5413133003644088,000608.SZ
-2024-08-20,0.49051366838742005,002629.SZ
-2024-08-20,0.5077349411070744,000608.SZ
-2024-08-21,0.47244418792671466,000890.SZ
-2024-08-21,0.501718432840517,000608.SZ
-2024-08-22,0.5149891015102862,000608.SZ
-2024-08-22,0.5659520507640715,002193.SZ
-2024-08-23,0.5167407784686329,002713.SZ
-2024-08-23,0.5360195749618207,000608.SZ
-2024-08-26,0.4666121996306318,603021.SH
-2024-08-26,0.5073234452000671,002629.SZ
-2024-08-27,0.4758095796983039,002713.SZ
-2024-08-27,0.5103248306260151,603021.SH
-2024-08-28,0.46985039546358776,603021.SH
-2024-08-28,0.4920596662951926,002713.SZ
-2024-08-29,0.43396088562676033,002633.SZ
-2024-08-29,0.4732520735996415,000608.SZ
-2024-08-30,0.4352824407647903,002713.SZ
-2024-08-30,0.5290347259700207,000679.SZ
-2024-09-02,0.4511797960101573,000679.SZ
-2024-09-02,0.5142685624864621,000608.SZ
-2024-09-03,0.3851762391773519,002713.SZ
-2024-09-03,0.5105353020844206,000608.SZ
-2024-09-04,0.4304232846662092,002193.SZ
-2024-09-04,0.5348641486895729,000608.SZ
-2024-09-05,0.4981909698319161,002193.SZ
-2024-09-05,0.5219169846000128,000608.SZ
-2024-09-06,0.4216403894860269,000679.SZ
-2024-09-06,0.4863012572999468,000608.SZ
-2024-09-09,0.44532016472990454,002629.SZ
-2024-09-09,0.48220958610158887,000608.SZ
-2024-09-10,0.45958653032319885,002207.SZ
-2024-09-10,0.5395871574791813,600539.SH
-2024-09-11,0.39678799068056514,002193.SZ
-2024-09-11,0.41323078498717536,603021.SH
-2024-09-12,0.4480341191589505,002629.SZ
-2024-09-12,0.44939252369621036,000668.SZ
-2024-09-13,0.4190619732383798,002629.SZ
-2024-09-13,0.44300532157944406,600193.SH
-2024-09-18,0.4560911988340902,002629.SZ
-2024-09-18,0.47646471850360256,000679.SZ
-2024-09-19,0.5145323945852247,600193.SH
-2024-09-19,0.6355455231909783,002856.SZ
-2024-09-20,0.45475703114190463,002856.SZ
-2024-09-20,0.5228030223247428,600193.SH
-2024-09-23,0.48366608432871777,600193.SH
-2024-09-23,0.4913286102387679,002856.SZ
-2024-09-24,0.47109914827596017,002856.SZ
-2024-09-24,0.5216743952758949,002193.SZ
-2024-09-25,0.5293067162805014,603316.SH
-2024-09-25,0.5356784833246918,002058.SZ
-2024-09-26,0.5991415096346312,002713.SZ
-2024-09-26,0.6410241654310591,002856.SZ
-2024-09-27,0.6013234642175007,603021.SH
-2024-09-27,0.6105013125101505,002629.SZ
-2024-09-30,0.5943267821692796,002856.SZ
-2024-09-30,0.6259597462568155,600455.SH
-2024-10-08,0.5804199262484346,603272.SH
-2024-10-08,0.5820447643364349,600539.SH
-2024-10-09,0.5374922520327248,002193.SZ
-2024-10-09,0.5788880911158559,603880.SH
-2024-10-10,0.5673228359152819,603880.SH
-2024-10-10,0.6202015325699344,000668.SZ
-2024-10-11,0.4894926442085428,000668.SZ
-2024-10-11,0.503209897898285,002629.SZ
-2024-10-14,0.5214818232665404,002620.SZ
-2024-10-14,0.5408808977147718,603880.SH
-2024-10-15,0.529254264030437,600539.SH
-2024-10-15,0.5358249817364001,002620.SZ
-2024-10-16,0.5833189920176324,002620.SZ
-2024-10-16,0.6151217629917985,600455.SH
-2024-10-17,0.5374593770546222,002856.SZ
-2024-10-17,0.5426032570196828,002620.SZ
-2024-10-18,0.5256733428900578,002620.SZ
-2024-10-18,0.5836686069387369,603021.SH
-2024-10-21,0.5584185209503029,600768.SH
-2024-10-21,0.5667335644798563,600539.SH
-2024-10-22,0.5321083930125152,603880.SH
-2024-10-22,0.5688138814555649,600539.SH
-2024-10-23,0.5774519431265102,600539.SH
-2024-10-23,0.606872312041986,002629.SZ
-2024-10-24,0.5532252477839248,002193.SZ
-2024-10-24,0.5671709660048536,600539.SH
-2024-10-25,0.5653868394334853,600768.SH
-2024-10-25,0.5898733925904155,600539.SH
-2024-10-28,0.604154234694659,600455.SH
-2024-10-28,0.6098857838520747,000679.SZ
-2024-10-29,0.5282163366972527,002719.SZ
-2024-10-29,0.5787652556132716,000668.SZ
-2024-10-30,0.5291739640459848,600193.SH
-2024-10-30,0.565114304541583,605303.SH
-2024-10-31,0.5322729883350548,600768.SH
-2024-10-31,0.5324386757357265,600193.SH
-2024-11-01,0.5084821806012167,002857.SZ
-2024-11-01,0.5086703195021437,603880.SH
-2024-11-04,0.49781601797008507,002629.SZ
-2024-11-04,0.4983532010073773,600539.SH
-2024-11-05,0.5345198193633951,600539.SH
-2024-11-05,0.5358229512697499,002629.SZ
-2024-11-06,0.5042805089117115,000679.SZ
-2024-11-06,0.5179675572113097,002629.SZ
-2024-11-07,0.5323902602618866,600539.SH
-2024-11-07,0.6134594019043403,000679.SZ
-2024-11-08,0.5065393180246067,605303.SH
-2024-11-08,0.512052250294497,002620.SZ
-2024-11-11,0.5478651918109297,000668.SZ
-2024-11-11,0.5912270536960514,002856.SZ
-2024-11-12,0.5402344543519102,002494.SZ
-2024-11-12,0.5517957066525712,002629.SZ
-2024-11-13,0.5189126274596964,002494.SZ
-2024-11-13,0.5436638566194338,002629.SZ
-2024-11-14,0.508568679224192,002193.SZ
-2024-11-14,0.5144708382597866,002629.SZ
-2024-11-15,0.4995103103626301,002629.SZ
-2024-11-15,0.5430168938760982,002193.SZ
-2024-11-18,0.5114165801354142,002188.SZ
-2024-11-18,0.5629674441544419,002193.SZ
-2024-11-19,0.49112440763814985,002193.SZ
-2024-11-19,0.5057030990019676,603272.SH
-2024-11-20,0.48819404207710293,002193.SZ
-2024-11-20,0.49284819886401715,603729.SH
-2024-11-21,0.5217672180495938,002193.SZ
-2024-11-21,0.5581451156466761,600539.SH
-2024-11-22,0.5653851364658148,002193.SZ
-2024-11-22,0.5705569686094542,603880.SH
-2024-11-25,0.6123206731575216,600193.SH
-2024-11-25,0.6168469442015003,002494.SZ
-2024-11-26,0.6053914946651479,002494.SZ
-2024-11-26,0.6406581700233512,600561.SH
-2024-11-27,0.6037324392573172,002207.SZ
-2024-11-27,0.639116822755081,605081.SH
-2024-11-28,0.6023105586940724,002494.SZ
-2024-11-28,0.6117675680990935,001211.SZ
-2024-11-29,0.6248514949703026,002193.SZ
-2024-11-29,0.6470745760165263,001211.SZ
-2024-12-02,0.6069847903546609,600493.SH
-2024-12-02,0.6590874391602951,603880.SH
-2024-12-03,0.5738663775549662,000890.SZ
-2024-12-03,0.5813986022265882,603272.SH
-2024-12-04,0.5878438583634147,603316.SH
-2024-12-04,0.6402244993083515,002629.SZ
-2024-12-05,0.5011292470671154,603272.SH
-2024-12-05,0.5527507684220888,002629.SZ
-2024-12-06,0.5126770278918454,002620.SZ
-2024-12-06,0.5674619253781006,002629.SZ
-2024-12-09,0.5459923322578609,000890.SZ
-2024-12-09,0.6240896581870989,002629.SZ
-2024-12-10,0.4884700004643531,002207.SZ
-2024-12-10,0.544399238417807,603880.SH
-2024-12-11,0.5101835044545397,000890.SZ
-2024-12-11,0.5533079066019814,603880.SH
-2024-12-12,0.6050203298902228,603880.SH
-2024-12-12,0.6057299288369684,603813.SH
-2024-12-13,0.5526662516310541,605303.SH
-2024-12-13,0.5777184740973587,002620.SZ
-2024-12-16,0.5589927053540179,603709.SH
-2024-12-16,0.5753129432996247,002856.SZ
-2024-12-17,0.5006648442739609,600847.SH
-2024-12-17,0.5265305998489237,002856.SZ
-2024-12-18,0.5458904954320435,002856.SZ
-2024-12-18,0.5593789657495397,600768.SH
-2024-12-19,0.4783156462871012,002856.SZ
-2024-12-19,0.5096306545780743,002620.SZ
-2024-12-20,0.45920768372009363,002652.SZ
-2024-12-20,0.6560681970638885,002856.SZ
-2024-12-23,0.5350960983254065,605081.SH
-2024-12-23,0.5611073511067375,605303.SH
-2024-12-24,0.5189868490091133,000668.SZ
-2024-12-24,0.5691038880366361,605081.SH
-2024-12-25,0.5563174745963443,000691.SZ
-2024-12-25,0.564825483550332,000668.SZ
-2024-12-26,0.5604728495677641,000691.SZ
-2024-12-26,0.5626806973192451,000668.SZ
-2024-12-27,0.47028741703412763,000668.SZ
-2024-12-27,0.5139447637267319,605081.SH
-2024-12-30,0.5480069150701858,605081.SH
-2024-12-30,0.5486097234275711,000668.SZ
-2024-12-31,0.5263751898746499,000668.SZ
-2024-12-31,0.5618315283070014,000691.SZ
-2025-01-02,0.5308435671038998,000691.SZ
-2025-01-02,0.5508952242739595,000668.SZ
-2025-01-03,0.5812556353778913,000668.SZ
-2025-01-03,0.617975342023924,000691.SZ
-2025-01-06,0.5617011890043043,000668.SZ
-2025-01-06,0.6034140828295801,000691.SZ
-2025-01-07,0.49368570662444405,000668.SZ
-2025-01-07,0.5886678408943351,000691.SZ
-2025-01-08,0.5146722058388552,002207.SZ
-2025-01-08,0.596141007481704,000691.SZ
-2025-01-09,0.5166258202059658,000668.SZ
-2025-01-09,0.5731562726012734,000691.SZ
-2025-01-10,0.5814346704914203,002848.SZ
-2025-01-10,0.5834224446579473,000691.SZ
-2025-01-13,0.5890304684009722,000691.SZ
-2025-01-13,0.6219069420633739,002848.SZ
-2025-01-14,0.5086502921981826,000691.SZ
-2025-01-14,0.5305389757913431,002848.SZ
-2025-01-15,0.541533163614502,600421.SH
-2025-01-15,0.5812101808632144,000890.SZ
-2025-01-16,0.565319788532714,000890.SZ
-2025-01-16,0.5928143558006098,600421.SH
-2025-01-17,0.5660661756817259,002848.SZ
-2025-01-17,0.6118445664619659,600421.SH
-2025-01-20,0.5494007296884283,603021.SH
-2025-01-20,0.5980522519893827,002848.SZ
-2025-01-21,0.5259310455071138,605081.SH
-2025-01-21,0.5300958931941658,600421.SH
-2025-01-22,0.5271610284784172,600421.SH
-2025-01-22,0.5489647150315013,002620.SZ
-2025-01-23,0.5356448072373576,002856.SZ
-2025-01-23,0.576670162463851,002620.SZ
-2025-01-24,0.5123805013810646,000668.SZ
-2025-01-24,0.5445259567028164,002789.SZ
-2025-01-27,0.5560435056160704,000668.SZ
-2025-01-27,0.5661770328619049,605081.SH
-2025-02-05,0.5459314646066364,605081.SH
-2025-02-05,0.5717063999569352,000668.SZ
-2025-02-06,0.5166599571559564,600421.SH
-2025-02-06,0.5381743094146662,002789.SZ
-2025-02-07,0.48074974978603424,603021.SH
-2025-02-07,0.49574004882337647,600753.SH
-2025-02-10,0.5357435507074139,603021.SH
-2025-02-10,0.5471460389817681,600421.SH
-2025-02-11,0.5066490625371096,002848.SZ
-2025-02-11,0.520870835364184,002789.SZ
-2025-02-12,0.48451291136484387,002789.SZ
-2025-02-12,0.5479197202974326,603021.SH
-2025-02-13,0.47962055326755326,002856.SZ
-2025-02-13,0.5114256327170359,002719.SZ
-2025-02-14,0.505061883345198,002789.SZ
-2025-02-14,0.5227493103334775,002848.SZ
-2025-02-17,0.5370550787143388,002848.SZ
-2025-02-17,0.5581209278104079,603021.SH
-2025-02-18,0.5340583807570124,002848.SZ
-2025-02-18,0.5661109486231837,002719.SZ
-2025-02-19,0.510754993575613,002719.SZ
-2025-02-19,0.5735770808521523,603813.SH
-2025-02-20,0.4966569924631116,002789.SZ
-2025-02-20,0.6330704768584301,603813.SH
-2025-02-21,0.4782830700422396,002789.SZ
-2025-02-21,0.4792128095603372,002856.SZ
-2025-02-24,0.512510242684576,002856.SZ
-2025-02-24,0.6294101495847108,603813.SH
-2025-02-25,0.49922773254554603,002789.SZ
-2025-02-25,0.5186734100589423,002848.SZ
-2025-02-26,0.4861759569172938,603021.SH
-2025-02-26,0.5562349183769997,603813.SH
-2025-02-27,0.5187286469860671,002848.SZ
-2025-02-27,0.5372465096147117,603813.SH
-2025-02-28,0.5582606636495544,600753.SH
-2025-02-28,0.5851995864473026,002789.SZ
-2025-03-03,0.4509155501658866,002789.SZ
-2025-03-03,0.4592646510616447,002848.SZ
-2025-03-04,0.3952508021938683,002789.SZ
-2025-03-04,0.4746082226160008,002620.SZ
-2025-03-05,0.4735655765903199,002789.SZ
-2025-03-05,0.4829218584122487,002620.SZ
-2025-03-06,0.4148145245970155,002620.SZ
-2025-03-06,0.4422551006011737,002789.SZ
-2025-03-07,0.42309418041498636,002789.SZ
-2025-03-07,0.46832160676890533,603813.SH
-2025-03-10,0.5092199297178214,000668.SZ
-2025-03-10,0.5406829675422269,605081.SH
-2025-03-11,0.4382276596061429,002620.SZ
-2025-03-11,0.5206145434755793,000929.SZ
-2025-03-12,0.4791640531572169,002620.SZ
-2025-03-12,0.4815749169050143,603813.SH
-2025-03-13,0.38559501423591686,002789.SZ
-2025-03-13,0.4689922602032549,002620.SZ
-2025-03-14,0.4188127396616979,000929.SZ
-2025-03-14,0.5586724237821609,002719.SZ
-2025-03-17,0.4292796638071908,605081.SH
-2025-03-17,0.6454707645731581,002789.SZ
-2025-03-18,0.46211345642300844,002719.SZ
-2025-03-18,0.5771898468545389,002789.SZ
-2025-03-19,0.5903913247156526,600243.SH
-2025-03-19,0.6433821332879789,002789.SZ
-2025-03-20,0.493841825290913,002620.SZ
-2025-03-20,0.5456034547507876,002789.SZ
-2025-03-21,0.4801712542507192,002620.SZ
-2025-03-21,0.4887571340501682,002207.SZ
-2025-03-24,0.409648898786885,002856.SZ
-2025-03-24,0.5997219412348627,605081.SH
-2025-03-25,0.44928140728452,600193.SH
-2025-03-25,0.5158067862624118,605081.SH
-2025-03-26,0.43313794910108006,000691.SZ
-2025-03-26,0.545472156385584,002856.SZ
-2025-03-27,0.3750789624131361,002856.SZ
-2025-03-27,0.40816972597322826,600753.SH
-2025-03-28,0.3593576335769705,600193.SH
-2025-03-28,0.36443463675414894,600753.SH
-2025-03-31,0.35241006250442464,600753.SH
-2025-03-31,0.35952026716697355,000668.SZ
-2025-04-01,0.35046180042123587,000668.SZ
-2025-04-01,0.3576721217348187,000691.SZ
-2025-04-02,0.3474020406282367,600243.SH
-2025-04-02,0.37222286371291596,600753.SH
-2025-04-03,0.36624404536676347,000820.SZ
-2025-04-03,0.3669581115433309,603389.SH
-2025-04-07,0.4387478029342671,000691.SZ
-2025-04-07,0.4446796476355896,000668.SZ
-2025-04-08,0.4442622366463472,000668.SZ
-2025-04-08,0.4933778790381524,000691.SZ
-2025-04-09,0.46705361801144224,000668.SZ
-2025-04-09,0.4767120973621606,000691.SZ
-2025-04-10,0.41761794025824617,000691.SZ
-2025-04-10,0.446764268086817,000668.SZ
-2025-04-11,0.39476706635024206,000691.SZ
-2025-04-11,0.397145341193042,000668.SZ
-2025-04-14,0.37921479858572477,002848.SZ
-2025-04-14,0.4290208985687097,000668.SZ
-2025-04-15,0.4016917605365959,000608.SZ
-2025-04-15,0.4754027759373213,002848.SZ
-2025-04-16,0.5080608627094043,002848.SZ
-2025-04-16,0.5550448390241084,000668.SZ
-2025-04-17,0.5533476451245244,000668.SZ
-2025-04-17,0.5583934864592958,002848.SZ
-2025-04-18,0.48961118064620157,000668.SZ
-2025-04-18,0.5256199096889275,002848.SZ
-2025-04-21,0.40812782769768013,000691.SZ
-2025-04-21,0.466280622521186,002848.SZ
-2025-04-22,0.44238165440997435,002848.SZ
-2025-04-22,0.5218445314770491,000691.SZ
-2025-04-23,0.42137074833182786,600421.SH
-2025-04-23,0.4511473546074882,002848.SZ
-2025-04-24,0.43985601870068725,600421.SH
-2025-04-24,0.4788627812339172,002848.SZ
-2025-04-25,0.38745570598234297,600421.SH
-2025-04-25,0.4496908288088646,000691.SZ
-2025-04-28,0.3996265301940592,002058.SZ
-2025-04-28,0.5924373048126123,000691.SZ
-2025-04-29,0.42289732958902154,002193.SZ
-2025-04-29,0.5842314413101098,002856.SZ
-2025-04-30,0.4226997139048077,002193.SZ
-2025-04-30,0.526914809804891,002856.SZ
-2025-05-06,0.4947875260828594,600768.SH
-2025-05-06,0.5540784475414463,002856.SZ
-2025-05-07,0.4821196303996206,002193.SZ
-2025-05-07,0.6093505021371906,002856.SZ
-2025-05-08,0.5391682538946719,603616.SH
-2025-05-08,0.5945159272234696,002856.SZ
-2025-05-09,0.5436346780203024,002856.SZ
-2025-05-09,0.561117329693233,603616.SH
-2025-05-12,0.47056655937645436,002193.SZ
-2025-05-12,0.5798508702474465,002856.SZ
-2025-05-13,0.4850621602732856,603616.SH
-2025-05-13,0.5478751226113883,002856.SZ
-2025-05-14,0.44187347046452846,002856.SZ
-2025-05-14,0.444526671722409,002193.SZ
-2025-05-15,0.4533234544561367,002193.SZ
-2025-05-15,0.61038525901338,002856.SZ
-2025-05-16,0.38683744279909565,002193.SZ
-2025-05-16,0.514055437651059,002856.SZ
-2025-05-19,0.48913837622094175,603616.SH
-2025-05-19,0.5508071560732005,002856.SZ
-2025-05-20,0.5452369723818307,603616.SH
-2025-05-20,0.6120301659146943,002856.SZ
-2025-05-21,0.45776469061151065,000890.SZ
-2025-05-21,0.47861983415123965,002856.SZ
-2025-05-22,0.41436488328336396,002193.SZ
-2025-05-22,0.43742008211231814,002856.SZ
-2025-05-23,0.4140954623533334,002193.SZ
-2025-05-23,0.4367625766999641,002856.SZ
-2025-05-26,0.3685336345419401,002207.SZ
-2025-05-26,0.42996448453326525,002856.SZ
-2025-05-27,0.4297290216582259,603616.SH
-2025-05-27,0.49968692947557297,000890.SZ
-2025-05-28,0.4299137674214491,603616.SH
-2025-05-28,0.5114380530333179,000890.SZ
-2025-05-29,0.399240666547396,002193.SZ
-2025-05-29,0.5501268699108494,002856.SZ
-2025-05-30,0.39804621033155085,600671.SH
-2025-05-30,0.5340572554872488,002856.SZ
-2025-06-03,0.41716867730242285,603616.SH
-2025-06-03,0.44568614809257706,600671.SH
-2025-06-04,0.42707398992141954,000890.SZ
-2025-06-04,0.5096598940208374,002719.SZ
-2025-06-05,0.39269454156386324,002652.SZ
-2025-06-05,0.6761703260102311,002856.SZ
-2025-06-06,0.3960345973287001,002652.SZ
-2025-06-06,0.5314286262044693,002856.SZ
-2025-06-09,0.37962578341584485,600671.SH
-2025-06-09,0.4019910318505269,002856.SZ
-2025-06-10,0.3717552851612577,002719.SZ
-2025-06-10,0.38998384338227593,002856.SZ
-2025-06-11,0.363076869390417,002856.SZ
-2025-06-11,0.5135232792171786,605303.SH
-2025-06-12,0.37147415849740006,002207.SZ
-2025-06-12,0.4451339571942381,600234.SH
-2025-06-13,0.3486624224579292,603022.SH
-2025-06-13,0.3666757106570096,000632.SZ
-2025-06-16,0.34364234515038156,002193.SZ
-2025-06-16,0.35378889084134363,002188.SZ
-2025-06-17,0.3024344683459937,603616.SH
-2025-06-17,0.30847376301668783,603880.SH
-2025-06-18,0.30414757560387906,000890.SZ
-2025-06-18,0.37100848145062565,605303.SH
-2025-06-19,0.34200520758811825,002652.SZ
-2025-06-19,0.3511545249388872,603616.SH
-2025-06-20,0.3286312033563591,002652.SZ
-2025-06-20,0.423970171992831,600493.SH
-2025-06-23,0.3246249168156114,002193.SZ
-2025-06-23,0.33520318938631,002652.SZ
-2025-06-24,0.37961808658449386,600847.SH
-2025-06-24,0.4549491587300636,002193.SZ
-2025-06-25,0.354959736595533,002193.SZ
-2025-06-25,0.3564002741768565,600847.SH
-2025-06-26,0.33986269789092205,002652.SZ
-2025-06-26,0.3896096385754582,600847.SH
-2025-06-27,0.38355077181271774,002652.SZ
-2025-06-27,0.4174429064964895,600847.SH
-2025-06-30,0.3672900078871005,002591.SZ
-2025-06-30,0.5305376491612133,600847.SH
-2025-07-01,0.3888992607833918,002193.SZ
-2025-07-01,0.4131148978777191,600847.SH
-2025-07-02,0.35786014791455645,002193.SZ
-2025-07-02,0.5150548557130361,600847.SH
-2025-07-03,0.3546159023173079,002652.SZ
-2025-07-03,0.39658849210755076,000890.SZ
-2025-07-04,0.33151475375559547,002652.SZ
-2025-07-04,0.34519469623866966,002188.SZ
-2025-07-07,0.3427717420320137,002856.SZ
-2025-07-07,0.35265379311224065,002193.SZ
-2025-07-08,0.3512473784796735,600847.SH
-2025-07-08,0.36414459626406614,002494.SZ
-2025-07-09,0.31913753061613687,600847.SH
-2025-07-09,0.326681352908171,002591.SZ
-2025-07-10,0.336106843344193,002188.SZ
-2025-07-10,0.3381540516866362,002494.SZ
-2025-07-11,0.37409029976060465,002188.SZ
-2025-07-11,0.43271329440951656,600234.SH
-2025-07-14,0.3666749642695876,002193.SZ
-2025-07-14,0.3872668235517794,002652.SZ
-2025-07-15,0.3754731314201716,002193.SZ
-2025-07-15,0.3820751785297385,002652.SZ
-2025-07-16,0.38733948055059886,002856.SZ
-2025-07-16,0.5749246518094874,000890.SZ
-2025-07-17,0.3245140970756944,002652.SZ
-2025-07-17,0.394535350807898,002719.SZ
-2025-07-18,0.34307756645227927,002719.SZ
-2025-07-18,0.6565455001797362,002652.SZ
-2025-07-21,0.3820385063606565,600768.SH
-2025-07-21,0.5472052434548086,603616.SH
-2025-07-22,0.3615170930177371,605567.SH
-2025-07-22,0.39443949774188597,002910.SZ
-2025-07-23,0.382936274751581,002856.SZ
-2025-07-23,0.6166446884558179,002652.SZ
-2025-07-24,0.5015012002330536,603880.SH
-2025-07-24,0.5253677728076843,002652.SZ
-2025-07-25,0.40769364038437894,600671.SH
-2025-07-25,0.4675031014090571,600768.SH
-2025-07-28,0.5629079896554027,002652.SZ
-2025-07-28,0.63058584483318,603272.SH
-2025-07-29,0.382994552582935,002856.SZ
-2025-07-29,0.4091444706986924,002719.SZ
-2025-07-30,0.36192777486956834,002910.SZ
-2025-07-30,0.376785879832847,002719.SZ
-2025-07-31,0.3408488576782125,002207.SZ
-2025-07-31,0.3526101340498444,002719.SZ
-2025-08-01,0.3671667110330312,603880.SH
-2025-08-01,0.4976138036253392,600671.SH
-2025-08-04,0.37109673825675765,603880.SH
-2025-08-04,0.45761205852747483,600671.SH
-2025-08-05,0.3732003434609069,603709.SH
-2025-08-05,0.4954281069974441,002634.SZ
-2025-08-06,0.4989002591411546,002634.SZ
-2025-08-06,0.5917669893703391,000890.SZ
-2025-08-07,0.35001660831754067,002719.SZ
-2025-08-07,0.3513602164407757,600671.SH
-2025-08-08,0.40658677851972536,002719.SZ
-2025-08-08,0.4190288454401117,000890.SZ
-2025-08-11,0.39941211885622446,002719.SZ
-2025-08-11,0.4408231334166079,000890.SZ
-2025-08-12,0.39300019954109294,000890.SZ
-2025-08-12,0.5495711841546548,603709.SH
-2025-08-13,0.37092919104840016,002719.SZ
-2025-08-13,0.38446759298303534,603880.SH
-2025-08-14,0.3546871222230211,002719.SZ
-2025-08-14,0.367073571500238,002856.SZ
-2025-08-15,0.34636654918309123,002193.SZ
-2025-08-15,0.37071167404625704,002856.SZ
-2025-08-18,0.35140957220109625,002193.SZ
-2025-08-18,0.35511417776950294,002856.SZ
-2025-08-19,0.41548403795617267,002193.SZ
-2025-08-19,0.43692738703276585,002856.SZ
-2025-08-20,0.37394205843040734,002719.SZ
-2025-08-20,0.3825509541595268,603709.SH
-2025-08-21,0.35471261405434756,603709.SH
-2025-08-21,0.5405894519009482,002207.SZ
-2025-08-22,0.3535407353874586,002719.SZ
-2025-08-22,0.3610428781167332,002193.SZ
-2025-08-25,0.3768491687125309,002856.SZ
-2025-08-25,0.38203062226569084,002207.SZ
-2025-08-26,0.32934051618243093,002719.SZ
-2025-08-26,0.39189559926752127,002652.SZ
-2025-08-27,0.34198828123594155,002193.SZ
-2025-08-27,0.3678980225541431,002856.SZ
-2025-08-28,0.34042157152555147,002856.SZ
-2025-08-28,0.3565842348663385,002193.SZ
-2025-08-29,0.2984946454794484,002193.SZ
-2025-08-29,0.3054162951255008,002856.SZ
-2025-09-01,0.40949707342074054,002188.SZ
-2025-09-01,0.4243594339750301,001211.SZ
-2025-09-02,0.3108011963460676,002193.SZ
-2025-09-02,0.33554680148963834,002188.SZ
-2025-09-03,0.292162901897396,002188.SZ
-2025-09-03,0.2959388668891339,603709.SH
-2025-09-04,0.3736693123893222,002494.SZ
-2025-09-04,0.40986586316152757,001211.SZ
-2025-09-05,0.3120369944751885,002193.SZ
-2025-09-05,0.31809837953063813,002719.SZ
-2025-09-08,0.3259793434918687,600847.SH
-2025-09-08,0.44873434681861735,001211.SZ
-2025-09-09,0.34521947382876167,600847.SH
-2025-09-09,0.3501745181665207,001211.SZ
-2025-09-10,0.45173289209851725,000890.SZ
-2025-09-10,0.5293678104934288,002207.SZ
-2025-09-11,0.29955442041284475,002719.SZ
-2025-09-11,0.31230809500829493,002207.SZ
-2025-09-12,0.3585716802936077,600235.SH
-2025-09-12,0.3602806764680237,600408.SH
-2025-09-15,0.36526653471092635,600448.SH
-2025-09-15,0.37432481950300156,603879.SH
-2025-09-16,0.3060121923000639,000890.SZ
-2025-09-16,0.4360926233268927,600448.SH
-2025-09-17,0.29826756689669726,600847.SH
-2025-09-17,0.31429381377638516,000890.SZ
-2025-09-18,0.31526067075328273,002193.SZ
-2025-09-18,0.3205013803449728,600847.SH
-2025-09-19,0.34362924748319856,600791.SH
-2025-09-19,0.3648551332044779,000890.SZ
-2025-09-22,0.2979328114631705,002719.SZ
-2025-09-22,0.3238922547426562,002193.SZ
-2025-09-23,0.2963511517549595,002193.SZ
-2025-09-23,0.3226749958691948,600847.SH
-2025-09-24,0.30356039233971976,002719.SZ
-2025-09-24,0.4020074285905707,002193.SZ
-2025-09-25,0.2710668182360752,002719.SZ
-2025-09-25,0.28751829880946983,002193.SZ
-2025-09-26,0.2858137199382879,002193.SZ
-2025-09-26,0.31352991683260567,002719.SZ
-2025-09-29,0.2890119641471979,002193.SZ
-2025-09-29,0.289970819670072,002719.SZ
-2025-09-30,0.27161184827114,002193.SZ
-2025-09-30,0.30525378614363885,600847.SH
-2025-10-09,0.2749550111920183,603356.SH
-2025-10-09,0.42154288661517764,002591.SZ
-2025-10-10,0.2807003627051253,002193.SZ
-2025-10-10,0.31259694334979216,002719.SZ
+2025-01-02,0.48575221785026895,000691.SZ
+2025-01-02,0.5084552497307804,000668.SZ
+2025-01-03,0.5088168009578125,000668.SZ
+2025-01-03,0.5096757053741493,000691.SZ
+2025-01-06,0.5359741960370495,000668.SZ
+2025-01-06,0.5465436636405955,000691.SZ
+2025-01-07,0.5002245807021557,000668.SZ
+2025-01-07,0.5559085865116036,000691.SZ
+2025-01-08,0.49817506843389986,000668.SZ
+2025-01-08,0.5236986700665764,000691.SZ
+2025-01-09,0.5044673830479516,000668.SZ
+2025-01-09,0.5167390892743996,000691.SZ
+2025-01-10,0.5338531383863315,002856.SZ
+2025-01-10,0.5822172740408927,000691.SZ
+2025-01-13,0.5286122798682193,000691.SZ
+2025-01-13,0.5369741250825144,002848.SZ
+2025-01-14,0.4731563324172883,002848.SZ
+2025-01-14,0.47674253975883624,002856.SZ
+2025-01-15,0.48203043587008115,000691.SZ
+2025-01-15,0.49610272191265153,002816.SZ
+2025-01-16,0.4749392953240603,002789.SZ
+2025-01-16,0.4932375626123076,002207.SZ
+2025-01-17,0.47708424620110595,002620.SZ
+2025-01-17,0.4817854930861554,600421.SH
+2025-01-20,0.4660113347066514,002620.SZ
+2025-01-20,0.49686207802924914,002816.SZ
+2025-01-21,0.49182844325161795,000691.SZ
+2025-01-21,0.4926130793975302,600421.SH
+2025-01-22,0.5024668244364524,600421.SH
+2025-01-22,0.5200124554893999,000691.SZ
+2025-01-23,0.5067700835717073,000668.SZ
+2025-01-23,0.5179756861050456,000691.SZ
+2025-01-24,0.473355248372156,000691.SZ
+2025-01-24,0.518271602554851,000668.SZ
+2025-01-27,0.49835899674547257,002848.SZ
+2025-01-27,0.5171081669752098,000668.SZ
+2025-02-05,0.4764687502797657,000691.SZ
+2025-02-05,0.5015890741023533,000668.SZ
+2025-02-06,0.4550405893600109,000668.SZ
+2025-02-06,0.4586014099265313,600421.SH
+2025-02-07,0.4417653502536386,002848.SZ
+2025-02-07,0.49313401032538356,600421.SH
+2025-02-10,0.4645427217414804,000668.SZ
+2025-02-10,0.4719459924337697,000691.SZ
+2025-02-11,0.4459294973827632,000668.SZ
+2025-02-11,0.45637716128453815,002848.SZ
+2025-02-12,0.4303930203564912,000668.SZ
+2025-02-12,0.44011788297505816,000691.SZ
+2025-02-13,0.4484474868664714,002816.SZ
+2025-02-13,0.4599519946491962,600753.SH
+2025-02-14,0.4299092070175065,000691.SZ
+2025-02-14,0.4553460008099199,002848.SZ
+2025-02-17,0.4818860397156218,000691.SZ
+2025-02-17,0.4924395332509645,002848.SZ
+2025-02-18,0.4536474340527136,002789.SZ
+2025-02-18,0.5114099521575034,002848.SZ
+2025-02-19,0.4523616451147736,000691.SZ
+2025-02-19,0.46801048153112906,002848.SZ
+2025-02-20,0.4633063832181587,002620.SZ
+2025-02-20,0.5309497118671036,603813.SH
+2025-02-21,0.44600508399321337,002789.SZ
+2025-02-21,0.46653522114845264,603813.SH
+2025-02-24,0.4480289666915957,002848.SZ
+2025-02-24,0.5151539794803903,603813.SH
+2025-02-25,0.4325003645659346,002789.SZ
+2025-02-25,0.4508487189371789,002848.SZ
+2025-02-26,0.45901754162960223,603813.SH
+2025-02-26,0.4617698074191845,002620.SZ
+2025-02-27,0.43366934565915116,002719.SZ
+2025-02-27,0.43370745865325844,002620.SZ
+2025-02-28,0.44495277676568473,002848.SZ
+2025-02-28,0.510934335522782,603813.SH
+2025-03-03,0.4407043546209257,002848.SZ
+2025-03-03,0.45120198676588524,002207.SZ
+2025-03-04,0.44647602863466446,603021.SH
+2025-03-04,0.4895095215149072,605303.SH
+2025-03-05,0.4458181607126485,002816.SZ
+2025-03-05,0.46316915044883006,603813.SH
+2025-03-06,0.4425974234270282,603880.SH
+2025-03-06,0.4437657635914727,600847.SH
+2025-03-07,0.4503054413613082,603021.SH
+2025-03-07,0.4508021863096924,603813.SH
+2025-03-10,0.4847926059485397,000668.SZ
+2025-03-10,0.48809805297236625,605081.SH
+2025-03-11,0.4499962488043251,002620.SZ
+2025-03-11,0.4847850458322176,000929.SZ
+2025-03-12,0.45104672531338963,000929.SZ
+2025-03-12,0.4554458491540237,002620.SZ
+2025-03-13,0.4459897044341812,000929.SZ
+2025-03-13,0.4479840866638049,002816.SZ
+2025-03-14,0.4727934540812753,000929.SZ
+2025-03-14,0.5116765036612626,002719.SZ
+2025-03-17,0.4834968535924071,002719.SZ
+2025-03-17,0.4945265911339743,002789.SZ
+2025-03-18,0.4973962922067608,002719.SZ
+2025-03-18,0.5269005021344412,002789.SZ
+2025-03-19,0.4570191817944485,002719.SZ
+2025-03-19,0.4996297165331988,600243.SH
+2025-03-20,0.5108477757617159,600243.SH
+2025-03-20,0.5121414124317395,002789.SZ
+2025-03-21,0.45540142671034817,002207.SZ
+2025-03-21,0.46058506330792043,002199.SZ
+2025-03-24,0.4712600962042179,002848.SZ
+2025-03-24,0.5153940431859242,605081.SH
+2025-03-25,0.4604939987616551,000668.SZ
+2025-03-25,0.4914572869653452,605081.SH
+2025-03-26,0.4699450554432216,605081.SH
+2025-03-26,0.4909860296823067,002856.SZ
+2025-03-27,0.46098039907077376,605081.SH
+2025-03-27,0.46962481053376487,600243.SH
+2025-03-28,0.4548747461298823,600243.SH
+2025-03-28,0.4793739124797844,002789.SZ
+2025-03-31,0.4803557141541311,002848.SZ
+2025-03-31,0.4811721612504024,600243.SH
+2025-04-01,0.4447817532941779,002816.SZ
+2025-04-01,0.44740891564760904,600243.SH
+2025-04-02,0.44564256544520675,000608.SZ
+2025-04-02,0.4601862930162698,600421.SH
+2025-04-03,0.4605417874679759,002789.SZ
+2025-04-03,0.4636056694201826,600421.SH
+2025-04-07,0.5227569140213769,000668.SZ
+2025-04-07,0.5334374470239354,002848.SZ
+2025-04-08,0.5592586088413695,000668.SZ
+2025-04-08,0.5651381431581303,000691.SZ
+2025-04-09,0.5579091888926818,002848.SZ
+2025-04-09,0.5620498009384342,000691.SZ
+2025-04-10,0.49366347874465394,000668.SZ
+2025-04-10,0.5206319195478307,002848.SZ
+2025-04-11,0.4952150714977896,002848.SZ
+2025-04-11,0.5241828849449841,000608.SZ
+2025-04-14,0.49868373484174566,000668.SZ
+2025-04-14,0.5166030589141276,000608.SZ
+2025-04-15,0.4796867840267776,000668.SZ
+2025-04-15,0.49179562038871466,002848.SZ
+2025-04-16,0.5007276515349811,002848.SZ
+2025-04-16,0.5044287501259049,000668.SZ
+2025-04-17,0.5087698954648902,000668.SZ
+2025-04-17,0.5100164996118136,002848.SZ
+2025-04-18,0.4967194524736862,000668.SZ
+2025-04-18,0.4996821862760594,002848.SZ
+2025-04-21,0.5061077291898582,002816.SZ
+2025-04-21,0.5089312440630234,600243.SH
+2025-04-22,0.48513725797487434,000691.SZ
+2025-04-22,0.5310029240480928,002816.SZ
+2025-04-23,0.47546351890105876,000668.SZ
+2025-04-23,0.5198189625222146,600421.SH
+2025-04-24,0.4762590935839992,000668.SZ
+2025-04-24,0.5232082296939546,600421.SH
+2025-04-25,0.47699212952746783,000691.SZ
+2025-04-25,0.48824623229765735,600421.SH
+2025-04-28,0.48482114140493093,000668.SZ
+2025-04-28,0.5028493027139268,000638.SZ
+2025-04-29,0.5001290797893917,002856.SZ
+2025-04-29,0.517915640150148,600107.SH
+2025-04-30,0.4723266534386995,002856.SZ
+2025-04-30,0.4779969813439058,600768.SH
+2025-05-06,0.4965676755232794,002856.SZ
+2025-05-06,0.4979532599826374,002193.SZ
+2025-05-07,0.47722904922933485,002188.SZ
+2025-05-07,0.48094615936325996,002856.SZ
+2025-05-08,0.46539740179455463,603316.SH
+2025-05-08,0.4739462483511505,603616.SH
+2025-05-09,0.4657470898043363,002591.SZ
+2025-05-09,0.4742853615021872,603616.SH
+2025-05-12,0.44747143422696956,603616.SH
+2025-05-12,0.4584479892428683,002193.SZ
+2025-05-13,0.44231526438541213,603316.SH
+2025-05-13,0.44596589075137094,603880.SH
+2025-05-14,0.4429898360219404,000890.SZ
+2025-05-14,0.4474203240801016,002193.SZ
+2025-05-15,0.44130749117352874,002193.SZ
+2025-05-15,0.4615533695913845,002856.SZ
+2025-05-16,0.427070280262467,002856.SZ
+2025-05-16,0.4296729341102661,603616.SH
+2025-05-19,0.5183639442382452,600137.SH
+2025-05-19,0.5210586440150645,002798.SZ
+2025-05-20,0.45629384435452625,600543.SH
+2025-05-20,0.4766617146103299,600671.SH
+2025-05-21,0.4483939652632463,600493.SH
+2025-05-21,0.46873197451642384,600671.SH
+2025-05-22,0.44846248782661846,002798.SZ
+2025-05-22,0.45595381775773614,600671.SH
+2025-05-23,0.43918272147001586,600671.SH
+2025-05-23,0.5049003173001358,600493.SH
+2025-05-26,0.44625273675613947,600493.SH
+2025-05-26,0.45509003559485867,002856.SZ
+2025-05-27,0.4333698435914157,002719.SZ
+2025-05-27,0.4561535696718566,600234.SH
+2025-05-28,0.42956188443102095,600234.SH
+2025-05-28,0.5145707349319139,605303.SH
+2025-05-29,0.4604402192147438,002856.SZ
+2025-05-29,0.4653520011561466,605303.SH
+2025-05-30,0.4570869203861263,000890.SZ
+2025-05-30,0.4732689766013935,002856.SZ
+2025-06-03,0.44261497661914373,600671.SH
+2025-06-03,0.44301607266486837,000890.SZ
+2025-06-04,0.44187346969090113,000890.SZ
+2025-06-04,0.4989864414819407,002719.SZ
+2025-06-05,0.4409526222227541,002719.SZ
+2025-06-05,0.5178097090446889,002856.SZ
+2025-06-06,0.45589882946872384,000890.SZ
+2025-06-06,0.4708731877712996,002856.SZ
+2025-06-09,0.42885519563031926,000890.SZ
+2025-06-09,0.4355094147754572,002856.SZ
+2025-06-10,0.43926412758662653,002634.SZ
+2025-06-10,0.45102194750312646,600234.SH
+2025-06-11,0.44269370754390264,600234.SH
+2025-06-11,0.4622845438793849,605303.SH
+2025-06-12,0.4277411460310388,002856.SZ
+2025-06-12,0.44702122059469745,605303.SH
+2025-06-13,0.5006885291004196,002207.SZ
+2025-06-13,0.5193477310902935,603880.SH
+2025-06-16,0.45292763041463824,001259.SZ
+2025-06-16,0.46756389663324616,603880.SH
+2025-06-17,0.4384292198864348,603880.SH
+2025-06-17,0.5072081446325097,600543.SH
+2025-06-18,0.4254615486920708,603880.SH
+2025-06-18,0.43311166498523346,002780.SZ
+2025-06-19,0.43472468483334836,002513.SZ
+2025-06-19,0.43611110373885886,603880.SH
+2025-06-20,0.41653249570631573,603880.SH
+2025-06-20,0.4672010127115613,600493.SH
+2025-06-23,0.4437394138721645,600493.SH
+2025-06-23,0.46692526901613346,603880.SH
+2025-06-24,0.43050553307595363,002591.SZ
+2025-06-24,0.4606928012317557,002193.SZ
+2025-06-25,0.4379880288384499,603316.SH
+2025-06-25,0.44060737032050956,603880.SH
+2025-06-26,0.4334644799991089,002591.SZ
+2025-06-26,0.45464390293261714,603616.SH
+2025-06-27,0.41793227605981687,600493.SH
+2025-06-27,0.46567687658007884,000632.SZ
+2025-06-30,0.4624745445271744,603616.SH
+2025-06-30,0.46279412906774514,000632.SZ
+2025-07-01,0.42801520896872314,603616.SH
+2025-07-01,0.4334783937860973,600493.SH
+2025-07-02,0.4313634081545836,603616.SH
+2025-07-02,0.4666951454657348,600847.SH
+2025-07-03,0.4282098301994513,603616.SH
+2025-07-03,0.45136877403373005,000890.SZ
+2025-07-04,0.4221911147360996,603616.SH
+2025-07-04,0.4362889749953873,000890.SZ
+2025-07-07,0.44234589915764044,000632.SZ
+2025-07-07,0.4424558257494038,600847.SH
+2025-07-08,0.42612082297504067,600847.SH
+2025-07-08,0.44109541406156283,002513.SZ
+2025-07-09,0.41943770079983383,600847.SH
+2025-07-09,0.4473499999237769,603616.SH
+2025-07-10,0.4328702753733362,002828.SZ
+2025-07-10,0.442330522312224,002634.SZ
+2025-07-11,0.4136134965609944,002634.SZ
+2025-07-11,0.4245365024333691,600234.SH
+2025-07-14,0.41438655502189603,002800.SZ
+2025-07-14,0.42422181281304,002830.SZ
+2025-07-15,0.42177974809802166,002883.SZ
+2025-07-15,0.42291784150478834,002652.SZ
+2025-07-16,0.43559110918815064,605178.SH
+2025-07-16,0.49878458409391485,000890.SZ
+2025-07-17,0.42705157242362923,600493.SH
+2025-07-17,0.4467963409393237,000890.SZ
+2025-07-18,0.43513085432028864,000890.SZ
+2025-07-18,0.504982256164385,002652.SZ
+2025-07-21,0.43727957386053756,002652.SZ
+2025-07-21,0.4905577959610804,603616.SH
+2025-07-22,0.4187752080208889,605303.SH
+2025-07-22,0.45088179089281943,002910.SZ
+2025-07-23,0.5081848378610908,002652.SZ
+2025-07-23,0.509701380613387,600137.SH
+2025-07-24,0.4621712509836576,600137.SH
+2025-07-24,0.468339551562014,002652.SZ
+2025-07-25,0.4611138582293754,600671.SH
+2025-07-25,0.4721524449584946,002652.SZ
+2025-07-28,0.43825176587808534,600671.SH
+2025-07-28,0.4568795464587085,002652.SZ
+2025-07-29,0.4348242067227072,600137.SH
+2025-07-29,0.43586990758292593,603880.SH
+2025-07-30,0.4166391899332019,002719.SZ
+2025-07-30,0.45303139431588485,002910.SZ
+2025-07-31,0.4399218915206572,002207.SZ
+2025-07-31,0.4430587661148507,002652.SZ
+2025-08-01,0.4986057466311933,600671.SH
+2025-08-01,0.5083761143554838,002652.SZ
+2025-08-04,0.41745627261262797,002207.SZ
+2025-08-04,0.4738520521926396,600671.SH
+2025-08-05,0.44526929812921434,600671.SH
+2025-08-05,0.4482621020176912,002652.SZ
+2025-08-06,0.47383109782179944,002634.SZ
+2025-08-06,0.5048227604706322,000890.SZ
+2025-08-07,0.41468646625825306,603880.SH
+2025-08-07,0.45472024209611334,000890.SZ
+2025-08-08,0.46816798976148494,000890.SZ
+2025-08-08,0.49401592435082264,603880.SH
+2025-08-11,0.43513290461716875,002652.SZ
+2025-08-11,0.47298488362283336,000890.SZ
+2025-08-12,0.4242572514721847,603709.SH
+2025-08-12,0.44140444552011704,000890.SZ
+2025-08-13,0.43090641166998905,600561.SH
+2025-08-13,0.4370743015430232,002652.SZ
+2025-08-14,0.42376771436367566,603880.SH
+2025-08-14,0.4363308843810403,600671.SH
+2025-08-15,0.41710474312973794,603709.SH
+2025-08-15,0.44968970464793767,600671.SH
+2025-08-18,0.41411850463763383,603709.SH
+2025-08-18,0.43547413113372346,600671.SH
+2025-08-19,0.4390579023058104,002193.SZ
+2025-08-19,0.44543831085997515,002856.SZ
+2025-08-20,0.4244680619203003,603903.SH
+2025-08-20,0.4393092162420351,603022.SH
+2025-08-21,0.42867204390477864,603709.SH
+2025-08-21,0.5133939814923181,002207.SZ
+2025-08-22,0.4217915677144619,603709.SH
+2025-08-22,0.4818647021898774,600671.SH
+2025-08-25,0.4371159694028512,002144.SZ
+2025-08-25,0.46114494109705395,002207.SZ
+2025-08-26,0.4290341214882247,002207.SZ
+2025-08-26,0.4578897797222096,002652.SZ
+2025-08-27,0.420457936872125,603709.SH
+2025-08-27,0.4257799171524529,002652.SZ
+2025-08-28,0.42471207679153844,002634.SZ
+2025-08-28,0.4331637169412904,002207.SZ
+2025-08-29,0.40575460215325926,002856.SZ
+2025-08-29,0.4121275879233786,002634.SZ
+2025-09-01,0.4582061959521783,002188.SZ
+2025-09-01,0.4852694335789012,001211.SZ
+2025-09-02,0.4245475405423297,002188.SZ
+2025-09-02,0.4349171652984928,001211.SZ
+2025-09-03,0.41112035433697386,603709.SH
+2025-09-03,0.41472471551462353,002188.SZ
+2025-09-04,0.4117685220091898,002188.SZ
+2025-09-04,0.4469296140994765,001211.SZ
+2025-09-05,0.5017903752096126,603709.SH
+2025-09-05,0.505534069111205,001211.SZ
+2025-09-08,0.4246795387689724,002780.SZ
+2025-09-08,0.45858213113702057,001211.SZ
+2025-09-09,0.437499189344085,001211.SZ
+2025-09-09,0.4835481698917984,603709.SH
+2025-09-10,0.4440121378438937,603709.SH
+2025-09-10,0.4804947658329566,000890.SZ
+2025-09-11,0.3986451553343955,002963.SZ
+2025-09-11,0.39977988715441215,603709.SH
+2025-09-12,0.4106654687183073,002963.SZ
+2025-09-12,0.42539144050565797,002207.SZ
+2025-09-15,0.4485941786964948,002207.SZ
+2025-09-15,0.4757615700191159,002830.SZ
+2025-09-16,0.4152125408172885,002486.SZ
+2025-09-16,0.5051994458745068,600448.SH
+2025-09-17,0.41594737892427636,603177.SH
+2025-09-17,0.47439300348206453,600448.SH
+2025-09-18,0.4115313716133038,002486.SZ
+2025-09-18,0.4135390345267935,603183.SH
+2025-09-19,0.41169553133472137,603183.SH
+2025-09-19,0.4206962836948867,000890.SZ
+2025-09-22,0.4092675589741215,000890.SZ
+2025-09-22,0.5022964698880688,002513.SZ
+2025-09-23,0.3987497516890855,002780.SZ
+2025-09-23,0.4100388296832059,000890.SZ
+2025-09-24,0.43555533439506605,002193.SZ
+2025-09-24,0.4614084373935514,603356.SH
+2025-09-25,0.39270041845319287,603356.SH
+2025-09-25,0.5089885681464139,000890.SZ
+2025-09-26,0.4238406303390824,001211.SZ
+2025-09-26,0.43316640216281754,000890.SZ
+2025-09-29,0.42453303080206484,603356.SH
+2025-09-29,0.46920040955025666,000890.SZ
+2025-09-30,0.41017057831051856,600561.SH
+2025-09-30,0.4365536796968746,000890.SZ
+2025-10-09,0.435765260094562,000890.SZ
+2025-10-09,0.4847581570869999,002591.SZ
+2025-10-10,0.4126054403302005,600561.SH
+2025-10-10,0.41805170222846444,000890.SZ