def __get_filter(self, filter: str): if filter == 'g': from stockpy.filter.goose import gooseFilter return gooseFilter() elif filter == 'a': return expr.Eq(expr.Value(1), expr.Value(1)) from stockpy.filter import horse return horse.horseFilter()
def eval(self, ts_code: str, year: int, quarter: int, path: str, report='w'): '''Evalute the value of a stock. Args: ts_code: stock code year: report year quarter: report quarter path: the path to be report: report type. w=white horse.default is w. ''' db = StockDb(**self.__cfg) stocks = db.list() filter = expr.Eq(expr.Get('i_ts_code'), expr.Value(ts_code)) if ts_code is None: filter = expr.Eq(expr.Value(1), expr.Value(1)) selected = stocks.query_by_basic_info(filter) Report = self.__get_report(report) def do_report(stock, y, q): try: print(stock['ts_code'], stock['name'], 'to_excel') report = Report(stock) report.eval(year, quarter) report.to_excel( f'{path}/{stock["ts_code"]}_{stock["name"]}_{year}_{quarter}.xlsx') return report except Exception as e: print(stock['ts_code'], stock['name'], e) fs = [] for stock in selected: with concurrent.futures.ThreadPoolExecutor() as executor: fs.append( { 'r': executor.submit(do_report, stock, year, quarter), 'ts_code': stock['ts_code'], 'name': stock['name'], }) for stock in fs: try: report = stock['r'].result() if report is None: continue print(stock['ts_code'], stock['name'], 'to_chart') report.to_chart( f'{path}/{stock["ts_code"]}_{stock["name"]}_{year}_{quarter}.pdf', f'{stock["ts_code"]} {stock["name"]} {year}年{quarter}季' ) except Exception as e: print(e)
def run(y, q): rm = expr.Range(expr.Before(expr.Get('f_roe_y'), past_year=1), year_count=6) nm = self.roe_ge_15_pct_now() v = rm.eval(self.stock, y, 4) v2 = expr.Ge(rm, expr.Value(0.15)).eval(self.stock, y, 4) print('last 6 years', v, v2) v3 = nm.eval(self.stock, y, q) print('current', v3, expr.Get('f_roe').eval(self.stock, y, q)) v4 = expr.And(expr.Ge(rm, expr.Value(0.15)), nm).eval(self.stock, y, q) print('last 7 years', v4)
def days_adv_receipts_y(): '''预收账款周转天数''' return MetricsMeta('f_days_adv_receipts_y', expr.Div( expr.Multi(expr.Get('f_adv_receipts_ave_y'), expr.Value(360)), expr.Get('revenue', period='y')), display='预收账款周转天数')
def days_prepayment_y(): '''预付账款周转天数''' return MetricsMeta('f_days_prepayment_y', expr.Div( expr.Multi(expr.Get('f_prepayment_ave_y'), expr.Value(360)), expr.Get('oper_cost', period='y')), display='预付账款周转天数')
def days_inventory_y(): '''存货周转天数''' return MetricsMeta('f_days_inventory_y', expr.Div( expr.Multi(expr.Get('f_inventory_ave_y'), expr.Value(360)), expr.Get('oper_cost', period='y')), display='存货周转天数')
def moat_factor(c: int): ''' 护城河等级系数 -1 负 0 无 1 弱 2 强 ''' return expr.Value(c)
def gross_profit_ratio(): '''毛利率%''' return MetricsMeta('f_gross_profit.r', expr.Sub( expr.Value(1), expr.Div(expr.Get('oper_cost'), expr.Get('revenue'))), display='毛利率')
def prepayment_ave_y(): '''平均预付账款''' return MetricsMeta( 'f_prepayment_ave_y', expr.Div( expr.Sum( expr.Get('prepayment', period='y'), expr.Before(expr.Get('prepayment', period='y'), past_year=1)), expr.Value(2)))
def inventroy_ave_y(): '''平均存货''' return MetricsMeta( 'f_inventory_ave_y', expr.Div( expr.Sum( expr.Get('inventories', period='y'), expr.Before(expr.Get('inventories', period='y'), past_year=1)), expr.Value(2)))
def days_acct_payable_y(): '''应付账款周转天数''' return MetricsMeta('f_days_acct_payable_y', expr.Div( expr.Multi(expr.Get('f_acct_payable_ave_y'), expr.Value(360)), expr.Sub(expr.Get('oper_cost', period='y'), expr.Get('inventories', period='y'))), display='应付账款周转天数')
def adv_receipts_ave_y(): '''平均预收账款''' return MetricsMeta( 'f_adv_receipts_ave_y', expr.Div( expr.Sum( expr.Get('adv_receipts', period='y'), expr.Before(expr.Get('adv_receipts', period='y'), past_year=1)), expr.Value(2)))
def market_cap(base: int, moat: int): ''' 估算总市值 = 净资产 * (1+滚动roe) ^ (基本因子+护城河因子+成长因子) ''' return expr.Multi(expr.Get('total_hldr_eqy_exc_min_int'), expr.Power(expr.Sum(expr.Value(1), expr.Get('f_roe_ttm')), expr.Sum(base_factor(base), moat_factor(moat), growth_factor())))
def acct_payable_ave_y(): '''平均应付账款''' return MetricsMeta( 'f_acct_payable_ave_y', expr.Div( expr.Sum( expr.Get('acct_payable', period='y'), expr.Get('notes_payable', period='y'), expr.Before(expr.Get('acct_payable', period='y'), past_year=1), expr.Before(expr.Get('notes_payable', period='y'), past_year=1)), expr.Value(2)))
def accounts_receiv_ave_y(): '''平均应收账款''' return MetricsMeta( 'f_accounts_receiv_ave_y', expr.Div( expr.Sum( expr.Get('accounts_receiv', period='y'), expr.Before(expr.Get('accounts_receiv', period='y'), past_year=1), expr.Get('notes_receiv', period='y'), expr.Before(expr.Get('notes_receiv', period='y'), past_year=1)), expr.Value(2)))
def show(self, ts_code: str, year: int, quarter: int, metrics: []): db = StockDb(**self.__cfg) stocks = db.list() filter = expr.Eq(expr.Get('i_ts_code'), expr.Value(ts_code)) selected = stocks.query_by_basic_info(filter) stock = selected[0] Report = self.__get_metrics_report() report = Report(stock) report.set_metrics(metrics) report.eval(year, quarter) report.show(f'{stock["ts_code"]}({stock["name"]})')
def roe(): ''' 年度ROE(平均) =净利润/净资产 =归母净利润/(期初+期末归母净资产)/2 =每股净利润/每股净资产 =销售净利率*总资产周转率*杠杆系数 ''' return MetricsMeta( 'f_roe', expr.Div( expr.Get('n_income_attr_p'), expr.Div( expr.Sum( expr.Get('total_hldr_eqy_exc_min_int'), expr.Get('total_hldr_eqy_exc_min_int', period_begin=True)), expr.Value(2))))
def growth_factor(): ''' 成长等级系数,最近5年同比增长率 -1 负增长, 净利润同比 < 5% 1 慢速增长, 5 <= 净利润同比 <= 20% 2 快速增长,净利润同比 > 20% ''' income_attr_p_y = expr.Range( expr.Get('f_income_attr_p_y.r_y2y'), year_count=5) return expr.Switch( expr.Case( expr.Gt(income_attr_p_y, expr.Value(0.2)), expr.Value(2)), expr.Case( expr.Ge(income_attr_p_y, expr.Value(0.05)), expr.Value(1)), expr.Case( expr.Le(income_attr_p_y, expr.Value(0.05)), expr.Value(-1)), default=expr.Value(0))
def current_y_gt_1_3_years(): return expr.Or( expr.And( expr.Gt(expr.Get('f_current_y.r'), expr.Value(1)), expr.Gt(expr.Before(expr.Get('f_current_y.r'), past_year=1), expr.Value(1))), expr.And( expr.Gt(expr.Before(expr.Get('f_current_y.r'), past_year=1), expr.Value(1)), expr.Gt(expr.Before(expr.Get('f_current_y.r'), past_year=2), expr.Value(1))), expr.And( expr.Gt(expr.Before(expr.Get('f_current_y.r'), past_year=2), expr.Value(1)), expr.Gt(expr.Before(expr.Get('f_current_y.r'), past_year=3), expr.Value(1))))
def roe_ttm(): ''' 年度ROE(加权平均) 根据中国证监会发布的《公开发行证券公司信息披露编报规则》第9号的通知的规定:加权平均净资产收益率(ROE)的计算公式如下:ROE= P/(E0 + NP÷2 + Ei×Mi÷M0 - Ej×Mj÷M0) 其中: P为报告期利润; NP为报告期净利润; E0为期初净资产; Ei为报告期发行新股或债转股等新增净资产; Ej为报告期回购或现金分红等减少净资产; M0为报告期月份数; Mi为新增净资产下一月份起至报告期期末的月份数; Mj为减少净资产下一月份起至报告期期末的月份数。 ''' return MetricsMeta('f_roe_ttm', expr.Div( expr.Get('f_income_attr_p_ttm'), expr.Div( expr.Sum( expr.Get('total_hldr_eqy_exc_min_int'), expr.Before( expr.Get('total_hldr_eqy_exc_min_int'), past_quarter=4)), expr.Value(2))), display='ROE(滚动)')
def eq_ts_code(ts_code: str): return expr.Eq(expr.Get('i_ts_code'), expr.Value(ts_code))
def test_crawl(self): filter = expr.Eq(expr.Get('i_ts_code'), expr.Value('688399.SH')) # filter = expr.Eq(expr.Get('i_ts_code'), expr.Value('000001.SZ')) ts = self.stocks.query_by_basic_info(filter) crawler = Crawler() crawler.crawl(ts, 2019, 2018)
def revenue_r_gt_0(): return expr.And(expr.Gt(last_year_f_revenue_y_r_y2y(), expr.Value(0)), expr.Gt(last_quarter_f_revenue_q_r_y2y(), expr.Value(0)))
def income_attr_p_r_gt_0(): return expr.And( expr.Gt(last_year_f_income_attr_p_y_r_y2y(), expr.Value(0)), expr.Gt(last_quarter_f_income_attr_p_q_r_y2y(), expr.Value(0)))
def roe_ge_15_pct_before_6_years(): return expr.Ge( expr.Range(expr.Before(expr.Get('f_roe_y'), past_year=1), year_count=6), expr.Value(0.15))
def premium_rate(): '''溢价率''' return expr.Value(1)
def safety_factor(): '''安全边际系数 50%到90% ''' return expr.Value(0.9)
def base_factor(c: int): ''' 基本因子 ''' return expr.Value(c)