def __init__(self): FundHolder.__init__(self) FundFactor.__init__(self) FundPool.__init__(self) FundStatic.__init__(self) FundExposure.__init__(self)
def cal_fund_holder_risk_alpha_return_quarter(self, fund, end_date): """ 根据季报持仓风格暴露进行收益拆分 """ beg_date = "20040101" type_list = ['STYLE', 'COUNTRY', 'INDUSTRY'] fund_exposure = FundHolderExposureQuarter( ).get_fund_holder_exposure_quarter_daily(fund, beg_date, end_date) barra_riskfactor_return = Barra().get_factor_return( beg_date, end_date, type_list=type_list) date_series = Date().get_trade_date_series(beg_date, end_date) fund_pct = FundFactor().get_fund_factor("Repair_Nav_Pct", fund_pool=[fund], date_list=date_series) fund_pct.columns = ["FundReturn"] if fund_exposure is None: return None fund_riskfactor_return = barra_riskfactor_return.mul(fund_exposure) fund_return = pd.concat([fund_pct, fund_riskfactor_return], axis=1) fund_return = fund_return.dropna() barra_factor_name = list( Barra().get_factor_name(type_list=["STYLE"])["NAME_EN"].values) fund_return["StyleReturn"] = fund_return[barra_factor_name].sum(axis=1) barra_factor_name = list( Barra().get_factor_name(type_list=["INDUSTRY"])["NAME_EN"].values) fund_return["IndustryReturn"] = fund_return[barra_factor_name].sum( axis=1) barra_factor_name = list( Barra().get_factor_name(type_list=["COUNTRY"])["NAME_EN"].values) fund_return["CountryReturn"] = fund_return[barra_factor_name].sum( axis=1) barra_factor_name = ["StyleReturn", "IndustryReturn", "CountryReturn"] fund_return["SumReturn"] = fund_return[barra_factor_name].sum(axis=1) fund_return["AlphaReturn"] = fund_return["FundReturn"] - fund_return[ "SumReturn"] data_new = fund_return.dropna() # 合并新数据 #################################################################### out_path = os.path.join(self.data_path_exposure, 'fund_holding_risk_alpha_return_quarter') out_file = os.path.join( out_path, 'Fund_Holder_Risk_Alpha_Return_Quarter_' + fund + "_" + end_date + '.csv') print(out_file) if os.path.exists(out_file): data_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') data_old.index = data_old.index.map(str) params = FactorOperate().pandas_add_row(data_old, data_new) else: params = data_new params.to_csv(out_file) return data_new
def cal_fund_regression_risk_alpha_return_index(self, fund): # 参数 #################################################################### exposure_index = FundRegressionExposureIndex( ).get_fund_regression_exposure_index(fund) if exposure_index is not None: # 取得数据 指数收益率数据 和 基金涨跌幅数据 print(fund) #################################################################### for i_index in range(len(self.index_code_list)): index_code = self.index_code_list[i_index] index_return = Index().get_index_factor(index_code, attr=["PCT"]) if i_index == 0: index_return = Index().get_index_factor(index_code, attr=["PCT"]) index_return_all = index_return else: index_return_all = pd.concat( [index_return_all, index_return], axis=1) index_return_all.columns = self.index_code_list if fund[len(fund) - 2:] == 'OF': fund_return = FundFactor().get_fund_factor( "Repair_Nav_Pct", None, [fund]) / 100.0 fund_return.columns = ["FundReturn"] else: fund_return = Index().get_index_factor(fund, attr=["PCT"]) fund_return.columns = ["FundReturn"] exposure_index = exposure_index.dropna(how="all") index_exposure_return = index_return_all.mul(exposure_index) index_exposure_return = index_exposure_return.dropna(how="all") data = pd.concat([fund_return, index_exposure_return], axis=1) data = data.dropna(how="all") data = data.loc[index_exposure_return.index, :] data = data.dropna(subset=["FundReturn"]) data["SumReturn"] = data[self.index_code_list].sum(axis=1, skipna=True) data["AlphaReturn"] = data["FundReturn"] - data["SumReturn"] data["CumFundReturn"] = (data["FundReturn"] + 1.0).cumprod() - 1.0 data["CumAlphaReturn"] = (data["AlphaReturn"] + 1.0).cumprod() - 1.0 data["CumSumReturn"] = (data["SumReturn"] + 1.0).cumprod() - 1.0 # 合并新数据 file = '%s_%s_%s.csv' % (self.file_prefix, self.folder_name, fund) out_file = os.path.join(self.index_return_path, file) data.to_csv(out_file)
def __init__(self, regress_length=25, regress_length_min=20, stock_ratio_up=0.95, stock_ratio_low=0.60, turnover_daily=0.035, index_code_list=None): Data.__init__(self) self.data_path = os.path.join(self.primary_data_path, r'fund_data\fund_stock_style_ratio') index_close = Index().get_index_cross_factor(factor_name='CLOSE') index_pct = index_close.pct_change() * 100 fund_return = FundFactor().get_fund_factor("Repair_Nav_Pct") self.data_return = pd.concat([index_pct, fund_return], axis=1) self.regress_length = regress_length self.regress_length_min = regress_length_min self.stock_ratio_up = stock_ratio_up self.stock_ratio_low = stock_ratio_low self.turnover_daily = turnover_daily if index_code_list is None: # 需要有债券指数 来测量股债仓位 self.index_code_list = [ "885062.WI", "801853.SI", "000300.SH", "000905.SH", "000852.SH", "399006.SZ" ] self.index_name_list = [ '短期纯债基金', '绩优股指数', '沪深300', '中证500', '中证1000', '创业板指' ] else: self.index_code_list = index_code_list
def get_data(self): """ 季度公募主动股票基金股票权重 作为指数股票权重参考标准 """ self.stock_ratio = FundFactor().get_fund_factor('Stock_Ratio').T self.industry_citic1 = Stock().read_factor_h5( "industry_citic1", Stock().get_h5_path("mfc_primary")) self.pct = Stock().read_factor_h5("Pct_chg") # 调整股票的调整日的权重
def get_data(self): """ 季度公募主动股票基金股票权重 作为指数股票权重参考标准 """ self.stock_ratio = FundFactor().get_fund_factor('Stock_Ratio').T self.free_mv = Stock().read_factor_h5( "Mkt_freeshares", Stock().get_h5_path("mfc_primary")) / 100000000.0 self.pct = Stock().read_factor_h5("Pct_chg") # 调整股票的调整日的权重
def example(self): """ 举例 """ setup_date = '20150101' beg_date = "20161231" new_fund_date = beg_date end_date = '20171130' fund_code = '229002.OF' excess = False rank_pool = "股票型基金" date_array = np.array([["2017年以来", '20170101', end_date, "20170101"], ["2016年", '20160101', '20161231', "20160101"], ["2015年", setup_date, '20151231', setup_date], ["成立以来", setup_date, end_date, setup_date]]) fund_pct = FundFactor().get_fund_factor("Repair_Nav_Pct") bench_pct = FundFactor().get_fund_factor("Fund_Bench_Pct") * 100 print( self.rank_fund_array2(fund_pct, bench_pct, fund_code, date_array, rank_pool, excess))
def update_data(self, beg_date=None, end_date=None): """ 更新计算基金暴露 所需要的数据 """ if end_date is None: end_date = datetime.today().strftime("%Y%m%d") if beg_date is None: beg_date = Date().get_trade_date_offset(end_date, -60) FundFactor().load_fund_factor("Repair_Nav_Pct", beg_date, end_date) for index_code in self.index_code_list: Index().load_index_factor(index_code, beg_date, end_date)
def rank_excess_fund(self, fund_pool_name, ge_index_code, my_index_code, my_fund_code, beg_date, end_date): """ 计算某只基金在基金池的超额收益排名 这只基金指定基准 其他默认为windqa """ fund_pool = FundPool().get_fund_pool_all(date="20181231", name=fund_pool_name) fund_pool = fund_pool[fund_pool['setupdate'] < beg_date] fund_pool = list(fund_pool['wind_code'].values) fund_pool.append(my_fund_code) result = pd.DataFrame([], index=fund_pool) data = FundFactor().get_fund_factor("Repair_Nav") for i in range(0, len(fund_pool)): fund_code = fund_pool[i] if fund_code == my_fund_code: index_code = my_index_code else: index_code = ge_index_code try: print(fund_code, index_code, beg_date, end_date) fund = pd.DataFrame(data[fund_code]) index = Index().get_index_factor(index_code, attr=["CLOSE"]) fs = FinancialSeries(pd.DataFrame(fund), pd.DataFrame(index)) fund_return = fs.get_interval_return(beg_date, end_date) bench_return = fs.get_interval_return_benchmark( beg_date, end_date) result.loc[fund_code, "基准收益"] = bench_return result.loc[fund_code, "基金收益"] = fund_return result.loc[fund_code, "超额收益"] = -bench_return + fund_return except Exception as e: print(e) result = result.dropna() result = result[~result.index.duplicated()] result = result.sort_values(by=['超额收益'], ascending=False) result['收益名次'] = range(1, len(result) + 1) result['收益排名'] = result['收益名次'].map( lambda x: str(x) + '/' + str(len(result))) result['收益排名百分比'] = result['收益名次'].map(lambda x: x / len(result)) excess_return = result.loc[my_fund_code, "超额收益"] pct = result.loc[my_fund_code, "收益排名百分比"] rank_str = result.loc[my_fund_code, "收益排名"] result.to_csv( os.path.join( self.data_path, "超额收益_%s_%s_%s.csv" % (my_fund_code, beg_date, end_date))) return excess_return, pct, rank_str
def split_flexible_fund_pool(self, date): """ 分离灵活配置基金池 """ data = self.get_fund_pool_all(date=date, name="灵活配置型基金") data.index = data['wind_code'] report_date = Date().get_last_fund_quarter_date(date) ratio = FundFactor().get_fund_factor("Stock_Ratio", [report_date], fund_pool=list(data['wind_code'])) ratio = ratio.T ratio.columns = ['stock_ratio'] data = pd.concat([data, ratio], axis=1) data['stock_ratio'] = ratio data_60 = data[data['stock_ratio'] > 60] add_fund = ['003501.OF', '004000.OF'] try: d = data.loc[add_fund, :] data_60 = data_60.append(d) data_60 = data_60.reset_index(drop=True) except Exception as e: print(e) print(add_fund, "is not in Fund Pool") name = "灵活配置型基金_60" print(" Split Flexible Fund Pool %s At %s" % (name, date)) file = name + '_' + date + '.csv' out_file = os.path.join(self.data_path_pool, name, file) data_60 = data_60.reset_index(drop=True) data_60.to_csv(out_file) data_30 = data[data['stock_ratio'] < 32] name = "灵活配置型基金_30" file = name + '_' + date + '.csv' out_file = os.path.join(self.data_path_pool, name, file) data_30 = data_30.reset_index(drop=True) data_30.to_csv(out_file)
def get_etf_fund_data(self, beg_date, end_date): """ 得到etf数据""" print("ETF Data %s %s" % (beg_date, end_date)) exchange_share = FundFactor().get_fund_factor("Exchange_Share") exchange_share = exchange_share.fillna(method='pad', limit=3) unit_nav = FundFactor().get_fund_factor("Unit_Nav") unit_nav = unit_nav.fillna(method='pad', limit=1) exchange_share_date = pd.DataFrame(exchange_share.T[end_date]) exchange_share_date.columns = ['Share'] exchange_share_date_last = pd.DataFrame(exchange_share.T[beg_date]) exchange_share_date_last.columns = ['ShareLast'] unit_nav_date = pd.DataFrame(unit_nav.T[end_date]) unit_nav_date.columns = ['UnitNav'] fund_pool = FundPool().get_fund_pool_all(name="ETF基金", date="20181231") fund_pool = fund_pool[[ 'sec_name', 'wind_code', 'setupdate', 'bench_code', 'bench_name' ]] fund_pool.index = fund_pool.wind_code concat_data = pd.concat([ fund_pool, unit_nav_date, exchange_share_date, exchange_share_date_last ], axis=1) concat_data = concat_data.dropna() concat_data['MvEnd'] = concat_data['Share'] * concat_data['UnitNav'] concat_data['Inflow'] = ( concat_data['Share'] - concat_data['ShareLast']) * concat_data['UnitNav'] concat_data['MvEnd'] /= 100000000.0 concat_data['Inflow'] /= 100000000.0 return concat_data
def cal_fund_regression_exposure_index(self, fund, beg_date, end_date, period="D"): """ 计算一只基金每日对不同指数的暴露 """ # 参数 #################################################################### one_index_up_limit = 1.0 one_index_low_limit = 0.0 sum_index = 1.0 beg_date = Date().change_to_str(beg_date) end_date = Date().change_to_str(end_date) # 取得 指数收益率数据 #################################################################### for i_index in range(len(self.index_code_list)): index_code = self.index_code_list[i_index] index_return = Index().get_index_factor(index_code, Nattr=["PCT"]) if i_index == 0: index_return = Index().get_index_factor(index_code, attr=["PCT"]) index_return_all = index_return else: index_return_all = pd.concat([index_return_all, index_return], axis=1) index_return_all.columns = self.index_code_list # 取得 基金涨跌幅数据 #################################################################### if fund[len(fund)-2:] == 'OF': fund_return = FundFactor().get_fund_factor("Repair_Nav_Pct", None, [fund]) / 100.0 else: fund_return = Index().get_index_factor(fund, attr=["PCT"]) fund_return.columns = [fund] # 合并数据 #################################################################### data = pd.concat([fund_return, index_return_all], axis=1) data = data.dropna(subset=[fund]) # 回归日期 #################################################################### date_series = Date().get_trade_date_series(beg_date, end_date, period=period) date_series = list(set(date_series) & set(data.index)) date_series.sort() # 循环优化计算每天的暴露 #################################################################### for i_date in range(0, len(date_series)): # 约束回归所需要的数据 ############################################################################################# period_end_date = date_series[i_date] period_beg_date = Date().get_trade_date_offset(period_end_date, -self.regression_period) period_date_series = Date().get_trade_date_series(period_beg_date, period_end_date) data_periods = data.ix[period_date_series, :] data_periods = data_periods.dropna(subset=[fund]) data_periods = data_periods.T.dropna(how='all').T data_periods = data_periods.T.fillna(data_periods.mean(axis=1)).T data_periods = data_periods.dropna() # 有约束的回归 可以转换为二次规划 ############################################################################################# if len(data_periods) > self.regression_period_min and (len(data_periods.columns) > 1): # 平方和最小 ############################################################################################# y = data_periods.ix[:, 0].values x = data_periods.ix[:, 1:].values P = 2 * np.dot(x.T, x) Q = -2 * np.dot(x.T, y) # 单个指数上下限为 0 ############################################################################################# G_up = np.diag(np.ones(x.shape[1])) G_low = - np.diag(np.ones(x.shape[1])) G = np.row_stack((G_up, G_low)) h_up = np.row_stack(np.ones((x.shape[1], 1))) * one_index_up_limit h_low = - np.row_stack(np.ones((x.shape[1], 1))) * one_index_low_limit h = np.row_stack((h_up, h_low)) ############################################################################################# A = np.column_stack(np.ones((x.shape[1], 1))) b = np.array([sum_index]) # 开始规划求解 ############################################################################################ try: P = matrix(P) Q = matrix(Q) G = matrix(G) h = matrix(h) A = matrix(A) b = matrix(b) result = sol.qp(P, Q, G, h, A, b) params_add = pd.DataFrame(np.array(result['x'][0:]), columns=[period_end_date], index=data_periods.columns[1:]).T print("########## Fund Regression Index Exposure GF %s %s ##########" % (fund, period_end_date)) except Exception as e: params_add = pd.DataFrame([], columns=[period_end_date], index=data_periods.columns[1:]).T print("########## Quadratic Programming is InCorrect %s %s ##########" % (fund, period_end_date)) else: params_add = pd.DataFrame([], columns=[period_end_date], index=data_periods.columns[1:]).T print("########## Fund Regression Data Len is Too Small %s %s ##########" % (fund, period_end_date)) if i_date == 0: params_new = params_add else: params_new = pd.concat([params_new, params_add], axis=0) # 合并新数据 并存储数据 #################################################################### out_file = os.path.join(self.data_path, self.file_prefix + fund + '.csv') if os.path.exists(out_file): params_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') params_old.index = params_old.index.map(str) params = FactorOperate().pandas_add_row(params_old, params_new) else: params = params_new params.to_csv(out_file)
def get_data(self): """ 收益率数据 """ index_pct = Index().get_index_cross_factor("PCT") * 100 fund_pct = FundFactor().get_fund_factor("Repair_Nav_Pct") self.asset_pct = pd.concat([fund_pct, index_pct], axis=1)
def cal_fund_holder_exposure_halfyear(self, fund_code, beg_date, end_date): """ 计算单个基金的半年持仓暴露(注意计算的是非满仓暴露) """ # fund_code, beg_date, end_date = "000001.OF", "20170101", "20190101" type_list = ['COUNTRY', 'STYLE', 'INDUSTRY'] barra_name = list(Barra().get_factor_name(type_list)['NAME_EN'].values) out_file = os.path.join( self.halfyear_exposure_path, 'Fund_Holder_Exposure_HalfYear_%s.csv' % fund_code) if not os.path.exists(out_file): beg_date = "20040101" date_series = Date().get_normal_date_series(beg_date, end_date, period='S') fund_holding = FundHolder().get_fund_stock_weight_halfyear(fund_code) if fund_holding is not None: date_series = list(set(date_series) & set(fund_holding.columns)) date_series.sort() print(date_series) else: return None if len(date_series) > 0: for i_date in range(0, len(date_series)): date = date_series[i_date] report_date = Date().get_normal_date_month_end_day(date) trade_date = Date().get_trade_date_month_end_day(date) print("Calculate HalfYear Holder Exposure %s %s" % (fund_code, report_date)) barra_exposure = Barra().get_factor_exposure_date( trade_date, type_list) fund_holding_date = FundHolder( ).get_fund_stock_weight_halfyear(fund_code) if (barra_exposure is None) or (len(fund_holding_date) == 0): exposure_add = pd.DataFrame([], columns=barra_name, index=[report_date]) else: fund_holding_date = pd.DataFrame(fund_holding[report_date]) fund_holding_date = fund_holding_date.dropna() fund_holding_date = fund_holding_date.sort_values( by=[report_date], ascending=False) fund_holding_date.columns = ["Weight"] fund_holding_date /= 100.0 data = pd.concat([fund_holding_date, barra_exposure], axis=1) data = data.dropna() if (len(data) == 0) or (data is None): exposure_add = pd.DataFrame([], columns=barra_name, index=[report_date]) else: exposure_add = pd.DataFrame([], columns=barra_name, index=[report_date]) for i_factor in range(len(barra_name)): factor_name = barra_name[i_factor] data_weight = data[['Weight', factor_name]] data_weight['StockExposure'] = data_weight[ 'Weight'] * data_weight[factor_name] exp = data_weight['StockExposure'].sum() exposure_add.ix[report_date, factor_name] = exp country_name = Barra().get_factor_name( ["COUNTRY"])["NAME_EN"].values[0] position = FundFactor().get_fund_factor( "Stock_Ratio", date_list=[report_date], fund_pool=[fund_code]) exposure_add.ix[ report_date, country_name] = position.values[0][0] / 100 if i_date == 0: exposure_new = exposure_add else: exposure_new = pd.concat([exposure_new, exposure_add], axis=0) else: exposure_new = pd.DataFrame([]) # 合并新数据 #################################################################### if os.path.exists(out_file): exposure_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') exposure_old.index = exposure_old.index.map(str) params = FactorOperate().pandas_add_row(exposure_old, exposure_new) else: params = exposure_new if len(params) > 0: params = params[barra_name] params.to_csv(out_file)
def get_data(self): """ 季度公募主动股票基金股票权重 作为指数股票权重参考标准 """ self.stock_ratio = FundFactor().get_fund_factor('Stock_Ratio').T self.pct = Stock().read_factor_h5("Pct_chg") # 调整股票的调整日的权重
def cal_fund_regression_risk_alpha_return_style(self, fund, beg_date, end_date): # 参数 #################################################################### exposure_index = FundRegressionExposureStyle( ).get_fund_regression_exposure_style(fund) if exposure_index is not None: # 取得数据 指数收益率数据 和 基金涨跌幅数据 #################################################################### barra_name = list(Barra().get_factor_name(['STYLE' ])['NAME_EN'].values) barra_name.extend( list(Barra().get_factor_name(["COUNTRY"])['NAME_EN'].values)) barra_return = Barra().get_factor_return( None, None, type_list=["INDUSTRY", "COUNTRY", "STYLE"]) barra_return = barra_return[barra_name] barra_return /= 100.0 if fund[len(fund) - 2:] == 'OF': fund_return = FundFactor().get_fund_factor( "Repair_Nav_Pct", None, [fund]) / 100.0 fund_return.columns = ["FundReturn"] else: fund_return = Index().get_index_factor(fund, attr=["PCT"]) fund_return.columns = ["FundReturn"] exposure_index = exposure_index.dropna(how="all") index_exposure_return = barra_return.mul(exposure_index) index_exposure_return = index_exposure_return.dropna(how="all") data = pd.concat([fund_return, index_exposure_return], axis=1) data = data.dropna(how="all") data = data.loc[index_exposure_return.index, :] data = data.dropna(subset=["FundReturn"]) data["SumReturn"] = data[barra_name].sum(axis=1, skipna=True) data["AlphaReturn"] = data["FundReturn"] - data["SumReturn"] data = data.loc[beg_date:end_date, :] data["CumFundReturn"] = (data["FundReturn"] + 1.0).cumprod() - 1.0 data["CumAlphaReturn"] = (data["AlphaReturn"] + 1.0).cumprod() - 1.0 data["CumSumReturn"] = (data["SumReturn"] + 1.0).cumprod() - 1.0 # 合并新数据 #################################################################### out_path = os.path.join(self.data_path_exposure, 'fund_regression_risk_alpha_return_style') out_file = os.path.join( out_path, 'Fund_Regression_Risk_Alpha_Style_' + fund + '.csv') if os.path.exists(out_file): params_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') params_old.index = params_old.index.map(str) params = FactorOperate().pandas_add_row(params_old, data) else: params = data print(params) params.to_csv(out_file)
def cal_fund_regression_risk_alpha_return_index(self, fund, beg_date, end_date): # 参数 #################################################################### exposure_index = FundRegressionExposureIndex( ).get_fund_regression_exposure_index(fund) if exposure_index is not None: # 取得数据 指数收益率数据 和 基金涨跌幅数据 #################################################################### for i_index in range(len(self.index_code_list)): index_code = self.index_code_list[i_index] index_return = Index().get_index_factor(index_code, attr=["PCT"]) if i_index == 0: index_return = Index().get_index_factor(index_code, attr=["PCT"]) index_return_all = index_return else: index_return_all = pd.concat( [index_return_all, index_return], axis=1) index_return_all.columns = self.index_code_list if fund[len(fund) - 2:] == 'OF': fund_return = FundFactor().get_fund_factor( "Repair_Nav_Pct", None, [fund]) / 100.0 fund_return.columns = ["FundReturn"] else: fund_return = Index().get_index_factor(fund, attr=["PCT"]) fund_return.columns = ["FundReturn"] exposure_index = exposure_index.dropna(how="all") index_exposure_return = index_return_all.mul(exposure_index) index_exposure_return = index_exposure_return.dropna(how="all") data = pd.concat([fund_return, index_exposure_return], axis=1) data = data.dropna(how="all") data = data.loc[index_exposure_return.index, :] data = data.dropna(subset=["FundReturn"]) data["SumReturn"] = data[self.index_code_list].sum(axis=1, skipna=True) data["AlphaReturn"] = data["FundReturn"] - data["SumReturn"] data = data.loc[beg_date:end_date, :] data["CumFundReturn"] = (data["FundReturn"] + 1.0).cumprod() - 1.0 data["CumAlphaReturn"] = (data["AlphaReturn"] + 1.0).cumprod() - 1.0 data["CumSumReturn"] = (data["SumReturn"] + 1.0).cumprod() - 1.0 # 合并新数据 #################################################################### out_path = self.data_path out_file = os.path.join(out_path, self.file_prefix + fund + '.csv') if os.path.exists(out_file): params_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') params_old.index = params_old.index.map(str) params = FactorOperate().pandas_add_row(params_old, data) else: params = data print(params) params.to_csv(out_file)
def update_data(self): """ 更新所需要的数据 """ Date().load_trade_date_series("D") end_date = datetime.today() beg_date = Date().get_trade_date_offset(end_date, -60) FundFactor().load_fund_factor_all(beg_date, end_date)
def cal_fund_holder_exposure_quarter(self, fund, beg_date, end_date): """ 计算单个基金的季度持仓暴露 (前十大重仓暴露) """ type_list = ['STYLE', 'COUNTRY', 'INDUSTRY'] date_series = Date().get_normal_date_series(beg_date, end_date, period='Q') fund_holding = FundHolder().get_fund_stock_weight_quarter(fund) if fund_holding is not None: date_series = list(set(date_series) & set(fund_holding.columns)) date_series.sort() else: return None for i_date in range(0, len(date_series)): date = date_series[i_date] report_date = Date().get_normal_date_month_end_day(date) trade_date = Date().get_trade_date_month_end_day(date) barra_name = list( Barra().get_factor_name(type_list)['NAME_EN'].values) barra_exposure = Barra().get_factor_exposure_date( trade_date, type_list) print( "########## Calculate Quarter Holder Exposure %s %s ##########" % (fund, report_date)) if (barra_exposure is None) or (fund_holding is None): exposure_add = pd.DataFrame([], columns=barra_name, index=[report_date]) else: fund_holding_date = pd.DataFrame(fund_holding[report_date]) fund_holding_date = fund_holding_date.dropna() fund_holding_date = fund_holding_date.sort_values( by=[report_date], ascending=False) fund_holding_date.columns = ["Weight"] data = pd.concat([fund_holding_date, barra_exposure], axis=1) data = data.dropna() if (len(data) == 0) or (data is None): exposure_add = pd.DataFrame([], columns=barra_name, index=[report_date]) else: exposure_add = pd.DataFrame([], columns=barra_name, index=[report_date]) for i_factor in range(len(barra_name)): factor_name = barra_name[i_factor] data_weight = data[['Weight', factor_name]] data_weight['StockExposure'] = data['Weight'] * data[ factor_name] exposure_add.ix[report_date, factor_name] = data_weight[ 'StockExposure'].sum() / 100.0 country_name = Barra().get_factor_name( ["COUNTRY"])["NAME_EN"].values[0] position = FundFactor().get_fund_factor( "Stock_Ratio", date_list=[report_date], fund_pool=[fund]) position = position.values[0][0] exposure_add.ix[report_date, country_name] = position / 100 if i_date == 0: exposure_new = exposure_add else: exposure_new = pd.concat([exposure_new, exposure_add], axis=0) # 合并新数据 #################################################################### out_path = os.path.join(self.data_path_exposure, 'fund_holding_exposure_quarter') out_file = os.path.join( out_path, 'Fund_Holder_Exposure_Quarter_' + fund + '.csv') if os.path.exists(out_file): exposure_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') exposure_old.index = exposure_old.index.map(str) params = FactorOperate().pandas_add_row(exposure_old, exposure_new) else: params = exposure_new params.to_csv(out_file)
def cal_fund_regression_exposure_style(self, fund, beg_date, end_date, period="D"): # 参数 #################################################################### up_style_exposure = 1.25 up_position_exposure = 0.95 low_position_exposure = 0.75 position_sub = 0.08 beg_date = Date().change_to_str(beg_date) end_date = Date().change_to_str(end_date) # 取得数据 因子收益率数据 和 基金涨跌幅数据 #################################################################### type_list = ['STYLE', 'COUNTRY'] barra_name = list(Barra().get_factor_name(type_list)['NAME_EN'].values) barra_return = Barra().get_factor_return(None, None, type_list) date_series = Date().get_trade_date_series(beg_date, end_date, period=period) if fund[len(fund) - 2:] == 'OF': fund_return = FundFactor().get_fund_factor("Repair_Nav_Pct", None, [fund]) else: fund_return = Index().get_index_factor(fund, attr=["PCT"]) * 100 fund_return.columns = [fund] data = pd.concat([fund_return, barra_return], axis=1) data = data.dropna() print(" Fund Code Total Len %s " % len(data)) factor_number = len(barra_name) stock_ratio = FundFactor().get_fund_factor("Stock_Ratio", None, [fund]) / 100 date_series = list(set(date_series) & set(data.index)) date_series.sort() # 循环回归计算每天的暴露 计算当天的暴露之时需要 前一天及之前数据 #################################################################### for i_date in range(0, len(date_series)): # 回归所需要的数据 #################################################################### period_end_date = date_series[i_date] period_beg_date = Date().get_trade_date_offset( period_end_date, -self.regression_period) data_end_date = Date().get_trade_date_offset(period_end_date, -0) period_date_series = Date().get_trade_date_series( period_beg_date, data_end_date) data_periods = data.ix[period_date_series, :] data_periods = data_periods.dropna() # 上个季度基金仓位 ##################################################################################### quarter_date = Date().get_last_fund_quarter_date(period_end_date) stock_ratio_fund = stock_ratio.loc[quarter_date, fund] print( "########## Calculate Regression Exposure %s %s %s %s %s %s ##########" % (fund, period_beg_date, period_end_date, quarter_date, len(data_periods), stock_ratio_fund)) if len(data_periods) > self.regression_period_min: y = data_periods.ix[:, 0].values x = data_periods.ix[:, 1:].values x_add = sm.add_constant(x) low_position_exposure = max(stock_ratio_fund - position_sub, low_position_exposure) if np.isnan(low_position_exposure): low_position_exposure = 0.75 P = 2 * np.dot(x_add.T, x_add) Q = -2 * np.dot(x_add.T, y) G_up = np.diag(np.ones(factor_number + 1)) G_low = -np.diag(np.ones(factor_number + 1)) G = np.row_stack((G_up, G_low)) h_up = np.row_stack((np.ones( (factor_number, 1)) * up_style_exposure, np.array([up_position_exposure]))) h_low = np.row_stack((np.ones( (factor_number, 1)) * up_style_exposure, np.array([-low_position_exposure]))) h = np.row_stack((h_up, h_low)) P = matrix(P) Q = matrix(Q) G = matrix(G) h = matrix(h) try: result = sol.qp(P, Q, G, h) params_add = pd.DataFrame(np.array(result['x'][1:]), columns=[period_end_date], index=barra_name).T print(params_add) except Exception as e: params_add = pd.DataFrame([], columns=[period_end_date], index=barra_name).T print(params_add) else: params_add = pd.DataFrame([], columns=[period_end_date], index=barra_name).T print(params_add) if i_date == 0: params_new = params_add else: params_new = pd.concat([params_new, params_add], axis=0) # 合并新数据 #################################################################### out_path = os.path.join(self.data_path_exposure, 'fund_regression_exposure_style') out_file = os.path.join( out_path, 'Fund_Regression_Exposure_Style_' + fund + '.csv') if os.path.exists(out_file): params_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') params_old.index = params_old.index.map(str) params = FactorOperate().pandas_add_row(params_old, params_new) else: params = params_new print(params) params.to_csv(out_file)
def cal_fund_regression_exposure(self, fund, beg_date, end_date, period="M"): # 参数 #################################################################### up_style_exposure = 1.5 up_position_exposure = 0.95 low_position_exposure = 0.75 position_sub = 0.10 beg_date = Date().change_to_str(beg_date) end_date = Date().change_to_str(end_date) # 取得数据 #################################################################### type_list = ['STYLE', 'COUNTRY'] barra_name = list(Barra().get_factor_name(type_list)['NAME_EN'].values) barra_return = Barra().get_factor_return(None, None, type_list) date_series = Date().get_trade_date_series(beg_date, end_date, period=period) fund_return = FundFactor().get_fund_factor("Repair_Nav_Pct", None, [fund]) data = pd.concat([fund_return, barra_return], axis=1) data = data.dropna() print(" Fund Code Total Len %s " % len(data)) factor_number = len(barra_name) # 循环回归计算每天的暴露 #################################################################### for i_date in range(0, len(date_series)): period_end_date = date_series[i_date] period_beg_date = Date().get_trade_date_offset( period_end_date, -self.regression_period) period_date_series = Date().get_trade_date_series( period_beg_date, period_end_date) data_periods = data.ix[period_date_series, :] data_periods = data_periods.dropna() quarter_date = Date().get_last_fund_quarter_date(period_end_date) stock_ratio = (FundFactor().get_fund_factor( "Stock_Ratio", [quarter_date], [fund]) / 100).values[0][0] print( "########## Calculate Regression Exposure %s %s %s %s %s %s ##########" % (fund, period_beg_date, period_end_date, quarter_date, len(data_periods), stock_ratio)) if len(data_periods) > self.regression_period_min: y = data_periods.ix[:, 0].values x = data_periods.ix[:, 1:].values x_add = sm.add_constant(x) low_position_exposure = max(stock_ratio - position_sub, low_position_exposure) print(low_position_exposure) P = 2 * np.dot(x_add.T, x_add) Q = -2 * np.dot(x_add.T, y) G_up = np.diag(np.ones(factor_number + 1)) G_low = -np.diag(np.ones(factor_number + 1)) G = np.row_stack((G_up, G_low)) h_up = np.row_stack((np.ones( (factor_number, 1)) * up_style_exposure, np.array([up_position_exposure]))) h_low = np.row_stack((np.ones( (factor_number, 1)) * up_style_exposure, np.array([-low_position_exposure]))) h = np.row_stack((h_up, h_low)) P = matrix(P) Q = matrix(Q) G = matrix(G) h = matrix(h) try: result = sol.qp(P, Q, G, h) params_add = pd.DataFrame(np.array(result['x'][1:]), columns=[period_end_date], index=barra_name).T print(params_add) except: params_add = pd.DataFrame([], columns=[period_end_date], index=barra_name).T print(params_add) else: params_add = pd.DataFrame([], columns=[period_end_date], index=barra_name).T print(params_add) if i_date == 0: params_new = params_add else: params_new = pd.concat([params_new, params_add], axis=0) # 合并新数据 #################################################################### out_path = Parameter().get_read_file(self.regression_exposure_name) out_file = os.path.join(out_path, 'Fund_Regression_Exposure_' + fund + '.csv') if os.path.exists(out_file): params_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') params_old.index = params_old.index.map(str) params = pandas_add_row(params_old, params_new) else: params = params_new print(params) params.to_csv(out_file)
def get_data(self): """ 季度公募主动股票基金股票权重 作为指数股票权重参考标准 """ self.stock_ratio = FundFactor().get_fund_factor('Stock_Ratio').T