def cal_dcf(self, fcf: Decimal, year: int, date: str) -> Decimal: fcf = decimal_utils.none_to_zero(fcf) if fcf <= 0: return Decimal(0), Decimal(0) inc_map: list = self._get_arr_by_name('inc_rate', date) dr_map: list = self._get_arr_by_name('discount_rate', date) mv = fcf inc_rate = 0.07 discount_rate = 0.1 # 计算10年的 for i in range(0, 10): y = year + i + 1 if y in inc_map: inc_rate = inc_map[y].value if y in dr_map: discount_rate = dr_map[y].value fcf = decimal_utils.div(decimal_utils.mul(fcf, (1 + inc_rate)), (1 + discount_rate)) if fcf < 0: fcf = 0 mv = decimal_utils.add(mv, fcf) inc_rate = inc_map[9999].value discount_rate = dr_map[9999].value mv_forever = decimal_utils.add(mv, decimal_utils.div( decimal_utils.mul(fcf, (1 + inc_rate)), (discount_rate - inc_rate))) return mv, mv_forever
def add_up(name: str, arr: list) -> MqQuarterMetric: report_type = 0 sum = None for i in arr: # type: MqQuarterMetric if i is not None: if sum is None: sum = MqQuarterMetric(ts_code=i.ts_code, period=i.period, update_date=i.update_date, name=name) report_type = report_type | i.report_type sum.value = decimal_utils.add(sum.value, i.value) if sum is not None: sum.report_type = report_type return sum
def sub_from(name: str, arr: list) -> MqQuarterMetric: report_type = 0 sum = None for index, i in enumerate(arr): # type: MqQuarterMetric if i is not None: if sum is None: sum = MqQuarterMetric(ts_code=i.ts_code, period=i.period, update_date=i.update_date, name=name) report_type = report_type | i.report_type if index == 0: sum.value = decimal_utils.add(sum.value, i.value) else: sum.value = decimal_utils.sub(sum.value, i.value) if sum is not None: sum.report_type = report_type return sum
def fetch_balance_sheet(self, ts_code: str = None, end_date: str = None, start_date: str = None, ann_date: str = None, period: str = None) -> DataFrame: """ https://tushare.pro/document/2?doc_id=36 :param ts_code: 股票编码 :param end_date: 起始日期 :param start_date: 结束日期 :param ann_date: 公告日期 :param period: 报告期 :return: """ df1 = self.__pro.balancesheet_vip(report_type=1, ts_code=ts_code, period=period, start_date=start_date, end_date=end_date, ann_date=ann_date) df2 = self.__pro.balancesheet_vip(report_type=4, ts_code=ts_code, period=period, start_date=start_date, end_date=end_date, ann_date=ann_date) df = df1.append(df2) if not df.empty: self.fix_ann_date_with_list_date(df, 'ann_date') self.fix_ann_date_with_list_date(df, 'f_ann_date') df.loc[:, 'mq_ann_date'] = df.apply(lambda row: mini(row.ann_date, row.f_ann_date), axis=1) df.loc[:, 'notes_receiv'] = df.apply(lambda row: decimal_utils.none_to_zero(row.notes_receiv), axis=1) df.loc[:, 'accounts_receiv'] = df.apply(lambda row: decimal_utils.none_to_zero(row.accounts_receiv), axis=1) df.loc[:, 'lt_rec'] = df.apply(lambda row: decimal_utils.none_to_zero(row.lt_rec), axis=1) df.loc[:, 'oth_receiv'] = df.apply(lambda row: decimal_utils.none_to_zero(row.oth_receiv), axis=1) df.loc[:, 'div_receiv'] = df.apply(lambda row: decimal_utils.none_to_zero(row.div_receiv), axis=1) df.loc[:, 'int_receiv'] = df.apply(lambda row: decimal_utils.none_to_zero(row.int_receiv), axis=1) df.loc[:, 'notes_payable'] = df.apply(lambda row: decimal_utils.none_to_zero(row.notes_payable), axis=1) df.loc[:, 'acct_payable'] = df.apply(lambda row: decimal_utils.none_to_zero(row.acct_payable), axis=1) df.loc[:, 'total_nca'] = df.apply(lambda row: decimal_utils.none_to_zero(row.total_nca), axis=1) df.loc[:, 'fa_avail_for_sale'] = df.apply(lambda row: decimal_utils.none_to_zero(row.fa_avail_for_sale), axis=1) df.loc[:, 'total_cur_liab'] = df.apply(lambda row: decimal_utils.none_to_zero(row.total_cur_liab), axis=1) df.loc[:, 'total_cur_assets'] = df.apply(lambda row: decimal_utils.none_to_zero(row.total_cur_assets), axis=1) df.loc[:, 'lt_borr'] = df.apply(lambda row: decimal_utils.none_to_zero(row.lt_borr), axis=1) df.loc[:, 'st_borr'] = df.apply(lambda row: decimal_utils.none_to_zero(row.st_borr), axis=1) df.loc[:, 'money_cap'] = df.apply(lambda row: decimal_utils.none_to_zero(row.money_cap), axis=1) df.loc[:, 'oth_cur_assets'] = df.apply(lambda row: decimal_utils.none_to_zero(row.oth_cur_assets), axis=1) # 待摊费用(新会计准则取消) -> 长期待摊费用 df.loc[:, 'lt_amor_exp'] = df.apply(lambda row: decimal_utils.add(row.amor_exp, row.lt_amor_exp), axis=1) return df
def cal_ltm_with_quarter(name: str, i1: MqQuarterMetric, i2: MqQuarterMetric, i3: MqQuarterMetric, i4) -> MqQuarterMetric: ''' 用4个单季去计算LTM ''' if i1 is not None and date_utils.get_quarter_num(i1.period) == 4: return MqQuarterMetric(ts_code=i1.ts_code, report_type=i1.report_type, period=i1.period, update_date=i1.update_date, name=name, value=i1.value) elif i1 is None or i2 is None or i3 is None or i4 is None: return None else: return MqQuarterMetric(ts_code=i1.ts_code, report_type=i1.report_type | i2.report_type | i3.report_type | i4.report_type, period=i1.period, update_date=i1.update_date, name=name, value=decimal_utils.add(i1.value, i2.value, i3.value, i4.value))
def cal(daily_store: mq_daily_store.MqDailyStore, quarter_store: mq_quarter_store.MqQuarterStore, ts_code: str, update_date: str) -> MqDailyMetric: daily_find = partial(daily_store.find_date_exact, ts_code=ts_code, update_date=update_date) quarter_find = partial(quarter_store.find_latest, ts_code=ts_code, update_date=update_date) score = -1 period = '00000000' dividend_yields = daily_find( name=mq_daily_metric_enum.dividend_yields.name) risk_point = quarter_find(name=mq_quarter_metric_enum.risk_point.name) revenue_quarter = quarter_find( name=mq_quarter_metric_enum.revenue_quarter.name) dprofit_quarter = quarter_find( name=mq_quarter_metric_enum.dprofit_quarter.name) if dividend_yields is None or \ calculate.gt(risk_point, 0, 'value', True) or \ calculate.lt(dividend_yields, 0.03, 'value', True) or \ not earn_and_dividend_in_year(quarter_store, ts_code, dividend_yields.period, update_date, 5) or \ not earn_in_period(quarter_store, ts_code, dividend_yields.period, update_date, 4) or \ calculate.lt(revenue_quarter, max_desc_yoy, 'yoy', True) or \ calculate.lt(revenue_quarter, dprofit_quarter, 'yoy', True): score = -1 else: period = dividend_yields.period pe = daily_find(name=mq_daily_metric_enum.pe.name) pb = daily_find(name=mq_daily_metric_enum.pb.name) dividend_score = decimal_utils.mul(dividend_yields.value, Decimal(1000)) # * 100 / 10 * 100 pe_score = decimal_utils.valid_score((1 - decimal_utils.div( calculate.get_val(pe, 'value', max_pe), max_pe, err_default=0)) * 100) pb_score = decimal_utils.valid_score((1 - decimal_utils.div( calculate.get_val(pb, 'value', max_pb), max_pb, err_default=0)) * 100) pepb_score = decimal_utils.valid_score((1 - decimal_utils.div( decimal_utils.mul(calculate.get_val(pe, 'value', max_pe), calculate.get_val(pb, 'value', max_pb)), max_pepb)) * 100) profit_yoy_score = history_profit_yoy_score(quarter_store, ts_code, dividend_yields.period, update_date, 5) dividend_yoy_score = history_dividend_yoy_score( quarter_store, ts_code, dividend_yields.period, update_date, 5) if profit_yoy_score == 0 or dividend_yoy_score == 0: score = 0 elif pe_score == 0 and pb_score == 0 and pepb_score == 0: score = 0 else: score = decimal_utils.add( decimal_utils.mul(dividend_score, 0.3), decimal_utils.mul(dividend_yoy_score, 0.2), decimal_utils.mul((pe_score + pb_score + pepb_score), 0.1), decimal_utils.mul(profit_yoy_score, 0.2)) val_score_metric = MqDailyMetric(ts_code=ts_code, report_type=mq_report_type.mq_predict, period=period, update_date=update_date, name=mq_daily_metric_enum.val_score.name, value=decimal_utils.valid_score(score)) return [val_score_metric]