def risk_multiple(model): # 风险因子业绩归因模块 # fof_multi_attr_riskmodel if not del_data('fof_multi_attr_riskmodel'): raise Error("删除历史数据失败,任务结束") stockIndus, indusReturn, factorExposure, factorReturn = publicData_riskModel( ) # 批量运行 ''' 跨期归因结果需要存储多个周期值 单期归因结果仅存储成立以来的值即可 跨期归因和单期归因可以用两张表来存储数据 ''' # dataframe 周期类型和数据库周期类型映射关系 cyleFormula = {'1': '1', '2': '2', '3': '3', '5': '4', '成立以来': '5'} fundSymbols = getData_fundSymbols(['股票型', '混合型']) cycleList = ['1', '2', '3', '5', '成立以来'] holdingTypeList = ['mainStockHolding', 'allStockHolding'] for holdingType in holdingTypeList: for symbol in fundSymbols: for cycle in cycleList: btParms = { 'symbol': symbol, 'cycle': cycle, 'holdingType': holdingType } self = attribution_riskModel(btParms, stockIndus, indusReturn, factorExposure, factorReturn) output = self.output tp = "1" if holdingType == 'mainStockHolding' else '2' # 持仓类型 param = output['multiAttr'] if len(param) == 0: continue for idx in param.index: di = param.loc[idx].to_dict() indexName = idx # 因子名称 indexType = di['factorType'] # 因子分类 indexAttr = di['multiAttr'] # 因子贡献收益 cyleTp = cyleFormula[cycle] # 周期类型 lsd = [] id_ = uuid_util.gen_uuid() lsd.append(id_) lsd.append(output['symbol']) lsd.append(tp) lsd.append(cyleTp) lsd.append(indexType) lsd.append(indexName) lsd.append(indexAttr) lsd.append("sys") lsd.append(datetime.now()) lsd.append("sys") lsd.append(datetime.now()) lsd = [transformFloatIfAvaliable4(l) for l in lsd] sql = 'INSERT INTO `fof`.`fof_multi_attr_riskmodel`(`OBJECT_ID`, `S_INFO_WINDCODE`, `DATA_TYPE`, `CYCLE_TYPE`, `FACTOR_TYPE`, `FACTOR_NAME`, `FACTOR_VALUE`, `CREATE_USER_ID`, `CREATE_TIME`, `UPDATE_USER_ID`, `UPDATE_TIME`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' mysqlops.insert_one(MysqlConf.DB.fof, sql, tuple(lsd))
def risk_single(model): # 风险因子业绩归因模块 # fof_single_attr_riskmodel if not del_data('fof_single_attr_riskmodel'): raise Error("删除历史数据失败,任务结束") stockIndus, indusReturn, factorExposure, factorReturn = publicData_riskModel( ) # 批量运行 ''' 跨期归因结果需要存储多个周期值 单期归因结果仅存储成立以来的值即可 跨期归因和单期归因可以用两张表来存储数据 ''' fundSymbols = getData_fundSymbols(['股票型', '混合型']) cycleList = ['成立以来'] # 这个程序跟之前的程序有一点特殊,就是多期归因要存多个周期的结果,单期归因只存成立以来的结果 holdingTypeList = ['mainStockHolding', 'allStockHolding'] for holdingType in holdingTypeList: for symbol in fundSymbols: for cycle in cycleList: btParms = { 'symbol': symbol, 'cycle': cycle, 'holdingType': holdingType } self = attribution_riskModel(btParms, stockIndus, indusReturn, factorExposure, factorReturn) output = self.output tp = "1" if holdingType == 'mainStockHolding' else '2' # 持仓类型 param = output['singleAttr'] if len(param) == 0: continue for idx in param.index: dt = idx # time di = param.loc[idx].to_dict() style = di['style'] # 风格因子归因 industry = di['industry'] # 行业因子归因 idiosyn = di['idiosyn'] # 特质因子归因 fundRet = di['fundRet'] # 基金当月收益率 lsd = [] id_ = uuid_util.gen_uuid() lsd.append(id_) lsd.append(output['symbol']) lsd.append(dt._short_repr.replace("-", "")) lsd.append(tp) lsd.append(style) lsd.append(industry) lsd.append(idiosyn) lsd.append(fundRet) lsd.append("sys") lsd.append(datetime.now()) lsd.append("sys") lsd.append(datetime.now()) lsd = [transformFloatIfAvaliable4(l) for l in lsd] sql = 'INSERT INTO `fof`.`fof_single_attr_riskmodel`(`OBJECT_ID`, `S_INFO_WINDCODE`, `TRADE_DT`, `DATA_TYPE`, `STYLE`, `INDUSTRY`, `IDIOSYN`, `FUND_RETURN`, `CREATE_USER_ID`, `CREATE_TIME`, `UPDATE_USER_ID`, `UPDATE_TIME`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' mysqlops.insert_one(MysqlConf.DB.fof, sql, tuple(lsd))
def other_indicator(model: OfflineTaskModel): # 离线计算其他指标 indicatorInfo = model.taskModel indicatorId = model.extVal if del_data(sqlPa="delete from fof_index_value where INDICATOR_ID = '%s'" % indicatorId) == False: raise Error("删除历史数据失败,任务结束") if indicatorId not in INDEX_CODE_NAME_CACHE.keys(): raise Error("指标id不存在:{}".format(indicatorId)) indexName = INDEX_CODE_NAME_CACHE[indicatorId] # fundAdjNav = getPublicData(['股票型', '混合型']) fundAdjNav = getPublicData() fundSymbols = list(fundAdjNav.columns) updatedType = [] fundClass_1 = pd.Series('混合型基金', index=fundSymbols) fundClass_tmp = getData_fundInformation(fundSymbols)['FUND_INVESTTYPE'] fundClass_1[fundClass_tmp.index] = fundClass_tmp for symbol in fundSymbols: allIndicators = [] fundType = fundClass_1[symbol] if fundType not in updatedType: for cycle in n_cycle_tp: btParms = {'indexName': indexName, 'cycle': cycle, 'symbol': symbol, 'sample': '一级', 'marketIndex': '', 'otherPar': ''} self = indexScore_fund(btParms, fundAdjNav, 'auto') op = self.output val = op['factorValue'] allIndicators.append(val) updatedType.append(fundType) df = pd.DataFrame(allIndicators).fillna(bus_const.blank) cols = df.columns.tolist() for col in cols: res = df[col] lst = res.values.tolist() lst = [transformFloatIfAvaliable(l) for l in lst] objId = uuid_util.gen_uuid() lst.insert(0, str(objId)) lst.insert(1, str(indicatorId)) lst.insert(2, col) date = formatDate2yyyymmdd() lst.insert(3, str(date)) lst.append("sys") lst.append(datetime.datetime.now()) lst.append("sys") lst.append(datetime.datetime.now()) tp = tuple(lst) sql = "INSERT INTO fof_index_value (`OBJECT_ID`, `INDICATOR_ID`, `J_WINDCODE`, `TRADE_DT`, `THISYEAR_VALUE`, `QUARTER_VALUE`, `HALFYEAR_VALUE`, `YEAR_VALUE`, `TWOYEA_VALUE`, `THREEYEAR_VALUE`, `FIVEYEAR_VALUE`, `N1_VALUE`, `N2_VALUE`, `CREATE_USER_ID`, `CREATE_TIME`, `UPDATE_USER_ID`, `UPDATE_TIME`, `DELETE_FLAG`) VALUES ( %s, %s, %s, %s, %s, %s,%s,%s, %s,%s, %s, %s, %s, %s, %s, %s, %s,0)" mysqlops.insert_one(MysqlConf.DB.fof, sql, tp) allIndicators.clear()
def volatility(model: OfflineTaskModel): # 离线计算年化波动率 if del_data('fof_variance') == False: raise Error("删除历史数据失败,任务结束") indicatorInfo = model.taskModel taskName = indicatorInfo.value[0] indiId = get_indicator_id(taskName) # fundAdjNav = getPublicData(['股票型', '混合型']) fundAdjNav = getPublicData() fundSymbols = list(fundAdjNav.columns) fundClass_1 = pd.Series('混合型基金', index=fundSymbols) fundClass_tmp = getData_fundInformation(fundSymbols)['FUND_INVESTTYPE'] fundClass_1[fundClass_tmp.index] = fundClass_tmp halfs = indicatorInfo.value[1] for half in halfs: updatedType = [] allIndicators = [] for symbol in fundSymbols: fundType = fundClass_1[symbol] if fundType not in updatedType: for cycle in n_cycle_tp: btParms = {'indexName': taskName, 'cycle': cycle, 'symbol': symbol, 'sample': '一级', 'marketIndex': '', 'otherPar': half} self = indexScore_fund(btParms, fundAdjNav, 'auto') op = self.output val = op['factorValue'] allIndicators.append(val) updatedType.append(fundType) df = pd.DataFrame(allIndicators).fillna(bus_const.blank) cols = df.columns.tolist() for col in cols: res = df[col] lst = res.values.tolist() lst = [transformFloatIfAvaliable(l) for l in lst] objId = uuid_util.gen_uuid() lst.insert(0, str(objId)) lst.insert(1, str(indiId)) lst.insert(2, str(col)) date = formatDate2yyyymmdd() lst.insert(3, str(date)) lst.insert(4, transformString2Decimal(half)) lst.append("sys") lst.append(datetime.datetime.now()) lst.append("sys") lst.append(datetime.datetime.now()) tp = tuple(lst) sql = "INSERT INTO fof_variance (`OBJECT_ID`, `INDICATOR_ID`, `J_WINDCODE`, `TRADE_DT`, `F_WEIGHT`, `THISYEAR_VALUE`, `QUARTER_VALUE`, `HALFYEAR_VALUE`, `YEAR_VALUE`, `TWOYEA_VALUE`, `THREEYEAR_VALUE`, `FIVEYEAR_VALUE`, `N1_VALUE`, `N2_VALUE`, `CREATE_USER_ID`, `CREATE_TIME`, `UPDATE_USER_ID`, `UPDATE_TIME`, `DELETE_FLAG`) VALUES ( %s, %s, %s, %s, %s, %s, %s,%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,%s,0)" mysqlops.insert_one(MysqlConf.DB.fof, sql, tp) allIndicators.clear()
def stockexpousre(model): # factorName即为mongodb数据库相关collection的名字,一次仅支持传入一个因子值 sql = "delete from fof_stockexpousre " mysqlops.fetch_one(MysqlConf.DB.fof, sql) if not del_data('fof_stockexpousre'): raise Error("删除历史数据失败,任务结束") fs = [ 'value', 'size', 'beta', 'earning', # 'factorReturn', 'growth', 'leverage', 'liquidity', 'momentum', 'nonlinear_size', 'size', 'volatility' ] sql = 'insert into ' \ 'fof_stockexpousre (OBJECT_ID,trade_dt,s_windcode,indicator_code,factor_value,CREATE_USER_ID,CREATE_TIME,UPDATE_USER_ID,UPDATE_TIME)' \ 'values (%s,%s,%s,%s,%s,%s,%s,%s,%s)' for fName in fs: valueExp = getData_factorExposure(fName) valueExp = valueExp.fillna("9999.000000") di = valueExp.to_dict() for k in di: # print("K===%s" % k) for v in di.get(k): s = uuid_util.gen_uuid() lsd = [] oid = s[:5] + '-' + s[5:9] + '-' + s[9:13] + '-' + s[ 13:18] + '-' + s[18:] lsd.append(oid) r = v._date_repr.replace("-", "") lsd.append(r) lsd.append(k[:-2] + "." + k[-2:]) lsd.append(fName) lsd.append(transformFloatIfAvaliable(di.get(k).get(v))) lsd.append("sys") lsd.append(datetime.now()) lsd.append("sys") lsd.append(datetime.now()) mysqlops.insert_one(MysqlConf.DB.fof, sql, tuple(lsd))
def indicator_score_rank(model: OfflineTaskModel): # 离线计算指标得分 indicatorId = model.extVal if indicatorId not in INDEX_CODE_NAME_CACHE.keys(): raise Error("指标id不存在:{}".format(indicatorId)) if not del_data( sqlPa="delete from fof_index_score where INDICATOR_ID = '%s' " % indicatorId): raise Error("删除历史数据失败,任务结束") iName = INDEX_CODE_NAME_CACHE[indicatorId] # fundAdjNav = getPublicData(['股票型', '混合型']) fundAdjNav = getPublicData() fundSymbols = list(fundAdjNav.columns) updatedType = [] fundClass_1 = pd.Series('混合型基金', index=fundSymbols) fundClass_tmp = getData_fundInformation(fundSymbols)['FUND_INVESTTYPE'] fundClass_1[fundClass_tmp.index] = fundClass_tmp for symbol in fundSymbols: indicators = [] ranks = [] fundType = fundClass_1[symbol] if fundType not in updatedType: for cycle in cycle_score: btParms = { 'indexName': iName, 'cycle': cycle, 'symbol': symbol, 'sample': '一级', 'marketIndex': '', 'otherPar': '' } self = indexScore_fund(btParms, fundAdjNav, 'auto') op = self.output score = op['factorScore'] rank = op['factorRank'] # 这个值是用来记录当前cycle及分类下参与排名的样本数量,因为前端显示的排名都是5 / 200 # 这种形式,本意是要存入数据库的,但我跟平赞沟通过了,他说他们前端直接根据数据库里的数据处理即可,不用存这个字段了 # sc = op['sampleCounts'] # tp = score # for ti in tp.index: # tp[ti] = str(sc) indicators.append(score) ranks.append(rank) ranks.append(pd.Series()) # 一级分类排名样本 ranks.append(pd.Series()) # 二级分类排名一期不上,先做个空值 ranks.append(pd.Series()) # 二级分类排名样本一期不上,先做个空值 updatedType.append(fundType) indicators.extend(ranks) df = pd.DataFrame(indicators).fillna('9999999999999.0') cols = df.columns.tolist() for col in cols: res = df[col] # [基金id,score,score,...] lst = res.values.tolist() lst = [transformFloatIfAvaliable2(l) for l in lst] objId = uuid_util.gen_uuid() lst.insert(0, str(objId)) lst.insert(1, str(indicatorId)) lst.insert(2, col) # lst.insert(2, list(map(lambda x: x[-2:] + x[:-2], [col]))[0]) date = formatDate2yyyymmdd() lst.insert(3, str(date)) lst.append("sys") lst.append(datetime.datetime.now()) lst.append("sys") lst.append(datetime.datetime.now()) lst = [ '9999999999999.0' if type(ele) == pd.Series else ele for ele in lst ] tp = tuple(lst) sql = "INSERT INTO fof_index_score VALUES ( %s, %s, %s, %s, %s, %s, %s,%s, %s, %s, %s, %s, %s, %s,%s, %s, %s, %s, %s, %s, %s, %s,%s,%s,%s, %s, %s, %s, %s, %s, %s, %s,%s,%s,%s, %s, %s, %s, %s, %s, %s, %s,%s,0)" mysqlops.insert_one(MysqlConf.DB.fof, sql, tp) indicators.clear() ranks.clear()
def information_ratio(model: OfflineTaskModel): # 离线计算信息比率 if del_data('fof_inforatio') == False: raise Error("删除历史数据失败,任务结束") # sql = "delete from fof_inforatio " # mysqlops.fetch_one(MysqlConf.DB.fof, sql) indicatorInfo = model.taskModel taskName = indicatorInfo.value[0] indiId = get_indicator_id(taskName) # fundAdjNav = getPublicData(['股票型', '混合型']) fundAdjNav = getPublicData() fundSymbols = list(fundAdjNav.columns) updatedType = [] fundClass_1 = pd.Series('混合型基金', index=fundSymbols) fundClass_tmp = getData_fundInformation(fundSymbols)['FUND_INVESTTYPE'] fundClass_1[fundClass_tmp.index] = fundClass_tmp for symbol in fundSymbols: allIndicators = [] fundType = fundClass_1[symbol] if fundType not in updatedType: for cycle in n_cycle_tp: btParms = {'indexName': taskName, 'cycle': cycle, 'symbol': symbol, 'sample': '一级', 'marketIndex': '', 'otherPar': ''} self = indexScore_fund(btParms, fundAdjNav, 'auto') op = self.output val = op['factorValue'] allIndicators.append(val) updatedType.append(fundType) df = pd.DataFrame(allIndicators).fillna(bus_const.blank) cols = df.columns.tolist() for col in cols: res = df[col] dd = res.values.tolist() lst = [transformFloatIfAvaliable(l) for l in dd] objId = uuid_util.gen_uuid() lst.insert(0, str(objId)) lst.insert(1, str(indiId)) lst.insert(2, col) date = formatDate2yyyymmdd() lst.insert(3, str(date)) # idxVal = None # try: # idxVal = CODE_INDEX_CACHE[col] # except: # # 缓存没有查一次数据库 # sql = "SELECT s_info_windcode,s_info_indexwindcode FROM chinamutualfundbenchmark where S_INFO_WINDCODE = '{}'".format( # col) # res = mysqlops.fetchmany(MysqlConf.DB.fof, sql) # if res and 's_info_indexwindcode' in res and res['s_info_indexwindcode'] is not None: # idxVal = res['s_info_indexwindcode'].decode() lst.insert(4, indicatorInfo.value[1]) # 比较基准wind代码 lst.append("sys") lst.append(datetime.datetime.now()) lst.append("sys") lst.append(datetime.datetime.now()) tp = tuple(lst) sql = "INSERT INTO fof_inforatio (`OBJECT_ID`, `INDICATOR_ID`, `J_WINDCODE`, `TRADE_DT`, `B_WINDCODE`, `THISYEAR_VALUE`, `QUARTER_VALUE`, `HALFYEAR_VALUE`, `YEAR_VALUE`, `TWOYEA_VALUE`, `THREEYEAR_VALUE`, `FIVEYEAR_VALUE`, `N1_VALUE`, `N2_VALUE`, `CREATE_USER_ID`, `CREATE_TIME`, `UPDATE_USER_ID`, `UPDATE_TIME`, `DELETE_FLAG`) VALUES ( %s, %s, %s, %s, %s, %s, %s,%s,%s,%s, %s, %s, %s, %s, %s, %s, %s, %s,0)" mysqlops.insert_one(MysqlConf.DB.fof, sql, tp) allIndicators.clear()