コード例 #1
0
ファイル: fund.py プロジェクト: rlcjj/quant
    def __init__(self):

        FundHolder.__init__(self)
        FundFactor.__init__(self)
        FundPool.__init__(self)
        FundStatic.__init__(self)
        FundExposure.__init__(self)
コード例 #2
0
    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
コード例 #3
0
    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)
コード例 #4
0
    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
コード例 #5
0
    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")  # 调整股票的调整日的权重
コード例 #6
0
    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")  # 调整股票的调整日的权重
コード例 #7
0
ファイル: fund_rank.py プロジェクト: easy00000000/quant
    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))
コード例 #8
0
    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)
コード例 #9
0
ファイル: fund_rank.py プロジェクト: easy00000000/quant
    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
コード例 #10
0
    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)
コード例 #11
0
    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
コード例 #12
0
    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)
コード例 #13
0
    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)
コード例 #14
0
    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)
コード例 #15
0
    def get_data(self):
        """ 季度公募主动股票基金股票权重 作为指数股票权重参考标准 """

        self.stock_ratio = FundFactor().get_fund_factor('Stock_Ratio').T
        self.pct = Stock().read_factor_h5("Pct_chg")  # 调整股票的调整日的权重
コード例 #16
0
    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)
コード例 #17
0
    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)
コード例 #18
0
 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)
コード例 #19
0
    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)
コード例 #20
0
    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)
コード例 #21
0
ファイル: fund_exposure.py プロジェクト: rlcjj/quant
    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)
コード例 #22
0
    def get_data(self):

        """ 季度公募主动股票基金股票权重 作为指数股票权重参考标准 """

        self.stock_ratio = FundFactor().get_fund_factor('Stock_Ratio').T