请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3364707 新帖:28

开源工具系列-杜邦分析生成器

蜡笔小新炒外汇发表于:5 月 9 日 23:10回复(1)

开源工具系列-杜邦分析生成器

此文的算法脱胎于《唐朝. 手把手教你读财报:财报是用来排除企业的 》

author: aaron-clark-aic
这货的其他文章目录

杜邦分析法(DuPont Analysis)是利用几种主要的财务比率之间的关系来综合地分析企业的财务状况。具体来说,它是一种用来评价公司赢利能力和股东权益回报水平,从财务角度评价企业绩效的一种经典方法。其基本思想是将企业净资产收益率逐级分解为多项财务比率乘积,这样有助于深入分析比较企业经营业绩。由于这种分析方法最早由美国杜邦公司使用,故名杜邦分析法。

安全性分析

所谓安全性,指 企业 能否在需要的时候及时偿还短期债务。短期债务在财报里的名字叫“ 流动负债”,是企业 在一年内或一个营业周期内需要偿付的债务。企业能够用以偿还流动债务的资产是流动资产。因此,安全性分析主要是观察流动资产与流动负债之间的关系,常见指标有两种,即流动比率和速动比率。

=÷=÷

1548391622746.png

教科书一般认为流动比率在2左右,速动比率在1左右,属于企业比较理想的状态。比率过高,说明流动资产未能有效利用,太低说明企业有短期偿债风险。

盈利能力分析

对于盈利 能力,老唐习惯从两个角度去看。一个是从营业收入的角度,即每单位的营业收入有多少可以转化为利润;另一个是从资产角度看,即每单位股东投入加上所借有息负债能产生多少利润。从收入角度看盈利 能力,投资者要关注营业利润率、毛利率和净利率。其中尤以营业利润率最为重要。

=??÷

1548392093495.png

成长性分析

企业的成长性,同样可以从收入和资产两个角度看。从收入角度看,重点看营业收入增长率和营业利润增长率;从资产角度看,重点看总资产增长率和净资产增长率。

=?÷=?÷

1548392542593.png

净利润并不是公司挣到的钱

企业缴纳了所得税后,便是公司净利润了。关于净利润,老唐强调一点:净利润 ≠ 挣到钱,两者可以有很大差别。净利润一定要和现金流量表的“ 经营现金流净额” 对照着看,投资者可以直接用

÷

来衡量净利润的含金量。该比值连续数年大于1,发现“ 印钞机” 概率就大;反之,连续数年远小于1,则需要投资者提高警惕,并挖掘原因。

1548392890940.png

费用率

费用一般习惯性被称为“ 三 费”,包括销售费用、管理费用和财务费用。费用率则指费用占营业总收入的比。 老唐个人看 费用率的时候,会采用保守一点的策略,单独考虑财务费用。如果利润表财务费用是正数(利息 收支相抵后,是净支出),就把它和销售、管理费用加总一起算费用率;如果财务费用是负数( 利息收入相抵后,是净收入),就只用

÷

计算费用率。

费用率也是用来排除企业的。

任何一家企业运营过程中,必然要产生费用。投资人看费用率,是要警惕费用率高的公司和费用率剧烈变化的 公司。

1548393254402.png

毛利率

营业收入减去营业成本是毛利润,它是企业利润的源头。毛利润在营业收入中所占比例是毛利率。

一般来说,老唐建议投资者选择高毛利率的企业。巴菲特说过:“我并不试图超过七英尺高的栏杆,我到处找的是我能跨过的一英尺高的栏杆。”投资不是竞技,投资者追求的不是克服困难的快感,而是稳定轻松的获利。

股神尚且如此,我们又何必跟自己的资本过不去呢?躲开低毛利率的企业,会使失败概率大大降低,这是利润表的重要用途之一。多低算低呢?一般来说,毛利率能保持在40%以上的企业,通常都具有某种持续竞争优势。A股中毛利率比较高的行业有信息技术、医药生物、食品饮料、餐饮旅游、文化传播、房地产等,基本也是牛股集中营;毛利率在40%以下的,企业通常处于高度竞争的环境中;至于毛利率低于20%的企业,老唐建议留给艺高胆大的高手或该行业专业人士吧。以上都是个人经验,仅供参考。

1548395489953.png

企业现金流肖像

1548393793049.png

类型 1:“ ” 型:

类型1代表的含义是经营活动现金为净流入,投资活动现金流为净流入,筹资活动现金为净流入。企业日进斗金,钞票滚滚而来。你喜欢这样的企业吗?喜欢!喜欢?等等,好像有什么地方不对劲儿,企业经营挣钱,又不向外投资,你干嘛要筹资?堆积一堆钞票数着玩?事反必妖,老唐把这一类型的企业归类为妖精型。这一类型要么是即将展开大规模的对内对外投资活动,正筹本钱;要么可能是起了鬼心思,借着上市公司躯壳搞钱,搞来后再将资金转给关联企业或关联人使用。如果是前者,那实际上只是类型3的序曲,可参照下述类型3的关注要点。如果你遍查资料,也没发现企业即将进行什么大规模的投资,呵呵,还是远离比较稳当。

类型 2:“ -” 型:

类型2中,经营活动现金流入,投资活动现金流入,筹资活动现金流出。经营活动现金流入,说明企业经营活动正常、良性,有钱挣。投资活动现金流入,就要分两种情况了,一种是以前投资的股利或利息收入,另一种是变卖家当。通常来说,是前者的可能性大。一家经营良好的企业,通常不会被迫秦琼卖马。筹资活动现金流出,说明企业要么在还债,要么是回报股东(分红或回购股票)。总体来说,如果投资现金不是变卖家当所得,且经营现金流入和投资现金流入足以覆盖筹资现金流出,投资者可以初步认定这是一家健康发展的企业。企业通过经营以及之前的投资,现在处于收获期,能够有多余的现金来归还借款或回报股东。需要投资者注意的是,投资活动现金净流入,显示企业已经不再继续扩张了,成长已是过去式。企业近似一只稳定产生现金的债券,如同一只定时定量产蛋的老母鸡。只要售价不高(低市盈率)、产蛋率不错(高股息率),这种老母鸡型企业,你值得拥有。

类型 3:“ - ” 型

类型3:“ - ”型类型3中,经营活动现金流入,投资活动现金流出,筹资活动现金流入。很明显,这家企业把经营活动挣的钱,加上借债或出让股权筹来的钱,一起投入新项目中去了。企业扩张的急切之心昭然若揭,如同一只勇往直前的蛮牛。所投项目如果创造辉煌,企业可能高速增长。反之,如果投资项目失败或与期望值差距较大,投资者的失望情绪可能会严重打压公司市值。这类蛮牛型企业,投资项目前景究竟如何,是投资者必须首先要考虑的因素。

类型 4:“ --” 型

类型4中,经营活动现金流入,投资活动现金流出,筹资活动现金流出。经营现金流入表明企业经营正常;投资现金流出表明企业正在扩张;筹资现金流出表明企业还债或回报股东。也就是说,企业靠着经营现金流入,实施投资并同时清偿债务或回报股东。这种企业怎么样,不错吧?当然不错,如果可以持续的话。

所以,对于“ --”奶牛型企业,关键是看经营活动现金流入量,减去投资活动现金流出,再减去不包括分红在内的筹资活动现金流出,差值是正是负。如果为正,恭喜你,可能发现一头优质成长奶牛。如果为负,企业随时可能变身“ - ”的蛮牛型企业,投资者可以参照蛮牛型企业关注事项。

1548395172023.png

import numpy as np
import datetime
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import math
#处理股票代码
class Stocks:

    def combineIdustryStocks(self,industries:list):
        return  np.hstack([ jq.get_industry_stocks(i)  for i in industries])

    def standardStocks(self,stockList):
        _stocks = list(get_all_securities('stock').index)
        _standardStocks = []
        for i in stockList:
            _standardStocks =_standardStocks+[code for code in _stocks if code.upper().startswith(i)]
        return _standardStocks
#生成查询年限
class YearsReports:
    def __init__(self,yearNum = 6):
        self.__today__ = datetime.date.today()
        self.__toyear__ = datetime.datetime(self.__today__.year,1,1)
        self.__yearNum__ = yearNum
        
    def Year(self):
        i =  self.__yearNum__
        out = []
        while i>0:
            out.append(self.__toyear__.year - i)
            i = i-1
        return out
#生成报告
class TargetStock:
    
    def setYearsReport(self,years,stock):
        list =[]
        # print(seasonDaily)
        for _year in years:
            jqv = valuation
            df = get_fundamentals(query(jqv.code,valuation.circulating_cap,valuation.capitalization,valuation.income.net_profit,jqv.market_cap,jq.balance.fixed_assets,jq.indicator.eps
                                              ).filter(valuation.code == stock
                                                       ).order_by(
                                                                  ),statDate = _year
                                    )
            if not df.empty:
                list.append([
                    ('net_profit',df['net_profit'][0]),
                    ('circulating_cap',df['circulating_cap'][0]),
                    ('capitalization',df['capitalization'][0]),
                    ('seasonReport',_season),
                    ('fixed_assets'+_season,df['fixed_assets'][0]),
                    ('eps',df['eps'][0])
                    ])
        return list

    def plt_operating_rate(self,stock,nYears ):
        '''
        看利润表, 最重要就是看营业利润和营业利润率(营业利润率=营业利润÷营业总收入)。
        看营业利润及营业利润率的历史变化趋势,以及与同行业其他公司进行对比。她若安好,便是晴天。
        '''
        arr = ReportAnalysis.targetStocksReport ([stock],nYears)       
        for stock in arr:
            x = []
            y = []
            y1 = []
            for i in stock["operating_rate"]:
                x.append (i[2])
                y1.append (i[1])
                y.append (i[0])
            title = '营业利润率=营业利润÷营业总收入'
            return  (title,x,y,y1)

    def plt_operate_cash_flow_rate(self,stock, nYears):
        '''
        经营现金流净额/净利润 >1   排查企业是否优质
        '''
        arr = ReportAnalysis.targetStocksReport ([stock], nYears)
        for stock in arr:
            x = []
            y = []
            for i in stock["operate_cash_rate"]:
                x.append (i[1])
                y.append (i[0])
            title ='经营现金流净额/净利润 >1   排查企业是否优质'
            return (title,x,y)

    def plt_expense_rate(self,stock, nYears):
        '''
        费用。如果利润表财务费用是正数(利息收支相抵后,是净支出),就把它和销售、管理费用加总一起算费用率;
        如果财务费用是负数(利息收入相抵后,是净收入),就只用( 销售 费用+管理费用)÷营业总收入计算费用率。
        '''
        arr = ReportAnalysis.targetStocksReport ([stock], nYears)
        for stock in arr:
            x = []
            y = []
            for i in stock["expense_rate"]:
                x.append (i[1])
                y.append (i[0])
            title = '费用率'
            return (title,x,y)

    def plt_rgb_net_cash_flow(self,stock, nYears):
        '''
        1.+++ 妖? 2.++- 母鸡? 3.+-+ 蛮牛? 4.+-- 奶牛? 5.-** 救命啊~
        '''
        arr = ReportAnalysis.targetStocksReport ([stock], nYears)
        for stock in arr:
            x = []
            y = []
            y1 = []
            y2 = []
            for i in stock["net_cash_flow"]:
                x.append (i[3])
                y.append (i[0])
                y1.append (i[1])
                y2.append (i[2])
            title = '+(r)+(g)+(b)妖/++-母鸡/+-+蛮牛/+--奶牛/-**救命啊~'
            return (title,x,y,y1,y2)

    def plt_current_assert_liability_rate(self,stock, nYears):
        '''
        流动 比率= 流动资产 ÷ 流动 负债
        '''
        arr = ReportAnalysis.targetStocksReport ([stock], nYears)
        for stock in arr:
            x = []
            y = []
            for i in stock["current_assert_liability_rate"]:
                x.append (i[1])
                y.append (i[0])
            title ='流动 比率= 流动资产 ÷ 流动 负债'
            return  (title,x,y)

    def plt_gross_profit_margin(self,stock, nYears):
        '''
        销售毛利率(%)  毛利/营业收入
        '''
        arr = ReportAnalysis.targetStocksReport ([stock], nYears)
        for stock in arr:
            x = []
            y = []
            for i in stock["gross_profit_margin"]:
                x.append (i[1])
                y.append (i[0])
            title = '销售毛利率(%)  毛利/营业收入'
            return (title,x,y)

    def plt_inc_operation_and_net_profit_year_on_year(self,stock, nYears):
        '''
        inc_revenue_year_on_year	营业收入同比增长率(%)
        inc_operation_profit_year_on_year	营业利润同比增长率(%)
        '''
        arr = ReportAnalysis.targetStocksReport ([stock], nYears)
        for stock in arr:
            x = []
            y = []
            _y = []
            _y1 = []
            x1 = []
            y1 = []
            for i in stock["inc_operation_profit_year_on_year"]:
                x.append (i[1])
                y.append (i[0])
            w = y[::-1]
            __i = 0
            for _i in w:
                if __i == 0:
                    _y.append (_i)
                    __i = _i
                else:
                    if _i > 0:
                        __i = (0.01 * __i + 0.01 * abs (__i) * 0.01 * abs (_i)) * 100
                    elif _i == 0:
                        pass
                    else:
                        __i = (0.01 * __i - 0.01 * abs (__i) * 0.01 * abs (_i)) * 100
                    _y.append (__i)
            # pl.plot (x, _y[::-1], "r")

            for i in stock["inc_net_profit_year_on_year"]:
                x1.append (i[1])
                y1.append (i[0])
            w1 = y1[::-1]
            __i1 = 0
            for _i1 in w1:
                if __i1 == 0:
                    _y1.append (_i1)
                    __i1 = _i1
                else:
                    # __i1 =  (((1+__i1*0.01)+(1+__i1*0.01)*(_i1*0.01))-1)*100
                    if _i1 > 0:
                        __i1 = (0.01 * __i1 + 0.01 * abs (__i1) * 0.01 * abs (_i1)) * 100
                    elif _i1 == 0:
                        pass
                    else:
                        __i1 = (0.01 * __i1 - 0.01 * abs (__i1) * 0.01 * abs (_i1)) * 100
                    _y1.append (__i1)
            # pl.plot (x1, _y1[::-1], "b")
            title = '营业收入同比增长率(%)[g] 营业利润同比增长率(%)[r]'
            return (title,(x,_y[::-1]),(x1,_y1[::-1]))


    def plotFigure(self,stock,years = 6):
        
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
        plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
        fig = plt.figure (tight_layout=False,figsize=(13, 30))
        gs = gridspec.GridSpec (4, 2)
       
        _sr = YearsReports (yearNum = years)
        _d3 = self.plt_operating_rate([stock],_sr.Year()) 
        ax = fig.add_subplot (gs[0, 0])
        ax.set_xlabel(_d3[0])
        ax.plot(_d3[1],_d3[2],'r')
        ax.plot(_d3[1],_d3[3],'b')

        _d4 = self.plt_operate_cash_flow_rate ([stock], _sr.Year ())
        ax = fig.add_subplot (gs[0, 1])
        ax.set_xlabel (_d4[0])
        ax.plot (_d4[1], _d4[2], 'r')
        _d5 = self.plt_expense_rate ([stock], _sr.Year ())
        ax = fig.add_subplot (gs[1, 0])
        ax.set_xlabel (_d5[0])
        ax.plot (_d5[1], _d5[2], 'r')
        _d6 = self.plt_rgb_net_cash_flow ([stock], _sr.Year ())
        ax = fig.add_subplot (gs[1, 1])
        ax.set_xlabel (_d6[0])
        ax.plot (_d6[1], _d6[2], 'r')
        ax.plot (_d6[1], _d6[3], 'g')
        ax.plot (_d6[1], _d6[4], 'b')
        _d7 = self.plt_current_assert_liability_rate ([stock], _sr.Year ())
        ax = fig.add_subplot (gs[2, 0])
        ax.set_xlabel (_d7[0])
        ax.plot (_d7[1], _d7[2], 'r')
        _d8 = self.plt_gross_profit_margin ([stock], _sr.Year ())
        ax = fig.add_subplot (gs[2, 1])
        ax.set_xlabel (_d8[0])
        ax.plot (_d8[1], _d8[2], 'r')
        _d9 = self.plt_inc_operation_and_net_profit_year_on_year ([stock], _sr.Year ())
        ax = fig.add_subplot (gs[3, 0])
        ax.set_xlabel (_d9[0])
        # print('1-',_d9[1][0])
        ax.plot (_d9[1][0], _d9[1][1], 'g')
        ax.plot (_d9[2][0], _d9[2][1], 'r')
        
        plt.show()
#获取报告内容
class ReportAnalysis:
    
     def targetStocksReport(stocks, nYears):
        report = []
        for stock in stocks:
            operating_rate = []
            operate_cash_rate = []
            expense_rate = []
            operating_revenue_rate = []
            net_cash_flow = []
            current_assert_liability_rate = []
            gross_profit_margin = []
            inc_operation_profit_year_on_year = []
            inc_net_profit_year_on_year = []
            for year in nYears:
                df = get_fundamentals (
                     query (income.total_operating_revenue, income.operating_profit, income.operating_revenue,
                              cash_flow.net_operate_cash_flow, income.net_profit,
                              income.sale_expense, income.administration_expense, income.financial_expense,
                              income.total_operating_revenue,
                              cash_flow.net_finance_cash_flow, cash_flow.net_invest_cash_flow,
                              balance.total_current_assets, balance.total_current_liability,
                              indicator.gross_profit_margin,
                              indicator.inc_operation_profit_year_on_year, indicator.inc_net_profit_year_on_year
                           ).filter (
                        # 这里不能使用 in 操作, 要使用in_()函数
                        valuation.code == stock[0],
                    ).order_by (
                    ), statDate=year)
                if not df.empty:
                    operating_rate.append ([df["operating_profit"][0] / df["total_operating_revenue"][0],
                                            df["operating_profit"][0] / df["operating_revenue"][0], year])
                    operate_cash_rate.append ([df["net_operate_cash_flow"][0] / df["net_profit"][0], year])
                    if df["financial_expense"][0] > 0:
                        # if True:
                        _out_rate = (df["sale_expense"][0] + df["administration_expense"][0] + df["financial_expense"][
                            0]) / df["total_operating_revenue"][0]
                    else:
                        _out_rate = (df["sale_expense"][0] + df["administration_expense"][0]) / \
                                    df["total_operating_revenue"][0]
                    expense_rate.append ([_out_rate, year])

                    operating_revenue_rate.append ([df["operating_profit"][0] / df["total_operating_revenue"][0], year])
                    net_cash_flow.append (
                        [df["net_operate_cash_flow"][0]/1000000, df["net_invest_cash_flow"][0]/1000000, df["net_finance_cash_flow"][0]/1000000,
                         year])
                    current_assert_liability_rate.append (
                        [df["total_current_assets"][0] / df["total_current_liability"][0], year])
                    gross_profit_margin.append ([df["gross_profit_margin"][0], year])
                    inc_operation_profit_year_on_year.append ([df["inc_operation_profit_year_on_year"][0], year])
                    inc_net_profit_year_on_year.append ([df["inc_net_profit_year_on_year"][0], year])
                    report.append ({'stock': stock, 'operating_rate': operating_rate, 'operate_cash_rate': operate_cash_rate,
                            "expense_rate": expense_rate, "net_cash_flow": net_cash_flow,
                            'current_assert_liability_rate': current_assert_liability_rate,
                            "gross_profit_margin": gross_profit_margin,
                            "inc_operation_profit_year_on_year": inc_operation_profit_year_on_year,
                            "inc_net_profit_year_on_year": inc_net_profit_year_on_year})
        return report
_st = Stocks()
_as = TargetStock()
#参数1 股票原始代码 
#参数2 计算年限 
_as.plotFigure(stock=_st.standardStocks(stockList=['000915'])[0],years=10)
 

全部回复

0/140

量化课程

    移动端课程