예제 #1
0
def fill_empty(result_list: list, store: MqQuarterStore, period_dict: dict,
               ts_code: str, update_date: str):
    period_list = list(period_dict.keys())
    period_list.sort()
    for key in period_list:
        period_o: PeriodObj = period_dict[key]
        period = period_o.end_date
        for i in mq_quarter_metric_enum.fill_after_copy_fail_list:
            exist = store.find_period_latest(ts_code, i.name, period,
                                             update_date)
            if exist is None:
                call_add_nx = partial(add_nx,
                                      ts_code=ts_code,
                                      period=period,
                                      update_date=update_date,
                                      store=store,
                                      result_list=result_list,
                                      period_dict=period_dict,
                                      name=i.name)
                if i.from_name == '':
                    call_add_nx(report_type=mq_report_type.report,
                                value=Decimal(0))
                else:
                    from_indicator = store.find_period_exact(
                        ts_code, i.from_name, period, update_date)
                    if from_indicator is None or from_indicator.value is None:
                        log.error(
                            'Cant find %s to fill %s for %s. Period: %s. Update date: %s'
                            % (i.from_name, i.name, ts_code, period,
                               update_date))
                    else:
                        add = call_add_nx(report_type=0,
                                          value=from_indicator.value)
                        add.report_type = from_indicator.report_type
예제 #2
0
def cal_yoy_mom(result_list: list, store: MqQuarterStore):
    for i in result_list:  # type: MqQuarterMetric
        lm = store.find_period_latest(i.ts_code, i.name,
                                      date_utils.period_delta(i.period, -1))
        i.mom = cal_inc_rate(i, lm)
        ly = store.find_period_latest(i.ts_code, i.name,
                                      date_utils.period_delta(i.period, -4))
        i.yoy = cal_inc_rate(i, ly)
예제 #3
0
def cal_pepb(result_list: list, daily_store: mq_daily_store.MqDailyStore,
             quarter_store: mq_quarter_store.MqQuarterStore,
             ts_code: str, update_date: str):
    call_add = partial(common_add, result_list=result_list, store=daily_store)
    call_log = partial(common_log_err, ts_code=ts_code, update_date=update_date)

    total_mv = daily_store.find_date_exact(ts_code, mq_daily_metric_enum.total_mv.name, update_date)

    dprofit_ltm = quarter_store.find_latest(ts_code, mq_quarter_metric_enum.dprofit_ltm.name, update_date)
    dq_dividend(call_add, call_log, total_mv, dprofit_ltm, mq_daily_metric_enum.pe.name)

    nassets = quarter_store.find_latest(ts_code, mq_quarter_metric_enum.nassets.name, update_date)
    dq_dividend(call_add, call_log, total_mv, nassets, mq_daily_metric_enum.pb.name)
예제 #4
0
def cal_dcf(result_list: list, daily_store: mq_daily_store.MqDailyStore, quarter_store: mq_quarter_store.MqQuarterStore,
            dcf_service: MqDcfService, ts_code: str, update_date: str):
    '''
        根据自由现金流估算市值
    '''
    call_add = partial(common_add, result_list=result_list, store=daily_store)

    fcf = quarter_store.find_latest(ts_code, mq_quarter_metric_enum.fcf_ltm.name, update_date)
    mv_10, mv = 0, 0
    report_type = mq_report_type.report
    period = '20000331'

    if fcf is not None:
        year = int(fcf.period[0:4])
        report_type = fcf.report_type
        period = fcf.period
        mv_10, mv = dcf_service.cal_dcf(fcf.value, year, update_date)
    else:
        log.error('Cant find fcf %s %s' % (ts_code, update_date))

    daily_mv_10 = MqDailyMetric(ts_code=ts_code, report_type=report_type, period=period, update_date=update_date,
                                name=mq_daily_metric_enum.mv_10.name, value=mv_10)

    daily_mv = MqDailyMetric(ts_code=ts_code, report_type=report_type, period=period, update_date=update_date,
                             name=mq_daily_metric_enum.mv.name, value=mv)

    call_add(to_add=daily_mv_10)
    call_add(to_add=daily_mv)
예제 #5
0
def extract_from_dividend(result_list: list, store: MqQuarterStore,
                          period_dict: dict, d: TsDividend):
    # 有可能有非固定分红的派钱
    lp: str = date_utils.latest_period_date(d.end_date)
    update_date: str = date_utils.format_delta(d.imp_ann_date, -1)

    call_add_nx = partial(add_nx,
                          ts_code=d.ts_code,
                          period=lp,
                          update_date=update_date,
                          report_type=mq_report_type.report,
                          store=store,
                          result_list=result_list,
                          period_dict=period_dict)

    # 叠加到最近一个季度的分红中
    dividend: Decimal = decimal_utils.mul(d.cash_div_tax, d.base_share)
    if lp != d.end_date:
        ori_d: MqQuarterMetric = store.find_period_latest(
            ts_code=d.ts_code,
            period=lp,
            update_date=update_date,
            name=mq_quarter_metric_enum.dividend.name)
        if ori_d is not None:
            dividend = dividend + ori_d.value
    call_add_nx(name='dividend', value=dividend)
예제 #6
0
def extract_from_cash_flow(result_list: list, store: MqQuarterStore,
                           period_dict: dict, cf: TsCashFlow):
    update_date = date_utils.format_delta(cf.mq_ann_date, -1)
    ts_code = cf.ts_code
    period = cf.end_date
    call_find = partial(store.find_period_exact,
                        ts_code=ts_code,
                        period=period,
                        update_date=update_date)
    call_add_nx = partial(add_nx,
                          ts_code=ts_code,
                          period=period,
                          update_date=update_date,
                          report_type=mq_report_type.report if cf.report_type
                          == '1' else mq_report_type.report_adjust,
                          store=store,
                          result_list=result_list,
                          period_dict=period_dict)

    for i in mq_quarter_metric_enum.extract_from_cf_list:
        if i.is_cf_h and date_utils.get_quarter_num(cf.end_date) == 3:
            q2: MqManualMetric = store.find_period_latest(
                ts_code=cf.ts_code,
                name=i.name,
                period=date_utils.period_delta(cf.end_date, -1),
                update_date=update_date)
            if q2 is None:
                log.error('Cant find q2 in cash flow %s %s %s' %
                          (cf.ts_code, cf.end_date, cf.mq_ann_date))
                call_add_nx(name=i.name, value=getattr(cf, i.from_name))
            else:
                call_add_nx(name=i.name, value=q2.value)
        else:
            call_add_nx(name=i.name, value=getattr(cf, i.from_name))
예제 #7
0
def cal(daily_store: mq_daily_store.MqDailyStore,
        quarter_store: mq_quarter_store.MqQuarterStore,
        ts_code: str, update_date: str) -> MqDailyMetric:
    score = 0
    peg = 0
    report_type = 0
    period = '00000000'
    pe: MqDailyMetric = daily_store.find_date_exact(ts_code, mq_daily_metric_enum.pe.name, update_date)
    dprofit_quarter = quarter_store.find_latest(ts_code, mq_quarter_metric_enum.dprofit_quarter.name, update_date)
    dprofit_quarter_ly = quarter_store.find_period_latest(
        ts_code, mq_quarter_metric_enum.dprofit_quarter.name,
        period=date_utils.period_delta(dprofit_quarter.period, -1),
        update_date=update_date) if dprofit_quarter is not None else None
    dprofit_ltm = quarter_store.find_latest(ts_code, mq_quarter_metric_enum.dprofit_ltm.name, update_date)

    if pe is None or dprofit_quarter is None or dprofit_quarter_ly is None or dprofit_ltm is None:
        score = -1
    elif calculate.gt(pe, max_pe, field='value') or calculate.lt(pe, zero, field='value'):
        score = -1
    elif calculate.lt(dprofit_quarter, zero, field='value') or calculate.lt(dprofit_quarter, min_yoy, field='yoy'):
        score = -1
    elif calculate.lt(dprofit_quarter_ly, min_dprofit, field='value'):
        score = -1
    elif calculate.lt(dprofit_ltm, zero, field='value') or \
            calculate.lt(decimal_utils.div(dprofit_quarter.value, dprofit_ltm.value), min_dprofit_percent):
        score = -1
    else:
        peg = decimal_utils.div(decimal_utils.div(pe.value, dprofit_quarter.yoy), 100)
        report_type = pe.report_type | dprofit_quarter.report_type
        period = max(pe.period, dprofit_quarter.period)
        if peg > max_peg:
            score = -1
        else:
            score = (1 - peg / max_peg) * 100

    peg_metric = MqDailyMetric(ts_code=ts_code, report_type=report_type,
                               period=period, update_date=update_date,
                               name=mq_daily_metric_enum.peg.name,
                               value=peg)
    grow_score_metric = MqDailyMetric(ts_code=ts_code, report_type=report_type,
                                      period=period, update_date=update_date,
                                      name=mq_daily_metric_enum.grow_score.name,
                                      value=valid_score(score))

    return [peg_metric, grow_score_metric]
예제 #8
0
def cal_dividend(result_list: list, daily_store: mq_daily_store.MqDailyStore,
                 quarter_store: mq_quarter_store.MqQuarterStore,
                 ts_code: str, update_date: str):
    call_add = partial(common_add, result_list=result_list, store=daily_store)
    call_log = partial(common_log_err, ts_code=ts_code, update_date=update_date)

    dividend_ltm = quarter_store.find_latest(ts_code, mq_quarter_metric_enum.dividend_ltm.name, update_date)
    total_mv = daily_store.find_date_exact(ts_code, mq_daily_metric_enum.total_mv.name, update_date)
    qd_dividend(call_add, call_log, dividend_ltm, total_mv, mq_daily_metric_enum.dividend_yields.name)
예제 #9
0
def earn_and_dividend_in_year(quarter_store: mq_quarter_store.MqQuarterStore,
                              ts_code: str, report_period: str,
                              update_date: str, year: int) -> bool:
    quarter_num = get_quarter_num(report_period)
    period = report_period if quarter_num == 4 else period_delta(
        report_period, -quarter_num)
    period = period_delta(period, 4)
    for i in range(year):
        period = period_delta(period, -4)
        dprofit_ltm = quarter_store.find_period_latest(
            ts_code, mq_quarter_metric_enum.dprofit_ltm.name, period,
            update_date)
        dividend_ltm = quarter_store.find_period_latest(
            ts_code, mq_quarter_metric_enum.dividend_ltm.name, period,
            update_date)
        if calculate.lt(dprofit_ltm, zero, 'value', True):
            return False
        if calculate.lt(dividend_ltm, zero, 'value', True):
            return False
    return True
예제 #10
0
def earn_in_period(quarter_store: mq_quarter_store.MqQuarterStore,
                   ts_code: str, report_period: str, update_date: str,
                   quarter_num: int) -> bool:
    period = period_delta(report_period, 1)
    for i in range(quarter_num):
        period = period_delta(period, -1)
        dprofit_quarter = quarter_store.find_period_latest(
            ts_code, mq_quarter_metric_enum.dprofit_quarter.name, period,
            update_date)
        if calculate.lt(dprofit_quarter, zero, 'value', True):
            return False
    return True
예제 #11
0
def extract_from_income_adjust(result_list: list, store: MqQuarterStore,
                               period_dict: dict, income: TsIncome):
    update_date = date_utils.format_delta(income.mq_ann_date, -1)

    nprofit_new = store.find_period_exact(income.ts_code,
                                          mq_quarter_metric_enum.nprofit.name,
                                          income.end_date, update_date)
    nprofit_old = store.find_period_latest(
        income.ts_code, mq_quarter_metric_enum.nprofit.name, income.end_date,
        date_utils.format_delta(update_date, -1))
    dprofit_old = store.find_period_latest(
        income.ts_code, mq_quarter_metric_enum.dprofit.name, income.end_date,
        date_utils.format_delta(update_date, -2))

    to_add = None
    if nprofit_new is None:
        log.error('Cant find nprofit in adjust income. %s %s' %
                  (income.ts_code, income.end_date))
    elif nprofit_old is None or dprofit_old is None:
        to_add = MqQuarterMetric(
            ts_code=income.ts_code,
            report_type=(1 << mq_report_type.report_adjust),
            period=income.end_date,
            update_date=update_date,
            name=mq_quarter_metric_enum.dprofit.name,
            value=nprofit_new.value)
    else:
        to_add = MqQuarterMetric(
            ts_code=income.ts_code,
            report_type=(1 << mq_report_type.report_adjust),
            period=income.end_date,
            update_date=update_date,
            name=mq_quarter_metric_enum.dprofit.name,
            value=decimal_utils.sub(
                nprofit_new.value,
                decimal_utils.sub(nprofit_old.value, dprofit_old.value)))

    if to_add is not None:
        common_add(result_list, store, to_add)
예제 #12
0
def add_nx(ts_code: str, report_type: int, period: str, update_date: str,
           name: str, value: Decimal, result_list: list, store: MqQuarterStore,
           period_dict: dict):
    if value is None or name is None:
        return
    exist = store.find_period_latest(ts_code, name, period)
    if exist is not None and exist.update_date == update_date:
        return None
    to_add = MqQuarterMetric(ts_code=ts_code,
                             report_type=(1 << report_type),
                             period=period,
                             update_date=update_date,
                             name=name,
                             value=value)
    common_add(result_list, store, to_add)
    period_dict[period] = PeriodObj(period, report_type)
    return to_add
예제 #13
0
def copy_indicator_from_latest(result_list: list,
                               store: MqQuarterStore,
                               period: PeriodObj,
                               ts_code: str,
                               update_date: str,
                               name: str,
                               from_name: str = None):
    if from_name is None:
        from_name = name
    i = store.find_period_latest(ts_code, from_name, period.end_date,
                                 update_date)
    if i is None or i.update_date == update_date:
        return
    ni = MqQuarterMetric(ts_code=i.ts_code,
                         report_type=i.report_type,
                         period=i.period,
                         update_date=update_date,
                         name=name,
                         value=i.value)
    common_add(result_list, store, ni)
예제 #14
0
def extract_from_forecast(result_list: list, store: MqQuarterStore,
                          period_dict: dict, forecast: TsForecast):
    update_date = date_utils.format_delta(forecast.ann_date, -1)
    call_add_nx = partial(add_nx,
                          ts_code=forecast.ts_code,
                          period=forecast.end_date,
                          update_date=update_date,
                          report_type=mq_report_type.forecast,
                          store=store,
                          result_list=result_list,
                          period_dict=period_dict)

    forecast_nprofit = None
    if forecast.net_profit_min is not None:
        forecast_nprofit = forecast.net_profit_min
    elif forecast.net_profit_max is not None:
        forecast_nprofit = forecast.net_profit_max
    else:
        percent = None
        # choose minimum percent.
        if forecast.p_change_min is not None:
            percent = forecast.p_change_min
        if forecast.p_change_max is not None:
            if percent is None or forecast.p_change_max < percent:
                percent = forecast.p_change_max
        if percent is not None:
            percent = (percent / 100) + 1
            if forecast.last_parent_net is not None:
                forecast_nprofit = percent * forecast.last_parent_net
            else:
                nprofit_ly = store.find_period_latest(
                    forecast.ts_code, mq_quarter_metric_enum.nprofit.name,
                    forecast.end_date, update_date)
                if nprofit_ly is not None and nprofit_ly.value is not None:
                    forecast_nprofit = percent * nprofit_ly.value

    call_add_nx(name=mq_quarter_metric_enum.nprofit.name,
                value=forecast_nprofit)
예제 #15
0
def history_dividend_yoy_score(quarter_store: mq_quarter_store.MqQuarterStore,
                               ts_code: str, report_period: str,
                               update_date: str, year: int) -> bool:
    quarter_num = get_quarter_num(report_period)
    period = report_period if quarter_num == 4 else period_delta(
        report_period, -quarter_num)
    period = period_delta(period, 4)
    yoy_list = []
    for i in range(year):
        period = period_delta(period, -4)
        dividend_ltm = quarter_store.find_period_latest(
            ts_code, mq_quarter_metric_enum.dividend_ltm.name, period,
            update_date)
        yoy_list.append(calculate.get_val(dividend_ltm, 'yoy', zero))

    result = 0
    score_per_one = 100 / year
    for yoy in yoy_list:
        if yoy > 0:
            result += score_per_one
        elif yoy < 0:
            result -= score_per_one / 2
    return decimal_utils.valid_score(result)
예제 #16
0
def common_add(result_list: list, store: MqQuarterStore,
               to_add: MqQuarterMetric):
    store.add(to_add)
    result_list.append(to_add)