def FundReturnQuarter(report_date): """ 计算在给定时间点前后一个月 一个基金收益 利用基金复权净值计算 """ T = 20 beg_date = Date().get_trade_date_offset(report_date, -T) end_date = Date().get_trade_date_offset(report_date, T) date_series = Date().get_trade_date_series(beg_date, end_date) fund_code_list = Fund().get_fund_pool_code(date=report_date, name="基金持仓基准基金池") fund_code_list3 = Fund().get_fund_pool_code(date=report_date, name="量化基金") fund_code_list2 = Fund().get_fund_pool_code(date="20180630", name="东方红基金") fund_code_list.extend(fund_code_list2) fund_code_list.extend(fund_code_list3) fund_code_list = list(set(fund_code_list)) fund_code_list.sort() fund_pct = Fund().get_fund_factor("Repair_Nav_Pct", date_series, fund_code_list) print(" Calculting fund Return At date %s " % report_date) fund_pct[fund_pct == 0] = np.nan fund_pct_period = pd.DataFrame(fund_pct.sum(skipna=True).values, index=fund_pct.columns, columns=[report_date]) fund_pct_period[fund_pct_period == 0] = np.nan return fund_pct_period
def AllFundBarraDecomposeReturnQuarter(fund_holding_all, path, report_date): """ 计算一个季报时间点 前后一个月 所有基金 拆分的 特异收益 风格收益 行业收益 和 市场收益 """ # 参数 ###################################################################################################### # report_date = '20171231' # path = 'E:\\3_Data\\4_fund_data\\7_fund_select_stock\\' # fund_holding_all = Fund().get_fund_holding_all() # 持仓信息 ###################################################################################################### fund_holding_date = fund_holding_all[fund_holding_all['Date'] == report_date] # 基金池信息 ###################################################################################################### fund_code_list = Fund().get_fund_pool_code(date=report_date, name="基金持仓基准基金池") fund_code_list3 = Fund().get_fund_pool_code(date=report_date, name="量化基金") fund_code_list2 = Fund().get_fund_pool_code(date="20180630", name="东方红基金") fund_code_list.extend(fund_code_list2) fund_code_list.extend(fund_code_list3) fund_code_list = list(set(fund_code_list)) fund_code_list.sort() # cal fund alpha on style ###################################################################################################### for i in range(0, len(fund_code_list)): fund_code = fund_code_list[i] if i == 0: result = FundBarraDecomposeReturnQuarter(fund_holding_date, report_date, path, fund_code) else: res = FundBarraDecomposeReturnQuarter(fund_holding_date, report_date, path, fund_code) result = pd.concat([result, res], axis=0) ###################################################################################################### file = "FundBarraDecomposeReturnQuarter" + report_date + '.csv' file = os.path.join(path, "FundBarraDecomposeReturnQuarter", file) result.to_csv(file)
def opt_date(self, end_date, end_last_date, turnover_control=False): """ 单期优化 1、风格不能偏离整体中位数太多 2、仓位不能偏离整体中位数太多 3、单个基金上限 4、换手率约束 5、每个基金管理公司最多有两只(未约束) 6、基金个数约束(未约束) """ print("Project Nice Stock Fund Optimization Fund Weight at %s ......" % end_date) # Fund Pool path = os.path.join(self.data_path, 'fund_factor') file = os.path.join(path, 'FundFactor_%s.csv' % end_date) data = pd.read_csv(file, index_col=[0], encoding='gbk') fund_benchmark_list = Fund().get_fund_pool_code("20181231", self.fund_pool_name) fund_benchmark_list = list(set(fund_benchmark_list) & set(data.index)) fund_benchmark_list.sort() data = data.loc[fund_benchmark_list, :] # Name of Columns barra_style_list = Barra().get_factor_name(type_list=['STYLE'])['NAME_EN'].values position_list = Barra().get_factor_name(type_list=['COUNTRY'])['NAME_EN'].values risk_factor_list = Barra().get_factor_name(type_list=['COUNTRY', "STYLE"])['NAME_EN'].values alpha_col = [self.alpha_column] use_col = list(alpha_col) use_col.extend(risk_factor_list) # Fund Pool Filter data = data.dropna(subset=use_col) alpha_values = data[alpha_col].values data['UpRatio'] = self.fund_up_ratio weight_up_values = data['UpRatio'].values # BenchMark fund_benchmark_list = Fund().get_fund_pool_code("20181231", self.benchmark_name) fund_benchmark_list = list(set(fund_benchmark_list) & set(data.index)) fund_benchmark_list.sort() # Val stock_style_values = data[barra_style_list].values stock_position_values = data[position_list].values bench_style_values = data.loc[fund_benchmark_list, barra_style_list].median().values bench_position_values = data.loc[fund_benchmark_list, position_list].median().values bench_style_up_values = bench_style_values.T + self.style_deviate bench_style_low_values = bench_style_values.T - self.style_deviate bench_position_up_values = bench_position_values.T + self.position_deviate bench_position_low_values = bench_position_values.T - self.position_deviate if len(data) == 0: print("Project Nice Stock Fund Length of Fund is %s at %s ...... is Zero" % (len(data), end_date)) else: print("Project Nice Stock Fund Length of Fund is %s at %s ......" % (len(data), end_date)) w = cvx.Variable(len(data)) if turnover_control: try: file = os.path.join(self.data_path, 'fund_opt', 'FundOpt_%s.csv' % end_last_date) weight_last = pd.read_csv(file, index_col=[0], encoding='gbk') weight_last = weight_last.dropna(subset=[self.alpha_column]) if len(weight_last) == 0: weight_last = pd.Series(index=data.index) weight_last = weight_last.fillna(0.0) turnover = 2.00 else: weight_last = weight_last.loc[data.index, "Weight"] weight_last = weight_last.fillna(0.0) turnover = self.turnover except Exception as e: print(e) weight_last = pd.Series(index=data.index) weight_last = weight_last.fillna(0.0) turnover = 2.00 print(len(weight_last)) weight_last_values = weight_last.values prob = cvx.Problem(cvx.Maximize(alpha_values.T * w), [cvx.sum(w) == 1, w >= 0, w <= weight_up_values, cvx.sum(cvx.abs(w - weight_last_values)) <= turnover, stock_style_values.T * w <= bench_style_up_values, stock_style_values.T * w >= bench_style_low_values, stock_position_values.T * w <= bench_position_up_values, stock_position_values.T * w >= bench_position_low_values, ]) prob.solve() else: prob = cvx.Problem(cvx.Maximize(alpha_values.T * w), [cvx.sum(w) == 1, w >= 0, w <= weight_up_values, stock_style_values.T * w <= bench_style_up_values, stock_style_values.T * w >= bench_style_low_values, stock_position_values.T * w <= bench_position_up_values, stock_position_values.T * w >= bench_position_low_values, ]) prob.solve() print("status:", prob.status) print("optimal value", prob.value) weight = pd.DataFrame(w.value, columns=['Weight'], index=data.index) weight['Weight'] = weight['Weight'].map(lambda x: 0.0 if x < 0.02 else x) weight['Weight'] /= weight['Weight'].sum() result_risk_exposure = weight.T.dot(data[risk_factor_list]) result_risk_exposure = result_risk_exposure.T result_risk_exposure.columns = ['ResultExposure'] up_risk_exposure = pd.DataFrame(data[risk_factor_list].median()) up_risk_exposure.columns = ["UpExposure"] up_risk_exposure.loc[barra_style_list, "UpExposure"] += self.style_deviate up_risk_exposure.loc[position_list, "UpExposure"] += self.position_deviate low_risk_exposure = pd.DataFrame(data[risk_factor_list].median()) low_risk_exposure.columns = ["LowExposure"] low_risk_exposure.loc[barra_style_list, "LowExposure"] -= self.style_deviate low_risk_exposure.loc[position_list, "LowExposure"] -= self.position_deviate bench_risk_exposure = pd.DataFrame(data[risk_factor_list].median()) bench_risk_exposure.columns = ["BenchExposure"] exposure_result = pd.concat([bench_risk_exposure, up_risk_exposure, low_risk_exposure, result_risk_exposure], axis=1) data = pd.concat([data, weight], axis=1) data = data[data['Weight'] > 0.0] result = pd.concat([data, exposure_result.T], axis=0) col = ["SecName", "InvestType", "Corp", "SetupDate", "Weight", "RegressAlpha", "RegressAlphaIR"] col.extend(risk_factor_list) result = result[col] path = os.path.join(self.data_path, 'fund_opt') file = os.path.join(self.data_path, 'fund_opt', 'FundOpt_%s.csv' % end_date) if not os.path.exists(path): os.makedirs(path) result.to_csv(file)