コード例 #1
0
    def update_adj(self, adj_type: str, latest_adj: str):
        """
        更新到想要的复权状态
        :param adj_type: 复权类型 qfq-前复权 hfq-后复权 其他-不复权
        :param latest_adj: 最新复权因子
        :return:
        """
        div_factor = 1
        if self.adj_type == 'qfq' and not decimal_utils.equals(
                self.adj, self.latest_adj):
            div_factor = decimal_utils.div(self.adj, self.latest_adj)
        elif self.adj_type == 'hfq':
            div_factor = self.adj

        mul_factor = 1
        if adj_type == 'qfq' and not decimal_utils.equals(
                self.adj, latest_adj):
            mul_factor = decimal_utils.div(self.adj, latest_adj)
        elif adj_type == 'hfq':
            mul_factor = self.adj

        factor = 1 if decimal_utils.equals(mul_factor,
                                           div_factor) else decimal_utils.div(
                                               mul_factor, div_factor)

        if factor == 1:
            return

        self.open = decimal_utils.mul(self.open, factor)
        self.high = decimal_utils.mul(self.high, factor)
        self.low = decimal_utils.mul(self.low, factor)
        self.close = decimal_utils.mul(self.close, factor)
        self.up_limit = decimal_utils.mul(self.up_limit, factor)
        self.down_limit = decimal_utils.mul(self.down_limit, factor)
        self.pre_close = decimal_utils.mul(self.pre_close, factor)
コード例 #2
0
    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
コード例 #3
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]
コード例 #4
0
def dividend(i1: MqQuarterMetric, i2: MqQuarterMetric,
             name: str) -> MqQuarterMetric:
    if i1 is None or i2 is None:
        return None
    return MqQuarterMetric(ts_code=i1.ts_code,
                           report_type=i1.report_type | i2.report_type,
                           period=i1.period,
                           update_date=i1.update_date,
                           name=name,
                           value=decimal_utils.div(i1.value, i2.value))
コード例 #5
0
ファイル: cal_mq_daily.py プロジェクト: SYSU-Momojie/MoQuant
def qd_dividend(call_add: partial, call_log: partial, i1: MqQuarterMetric, i2: MqDailyMetric, name: str):
    if i1 is None or i2 is None:
        call_log(name=name)
        return None
    else:
        to_add = MqDailyMetric(ts_code=i1.ts_code, report_type=i1.report_type | i2.report_type,
                               period=i1.period, update_date=i2.update_date,
                               name=name, value=decimal_utils.div(i1.value, i2.value))
        call_add(to_add=to_add)
        return to_add
コード例 #6
0
def cal_by_ths_index_code(index_code,
                          index_name,
                          to_date: str = date_utils.get_current_dt()):
    from_date = get_from_date(index_code)
    history_avl = get_history_percent(index_code, from_date)

    s: Session = db_client.get_session()
    member_list = s.query(ThsMember).filter(
        ThsMember.ts_code == index_code).all()
    s.close()

    share_code_list = [m.code for m in member_list]
    result_list = []
    while from_date <= to_date:
        log.info('Calculating %s %s %s' %
                 (MqIndexTradeAmount.__tablename__, index_code, from_date))
        s: Session = db_client.get_session()
        trade_list = s.query(TsDailyTradeInfo) \
            .filter(TsDailyTradeInfo.trade_date == from_date) \
            .all()
        s.close()
        if len(trade_list) > 0:
            total_amount = Decimal(0)
            target_amount = Decimal(0)
            for i in trade_list:  # type: TsDailyTradeInfo
                total_amount += i.amount
                if i.ts_code in share_code_list:
                    target_amount += i.amount

            val = float(decimal_utils.div(target_amount, total_amount))
            history_percent = get_history_high_percent(history_avl, val)

            history_avl.add(val)
            result_list.append(
                MqIndexTradeAmount(index_code=index_code,
                                   index_name=index_name,
                                   trade_date=from_date,
                                   amount=target_amount,
                                   percent=val,
                                   history_high_ratio=history_percent))
        from_date = date_utils.format_delta(from_date, 1)
        if len(result_list) >= 1000:
            db_client.batch_insert(result_list)
            result_list = []
    db_client.batch_insert(result_list)
コード例 #7
0
def cal_top_amount_share(to_date: str = date_utils.get_current_dt()):
    from_date = get_from_date(mq_index.top_amount_code)
    history_avl = get_history_percent(mq_index.top_amount_code, from_date)

    result_list = []
    while from_date <= to_date:
        log.info('Calculating %s %s %s' %
                 (MqIndexTradeAmount.__tablename__, mq_index.top_amount_code,
                  from_date))
        s: Session = db_client.get_session()
        trade_list = s.query(TsDailyTradeInfo) \
            .filter(TsDailyTradeInfo.trade_date == from_date) \
            .order_by(TsDailyTradeInfo.amount.desc()) \
            .all()
        s.close()
        if len(trade_list) > 0:
            top_to_count = math.floor(len(trade_list) * 0.05)
            total_amount = Decimal(0)
            top_amount = Decimal(0)
            for i in range(len(trade_list)):
                total_amount += trade_list[i].amount
                if i <= top_to_count:
                    top_amount += trade_list[i].amount

            val = float(decimal_utils.div(top_amount, total_amount))
            history_percent = get_history_high_percent(history_avl, val)

            history_avl.add(val)
            result_list.append(
                MqIndexTradeAmount(index_code=mq_index.top_amount_code,
                                   index_name=mq_index.top_amount_name,
                                   trade_date=from_date,
                                   amount=top_amount,
                                   percent=val,
                                   history_high_ratio=history_percent))
        from_date = date_utils.format_delta(from_date, 1)
        if len(result_list) >= 1000:
            db_client.batch_insert(result_list)
            result_list = []
    db_client.batch_insert(result_list)
コード例 #8
0
    def __init__(self, ts_code: str, trade_date: str, is_trade: int,
                 adj_type: str, adj: decimal, latest_adj: decimal,
                 open_price: decimal, high: decimal, low: decimal,
                 close: decimal, up_limit: decimal, down_limit: decimal,
                 pre_close: decimal):
        factor = 1
        if adj_type == 'qfq' and not decimal_utils.equals(adj, latest_adj):
            factor = decimal_utils.div(adj, latest_adj)
        elif adj_type == 'hfq':
            factor = adj

        self.ts_code = ts_code
        self.trade_date = trade_date
        self.is_trade = is_trade
        self.adj_type = adj_type
        self.adj = adj
        self.latest_adj = latest_adj
        self.open = decimal_utils.mul(open_price, factor)
        self.high = decimal_utils.mul(high, factor)
        self.low = decimal_utils.mul(low, factor)
        self.close = decimal_utils.mul(close, factor)
        self.up_limit = decimal_utils.mul(up_limit, factor)
        self.down_limit = decimal_utils.mul(down_limit, factor)
        self.pre_close = decimal_utils.mul(pre_close, factor)
コード例 #9
0
ファイル: cal_val.py プロジェクト: SYSU-Momojie/MoQuant
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]