# 小果可转债自定义因子选择系统 **Repository Path**: li-xingguo11111/small_fruit_custom_factor_selection_system ## Basic Information - **Project Name**: 小果可转债自定义因子选择系统 - **Description**: 小果可转债自定义因子选择系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 3 - **Created**: 2025-01-15 - **Last Updated**: 2025-08-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 小果可转债自定义因子选择系统 #### 介绍 小果可转债自定义因子选择系统 小果可转债自定义因子选择系统是一套用于分析和筛选可转债投资机会的工具,以下是其详细介绍: 功能特点 多因子分析:系统提供多种预设因子,如规模因子、估值因子、成长因子、盈利因子、动量反转因子、交投因子等,投资者也可根据自身需求和投资策略自定义因子,对可转债进行综合评估。 数据整合与处理:能够整合来自不同数据源的可转债相关数据,包括财务数据、市场行情数据、交易数据等,并进行清洗、整理和标准化处理,确保数据的质量和一致性,为因子分析提供准确的数据基础。 因子权重计算:通过一定的数学模型和算法,计算每个因子在综合评估中的权重,以反映其对可转债投资价值的影响程度。权重的确定可以基于历史数据的分析,也可以根据投资者的主观判断进行调整。 回测与验证:支持对自定义因子组合进行历史回测,通过模拟过去的市场情况,检验因子组合的有效性和稳定性,帮助投资者评估策略的风险收益特征,优化投资决策。 可视化展示:以直观的图表和报表形式展示因子分析的结果,如因子值分布、因子权重变化、投资组合的表现等,使投资者能够更清晰地了解可转债的特征和投资机会 #### 软件架构 软件架构说明 #### 安装教程 当作第三方库使用 #### 使用说明 ### 1服务器数据使用 打开网页http://120.78.132.143:8023/ ![输入图片说明](1image.png) 点击可转债实时因子 ![输入图片说明](2image.png) 点击选择交易日 ![输入图片说明](3image.png) 默认因子点击选择数据类型 ![输入图片说明](4image.png) 全部的合成因子 ![输入图片说明](5image.png) 点击可以下载数据 ![输入图片说明](6image.png) 下载的数据 ![输入图片说明](7image.png) ### 2本地使用 1设置自定义因和录得一样 ``` { "小果自定义因子选择系统": "小果可转债服务器提供实时因子数据支持,完全兼容实盘", "可转债数据源说明": "服务器/集思录", "数据源":"服务器", "服务器数据源设置": "服务器数据源设置********", "服务器": "http://124.220.32.224", "端口": "8888", "授权码": "xg123456", "是否测试": "否", "测试时间": "20241227", "集思录数据源设置": "集思录数据源设置********", "集思录账户": "199856", "集思录密码": "", "是否数据没有更新的情况下更新": "是", "可转债自定义因子计算": "可转债自定义因子计算************,基于默认因子表计算,df是因子表名称", "是否开启默认因子计算": "是", "默认因子计算": { "三要素评分": "df['溢价率']*100+df['剩余年限']-df['到期税前收益']*100" }, "强制赎回设置": "************************", "是否剔除强制赎回": "是", "满足强制赎回天数": 10, "排除上市天数": 3, "是否排除ST": "是", "排除市场": [], "行业说明": "查询行业表**********,混合排除不区分一二三级行业", "排除行业": [], "排除企业类型": [], "排除地域": [], "排除外部评级": [], "排除三方评级": [], "添加排除因子": "排除因子设置************************", "因子计算符号说明": "大于,小于,大于排名%,小于排名%,空值,排除是相反的,大于是小于", "排除因子": [ "价格", "价格", "涨幅", "涨幅", "溢价率", "溢价率", "剩余规模(亿)", "剩余规模(亿)", "换手率" ], "因子计算符号": [ "大于", "小于", "大于", "小于", "大于", "小于", "大于", "小于", "小于" ], "因子值": [ 130, 100, 8, -1, 30, -1, 8, 0, 3 ], "打分因子设置": "*************************************************", "打分因子说明": "正相关:因子值越大得分越高;负相关:因子值越大得分越低,", "打分因子": [ "溢价率", "价格", "剩余规模(亿)" ], "因子相关性": [ "负相关", "负相关", "负相关" ], "因子权重": [ 1, 1, 1 ], "持有限制": 10, "持股限制": 10, "策略轮动设置": "策略轮动设置************************,轮动都按排名来", "轮动方式说明": "每天/每周/每月/特别时间", "轮动方式": "每天", "说明": "每天按自定义函数运行", "每周轮动是说明": "每周比如0是星期一,4是星期五**********", "每周轮动时间": 0, "每月轮动是说明": "必须是交易日,需要自己每个月自动输入**********", "每月轮动时间": [ "2024-02-29", "2024-02-29" ], "特定时间说明": "特别的应该交易日", "特定时间": [ "2024-02-23", "2024-02-24" ], "轮动规则设置": "轮动规则设置88888888**********排名", "买入排名前N": 10, "持有排名前N": 10, "跌出排名卖出N": 10, "买入前N": 10, "自定义因子模块": "自定义因子模块设置***********************", "是否开启自定义因子": "否", "自定义因子": { "5日收益": "return_5()", "均线金叉": "ma_gold_fork()", "macd金叉": "macd_gold_fork()" } } ``` 修改自定义因子就可以选股条件 2点击运行源代码就可以 ![输入图片说明](8image.png) 9运行的结果 ![输入图片说明](9image.png) ``` 用户名称 用户密码 授权码 到期时间 到期天数 0 xg123456 xg123456 123456 2025-03-30 74 开启计算默认因子*********************** 三要素评分 因子计算完成 unsupported operand type(s) for -: 'str' and 'str' 三要素评分 因子计算有问题 [] __________________________________________ 不开启自定义函数 可转债名称 可转债代码 正股名称 正股代码 一级行业 二级行业 三级行业 价格 转股价值 ... 行业排除 排除地域 排除外部评 级 排除三方评级 溢价率_得分 总分 排名 价格_得分 剩余规模(亿)_得分 92 维格转债 113527 锦泓集团 603518 纺织服饰 服装家纺 非运动服装纺织服饰 -115.000 99.04 ... 不是 不是 不是 不是 10.0 19.0 1.0 2.0 7.0 81 金埔转债 123198 金埔园林R 301098 建筑装饰 基础建设 园林工程建筑装饰 -115.806 102.11 ... 不是 不是 不是 不是 7.0 22.0 2.0 3.0 12.0 44 鼎胜转债 113534 鼎胜新材R 603876 有色金属 工业金属 铝有色金属 -123.030 112.35 ... 不是 不是 不是 不是 5.0 26.0 3.0 13.0 8.0 113 亚药转债 128062 亚太药业R 2370 医药生物 化学制药 化学制剂医药生物 -118.391 100.33 ... 不是 不是 不是 不是 15.0 30.0 4.0 6.0 9.0 84 金轮转债 128076 物产金轮 2722 机械设备 专用设备 纺织服装设备机械设备 -125.533 109.43 ... 不是 不是 不是 不是 9.0 32.0 5.0 21.0 2.0 97 伊力转债 110055 伊力特R 600197 食品饮料 白酒Ⅱ 白酒Ⅲ食品饮料 -123.900 105.99 ... 不是 不是 不是 不是 12.0 34.0 6.0 18.0 4.0 109 宏丰转债 123141 温州宏丰 300283 电力设备 电网设备 配电设备电力设备 -122.445 103.74 ... 不是 不是 不是 不是 16.0 38.0 7.0 12.0 10.0 103 煜邦转债 118039 煜邦电力R 688597 电力设备 电网设备 电工仪器仪表电力设备 -120.334 102.08 ... 不是 不是 不是 不是 14.0 39.0 8.0 7.0 18.0 93 泉峰转债 113629 泉峰汽车R 603982 汽车 汽车零部件 底盘与发动机系统汽车 -116.275 100.25 ... 不是 不是 不是 不是 11.0 42.0 9.0 4.0 27.0 101 贵广转债 110052 贵广网络R 600996 传媒 电视广播Ⅱ 电视广播Ⅲ传媒 -128.270 109.24 ... 不是 不是 不是 不是 13.0 44.0 10.0 30.0 1.0 4 亚泰转债 128066 郑中设计 2811 建筑装饰 装修装饰Ⅱ 装修装饰Ⅲ建筑装饰 -127.422 127.65 ... 不是 不是 不是 不是 1.0 45.0 11.0 25.0 19.0 179 易瑞转债 123220 易瑞生物R 300942 医药生物 医疗器械 体外诊断医药生物 -118.210 94.26 ... 不是 不是 不是 不是 30.0 46.0 12.0 5.0 11.0 149 智能转债 128070 智能自控 2877 机械设备 通用设备 金属制品机械设备 -126.621 103.75 ... 不是 不是 不是 不是 23.0 50.0 13.5 24.0 3.0 77 白电转债 113549 白云电器 603861 电力设备 电网设备 配电设备电力设备 -128.138 112.94 ... 不是 不是 不是 不是 8.0 50.0 13.5 28.0 14.0 127 中旗转债 127081 中旗新材 1212 建筑材料 装修建材 其他建材建筑材料 -121.892 101.88 ... 不是 不是 不是 不是 20.0 52.0 15.0 11.0 21.0 137 中辰转债 123147 中辰股份R 300933 电力设备 电网设备 线缆部件及其他电力设备 -121.562 100.93 ... 不是 不是 不是 不是 21.0 56.0 16.0 10.0 25.0 157 朗科转债 123100 朗科智能 300543 家用电器 家电零部件Ⅱ 家电零部件Ⅲ家用电器 -123.739 100.81 ... 不是 不是 不是 不是 26.0 57.0 17.5 16.0 15.0 171 天壕转债 123092 天壕能源R 300332 公用事业 燃气Ⅱ 燃气Ⅲ公用事业 -123.465 99.0 ... 不是 不是 不是 不是 29.0 57.0 17.5 15.0 13.0 161 科达转债 113569 苏州科达R 603660 计算机 计算机设备 其他计算机设备计算机 -127.444 103.77 ... 不是 不是 不是 不是 27.0 58.0 19.0 26.0 5.0 124 润禾转债 123152 润禾材料 300727 基础化工 化学制品 有机硅基础化工 -129.963 108.99 ... 不是 不是 不是 不是 18.0 60.0 20.5 36.0 6.0 60 力诺转债 123221 力诺药包R 301188 医药生物 医疗器械 医疗耗材医药生物 -128.899 115.94 ... 不是 不是 不是 不是 6.0 60.0 20.5 32.0 22.0 30 金丹转债 123204 金丹科技 300829 基础化工 化学制品 食品及饲料添加剂基础化工 -129.061 119.63 ... 不是 不是 不是 不是 3.0 64.0 22.0 35.0 26.0 203 雪榕转债 123056 雪榕生物 300511 农林牧渔 种植业 食用菌农林牧渔 -107.200 83.9 ... 不是 不是 不是 不是 36.0 67.0 24.5 1.0 30.0 15 星球转债 118041 星球石墨R 688633 机械设备 专用设备 能源及重型设备机械设备 -128.967 124.5 ... 不是 不是 不是 不是 2.0 67.0 24.5 34.0 31.0 39 智尚转债 123191 南山智尚R 300918 纺织服饰 纺织制造 其他纺织纺织服饰 -128.624 118.61 ... 不是 不是 不是 不是 4.0 67.0 24.5 31.0 32.0 120 景兴转债 128130 景兴纸业R 2067 轻工制造 造纸 大宗用纸轻工制造 -123.082 103.54 ... 不是 不是 不是 不是 17.0 67.0 24.5 14.0 36.0 159 利扬转债 118048 利扬芯片R 688135 电子 半导体 集成电路封测电子 -124.410 101.36 ... 不是 不是 不是 不是 25.0 68.0 27.0 19.0 24.0 195 华设转债 113674 华设集团R 603018 建筑装饰 工程咨询服务Ⅱ 工程咨询服务Ⅲ建筑装饰 -125.172 98.71 ... 不是 不是 不是 不是 33.0 70.0 28.5 20.0 17.0 197 富仕转债 123217 四会富仕 300852 电子 元件 印制电路板电子 -120.422 94.68 ... 不是 不是 不是 不是 34.0 70.0 28.5 8.0 28.0 166 嘉益转债 123250 嘉益股份R 301004 轻工制造 家居用品 其他家居用品轻工制造 -127.791 102.69 ... 不是 不是 不是 不是 28.0 71.0 30.0 27.0 16.0 126 博杰转债 127051 博杰股份 2975 机械设备 自动化设备 工控设备机械设备 -128.940 107.83 ... 不是 不是 不是 不是 19.0 72.0 31.0 33.0 20.0 201 江山转债 113625 江山欧派 603208 轻工制造 家居用品 定制家居轻工制造 -120.516 94.36 ... 不是 不是 不是 不是 35.0 73.0 32.0 9.0 29.0 186 亿田转债 123235 亿田智能R 300911 家用电器 厨卫电器 厨房电器家用电器 -126.511 100.56 ... 不是 不是 不是 不是 32.0 78.0 33.0 23.0 23.0 153 佩蒂转债 123133 佩蒂股份 300673 农林牧渔 饲料 宠物食品农林牧渔 -126.213 103.12 ... 不是 不是 不是 不是 24.0 81.0 34.5 22.0 35.0 183 福立转债 118043 福立旺R 688678 电子 消费电子 消费电子零部件及组装电子 -123.757 98.47 ... 不是 不是 不是 不是 31.0 81.0 34.5 17.0 33.0 151 华兴转债 118003 华兴源创R 688001 机械设备 通用设备 仪器仪表机械设备 -128.230 105.08 ... 不是 不是 不是 不是 22.0 85.0 36.0 29.0 34.0 [36 rows x 166 columns] ``` ### 3在线编译器使用 1点击网页http://120.78.132.143:8023/ ![输入图片说明](10image.png) 2点击小果量化编译器 ![输入图片说明](11image.png) 3点击可转债自定义因子选择系统 ![输入图片说明](12image.png) 4进入 ![输入图片说明](13image.png) 1导入系统库 ``` from small_fruit_custom_factor_selection_system.small_fruit_custom_factor_selection_system import small_fruit_custom_factor_selection_system ``` 2导入因子设置 ![输入图片说明](14image.png) 3设置允许系统 ``` data=small_fruit_custom_factor_selection_system(url='http://124.220.32.224', port='8023', password='xg123456', date='20250115', text=text) df=data.get_select_result() ``` 点击运行 ![输入图片说明](15image.png) ### 4源代码分析框架源代码 ``` import pandas as pd from tqdm import tqdm import numpy as np import json import numpy as np import os from datetime import datetime import time from xg_data.xg_data import xg_data from xg_data.stock_data import stock_data class small_fruit_custom_factor_selection_system: def __init__(self,url='http://124.220.32.224', port='8023', password='xg123456', text={}, date='20250114'): ''' 小果可转债自定义因子选择系统 ''' print('小果可转债自定义因子选择系统 ') print('作者:小果') print('作者微信:15117320079,开实盘qmt可以联系我,开户也可以') print('作者微信公众号:数据分析与运用') print('公众号链接:https://mp.weixin.qq.com/s/rxGJpZYxdUIHitjvI-US1A') print("作者知识星球:金融量化交易研究院 https://t.zsxq.com/19VzjjXNi") self.url=url self.port=port self.password=password self.text=text self.xg_data=xg_data(url=self.url,port=self.port,password=self.password) self.stock_data=stock_data() self.date=date def select_bond_cov(self,x): ''' 选择证券代码 ''' if x[:3] in ['110','113','123','127','128','111'] or x[:2] in ['11','12']: return '是' else: return '不是' def get_bond_spot_fcator(self,date='20241101'): ''' 获取可转债实时因子数据 ''' func=''' import pandas as pd df=pd.read_csv(r'C:/Users/Administrator/Desktop/集思录数据/data/实时数据/{}.csv') '''.format(date) info,df=self.get_user_def_data(func=func) return info,df def get_bond_spot_fcator(self,date='20241101'): ''' 获取可转债实时因子数据 ''' df=self.xg_data.get_bond_spot_fcator(date) return df def get_bond_default_fcator(self,date='20241101'): ''' 获取可转债默认因子 ''' df=self.xg_data.get_bond_default_fcator(date) return df def get_bond_raft_fcator(self,date='20241101'): ''' 获取可转债合并因子 ''' df=self.xg_data.get_bond_raft_fcator(date) return df def get_all_factor_data(self): ''' 获取可转债全部数据 ''' print("获取可转债全部数据************") text=self.text data_type=text['数据源'] url=text['服务器'] port=text['端口'] user_password=text['授权码'] jsl_user=text['集思录账户'] jsl_password=text['集思录密码'] test=text['是否测试'] test_time=text['测试时间'] data=xg_data(url=url,port=port,password=user_password) if test=='是': print('启动测试数据') now_date=test_time else: now_date=self.date if data_type=='服务器': func=''' from xg_data.xg_data import xg_data api=xg_data(url='{}',port='{}',password='{}') info,df=api.get_bond_raft_fcator(date='{}') print(df) '''.format(url,port,user_password,now_date) else: func=''' from trader_tool import jsl_data df=jsl_data.get_all_cov_bond_data(jsl_user='{}',jsl_password='{}') print(df) '''.format(jsl_user,jsl_password) try: info,df=data.get_user_def_data(func=func) except Exception as e: print(e) print('{}可能不是交易时间'.format(now_date)) df=pd.DataFrame() stats=df['数据状态'].tolist()[-1] if df.shape[0]>2: df['转债代码']=df['可转债代码'] df=df else: print('获取数据源没有数据可能不是交易日************') df=pd.DataFrame() df.to_excel(r'全部因子数据.xlsx') return df def get_cacal_factor_base_table(self): ''' 计算默认因子 ''' print('计算默认因子***********************') text=self.text is_open=text['是否开启默认因子计算'] df=self.get_all_factor_data() try: del df['Unnamed: 0'] del df['Unnamed: 0.1'] except: pass factor=text['默认因子计算'] if is_open=='是': print('开启计算默认因子***********************') factor_name=list(factor.keys()) if len(factor_name)>0: for name in factor_name: try: print(name,'因子计算完成') func=factor[name] df[name]=eval(func) except Exception as e: print(e,name,'因子计算有问题') else: print('没有默认因子需要计算') else: print('不开启计算默认因子***********************') return df def get_del_qzsh_data(self): ''' 剔除强制赎回 ''' print('剔除强制赎回') text=self.text del_select=text['是否剔除强制赎回'] n=text['满足强制赎回天数'] #df=pd.read_excel(r'{}\默认因子计算\默认因子计算.xlsx'.format(self.path)) df=self.get_cacal_factor_base_table() select_list=['公告要强赎','已公告'] df['强赎']=df['强赎天计数'].apply(lambda x : '是' if '公告要强赎' in x or '已公告' in x else '不是') df1=df[df['强赎']=='是'] df2=df[df['强赎']=='不是'] df2['强赎天计数']=df2['强赎天计数'].apply(lambda x: '0/15 | 30' if str(x)[:4]=='暂不强赎' or '不强赎' in x else x) df2['强赎天数']=df2['强赎天计数'].apply(lambda x: int(str(x).split('/')[0])) df2=df2[df2['强赎天数']<=n] #df2.to_excel(r'{}\非强制赎回\非强制赎回.xlsx'.format(self.path)) return df2 def days_excluded_from_market(self): ''' 排除上市天数 ''' print('排除上市天数') text=self.text #df=pd.read_excel(r'{}\非强制赎回\非强制赎回.xlsx'.format(self.path),dtype='object') df=self.get_del_qzsh_data() try: del df['Unnamed: 0'] del df['Unnamed: 0.1'] except: pass n=text['排除上市天数'] trader_list=self.stock_data.get_trader_date_list() start_date=trader_list[-n] try: df=df[df['上市日']<=start_date] except: df['上市天数']=df['上市天数'].apply(lambda x: float(str(x).split('days')[0])) df=df[df['上市天数']>=n] #df.to_excel(r'{}\排除上市天数\排除上市天数.xlsx'.format(self.path)) return df def st_exclusion(self): ''' 排除st ''' print('排除st') text=self.text is_del=text['是否排除ST'] #df=pd.read_excel(r'{}\排除上市天数\排除上市天数.xlsx'.format(self.path)) df=self.days_excluded_from_market() try: del df['Unnamed: 0'] except: pass if is_del=='是': def_list=['ST','st','*ST','*st'] df['ST']=df['正股名称'].apply(lambda x: '是' if 'st' in x or 'ST' in x or '*st' in x or '*ST' in x else '不是' ) df=df[df['ST']=='不是'] else: df=df #df.to_excel(r'{}\排除ST\排除ST.xlsx'.format(self.path)) return df def exclusion_of_market(self): ''' 排除市场 ''' print("排除市场") text=self.text exclusion_market_list = [] del_stock_list=text['排除市场'] for exclusion_market in del_stock_list: if exclusion_market == '沪市主板': exclusion_market_list.append(['110','113']) elif exclusion_market == '深市主板': exclusion_market_list.append(['127','128']) elif exclusion_market == '创业板': exclusion_market_list.append('123') elif exclusion_market == '科创板': exclusion_market_list.append('118') else: pass #df=pd.read_excel(r'{}\排除ST\排除ST.xlsx'.format(self.path)) df=self.st_exclusion() try: del df['Unnamed: 0.1'] except: pass print(exclusion_market_list,"__________________________________________") df['market'] = df['转债代码'].apply(lambda x: '排除' if str(x)[:3] in exclusion_market_list else '不排除') df = df[df['market'] == '不排除'] #df.to_excel(r'{}\排除市场\排除市场.xlsx'.format(self.path)) return df def excluded_industry(self): ''' 排除行业 ''' print('排除行业') text=self.text del_list=text['排除行业'] #df=pd.read_excel(r'{}\排除市场\排除市场.xlsx'.format(self.path)) df=self.exclusion_of_market() try: del df['Unnamed: 0'] except: pass industry_list=[] data=pd.DataFrame() industry_1=df['一级行业'].tolist() for i in industry_1: industry_list.append(i) industry_2=df['二级行业'].tolist() for i in industry_2: industry_list.append(i) industry_3=df['三级行业'].tolist() for i in industry_3: industry_list.append(i) industry_list=list(set(industry_list)) data['可转债行业']=industry_list industry_name=['一级行业','二级行业','三级行业'] for name in industry_name: df['行业排除']=df[name].apply(lambda x: '是' if x in del_list else '不是') df=df[df['行业排除']=='不是'] #df.to_excel(r'{}\排除行业\排除行业.xlsx'.format(self.path)) return df def exclusion_of_enterprise(self): ''' 排除企业 ''' print('排除企业') text=self.text #df=pd.read_excel(r'{}\排除行业\排除行业.xlsx'.format(self.path)) df=self.excluded_industry() ''' try: del df['Unnamed: 0'] except: pass del_list=text['排除企业类型'] df['排除企业']=df['企业类型'].apply(lambda x:'是' if str(x) in del_list else '不是') df=df[df['排除企业']=='不是'] ''' #df.to_excel(r'{}\排除企业\排除企业.xlsx'.format(self.path)) return df def exclusion_area(self): ''' 排除地域 ''' print('排除地域') text=self.text #df=pd.read_excel(r'{}\排除企业\排除企业.xlsx'.format(self.path)) df=self.exclusion_of_enterprise() try: del df['Unnamed: 0'] except: pass del_list=text['排除地域'] df['排除地域']=df['地域'].apply(lambda x:'是' if str(x) in del_list else '不是') df=df[df['排除地域']=='不是'] #df.to_excel(r'{}\排除地域\排除地域.xlsx'.format(self.path)) return df def exclusion_of_external_rating(self): ''' 排除外部评级 ''' print('排除外部评级') text=self.text df=self.exclusion_area() try: del df['Unnamed: 0'] except: pass del_list=text['排除外部评级'] df['排除外部评级']=df['主体评级'].apply(lambda x:'是' if str(x) in del_list else '不是') df=df[df['排除外部评级']=='不是'] #df.to_excel(r'{}\排除外部评级\排除外部评级.xlsx'.format(self.path)) return df def tripartite_exclusion(self): ''' 排除三方评级 ''' print('排除三方评级') text=self.text #df=pd.read_excel(r'{}\排除外部评级\排除外部评级.xlsx'.format(self.path)) df=self.exclusion_of_external_rating() try: del df['Unnamed: 0'] except: pass del_list=text['排除三方评级'] df['排除三方评级']=df['主体评级'].apply(lambda x:'是' if str(x) in del_list else '不是') df=df[df['排除三方评级']=='不是'] #df.to_excel(r'{}\排除三方评级\排除三方评级.xlsx'.format(self.path)) return df def cacal_user_def_factor(self): ''' 计算自定义因子 ''' print('计算自定义因子') text=self.text #df=pd.read_excel(r'{}\排除三方评级\排除三方评级.xlsx'.format(self.path)) df=self.tripartite_exclusion() try: del df['Unnamed: 0'] except: pass is_open=text['是否开启自定义因子'] user_def_factor_list=text['自定义因子'] name_list=list(user_def_factor_list.keys()) func_list=list(user_def_factor_list.values()) value_list=[] if is_open=='是': print('开启自定义因子****************') stock_list=df['证券代码'].tolist() for i in tqdm(range(len(stock_list))): stock=stock_list[i] hist=self.data.get_hist_data_em(stock=stock) models=user_def_factor(df=hist,index_df='') func_value=[] for func in func_list: name,value=eval('models.{}'.format(func)) func_value.append(value) value_list.append(func_value) user_df=pd.DataFrame(value_list) user_df.columns=name_list user_df['证券代码']=stock_list data=pd.merge(df,user_df,on='证券代码') else: print('不开启自定义函数') return df def cacal_exclusion_factor(self): ''' 计算排除因子 ''' print('计算排除因子') text=self.text #df=pd.read_excel(r'{}\自定义因子\自定义因子.xlsx'.format(self.path)) df=self.cacal_user_def_factor() try: del df['Unnamed: 0'] del df['Unnamed: 0.1'] del df['Unnamed: 0.2'] except: pass factor_list=text['排除因子'] factor_func_list=text['因子计算符号'] factor_value_list=text['因子值'] all_factor_list=df.columns.tolist() for factor,func,value in zip(factor_list,factor_func_list,factor_value_list): df[factor]=pd.to_numeric(df[factor]) if factor in all_factor_list: if func=='大于': df=df[df[factor]<=value] elif func=='小于': df=df[df[factor]>=value] elif func=='大于排名%': df=df.sort_values(by=factor,ascending=True)[value:] elif func=='小于排名%': df=df.sort_values(by=factor,ascending=True)[:value] elif func=='空值': df=df else: print('{}未知的计算方式'.format(func)) else: print('{}排除因子不在全部的因子表里面全部因子表{}'.format(factor,all_factor_list)) #df.to_excel(r'{}\排除因子\排除因子.xlsx'.format(self.path)) return df def cacal_score_factor(self): ''' 计算打分因子 升序从小到大 降序从大到小 ''' print("计算打分因子") text=self.text #df=pd.read_excel(r'{}\排除因子\排除因子.xlsx'.format(self.path)) df=self.cacal_exclusion_factor() try: del df['Unnamed: 0'] except: pass factor_list=text['打分因子'] factor_cov_list=text['因子相关性'] factor_weight_list=text['因子权重'] all_factor_list=df.columns.tolist() score_list=[] for factor,cov,weight in zip(factor_list,factor_cov_list,factor_weight_list): if factor in all_factor_list: if cov=='正相关': df[factor]=df[factor]*1 elif cov=='负相关': df[factor]=df[factor]*-1 else: print('{}未知的相关性'.format(cov)) df['{}_得分'.format(factor)]=df[factor].rank(ascending=False)*weight score_list.append('{}_得分'.format(factor)) else: print('{}打分因子不在全部的因子表里面全部因子表{}'.format(factor,all_factor_list)) df['总分']=df[score_list].sum(axis=1).tolist() df['排名']=df['总分'].rank( ascending=True) df=df.sort_values(by='总分',ascending=True) #df.to_excel(r'{}\打分因子\打分因子.xlsx'.format(self.path)) return df def get_time_rotation(self): ''' 轮动方式 ''' text=self.text now_date=''.join(str(datetime.now())[:10].split('-')) now_time=time.localtime() trader_type=text['轮动方式'] trader_wday=text['每周轮动时间'] moth_trader_time=text['每月轮动时间'] specific_time=text['特定时间'] year=now_time.tm_year moth=now_time.tm_mon wday=now_time.tm_wday daily=now_time.tm_mday if trader_type=='每天': print('轮动方式每天') return True elif trader_type=='每周': if trader_wday==wday: return True elif trader_wday