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)
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 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 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))
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 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)
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)
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)
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]