def calc_factor_loading_(cls, start_date, end_date=None, month_end=True, save=False, **kwargs): """ 计算指定日期的样本个股的因子载荷, 并保存至因子数据库 Parameters: -------- :param start_date: datetime-like, str 开始日期, 格式: YYYY-MM-DD or YYYYMMDD :param end_date: datetime-like, str 结束日期, 如果为None, 则只计算start_date日期的因子载荷, 格式: YYYY-MM-DD or YYYYMMDD :param month_end: bool, 默认为True 如果为True, 则只计算月末时点的因子载荷 :param save: bool, 默认为True 是否保存至因子数据库 :param kwargs: 'multi_proc': bool, True=采用多进程, False=采用单进程, 默认为False :return: dict 因子载荷数据 """ # 取得交易日序列 start_date = Utils.to_date(start_date) if end_date is not None: end_date = Utils.to_date(end_date) trading_days_series = Utils.get_trading_days(start=start_date, end=end_date) else: trading_days_series = Utils.get_trading_days(end=start_date, ndays=1) # 遍历交易日序列, 计算Beta因子下各个成分因子的因子载荷 if 'multi_proc' not in kwargs: kwargs['multi_proc'] = False for calc_date in trading_days_series: if month_end and (not Utils.is_month_end(calc_date)): continue # 计算各成分因子的因子载荷 for com_factor in risk_ct.BETA_CT.component: factor = eval(com_factor + '()') factor.calc_factor_loading(start_date=calc_date, end_date=None, month_end=month_end, save=save, multi_proc=kwargs['multi_proc']) # 合成Beta因子载荷 Beta_factor = pd.DataFrame() for com_factor in risk_ct.BETA_CT.component: factor_path = os.path.join( factor_ct.FACTOR_DB.db_path, eval('risk_ct.' + com_factor + '_CT')['db_file']) factor_loading = Utils.read_factor_loading( factor_path, Utils.datetimelike_to_str(calc_date, dash=False)) factor_loading.drop(columns='date', inplace=True) factor_loading[com_factor] = Utils.normalize_data( Utils.clean_extreme_value( np.array(factor_loading['factorvalue']).reshape( (len(factor_loading), 1)))) factor_loading.drop(columns='factorvalue', inplace=True) if Beta_factor.empty: Beta_factor = factor_loading else: Beta_factor = pd.merge(left=Beta_factor, right=factor_loading, how='inner', on='id') Beta_factor.set_index('id', inplace=True) weight = pd.Series(risk_ct.BETA_CT.weight) Beta_factor = (Beta_factor * weight).sum(axis=1) Beta_factor.name = 'factorvalue' Beta_factor.index.name = 'id' Beta_factor = pd.DataFrame(Beta_factor) Beta_factor.reset_index(inplace=True) Beta_factor['date'] = Utils.get_trading_days(start=calc_date, ndays=2)[1] # 保存Beta因子载荷 if save: Utils.factor_loading_persistent( cls._db_file, Utils.datetimelike_to_str(calc_date, dash=False), Beta_factor.to_dict('list'), ['date', 'id', 'factorvalue'])
def calc_factor_loading(cls, start_date, end_date=None, month_end=True, save=False, **kwargs): """ 计算指定日期的样本个股的因子载荷, 并保存至因子数据库 Parameters: -------- :param start_date: datetime-like, str 开始日期, 格式: YYYY-MM-DD or YYYYMMDD :param end_date: datetime-like, str 结束日期, 如果为None, 则只计算start_date日期的因子载荷, 格式: YYYY-MM-DD or YYYYMMDD :param month_end: bool, 默认为True 如果为True, 则只计算月末时点的因子载荷 :param save: bool, 默认True 是否保存至因子数据库 :param kwargs: :return: dict 因子载荷 """ # 取得交易日序列及股票基本信息表 start_date = Utils.to_date(start_date) if end_date is not None: end_date = Utils.to_date(end_date) trading_days_series = Utils.get_trading_days(start=start_date, end=end_date) else: trading_days_series = Utils.get_trading_days(end=start_date, ndays=1) all_stock_basics = CDataHandler.DataApi.get_secu_basics() # 遍历交易日序列, 计算筹码分布因子载荷 dict_beta = {} dict_hsigma = {} for calc_date in trading_days_series: if month_end and (not Utils.is_month_end(calc_date)): continue logging.info('[%s] Calc BETA factor loading.' % Utils.datetimelike_to_str(calc_date)) # 遍历个股, 计算个股BETA因子值 s = (calc_date - datetime.timedelta( days=risk_ct.DBETA_CT.listed_days)).strftime('%Y%m%d') stock_basics = all_stock_basics[all_stock_basics.list_date < s] ids = [] # 个股代码list betas = [] # BETA因子值 hsigmas = [] # HSIGMA因子值 if 'multi_proc' not in kwargs: kwargs['multi_proc'] = False if not kwargs['multi_proc']: # 采用单进程计算BETA因子和HSIGMA因子值, for _, stock_info in stock_basics.iterrows(): logging.info( "[%s] Calc %s's BETA and HSIGMA factor data." % (calc_date.strftime('%Y-%m-%d'), stock_info.symbol)) beta_data = cls._calc_factor_loading( stock_info.symbol, calc_date) if beta_data is None: ids.append(Utils.code_to_symbol(stock_info.symbol)) betas.append(np.nan) hsigmas.append(np.nan) else: ids.append(beta_data['code']) betas.append(beta_data['beta']) hsigmas.append(beta_data['hsigma']) else: # 采用多进程并行计算BETA因子和HSIGMA因子值 q = Manager().Queue() # 队列, 用于进程间通信, 存储每个进程计算的因子载荷 p = Pool(4) # 进程池, 最多同时开启4个进程 for _, stock_info in stock_basics.iterrows(): p.apply_async(cls._calc_factor_loading_proc, args=( stock_info.symbol, calc_date, q, )) p.close() p.join() while not q.empty(): beta_data = q.get(True) ids.append(beta_data['code']) betas.append(beta_data['beta']) hsigmas.append(beta_data['hsigma']) date_label = Utils.get_trading_days(calc_date, ndays=2)[1] dict_beta = { 'date': [date_label] * len(ids), 'id': ids, 'factorvalue': betas } dict_hsigma = { 'date': [date_label] * len(ids), 'id': ids, 'factorvalue': hsigmas } if save: Utils.factor_loading_persistent( cls._db_file, Utils.datetimelike_to_str(calc_date, dash=False), dict_beta, ['date', 'id', 'factorvalue']) hsigma_path = os.path.join(factor_ct.FACTOR_DB.db_path, risk_ct.HSIGMA_CT.db_file) Utils.factor_loading_persistent( hsigma_path, Utils.datetimelike_to_str(calc_date, dash=False), dict_hsigma, ['date', 'id', 'factorvalue']) # 休息180秒 logging.info('Suspending for 180s.') # time.sleep(180) return dict_beta
def calc_factor_loading(cls, start_date, end_date=None, month_end=True, save=False, **kwargs): """ 计算指定日期的样本个股的因子载荷, 并保存至因子数据库 Parameters: -------- :param start_date: datetime-like, str 开始日期, 格式: YYYY-MM-DD or YYYYMMDD :param end_date: datetime-like, str 结束日期, 如果为None, 则只计算start_date日期的因子载荷, 格式: YYYY-MM-DD or YYYYMMDD :param month_end: bool, 默认为True 如果为True, 则只计算月末时点的因子载荷 :param save: bool, 默认为True 是否保存至因子数据库 :param kwargs: 'multi_proc': bool, True=采用多进程, False=采用单进程, 默认为False :return: dict 因子载荷数据 """ # 取得交易日序列及股票基本信息表 start_date = Utils.to_date(start_date) if end_date is not None: end_date = Utils.to_date(end_date) trading_days_series = Utils.get_trading_days(start=start_date, end=end_date) else: trading_days_series = Utils.get_trading_days(end=start_date, ndays=1) # all_stock_basics = CDataHandler.DataApi.get_secu_basics() # 遍历交易日序列, 计算BLEV因子载荷 dict_blev = None for calc_date in trading_days_series: if month_end and (not Utils.is_month_end(calc_date)): continue logging.info('[%s] Calc BLEV factor loading.' % Utils.datetimelike_to_str(calc_date)) # 遍历个股, 计算个股的BLEV因子值 # s = (calc_date - datetime.timedelta(days=risk_ct.BLEV_CT.listed_days)).strftime('%Y%m%d') # stock_basics = all_stock_basics[all_stock_basics.list_date < s] s = calc_date - datetime.timedelta( days=risk_ct.BLEV_CT.listed_days) stock_basics = Utils.get_stock_basics(s, False) ids = [] # 个股代码list blevs = [] # BLEV因子值list if 'multi_proc' not in kwargs: kwargs['multi_proc'] = False if not kwargs['multi_proc']: # 采用单进程计算BLEV因子值 for _, stock_info in stock_basics.iterrows(): logging.debug( "[%s] Calc %s's BLEV factor loading." % (calc_date.strftime('%Y-%m-%d'), stock_info.symbol)) blev_data = cls._calc_factor_loading( stock_info.symbol, calc_date) if blev_data is None: ids.append(Utils.code_to_symbol(stock_info.symbol)) blevs.append(np.nan) else: ids.append(blev_data['code']) blevs.append(blev_data['blev']) else: # 采用多进程并行计算BLEV因子值 q = Manager().Queue() # 队列, 用于进程间通信, 存储每个进程计算的因子载荷 p = Pool(SETTINGS.CONCURRENCY_KERNEL_NUM) # 进程池, 最多同时开启4个进程 for _, stock_info in stock_basics.iterrows(): p.apply_async(cls._calc_factor_loading_proc, args=( stock_info.symbol, calc_date, q, )) p.close() p.join() while not q.empty(): blev_data = q.get(True) ids.append(blev_data['code']) blevs.append(blev_data['blev']) date_label = Utils.get_trading_days(start=calc_date, ndays=2)[1] dict_blev = { 'date': [date_label] * len(ids), 'id': ids, 'factorvalue': blevs } if save: Utils.factor_loading_persistent( cls._db_file, Utils.datetimelike_to_str(calc_date, dash=False), dict_blev, ['date', 'id', 'factorvalue']) # 暂停180秒 # logging.info('Suspending for 180s.') # time.sleep(180) return dict_blev
def mom_backtest(start, end): """ 日内动量因子历史回测 Parameters: -------- :param start: datetime-like, str 回测开始日期,格式YYYY-MM-DD or YYYYMMDD :param end: datetime-like, str 回测结束日期,格式:YYYY-MM-DD or YYYYMMDD :return: """ # 取得开始、结束日期之间的交易日序列 trading_days = Utils.get_trading_days(start, end) # 读取截止开始日期前最新的组合回测数据 prev_trading_day = Utils.get_prev_n_day(trading_days.iloc[0], 1) backtest_path = os.path.join(alphafactor_ct.FACTOR_DB.db_path, alphafactor_ct.INTRADAYMOMENTUM_CT.backtest_path) factor_data, port_nav = Utils.get_backtest_data(backtest_path, trading_days.iloc[0]) if port_nav is None: port_nav = DataFrame({'date': [prev_trading_day.strftime('%Y-%m-%d')], 'nav': [1.0]}) # 遍历交易日,如果是月初,则读取动量因子载荷值;如果不是月初,则进行组合估值 for trading_day in trading_days: if factor_data is None: nav = port_nav[port_nav.date == prev_trading_day.strftime('%Y-%m-%d')].iloc[0].nav else: nav = port_nav[port_nav.date == factor_data.iloc[0].date].iloc[0].nav interval_ret = 0.0 # 月初进行调仓 if Utils.is_month_start(trading_day): logging.info('[%s] 月初调仓.' % Utils.datetimelike_to_str(trading_day, True)) # 调仓前,先计算按均价卖出原先组合个股在当天的组合nav if factor_data is not None: for ind, factor_info in factor_data.iterrows(): daily_mkt = Utils.get_secu_daily_mkt(factor_info.id, trading_day, fq=True, range_lookup=True) if daily_mkt.date == trading_day.strftime('%Y-%m-%d'): vwap_price = daily_mkt.amount / daily_mkt.vol * daily_mkt.factor else: vwap_price = daily_mkt.close interval_ret += vwap_price / factor_info.buyprice - 1.0 interval_ret /= float(len(factor_data)) nav *= (1.0 + interval_ret) # 读取factor_data factor_data_path = os.path.join(alphafactor_ct.FACTOR_DB.db_path, alphafactor_ct.INTRADAYMOMENTUM_CT.synthetic_db_file) factor_data = Utils.read_factor_loading(factor_data_path, Utils.datetimelike_to_str(prev_trading_day, False)) # 遍历factor_data,剔除在调仓日期没有正常交易(如停牌)、及涨停的个股 ind_to_be_deleted = [] for ind, factor_info in factor_data.iterrows(): trading_status = Utils.trading_status(factor_info.id, trading_day) if trading_status == SecuTradingStatus.Suspend or trading_status == SecuTradingStatus.LimitUp: ind_to_be_deleted.append(ind) factor_data = factor_data.drop(ind_to_be_deleted, axis=0) # 对factor_data按因子值升序排列,取前10%个股 factor_data = factor_data.sort_values(by='factorvalue', ascending=True) factor_data = factor_data.iloc[:int(len(factor_data)*0.1)] # 遍历factor_data,添加买入价格,并估值计算当天调仓后的组合收益 factor_data['buyprice'] = 0.0 interval_ret = 0.0 for ind, factor_info in factor_data.iterrows(): daily_mkt = Utils.get_secu_daily_mkt(factor_info.id, trading_day, fq=True, range_lookup=False) assert len(daily_mkt) > 0 factor_data.loc[ind, 'buyprice'] = daily_mkt.amount / daily_mkt.vol * daily_mkt.factor interval_ret += daily_mkt.close / factor_data.loc[ind, 'buyprice'] - 1.0 interval_ret /= float(len(factor_data)) nav *= (1.0 + interval_ret) # 保存factor_data port_data_path = os.path.join(alphafactor_ct.FACTOR_DB.db_path, alphafactor_ct.INTRADAYMOMENTUM_CT.backtest_path, 'port_data_%s.csv' % Utils.datetimelike_to_str(trading_day, False)) factor_data.to_csv(port_data_path, index=False) else: # 非调仓日,对组合进行估值 logging.info('[%s] 月中估值.' % Utils.datetimelike_to_str(trading_day, True)) if factor_data is not None: for ind, factor_info in factor_data.iterrows(): daily_mkt = Utils.get_secu_daily_mkt(factor_info.id, trading_day, fq=True, range_lookup=True) interval_ret += daily_mkt.close / factor_info.buyprice - 1.0 interval_ret /= float(len(factor_data)) nav *= (1.0 + interval_ret) # 添加nav port_nav = port_nav.append(Series({'date': trading_day.strftime('%Y-%m-%d'), 'nav': nav}), ignore_index=True) # 设置prev_trading_day prev_trading_day = trading_day # 保存port_nav port_nav_path = os.path.join(alphafactor_ct.FACTOR_DB.db_path, alphafactor_ct.INTRADAYMOMENTUM_CT.backtest_path, 'port_nav.csv') port_nav.to_csv(port_nav_path, index=False)
def calc_factor_loading(cls, start_date, end_date=None, month_end=True, save=False, **kwargs): """ 计算指定日期的样本个股的因子载荷,并保存至因子数据库 Parameters -------- :param start_date: datetime-like, str 开始日期,格式:YYYY-MM-DD or YYYYMMDD :param end_date: datetime-like, str 结束日期,如果为None,则只计算start_date日期的因子载荷,格式:YYYY-MM-DD or YYYYMMDD :param month_end: bool,默认True 如果为True,则只计算月末时点的因子载荷 :param save: bool,默认False 是否保存至因子数据库 :param kwargs: 'multi_proc': bool, True=采用多进程并行计算, False=采用单进程计算, 默认为False :return: 因子载荷,DataFrame -------- 因子载荷,DataFrame 0. date: 日期 1. id: 证券symbol 2. m0: 隔夜时段动量 3. m1: 第一个小时动量 4. m2: 第二个小时动量 5. m3: 第三个小时动量 6. m4: 第四个小时动量 7. m_normal: 传统动量 """ # 取得交易日序列及股票基本信息表 start_date = Utils.to_date(start_date) if end_date is not None: end_date = Utils.to_date(end_date) trading_days_series = Utils.get_trading_days(start=start_date, end=end_date) else: trading_days_series = Utils.get_trading_days(end=start_date, ndays=1) # all_stock_basics = CDataHandler.DataApi.get_secu_basics() # 遍历交易日序列,计算日内动量因子值 dict_intraday_momentum = None for calc_date in trading_days_series: if month_end and (not Utils.is_month_end(calc_date)): continue # 计算日内各时段动量因子 dict_intraday_momentum = {'date': [], 'id': [], 'm0': [], 'm1': [], 'm2': [], 'm3': [], 'm4': [], 'm_normal': []} # 遍历个股,计算个股日内动量值 s = (calc_date - datetime.timedelta(days=90)).strftime('%Y%m%d') stock_basics = Utils.get_stock_basics(s) if 'multi_proc' not in kwargs: kwargs['multi_proc'] = False if not kwargs['multi_proc']: # 采用单进程进行计算 for _, stock_info in stock_basics.iterrows(): momentum_data = cls._calc_factor_loading(stock_info.symbol, calc_date) if momentum_data is not None: logging.info("[%s] %s's intraday momentum = (%0.4f,%0.4f,%0.4f,%0.4f,%0.4f,%0.4f)" % (calc_date.strftime('%Y-%m-%d'),stock_info.symbol, momentum_data.m0, momentum_data.m1, momentum_data.m2, momentum_data.m3, momentum_data.m4, momentum_data.m_normal)) dict_intraday_momentum['id'].append(Utils.code_to_symbol(stock_info.symbol)) dict_intraday_momentum['m0'].append(round(momentum_data.m0, 6)) dict_intraday_momentum['m1'].append(round(momentum_data.m1, 6)) dict_intraday_momentum['m2'].append(round(momentum_data.m2, 6)) dict_intraday_momentum['m3'].append(round(momentum_data.m3, 6)) dict_intraday_momentum['m4'].append(round(momentum_data.m4, 6)) dict_intraday_momentum['m_normal'].append(round(momentum_data.m_normal, 6)) else: # 采用多进程并行计算日内动量因子载荷 q = Manager().Queue() # 队列,用于进程间通信,存储每个进程计算的因子载荷 p = Pool(4) # 进程池,最多同时开启4个进程 for _, stock_info in stock_basics.iterrows(): p.apply_async(cls._calc_factor_loading_proc, args=(stock_info.symbol, calc_date, q,)) p.close() p.join() while not q.empty(): momentum_data = q.get(True) dict_intraday_momentum['id'].append(momentum_data[0]) dict_intraday_momentum['m0'].append(round(momentum_data[1], 6)) dict_intraday_momentum['m1'].append(round(momentum_data[2], 6)) dict_intraday_momentum['m2'].append(round(momentum_data[3], 6)) dict_intraday_momentum['m3'].append(round(momentum_data[4], 6)) dict_intraday_momentum['m4'].append(round(momentum_data[5], 6)) dict_intraday_momentum['m_normal'].append(round(momentum_data[6], 6)) date_label = Utils.get_trading_days(calc_date, ndays=2)[1] dict_intraday_momentum['date'] = [date_label] * len(dict_intraday_momentum['id']) # 保存因子载荷至因子数据库 if save: # Utils.factor_loading_persistent(cls._db_file, calc_date.strftime('%Y%m%d'), dict_intraday_momentum) cls._save_factor_loading(cls._db_file, Utils.datetimelike_to_str(calc_date, dash=False), dict_intraday_momentum, 'periodmomentum', factor_type='raw') # 计算日内各时段动量因子的Rank IC值向量, 并保存 cls._calc_periodmomentum_ic(calc_date, 'month') # 计算最优化权重 if alphafactor_ct.INTRADAYMOMENTUM_CT['optimized']: cls._optimize_periodmomentum_weight(calc_date) # 计算合成日内动量因子 if alphafactor_ct.INTRADAYMOMENTUM_CT['synthesized']: logging.info('[%s] calc synthetic intraday momentum factor loading.' % Utils.datetimelike_to_str(calc_date)) dict_intraday_momentum = {'date': [], 'id': [], 'factorvalue': []} # 读取日内个时段动量因子值 # period_momentum_path = os.path.join(SETTINGS.FACTOR_DB_PATH, alphafactor_ct.INTRADAYMOMENTUM_CT.db_file, 'raw/periodmomentum') # df_factor_loading = Utils.read_factor_loading(period_momentum_path, Utils.datetimelike_to_str(calc_date, False)) df_factor_loading = cls._get_factor_loading(cls._db_file, Utils.datetimelike_to_str(calc_date, dash=False), factor_name='periodmomentum', factor_type='raw', drop_na=False) if df_factor_loading.shape[0] <= 0: logging.info("[%s] It doesn't exist intraday momentum factor loading." % Utils.datetimelike_to_str(calc_date)) return df_factor_loading.fillna(0, inplace=True) # 读取因子最优权重 factor_weight = cls._get_factor_weight(calc_date) if factor_weight is None: logging.info("[%s] It doesn't exist factor weight.") return # 计算合成动量因子, 合成之前先对日内各时段动量因子进行去极值和标准化处理 arr_factor_loading = np.array(df_factor_loading[['m0', 'm1', 'm2', 'm3', 'm4']]) arr_factor_loading = Utils.normalize_data(arr_factor_loading, treat_outlier=True) arr_factor_weight = np.array(factor_weight.drop('date')).reshape((5, 1)) arr_synthetic_factor = np.dot(arr_factor_loading, arr_factor_weight) dict_intraday_momentum['date'] = list(df_factor_loading['date']) dict_intraday_momentum['id'] = list(df_factor_loading['id']) dict_intraday_momentum['factorvalue'] = list(arr_synthetic_factor.astype(float).round(6).reshape((arr_synthetic_factor.shape[0],))) # 标准化合成动量因子 df_std_intradaymonmentum = Utils.normalize_data(pd.DataFrame(dict_intraday_momentum), columns='factorvalue', treat_outlier=True, weight='eq') # 保存合成因子 if save: # Utils.factor_loading_persistent(synthetic_db_file, Utils.datetimelike_to_str(calc_date, False), dict_intraday_momentum) cls._save_factor_loading(cls._db_file, Utils.datetimelike_to_str(calc_date, dash=False), dict_intraday_momentum, 'IntradayMomentum', factor_type='raw', columns=['date', 'id', 'factorvalue']) cls._save_factor_loading(cls._db_file, Utils.datetimelike_to_str(calc_date, dash=False), df_std_intradaymonmentum, 'IntradayMomentum', factor_type='standardized', columns=['date', 'id', 'factorvalue']) # 休息360秒 logging.info('Suspending for 360s.') time.sleep(360) return dict_intraday_momentum
def load_industry_classify(standard='sw', date=datetime.date.today()): """导入个股行业分类数据""" cfg = ConfigParser() cfg.read('config.ini') # 读取申万一级行业信息 sw_classify_info_path = os.path.join( cfg.get('factor_db', 'db_path'), cfg.get('industry_classify', 'classify_data_path'), 'classify_standard_sw.csv') df_sw_classify = pd.read_csv(sw_classify_info_path, names=['ind_code', 'ind_name'], header=0) # 读取申万非银金融下二级行业信息 sw_fyjr_classify_path = os.path.join( cfg.get('industry_classify', 'raw_data_path'), 'sw_fyjr_classify.csv') df_sw_fyjr_classify = pd.read_csv(sw_fyjr_classify_path, dtype={'code': object}, header=0) # 读取股票最新行业分类原始数据,导入本系统的股票申万一级行业分类数据文件 # 同时把非银金融一级行业替换成二级行业 raw_data_path = os.path.join(cfg.get('industry_classify', 'raw_data_path'), 'industry_classify_sw.csv') classify_data = [['证券代码', '申万行业代码', '申万行业名称']] with open(raw_data_path, 'r', newline='') as f: f.readline() csv_reader = csv.reader(f, delimiter='\t') for row in csv_reader: code = 'SH' + row[1] if row[1][0] == '6' else 'SZ' + row[1] ind_name = row[0] if row[1] in df_sw_fyjr_classify['code'].values: ind_name = df_sw_fyjr_classify[df_sw_fyjr_classify.code == row[1]].iloc[0].c_name ind_code = df_sw_classify[df_sw_classify.ind_name == ind_name].iloc[0].ind_code classify_data.append([code, ind_code, ind_name]) # 添加退市或暂停交易个股的行业分类数据 delisted_data_path = os.path.join( cfg.get('factor_db', 'db_path'), cfg.get('industry_classify', 'classify_data_path'), 'delisted_classify_sw.csv') with open(delisted_data_path, 'r', newline='') as f: f.readline() csv_reader = csv.reader(f, delimiter=',') for row in csv_reader: code = row[0] listed_date = row[2] delisted_date = row[3] ind_code = row[7] ind_name = row[8] if delisted_date > Utils.datetimelike_to_str( date, dash=False) and listed_date <= Utils.datetimelike_to_str( date, dash=False): classify_data.append([code, ind_code, ind_name]) # 保存股票行业分类文件 ind_files = [ 'industry_classify_sw.csv', 'industry_classify_sw_{}.csv'.format( Utils.datetimelike_to_str(date, dash=False)) ] for file_name in ind_files: classify_data_path = os.path.join( cfg.get('factor_db', 'db_path'), cfg.get('industry_classify', 'classify_data_path'), file_name) with open(classify_data_path, 'w', newline='') as f: csv_writer = csv.writer(f) csv_writer.writerows(classify_data) # 检查退市股票行业分类数据中是否已包含所有的已退市股票 _check_dlisted_indclassify()