Example #1
0
    def _calc_factor_loading(cls, code, calc_date):
        """
        计算指定日期、指定个股ETOP因子载荷
        Parameters:
        --------
        :param code: str
            个股代码, 如SH600000, 600000
        :param calc_date: datetime-like, str
            计算日期, 格式: YYYY-MM-DD
        :return: pd.Series
        --------
            个股的ETOP因子载荷
            0. code
            1. etop
            如果计算失败, 返回None
        """
        code = Utils.code_to_symbol(code)
        # 读取个股的ttm净利润
        ttm_fin_data = Utils.get_ttm_fin_basic_data(code, calc_date)
        if ttm_fin_data is None:
            return None
        ttm_netprofit = ttm_fin_data['NetProfit']
        if pd.isnull(ttm_netprofit):
            return None
        # 读取个股市值
        lncap_path = os.path.join(factor_ct.FACTOR_DB.db_path, risk_ct.LNCAP_CT.db_file)
        lncap_data = Utils.read_factor_loading(lncap_path, Utils.datetimelike_to_str(calc_date, dash=False), code)
        if lncap_data.empty:
            return None
        secu_cap = np.exp(lncap_data['factorvalue'])
        # etop = ttm净利润/市值
        etop = ttm_netprofit * 10000 / secu_cap

        return pd.Series([code, etop], index=['code', 'etop'])
Example #2
0
 def _calc_factor_loading(cls, code, calc_date):
     """
     计算指定日期、指定个股的成长因子,包含npg_ttm, opg_ttm
     Parameters:
     --------
     :param code: str
         个股代码,如600000或SH600000
     :param calc_date: datetime-like or str
         计算日期,格式YYYY-MM-DD, YYYYMMDD
     :return: pd.Series
     --------
         成长类因子值
         0. id: 证券代码
         1. npg_ttm: 净利润增长率_TTM
         2. opg_ttm: 营业收入增长率_TTM
         若计算失败, 返回None
     """
     code = Utils.code_to_symbol(code)
     calc_date = Utils.to_date(calc_date)
     # 读取最新的TTM财务数据
     ttm_fin_data_latest = Utils.get_ttm_fin_basic_data(code, calc_date)
     if ttm_fin_data_latest is None:
         return None
     # 读取去年同期TTM财务数据
     try:
         pre_date = datetime.datetime(calc_date.year-1, calc_date.month, calc_date.day)
     except ValueError:
         pre_date = calc_date - datetime.timedelta(days=366)
     ttm_fin_data_pre = Utils.get_ttm_fin_basic_data(code, pre_date)
     if ttm_fin_data_pre is None:
         return None
     # 计算成长类因子值
     if abs(ttm_fin_data_pre['NetProfit']) < 0.1:
         return None
     npg_ttm = (ttm_fin_data_latest['NetProfit'] - ttm_fin_data_pre['NetProfit']) / abs(ttm_fin_data_pre['NetProfit'])
     if abs(ttm_fin_data_pre['MainOperateRevenue']) < 0.1:
         return None
     opg_ttm = (ttm_fin_data_latest['MainOperateRevenue'] - ttm_fin_data_pre['MainOperateRevenue']) / abs(ttm_fin_data_pre['MainOperateRevenue'])
     return Series([code, round(npg_ttm, 4), round(opg_ttm, 4)], index=['id', 'npg_ttm', 'opg_ttm'])
Example #3
0
 def _calc_factor_loading(cls, code, calc_date):
     """
     计算指定日期、指定个股的价值因子,包含ep_ttm, bp_lr, ocf_ttm
     Parameters:
     --------
     :param code: str
         个股代码:如600000或SH600000
     :param calc_date: datetime-like or str
         计算日期,格式YYYY-MM-DD, YYYYMMDD
     :return: pd.Series
     --------
         价值类因子值
         0. ep_ttm: TTM净利润/总市值
         1. bp_lr: 净资产(最新财报)/总市值
         2. ocf_ttm: TTM经营性现金流/总市值
         若计算失败,返回None
     """
     code = Utils.code_to_symbol(code)
     calc_date = Utils.to_date(calc_date)
     # 读取TTM财务数据
     ttm_fin_data = Utils.get_ttm_fin_basic_data(code, calc_date)
     if ttm_fin_data is None:
         return None
     # 读取最新财报数据
     report_date = Utils.get_fin_report_date(calc_date)
     fin_basic_data = Utils.get_fin_basic_data(code, report_date)
     if fin_basic_data is None:
         return None
     # 计算总市值
     mkt_daily = Utils.get_secu_daily_mkt(code,
                                          calc_date,
                                          fq=False,
                                          range_lookup=True)
     if mkt_daily.shape[0] == 0:
         return None
     cap_struct = Utils.get_cap_struct(code, calc_date)
     if cap_struct is None:
         return None
     total_cap = cap_struct.total - cap_struct.liquid_b - cap_struct.liquid_h
     total_mkt_cap = total_cap * mkt_daily.close
     # 计算价值类因子
     ep_ttm = ttm_fin_data[
         'NetProfit'] * util_ct.FIN_DATA_AMOUNT_UNIT / total_mkt_cap
     ocf_ttm = ttm_fin_data[
         'NetOperateCashFlow'] * util_ct.FIN_DATA_AMOUNT_UNIT / total_mkt_cap
     bp_lr = fin_basic_data[
         'ShareHolderEquity'] * util_ct.FIN_DATA_AMOUNT_UNIT / total_mkt_cap
     return Series([round(ep_ttm, 6),
                    round(bp_lr, 6),
                    round(ocf_ttm, 6)],
                   index=['ep_ttm', 'bp_lr', 'ocf_ttm'])
Example #4
0
    def _calc_factor_loading(cls, code, calc_date):
        """
        计算指定日期、指定个股EPFWD因子载荷
        Parameters:
        --------
        :param code: str
            个股代码, 如SH600000, 600000
        :param calc_date: datetime-like, str
            计算日期, 格式: YYYY-MM-DD
        :return: pd.Series
        --------
            个股的EPFWD因子载荷
            0. code
            1. epfwd
            如果计算失败, 返回None
        """
        code = Utils.code_to_symbol(code)
        # 读取个股的预期盈利数据
        predictedearnings_data = Utils.get_consensus_data(
            calc_date, code, ConsensusType.PredictedEarings)
        if predictedearnings_data is None:
            # 如果个股的预期盈利数据不存在, 那么代替ttm净利润
            ttm_fin_data = Utils.get_ttm_fin_basic_data(code, calc_date)
            if ttm_fin_data is None:
                return None
            predictedearnings_data = pd.Series(
                [code, ttm_fin_data['NetProfit']],
                index=['code', 'predicted_earnings'])
        fpredictedearnings = predictedearnings_data['predicted_earnings']
        if np.isnan(fpredictedearnings):
            return None
        # 读取个股市值
        size_path = os.path.join(factor_ct.FACTOR_DB.db_path,
                                 risk_ct.LNCAP_CT.db_file)
        size_factor_loading = Utils.read_factor_loading(
            size_path, Utils.datetimelike_to_str(calc_date, dash=False), code)
        if size_factor_loading.empty:
            return None
        # epfwd = 盈利预期/市值
        epfwd = fpredictedearnings * 10000.0 / np.exp(
            size_factor_loading['factorvalue'])

        return pd.Series([code, epfwd], index=['code', 'epfwd'])
Example #5
0
    def _calc_factor_loading(cls, code, calc_date):
        """
        计算指定日期、指定个股CETOP因子载荷
        Parameters:
        --------
        :param code: str
            个股代码, 如SH600000, 600000
        :param calc_date: datetime-like, str
            计算日期, 格式: YYYY-MM-DD
        :return: pd.Series
        --------
            个股的CETOP因子载荷
            0. code
            1. cetop
            如果计算失败, 返回None
        """
        code = Utils.code_to_symbol(code)
        # 读取个股的主要财务指标数据ttm值
        ttm_fin_data = Utils.get_ttm_fin_basic_data(code, calc_date)
        if ttm_fin_data is None:
            return None
        ttm_cash = ttm_fin_data['NetOperateCashFlow']
        if np.isnan(ttm_cash):
            return None
        # 读取个股市值
        lncap_path = os.path.join(factor_ct.FACTOR_DB.db_path,
                                  risk_ct.LNCAP_CT.db_file)
        lncap_data = Utils.read_factor_loading(
            lncap_path, Utils.datetimelike_to_str(calc_date, dash=False), code)
        if lncap_data.empty:
            return None
        secu_cap = np.exp(lncap_data['factorvalue'])
        # cetop = 经营活动现金流ttm值/市值
        cetop = ttm_cash * 10000 / secu_cap

        return pd.Series([code, cetop], index=['code', 'cetop'])
Example #6
0
def _get_prevN_years_finbasicdata(date, code, years):
    """
    读取过去n年的主要财务指标数据, 其中每股数据会经过复权因子调整
    :param date: datetime-like
        日期
    :param code: str
        个股代码, 格式: SH600000
    :param years: int
        返回的报告期年数
    :return: list of pd.Series
    """
    year = date.year
    month = date.month
    if month in (1, 2, 3, 4):
        # report_dates = [datetime.datetime(year-5, 12, 31),
        #                 datetime.datetime(year-4, 12, 31),
        #                 datetime.datetime(year-3, 12, 31),
        #                 datetime.datetime(year-2, 12, 31)]
        report_dates = [
            datetime.datetime(year - n, 12, 31) for n in range(years, 1, -1)
        ]
        is_ttm = True
    elif month in (5, 6, 7, 8):
        # report_dates = [datetime.datetime(year-5, 12, 31),
        #                 datetime.datetime(year-4, 12, 31),
        #                 datetime.datetime(year-3, 12, 31),
        #                 datetime.datetime(year-2, 12, 31),
        #                 datetime.datetime(year-1, 12, 31)]
        report_dates = [
            datetime.datetime(year - n, 12, 31) for n in range(years, 0, -1)
        ]
        is_ttm = False
    else:
        # report_dates = [datetime.datetime(year-4, 12, 31),
        #                 datetime.datetime(year-3, 12, 31),
        #                 datetime.datetime(year-2, 12, 31),
        #                 datetime.datetime(year-1, 12, 31)]
        report_dates = [
            datetime.datetime(year - n, 12, 31)
            for n in range(years - 1, 0, -1)
        ]
        is_ttm = True

    df_mkt_data = Utils.get_secu_daily_mkt(code, end=date,
                                           fq=True)  # 个股复权行情, 用于调整每股数据

    prevN_years_finbasicdata = []
    for report_date in report_dates:
        fin_basic_data = Utils.get_fin_basic_data(code,
                                                  report_date,
                                                  date_type='report_date')
        if fin_basic_data is None:
            return None
        fin_basic_data = fin_basic_data.to_dict()
        df_extract_mkt = df_mkt_data[
            df_mkt_data.date <= report_date.strftime('%Y-%m-%d')]
        if not df_extract_mkt.empty:
            fq_factor = df_extract_mkt.iloc[-1]['factor']
            # 调整每股数据
            fin_basic_data[
                'BasicEPS_adj'] = fin_basic_data['BasicEPS'] * fq_factor
            fin_basic_data['UnitNetAsset_adj'] = fin_basic_data[
                'UnitNetAsset'] * fq_factor
            fin_basic_data['UnitNetOperateCashFlow_adj'] = fin_basic_data[
                'UnitNetOperateCashFlow'] * fq_factor
            # 计算调整后的主营业务收入
            fin_basic_data['MainOperateRevenue_adj'] = fin_basic_data[
                'MainOperateRevenue'] / fq_factor
        else:
            fin_basic_data['BasicEPS_adj'] = fin_basic_data['BasicEPS']
            fin_basic_data['UnitNetAsset_adj'] = fin_basic_data['UnitNetAsset']
            fin_basic_data['UnitNetOperateCashFlow_adj'] = fin_basic_data[
                'UnitNetOperateCashFlow']
            fin_basic_data['MainOperateRevenue_adj'] = fin_basic_data[
                'MainOperateRevenue']
        prevN_years_finbasicdata.append(fin_basic_data)
    if is_ttm:
        ttm_fin_basic_data = Utils.get_ttm_fin_basic_data(code, date)
        if ttm_fin_basic_data is None:
            return None
        ttm_fin_basic_data = ttm_fin_basic_data.to_dict()
        df_extract_mkt = df_mkt_data[
            df_mkt_data.date <= ttm_fin_basic_data['ReportDate'].strftime(
                '%Y-%m-%d')]
        if not df_extract_mkt.empty:
            fq_factor = df_extract_mkt.iloc[-1]['factor']
            # 调整每股数据
            ttm_fin_basic_data[
                'BasicEPS_adj'] = ttm_fin_basic_data['BasicEPS'] * fq_factor
            # 计算调整后的主营业务收入
            ttm_fin_basic_data['MainOperateRevenue_adj'] = ttm_fin_basic_data[
                'MainOperateRevenue'] / fq_factor
        else:
            ttm_fin_basic_data['BasicEPS_adj'] = ttm_fin_basic_data['BasicEPS']
            ttm_fin_basic_data['MainOperateRevenue_adj'] = ttm_fin_basic_data[
                'MainOperateRevenue']
        prevN_years_finbasicdata.append(ttm_fin_basic_data)
    return prevN_years_finbasicdata