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)
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]
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
def add_nx(ts_code: str, report_type: int, period: str, update_date: str, name: str, value: Decimal, result_list: list, store: mq_daily_store.MqDailyStore): if value is None: return exist = store.find_date_exact(ts_code, name, period) if exist is not None: return to_add = MqDailyMetric(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)
def add_trade_status( result_list: dict(type=list, help="需要插入结果的列表"), store: dict(type=mq_daily_store.MqDailyStore, help="日指标存放"), ts_code: dict(type=str, help="股票编码"), now_date: dict(type=str, help="日期"), is_suspend: dict(type=int, help="是否停牌")): """ 记录这天是否停牌 """ to_add = MqDailyMetric(ts_code=ts_code, report_type=mq_report_type.none_report_type, period='-', update_date=now_date, name=mq_daily_metric_enum.suspend.name, value=is_suspend) common_add(result_list, store, to_add)
def copy_for_suspend( result_list: dict(type=list, help="需要插入结果的列表"), store: dict(type=mq_daily_store.MqDailyStore, help="日指标存放"), ts_code: dict(type=str, help="股票编码"), now_date: dict(type=str, help="日期")): """ 针对停牌日,从上一个交易日复制 """ for i in mq_daily_metric_enum.copy_for_suspend: now = store.find_date_exact(ts_code, i.name, now_date) if now is not None: continue yesterday = store.find_latest(ts_code, i.name, now_date) if yesterday is None: log.error('Cant find latest daily data of %s %s to copy for non-trade-day' % (ts_code, now_date)) else: to_add = MqDailyMetric(ts_code=yesterday.ts_code, report_type=yesterday.report_type, period=yesterday.period, update_date=now_date, name=yesterday.name, value=yesterday.value) common_add(result_list, store, to_add)
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]
def find_latest(self, ts_code: str, name: str, update_date: str) -> MqDailyMetric: tree = self.get_tree(ts_code, name) max_to_find = MqDailyMetric(update_date=update_date) target = tree.find_max_under(max_to_find) return self.val(target)