<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Liang的风险平价观</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://www.keepswalking.com/"/>
  <updated>2020-11-03T08:01:28.927Z</updated>
  <id>https://www.keepswalking.com/</id>
  
  <author>
    <name>Liang</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>screen（筛选器）之三 -- aggregate z-score 权重优化</title>
    <link href="https://www.keepswalking.com/2020/10/26/screen-optimal-weight-for-aggregate-z-score/"/>
    <id>https://www.keepswalking.com/2020/10/26/screen-optimal-weight-for-aggregate-z-score/</id>
    <published>2020-10-26T09:37:46.000Z</published>
    <updated>2020-11-03T08:01:28.927Z</updated>
    
    <content type="html"><![CDATA[<p>上篇<a href="/2020/09/30/screening-improvement/" title="screen（股票筛选器）之二 -- 回测，没有全面调查就没有伤害">screen（股票筛选器）之二 -- 回测，没有全面调查就没有伤害</a> 解决了回测过程中碰到的种种陷阱，并对原来在构建portfolio时使用等权重的方式进行优化，给出了一个基于股票流通市值为基础可灵活设置的权重分配方式。经过修改后的策略已经可以获得不错的收益。</p><a id="more"></a><p>本篇主要目标是对另一个参数—aggregate z-score的权重进行优化。回顾本系列的第一篇<a href="/2020/09/23/screening-in-practice/" title="一个基于价值的screen（筛选器） -- 大概是最简单的量化投资">一个基于价值的screen（筛选器） -- 大概是最简单的量化投资</a>，在里面我们使用下面8个因子（factor）：</p><ul><li>Price<ul><li>EV / EBIT</li></ul></li><li>Risk<ul><li>book debt-to-equity ratio</li><li>Change in book D/E</li><li>ACCRUAL = (NI-CFO)/TA</li></ul></li><li>Growth<ul><li>Revenue growth</li><li>M3M = 3-Month price change</li></ul></li><li>Quality<ul><li>ROIC</li><li>Change in ROIC</li></ul></li></ul><p>并分别计算这8个因子的z-score，在计算aggregate z-score的时候，使用等权重的方式，即简单地将这8个z-score加总。在文中也提到，这种方式的好处就是简单，也不用担心overfitting。但一个很明显的问题是它忽略了数据内部隐藏的信息，即每个因子的z-score在预测股票收益时重要性是不一样的，并且还忽略了不同因子之间存在的相关性（correlation）。那么，肯定还是有一种更好的方法来组合这些z-score，使得最后生成的portfolio能更优。</p><h2 id="Panel-Regression"><a href="#Panel-Regression" class="headerlink" title="Panel Regression"></a>Panel Regression</h2><p>一种比较常见的优化方法是通过线性回归对权重进行优化，具体来说就是投资组合的管理者收集对应股票收益的时间序列，例如月度收益，再结合相关因子在每月初的z-score，然后在数据样本的时间区间（period）内运行截面回归（cross-sectional regression），也就是面板数据回归（panel regression），从而获得最优的z-score权重。</p><p>举例来说，我有5个因子的Z-score，对应的股票池里有300只股票，并且收集了60个月度return。我们可以使用如下公式估计每个z-score对应的敞口（exposure）:</p><script type="math/tex; mode=display">r_{i,t} = \gamma_i + \delta_1z_{i,1,t-1} + \delta_2z_{i,2,t-1}+...+ \delta_kz_{i,k,t-1} + \epsilon_{i,t} \text{其中k=5}</script><p>通过以上这个panel regression可以让我们获得各个因子上Z-score的最佳组合，因为该regression利用了z-score和return的variance-covariance matrix的信息。其中$ \gamma_i$代表了一个常量，$\delta_k$是regression运行后产生的系数（coefficient），用于表示对应的因子对return的贡献程度。$\epsilon_i$ 是error term。$\delta$就是我们需要的各z-score因子的最优组合。</p><p>以上这个Panel regression使用了Fix-Effects模型，参见下文。</p><h3 id="Panel-Regression-简单介绍"><a href="#Panel-Regression-简单介绍" class="headerlink" title="Panel Regression 简单介绍"></a>Panel Regression 简单介绍</h3><p>用于panel regression的数据有2个维度: cross-sectional 加 time-serise，如下图所示。</p><img src="/2020/10/26/screen-optimal-weight-for-aggregate-z-score/panel_data.PNG" class=""><p>Panel Data可以让你控制那些你无法观测的变量例如文化因素或是不同公司之间业务实操上的区别；还包括那些随着时间而改变的变量，但这些变量在不同的实体间则保持稳定（例如：国家的政策，央行的管理，国际间的协议等）。也就是说panel data能解释个体的异质性。</p><p>通过panel data，你可以在不同层次的分析中（例如：学生，学校，区，市）引入对应变量，适用于多层次建模或层级关系建模。</p><p>Panel data在数据收集方面会面临一些问题（例如抽样设计，样本覆盖），对于微观panel会面临无应答的问题，对于宏观panel会有跨国家依赖关系（如：国家间的correlation）</p><p>为何不能直接把panel data直接用linear regression进行处理(Pooled ordinary least squares)。假设我们的模型是：</p><script type="math/tex; mode=display">y_i = \beta_0 + \beta_1x_{i,1} +  \epsilon_i</script><p>为了能是linear regression 输出有效的结果(coefficient) 需要满足如下这些前提：</p><ul><li>Covariates are Exogenous：$\epsilon_i$ 的期望值为0</li><li>Uncorrelated errors：$ Cov(epsilon_i, epsilon_j) = 0 $</li><li>Homoskedastic errors: $ Var(epsilon_i) = \sigma^2 $ 即方差保持稳定</li></ul><p>显然，对于panel data来说，以上每一条几乎都很难满足：</p><ul><li>Covariates are Exogenous：无法满足是因为panel data一般都包含了无法观测到的特征（上文已提及的文化因素等），因此$\epsilon_i$ 的期望值不为0</li><li>Uncorrelated errors：无法满足是因为panel包括了time serise维度，一般会有correltion</li><li>Homoskedastic errors: 如果将panel data混在一起用Pooled ordinary least squares进行处理，显然不同个体的Var很难保持相同</li></ul><p>那么对于panel data 有哪些处理方法？最常用的有以下两种：</p><h4 id="Fixed-effects"><a href="#Fixed-effects" class="headerlink" title="Fixed effects"></a>Fixed effects</h4><p>当你只关心那些会随着时间而改变的变量会对结果产生何种影响的时候，应该使用fixed-effects (FE)。</p><p>FE用来研究在同一个实体内（国家，个人，公司等）预测变量和输出结果之间的关系。每个实体拥有各自的特征，这些特征可能会或不会影响预测变量（例如，作为男性或女性可能对某些问题的看法有所不同；或是某些国家的政治体制可能对贸易或GDP产生影响；或是某家公司的业务实践会对股价产生影响）</p><p>当使用FE时，我们假设实体内的一些特征会影响预测变量、输出结果，或造成预测变量、输出结果的偏差。这实际上是关于实体的错误项（error term）和预测变量之间的相关性的假设背后的原理（对应上文提到的前提条件：Covariates are Exogenous）。FE剔除了那些不随时间改变的特征的影响，使我们能评估预测变量对输出结果的净影响。</p><p>下图显示了FE模型：</p><img src="/2020/10/26/screen-optimal-weight-for-aggregate-z-score/FE_model.PNG" class=""><p>另一个关于FE的重要假设是那些不随时间改变的特征对每个个体来说都是唯一的，不会同其他个体的特征有相关性。每个实体是不同的，因此实体的错误项（error term）和常量（所谓的截距，用来表现个体的特征）不应和其他实体的error term和常量有相关性。如果error term之间有相关性，那么FE就不适用，因为无法用该模型做出准确的推断，而你的模型需要考虑该相关性（可能利用下面所讲的random-effects），这也是Hausman test的原理（用来判断是使用Fixed effects 还是Random effects）</p><p>如果你不清楚上面说了什么，那就记住下面的话：FE剔除了那些不随时间改变的特征的影响，便于我们研究什么因素造成了实体内部的改变。</p><p>简单说一下实现方式：基本思路就是：</p><script type="math/tex; mode=display">y_{i,t} - \bar y_i = (x_{i,t} - \bar x_i)\beta + (c_i - \bar c_i) + (u_{i,t} - \bar u_i)</script><p>也就是dependent variables 和 independent variables在时间维度计算平均值，并在time series的数据中减去该平均值。上式中$c_i$是无法观测到的特征，对于FE 模型来说，$c_i$不随着时间而改变，那么易知$ c_i == \bar c_i $，因此就能将$ c_i $消除。</p><h4 id="Random-effects"><a href="#Random-effects" class="headerlink" title="Random effects"></a>Random effects</h4><p>与FE有所不同，random effects （RE）模型背后的基本原理认为实体间的变动被认为是随机的，并且同independent varialbls不相关。FE和RE最重要的区别是各个无法观测到的影响是否体现了同independent varialbls具有<strong>相关性</strong>的因素，而非这些影响是否是随机的。</p><p>如果你认为不同实体间差异会影响到dependent variable，那么你应该使用RE。</p><p>RE的一个优势是你可以在你的模型里引入不随时间改变的变量（如：性别）。但在FE模型里这些变量会被并入截距（intercept）（注：因为在Panel regression中，不同实体有各自的截距）。</p><p>RE假设实体的错误项（error term）同预测变量之间无相关性。这使得不随时间改变的变量可以作为解释变量（explanatory variables）出现在FE模型里。</p><p>下图显示了RE模型：</p><img src="/2020/10/26/screen-optimal-weight-for-aggregate-z-score/RE_model.PNG" class=""><h2 id="选择时间间隔（time-interval）和时间区间-time-period"><a href="#选择时间间隔（time-interval）和时间区间-time-period" class="headerlink" title="选择时间间隔（time interval）和时间区间(time period)"></a>选择时间间隔（time interval）和时间区间(time period)</h2><p>另外两个相互关联的问题也会影响到数据的质量：</p><ul><li>数据之间的时间间隔该怎么取？</li><li>数据需要覆盖多久时间跨度？</li></ul><p>理想情况下，时间间隔应同你的投资期保持一致（如rebalance的周期）。如果投资组合每月会做一次rebalance，那么就以月度为间隔。如果投资组合每年做一次rebalance，那么就以年度为间隔（其实目的就是为了计算对应间隔下的return）。这么做使得后面的分析变得更为简单。</p><p>然而实际情况可能不是那么简单。例如某些因子同return的关系可能在月度上是稳定的，但是在年度上则不明显。在这种情况下，如果你依旧选择年度时间间隔那显然就不合理，即使你rebalance的频率是以年度为单位。另外，必须小心的一点是：时间间隔也不能取得太小！这会导致预测结果的精度变差。原因其实很简单，越是短期则股价的波动越趋于随机而非由相关因子的敞口决定。</p><p>再来聊一下样本时间区间（sample period）。sample period也会影响预测的精度。如果time period太短，那就会导致其包含的time interval太少，使得预测精度变差。一个常用的原则是样本越多精度越高。然而，如果样本的时间跨度太长，一个潜在的问题是股票的return同因子敞口之间的关系可能发生了改变。不太可能说因子的风险溢价在10年时间里都能保持稳定不变。</p><p>这里提供几条比较实用的经验：</p><ul><li>当使用monthly interval时，样本数据需要包括36至60条time interval，也就是说total time period为3到5年。</li><li>当使用weekly interval时，样本的数量一般需要超过60条，也就是说总的time period会少于3年。</li><li>当使用季度或年度interval时，interval的数量会少很多，而总的time period一般会大于5年</li></ul><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><h3 id="确定time-interval"><a href="#确定time-interval" class="headerlink" title="确定time interval"></a>确定time interval</h3><p>首先确定确定time interval。我的回测使用的是半年做一次调仓。但是，如果用半年作为interval那估计差不多要10年的历史数据甚至更多。我觉得还是用月度做为interval，理由是：长期（半年）的return是由短期（一个月）的return构成的。具体来说，策略中的8个因子在每个月或多或少都发挥着一定的作用。</p><h3 id="确定sample-period"><a href="#确定sample-period" class="headerlink" title="确定sample period"></a>确定sample period</h3><p>接下来，对于sample period来说，使用3年跨度，那么样本中有36组数据。</p><h3 id="如何更新z-score权重"><a href="#如何更新z-score权重" class="headerlink" title="如何更新z-score权重"></a>如何更新z-score权重</h3><p>并且使用滚动更新的策略。具体来说每年更新一次z-score权重。每年有两次调仓，分别在：</p><ul><li>1季报：4月30日以后的第一个交易日。</li><li>3季报： 10月31日以后的第一个交易日。</li></ul><p>这两次调仓将使用<strong>相同</strong>的优化后的z-score权重，因此在每年的4月30获取前3年（36个月）的历史数据，包括每个月月初的8个因子的z-score以及对应该月的return。</p><h3 id="历史数据"><a href="#历史数据" class="headerlink" title="历史数据"></a>历史数据</h3><p>为了方便panel regression的运行，将历史数据导出为csv格式，包括以下各列：</p><ul><li>stock_id，股票代码</li><li>date，日期</li><li>ev_to_ebit_ratio，EV / EBIT</li><li>d_to_e_ratio，book debt-to-equity ratio</li><li>chg_d_e，Change in book D/E</li><li>accrual，(NI-CFO)/TA</li><li>revenue_growth，Revenue growth</li><li>m3m，3-Month price change</li><li>roic，return on invested capital</li><li>roic_change，Change in ROIC</li><li>return，interval return</li></ul><h3 id="测试结果"><a href="#测试结果" class="headerlink" title="测试结果"></a>测试结果</h3><p>结果同我的预期有相当大的差距。。。</p><p>我使用R的plm包，运行fixed-effects model，历史数据使用了2017到2020年这3年的monthly return，获得如下结果：</p><img src="/2020/10/26/screen-optimal-weight-for-aggregate-z-score/result_1.PNG" class=""><p>R-Squared=0.0073986，相当于说这些特征同return之间几乎没有相关性，吐血了。。。另外有几个特征对结果的影响同预期正好相反：</p><ul><li>accrual， 预期他应该对return产生负面影响，因为accural越大说明公司在财务方面存在潜在问题的可能性越大，那对应的return应该下降。但是，结果显示accrual的beta为正，虽然t值不显著。</li><li>revenue_growth，预期应该对return产生正面影响，因为收入增速提高对应return升高。但结果显示beta为负，而且显著！</li><li>m3m，这是一个动量特征，预期应该是同return正相关。但是结果显示为负，且显著！</li><li>roic，这个代表了公司的质地，应该同return正相关。但是结果显示为负，且显著！</li></ul><p>我还使用了5年quarterly return做了测试，结果也差不多。</p><p>注视了上面的结果良久之后，我想到一个问题，就是特征对应的值都经过normalize的处理，也就是转换成了z-score，但是，这个转换是在cross-sectinoal的维度进行的，因此在不同的时点，相同的特征就没有了可比性，例如，roic从t1到t2是增长的，但是因为在t1和t2分别对roic计算了z-score，因此，这个增长的趋势可能就被消除了。我重新用raw data（未经normalize处理）跑了panel regression，结果参见下图：</p><img src="/2020/10/26/screen-optimal-weight-for-aggregate-z-score/result_2.PNG" class=""><p>从r-squared角度来看依旧没有什么大的改变。</p><h2 id="总结-amp-思考"><a href="#总结-amp-思考" class="headerlink" title="总结&amp;思考"></a>总结&amp;思考</h2><p>还是要本着实事求是的精神对测试结果进行总结吧。首先，利用panel regression对z-score权重进行优化理论上可行，但实际应用过程中可能无法得到确定性的结果。比如本篇得到的结果就无法应用，因为甚至连特征和收益的相关性都出现了同预期相反的情况。</p><p>个人觉得这些特征都符合economic sense，我的预期是panel regression产生的结果应该有一个比较高的r-squared，至少也应该有个10%吧。但是实际市场表现取同预期产生了矛盾。那是什么原因，接下来该怎么办？</p><ul><li>r-squared几乎是0说明这些feature对return没有产生什么实质性的影响。那么会是什么原因呢？是因为3年的period太短，需要从更长的周期来看（unlikely）？还是这些feature选择有问题，或是中国市场有自己的特性？还是我的panel regression设计上出了问题？这需要进一步的分析研究，但我目前还没啥好的想法。</li><li>接下来该怎么办？我个人觉得这些feature是符合economic sense。但是，panel regression并不支持我的观点。在这种情况下，我会<strong>保留等权重的aggregate z-score</strong>，同时需要更多的人工干预，或者说，不能完全依赖模型给出的结果。以模型给出的结果为基础，接下来需要人工筛选，比如对财报和行业进行做更深入的分析以获得最终的入围标的。</li></ul><p>我个人觉得量化投资还是要基于道理上说得通，也就是符合economic sense。在出现矛盾的时候，比如量化跑出了好的结果但是无法给出合理的解释，或是符合economic sense但却无法获得预期的return，我会偏向选择符合economic sense这一边。当然，随着自己在知识和经验上不断地积累，以前觉得没道理的事情可能就变得有道理了，反之亦然。一定是一个不断迭代不断自我否定的过程。</p><p>最近写了很多代码，也做了很多的测试。感觉基础方面的工作已经七七八八基本就绪了，包括：</p><ul><li>如何计算市场的expected risk premium：<a href="/2020/09/04/cn-market-implied-RP-with-FCFE/" title="基于FCFE重新计算中国市场隐含风险溢价">基于FCFE重新计算中国市场隐含风险溢价</a>，用于计算股票的discount rate</li><li>如何使用bottom-up beta：<a href="/2020/08/27/ten-question-about-bottom-up-betas/" title="关于自底向上贝塔(bottom-up beta)的10个常见问题">关于自底向上贝塔(bottom-up beta)的10个常见问题</a>，用于确定个股的beta</li><li>如何确定DCF的永续增长率g：<a href="/2020/10/21/rf-gdp-and-g/" title="无风险利率，GDP增速以及DCF中的永续增长率g">无风险利率，GDP增速以及DCF中的永续增长率g</a>，用来对股票进行估值时确定terminal value</li><li>如何估计市场总体风险：<a href="/2020/10/16/a-simple-way-to-evaluate-the-market/" title="一个简单的衡量股市估值高低的方法">一个简单的衡量股市估值高低的方法</a>，用于确定投资组合的风险敞口</li><li>设计了一个基于价值投资风格的screen：<a href="/2020/09/23/screening-in-practice/" title="一个基于价值的screen（筛选器）">一个基于价值的screen（筛选器）</a>，用来获得备选股票</li></ul><p>除了以上这些，我还打算加入外资跟踪策略和超跌策略。因此，一个股票主动投资系统基本搭建起来了。接下来就是不断实践和总结了。我打算每周定期更新相关的数据。并在雪球上建两个组合。一个是纯量化策略基于本文讨论的screen，没有人工干预。另外一个是主动投资组合，基于这个screen但会加入自己的分析和判断。因此，接下来的主要工作就是拼命看公司了。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;上篇&lt;a href=&quot;/2020/09/30/screening-improvement/&quot; title=&quot;screen（股票筛选器）之二 -- 回测，没有全面调查就没有伤害&quot;&gt;screen（股票筛选器）之二 -- 回测，没有全面调查就没有伤害&lt;/a&gt; 解决了回测过程中碰到的种种陷阱，并对原来在构建portfolio时使用等权重的方式进行优化，给出了一个基于股票流通市值为基础可灵活设置的权重分配方式。经过修改后的策略已经可以获得不错的收益。&lt;/p&gt;
    
    </summary>
    
    
      <category term="量化投资组合管理" scheme="https://www.keepswalking.com/categories/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%BB%84%E5%90%88%E7%AE%A1%E7%90%86/"/>
    
    
  </entry>
  
  <entry>
    <title>无风险利率，GDP增速以及DCF中的永续增长率g</title>
    <link href="https://www.keepswalking.com/2020/10/21/rf-gdp-and-g/"/>
    <id>https://www.keepswalking.com/2020/10/21/rf-gdp-and-g/</id>
    <published>2020-10-21T06:23:18.000Z</published>
    <updated>2020-10-21T08:56:24.915Z</updated>
    
    <content type="html"><![CDATA[<p>本文虽短，但是涉及到一个非常重要的知识点—如何确定DCF模型里的永续增长率g。为何会想到写这个问题？因为我自己对如何确定永续增长率也一直比较迷茫。最近读到泰康资产CEO段国圣一篇关于“后疫情时代的资产配置”的主题演讲，里面的一些内容让我有了方向。</p><a id="more"></a><p>其实，本来g不是问题！因为根据Damodaran的方法，g的<strong>上限</strong>就是无风险利率。但是，什么事情到了中国就必须得有中国特色。我们先来看一个通用的DCF模型，如下图所示：</p><img src="/2020/10/21/rf-gdp-and-g/dcf.PNG" class=""><p>DCF被人诟病的一大问题是terminal value，因为terminal value占最终估值的比例非常大，即使使用10年的长度情况也差不多。这直接导致一个问题，那就是如果terminal value有些偏差，那整个结果就废了！如何确定terminal value？</p><script type="math/tex; mode=display">TV_t = \frac {CF_{t+1}} {r-g_{stable}}</script><p>由以上公式可见，影响terminal value的因素有3个。cashflow, r和g。通常来说，cashflow估计的准确与否是由你对目标公司业务的熟悉程度决定的。r即discount rate一般由beta决定，如果使用bottom up beta方法，那相对把握还是比较大。而g该如何确定呢？Damodaran是用risk free rate，一般是指10年期国债。他的理由如下：</p><img src="/2020/10/21/rf-gdp-and-g/why_10ybond.PNG" class=""><p>他的理由是：</p><ul><li>长期来说，实际增长率<strong>不能低于</strong>实际利率，因为商品和服务的增长必须能抵得过实际利率，否则借款人就不应该借钱</li><li>长期来说，实际增长率<strong>可能高于</strong>实际利率，相当于是对借款人的一种风险补偿。然而，随着经济趋向成熟，两者的差异将会缩小。而由于经济体里会出现成长性公司，因此可以谨慎假设高出的部分来自于这些公司。（我不知道这段Damodaran想表达啥？感觉逻辑混乱，根据他的论述那得出的结论应该是Nominal GDP growth &gt; Risk free rate）</li><li>由历史数据可见，总体上Nominal GDP还是会高出T Bond Rate，但是比较接近。确实有些时间T Bond Rate还会比Nominal GDP高</li></ul><img src="/2020/10/21/rf-gdp-and-g/why_10ybond_1.PNG" class=""><p>上图更加直观！蓝柱=Real GDP growth，灰柱=inflation rate，蓝柱+灰柱=intrinsic risk free rate，由以上理论，intrinsic risk free rate应该接近10-year T bond（红色）。实际来看基本还是比较吻合。</p><p>综上，从美国市场看Nominal GDP growth和T Bond Rate相当接近。考虑到T Bond Rate的获得<strong>极其方便</strong>，因此Damodaran提出用risk free rate，即10-year T Bond Rate作为g的<strong>cap（上限）</strong>。注意，他给出的rule是用无风险利率作为上限。</p><p>那么他的方法是否可以直接用在我们大A股市场呢？我也一直比较犹豫，是因为我们的GDP明显高于10年期国债ytm！如果用10年期国债ytm作为g那有可能估出来的价值都偏低，但<strong>我一直不清楚我们的GDP和无风险利率之间的差异会如此巨大的原因是什么</strong>？因此就不知道到底<strong>该用无风险利率作为g更合适，还是用预期GDP增长率更合适</strong>？直到我昨天读了泰康资产CEO段国圣一篇关于“后疫情时代的资产配置”的主题演讲。引用相关内容如下：</p><p><em>。。。我们过去，不仅是中国，新兴市场国家在建设初期都是<strong>利率抑制</strong>的，实际上是用老百姓的储蓄来支持整个国家的建设，所以导致<strong>中国的债券收益率的中枢明显比GDP中枢要低。西方国家、发达国家国债的收益率中枢跟GDP的中枢基本是一致的，有一定的差异，但总体是差异很小的</strong>，所以在利率市场化过程中，这样一个缺口会缩窄。。。</em></p><p><em>。。。<strong>中国利率市场化没有完成，利率体系的中枢和名义GDP之间有一定的缺口</strong>。我们利率体系的中枢，我们讲利率一般都是用无风险利率，就是十年期国债作为一个基准，它跟名义GDP有一个系统性的缺口，反映整个发展中国家（包括中国）金融抑制，<strong>利率市场化在逐步完成的时候，国债的收益率中枢和名义GDP会趋向一致，这是美国和日本等一些成熟的发达国家已经发生的过程</strong>。随着我们国家利率市场化的推进，我们十年期的国债与名义GDP的缺口在缩小。2012年和2013年利率市场化改革，以这个时候为界，<strong>前面这个缺口是大概12%</strong>，利率本身加12%才到的名义GDP，<strong>实行利率化改革以后，逐步收窄到5%</strong>，随着未来一段时间利率市场化继续的推进，对利率的底部形成一个支持。。。</em></p><p>当我读到这些内容时有点eureka moment的感觉！之所以我们的GDP和无风险利率有如此大的差异是因为发展中国家都会进行利率抑制。我理解就是人为压低名义利率，使得实际利率变得非常低，甚至是负，通过这种方式促进投资和消费，设想一下，借款人可以以很低的利率借到钱，由于实际上是负利率，当他还钱的时候其实还的更少！</p><p>碎片阅读还是能带来一些价值啊。。。（其实我是用讯飞有声一边骑车一边听的。。。），好了，这下就明确了，<strong>在计算terminal value的时候永续增长率g应该使用GDP的增长率</strong>。但在实际操作中其实还是需要一些假设，因为使用g的时点是在若干年后e.g. 5年或10年；显然直接用当下时点的GDP增长率就不适合。而对于美国市场使用10年期国债YTM的情景，ytm是IRR（internal rate of return）天然就自带预期成分，因此这也是直接使用10年期国债YTM的好处之一（另外一个就是很容易获得，每天都想查就有！）。因此，为了更好估计出terminal value，g应该使用expected GDP growth rate。暂不清楚哪里能查到比较靠谱的5年后甚至10年后GDP的预期增长。这里可能需要扮演上帝，但至少我们还有10年期国债做参考嘛！要错也不至于错的太离谱！！</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;本文虽短，但是涉及到一个非常重要的知识点—如何确定DCF模型里的永续增长率g。为何会想到写这个问题？因为我自己对如何确定永续增长率也一直比较迷茫。最近读到泰康资产CEO段国圣一篇关于“后疫情时代的资产配置”的主题演讲，里面的一些内容让我有了方向。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
  </entry>
  
  <entry>
    <title>一个简单的衡量股市估值高低的方法</title>
    <link href="https://www.keepswalking.com/2020/10/16/a-simple-way-to-evaluate-the-market/"/>
    <id>https://www.keepswalking.com/2020/10/16/a-simple-way-to-evaluate-the-market/</id>
    <published>2020-10-16T03:46:05.000Z</published>
    <updated>2020-10-17T13:33:55.680Z</updated>
    
    <content type="html"><![CDATA[<p>本文详细介绍了如何利用PE对市场总体估值进行评价。并通过回测显示该模型具有较好的实用性。当前市场（2020-10-14）所处percentile为50%左右，可以认为处于合理区间。</p><a id="more"></a><p>这次扯一点稍微宏观的（虽然我越来越觉得宏观的东西很多都是扯淡。。。但是无奈扯淡才有市场啊）。相信大家都有过这样的经历：某某专家说，现在股市低估了，是时候买入了。或者是现在股市高估了，存在明显的泡沫。听到这些关于市场的评论，你大概要么是无感，要么就是陷入深深的焦虑中。。。</p><p>那么有没有一个量化的指标能让我们判断现在的市场到底处于什么位置，是高估，低估还是正常？我们就一步一步来，明明白白的自己动手做个模型。</p><h2 id="PE，对！没错还是PE"><a href="#PE，对！没错还是PE" class="headerlink" title="PE，对！没错还是PE"></a>PE，对！没错还是PE</h2><p>price-to-earnings ratio简称PE，是衡量股票贵贱的一个常用指标。这么个广为人知的指标怎么来衡量市场呢？说来逻辑也简单，如果我们能知道市场的PE，那我们至少就有了对市场估值的一种量化指标。这里我使用“中证全指”作为市场的proxy，PE使用的是median（中位数），earning使用TTM方式计算。从Choice终端里面，我可以很方便地获得对应的历史数据。先来直观感受一下中证全指PE的历史，见下图：</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/pe_ts.PNG" class=""><p>上图中开始时间是2005年，结束时间2020年10月14日。从图中我们可以观察到以下几个特点：</p><ul><li>存在明显的波峰，波谷；波峰比波谷更显著。2个非常明显波峰分别发生在2007年6月和2015年6月。一个明显的波谷在2008年11月</li><li>总体似乎运行在20到60倍的区间</li><li>当前PE在40左右，似乎不高也不低。。。</li></ul><p>有了历史数据，那接下来就好办了，一个直观的想法是通过PE的分布获得当前的percentile，如果以5%和95%作为confidence interval，那么当PE落在5%的percentile段则可以认为市场是明显低估，反之如果PE落在了95%的percentile段则认为市场明显高估。 </p><p>接下来就看看PE的分布，如下图所示：</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/pe_dis.PNG" class=""><p>hmm…看上去不太对称，好像是log normal 分布嘛！那就对PE取对数，参见下图：</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/log_pe_dis.PNG" class=""><p>OK, 看上去好多了，比较像normal distribution了！接着，我们希望找到5%和95% percentile对应的log PE的值。有两种方法：</p><ul><li>方法一：直接使用Empirical Cumulative Distribution Function，直接使用现有数据，根据5%和95% percentile切分点获得对应的PE。</li><li>方法二：distribution fitting，找到符合数据的分布，并利用该分布的pdf计算获得5%和95% percentile对应的PE。</li></ul><p>方法一适合有大量历史数据的场景，而方法二对于数据量要求不高而同时能获得更加精确的结果。我们就用方法二，利用normal distribution去对数据进行拟合，参见下图：</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/log_pe_fit.PNG" class=""><p>normal distribution拟合的结果为mean=3.706，standard deviation=0.32。那么容易得到：</p><ul><li>5% percentile 对应的log(PE) = 3.18</li><li>95% percentile 对应的log(PE) = 4.23</li></ul><p>转换后对应真实的PE为：</p><ul><li>5% percentile 对应的PE = 24.1</li><li>95% percentile 对应的PE = 68.8</li></ul><p>因此，对于<strong>当前</strong>的市场，<strong>如果PE中位数低于24.1那么可以认为是明显低估，如果PE中位数高于68.8那么可以认为是明显高估</strong>。2020-10-14 PE的中位数是40.8，位于log(PE)分布的50%左右，可以认为处于合理区间。</p><p>我们用此方法来直观感受一下过去历史上出现过的极端行情。在做回测的时候，我不能用现在拟合出来的model，这样就造成了forward looking bias！准确的做法是基于某日之前的历史数据拟合并生成model，用该model来分析PE。由于我用的历史数据始于2005年，我先用前5年的数据作生成model，因此回测结果将从2010年开始显示。另外，随着时间的推移，历史数据将不断积累，并输入model进行训练。结果如下图所示：</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/log_pe_results.PNG" class=""><p>上图中，上半部分是中证全指的走势，下半部分是PE，红色阴影代表高估时间，绿色代表低估时间。红色主要分布在2015年股灾那段时间，基本上进入红色区域，可以开始逐步减仓。但是，如果一进入红色区域如果马上清仓，可能后面那一大段“肥肉”完完全全错过了。而绿色区域很少，只出现在2018-10-18日那天。在绿色区域买入基本没啥问题。</p><p>貌似看上去，这个model对时机的定位还算准确。我个人觉得这个模型可以对市场总体估值水平提供一个参考。不过，这种极端的情况的出现需要长久的等待，而且真的到了极端情况，你还会出手吗？大概率还是会以种种理由说服自己不要动。投资就是这么反人性的。。。</p><h2 id="PE，增强！"><a href="#PE，增强！" class="headerlink" title="PE，增强！"></a>PE，增强！</h2><p>普通青年知道降息利好股市。</p><p>优秀青年知道降息导致discount rate下降，而discount rate下降导致股价上升（当然，降息对股价并非单向催升，因为降息通常伴随着企业增长的放缓。因此从估值角度看，降息未必是绝对利好。扯远了。）。</p><p>回到PE，PE伴随着股价的波动而波动，如果市场处在降息环境下，假设盈利没有明显变化，那么股价通常会上涨，因此PE也上涨。这种情况就好比水涨船高！那么我们来考虑一下，这个时候，PE处于高位，按照静态的观点应该要抛股票，或是从进攻策略调整为防守，但是，由于降息（水涨船高），这种环境下对应的高PE具有合理性。换句话说，要评估PE是高是低，应该要剔除利率的影响。</p><p>综上所述，感觉上<strong>利率和PE应该具有一定的线性关系，即利率低，PE高</strong>；利率高PE低。或者，用E/P，即<strong>Earnings Yield和interest rate具有同向关系</strong>（也是CFA level III的考点：FED Model ratio = S&amp;P earning yield / 10-year treasury yield。当FED Model ratio &gt; 1 则认为市场被低估，反之则高估）。</p><p>现实情况是否是这样呢？我们先来看看教科书市场—美国，参见下图:</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/fed_model_us.PNG" class=""><p>数据来源：Julex Capital Management, LLC Volume 3, 2017</p><p>简直是perfect啊！R squared竟能高达40%，说明利率确实对PE有很大的影响。有了利率和E/P的线性关系，那接下来的思路就是：</p><ul><li><strong>利用这个线性关系，根据现有的interest rate计算出E/P，也就能获得预期PE</strong></li><li><strong>用实际PE 减 预期PE，可得剔除了interest rate影响的残余PE</strong></li><li><strong>根据残余(Residual)PE的分布，判断当前市场是高估了还是被低估了</strong></li></ul><p>通过这种方式，我们可以不受“水涨船高”的影响，能更好的判断市场的估值情况。</p><p>可是，我们处在中国市场—专治各种不服。先来看看历史数据，见下图（10年期国债YTM同中证全指中位数E/P）：</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/10y_ep_history.PNG" class=""><p>What?! 理论上应该如美国市场是一种正向关系，但这感觉是反向关系啊。。。尤其是2014年2月以前的这段数据，完美反向关系啊！！！</p><p>惨遭打击，难道说是因为我国的利率市场化很晚才开始？但是10年期国债一直是一个可交易的品种。实在很难理解，为啥<strong>中国市场</strong>是这样：<strong>降息不利股市，升息利好股市</strong>。</p><p>那我就从2014年的数据开始计算E/P和interest rate的关系吧。参见下图：</p><img src="/2020/10/16/a-simple-way-to-evaluate-the-market/fed_model_cn.PNG" class=""><p>简直吐血，R squared 只有0.38%，也就是说earning yeild的波动基本无法用利率的波动来解释。要知道，这还是根据历史数据截取了一段看似比较相关的数据。如果从2005年开始做线性回归，那估计得到的是负相关。。。同时，根据线性关系 y = 0.0921x + 0.0202，可见，从系数0.0921也能看出利率对E/P的贡献相当小。因此从目前掌握的数据来看，利率对A股的影响几乎可以忽略不计，也许这是中国市场的特色，也许这是emerging market的特色。也许随着市场的发展，利率将对A股的影响越来越大。这还有待更多市场数据作观察。</p><p>由于利率和E/P直接的关系不明显，因此，这个对PE的增强就不去做了（做了也没有意义，因为系数0.0921乘以利率几乎可以忽略），我在上面已经把思路写出来了，有兴趣的同学可以对美国这样的市场做测试。</p><h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>本文详细说明了如何利用PE对市场总体估值进行评价。并通过回测显示该模型具有较好的实用性。但是，个人觉得如果等极端行情出现再投资那机会成本是相当大的。每个人有不同的投资风格，在市场总体处于正常范围内，如果你有很强的选股能力，或有很强的择时能力，同样还是能取得alpha。总是想着等极端行情出现，然后一把梭哈，这种想法本身就很危险，加之真的极端行情来了，你还能下手吗？想想2020年3月份美国市场暴跌的时候，天天熔断，这样的环境下你下得了手吗？因此，<strong>本篇提供的模型可以给你一个参考，帮助你衡量风险，调整风险敞口</strong>。我打算接下来根据这个model每周更新中证全指所处percentile。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;本文详细介绍了如何利用PE对市场总体估值进行评价。并通过回测显示该模型具有较好的实用性。当前市场（2020-10-14）所处percentile为50%左右，可以认为处于合理区间。&lt;/p&gt;
    
    </summary>
    
    
      <category term="量化投资组合管理" scheme="https://www.keepswalking.com/categories/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%BB%84%E5%90%88%E7%AE%A1%E7%90%86/"/>
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%BB%84%E5%90%88%E7%AE%A1%E7%90%86/Valuation/"/>
    
    
  </entry>
  
  <entry>
    <title>screen（股票筛选器）之二 -- 回测，没有全面调查就没有伤害</title>
    <link href="https://www.keepswalking.com/2020/09/30/screening-improvement/"/>
    <id>https://www.keepswalking.com/2020/09/30/screening-improvement/</id>
    <published>2020-09-30T02:42:18.000Z</published>
    <updated>2020-10-12T14:18:05.376Z</updated>
    
    <content type="html"><![CDATA[<p>本文描述了在对screen（股票筛选器）进行回测的过程中所碰到的各种问题以及对应的解决方法。最后，通过对portfolio中个股权重进行优化，获得了一个相当不错的回测结果。回测以股灾顶峰（2015-06-12）为开始时点一直到2020-09-25，并以比较保守的参数设置，期间获得了近45%的总收益或年化7.5%的收益。</p><a id="more"></a><p>这段时间真的是做回测做到吐了。回测真的是一件超重体力活啊！自己刚从一个坑爬出来紧接着又跌入下一个坑，不断往复。。。痛不欲生！如果有人告诉你一个量化策略并说能盈利，但是没有回测记录那是在耍流氓。如果他给你看回测记录而没有告诉你回测条件那也是在耍流氓。</p><p>上篇<a href="/2020/09/23/screening-in-practice/" title="一个基于价值的screen（筛选器） -- 大概是最简单的量化投资">一个基于价值的screen（筛选器） -- 大概是最简单的量化投资</a>介绍了一个基于价值的Screen，并且用最原始的方式做了回测，包括：</p><ul><li>在计算aggregate z-score的时候使用等权重</li><li>在构建portfolio时简单地使用aggregate z-score为top n的股票</li><li>rebalance时的操作为先全部卖出，再全部买入</li></ul><p>回测的结果显示能明显跑赢基准，当时心理还是沾沾自喜，要知道这可是一把成功，没有overfitting这回事啊！想接下来再做一些优化，最主要想对aggregate z-score的权重进行优化。但转念觉得自己还没有评估过该策略在不同情况下的表现，比如：</p><ul><li>调整rebalance的时间点，如前移或后移</li><li>增加或减少rebalance 的次数</li></ul><p>第一感觉是这些调整对回测结果只会产生微弱的影响。但是噩梦就此开始。。。</p><h2 id="问题暴露"><a href="#问题暴露" class="headerlink" title="问题暴露"></a>问题暴露</h2><p>说干就干，撸起袖子开始改代码（尽显码农本色）。</p><h3 id="改变调仓（rebalance）周期"><a href="#改变调仓（rebalance）周期" class="headerlink" title="改变调仓（rebalance）周期"></a>改变调仓（rebalance）周期</h3><p>上篇screen中每年做3次rebalance，分别对应三个财报季：</p><ul><li>1季报：4月30日以后的第一个交易日。</li><li>2季报（中报）：8月31日以后的第一个交易日。</li><li>3季报： 10月31日以后的第一个交易日。</li></ul><p>由以上描述可以看出，从三季报到次年一季报之间有6个月的时间，这就导致了rebalance之间的interval不一致，因此<strong>考虑在1月31日以后的第一个交易日新增一次rebalance</strong>（年报：每年1月1日——4月30日，因此同1季报的时间重叠，因此等年报出来一季报也基本发布了，那么年报的信息相对就有些过期了，所以，原本3次调仓其实是忽略了年报的信息）。那么rebalance每年4次，interval基本上在3个月左右。</p><p>可是结果有点出乎意料，5年的回测成绩不理想，如下图所示：</p><img src="/2020/09/30/screening-improvement/four_interval.PNG" class=""><p>而如果换作半年一次调仓，调仓时点放在一季报和三季报发布的时间段，那么5年的回测收益接近原来的收益。如下图所示：</p><img src="/2020/09/30/screening-improvement/two_interval.PNG" class=""><p>增加一次调仓的结果真的让我大跌眼镜！隐约感觉策略可能出问题了。继续测试其他场景。。。</p><h3 id="改变调仓时点"><a href="#改变调仓时点" class="headerlink" title="改变调仓时点"></a>改变调仓时点</h3><p>如果改变调仓的时间点，则回测收益也出现了明显的下滑。首先，测试将调仓时间后移2周，每年两次调仓，即调仓的时间点为：</p><ul><li>1季报：5月15日以后的第一个交易日。</li><li>3季报： 11月15日以后的第一个交易日。</li></ul><p>测试结果如下图所示：</p><img src="/2020/09/30/screening-improvement/post_reb.PNG" class=""><p>如果说将调仓时间后移使得相关财报信息被市场消化，导致收益下降是一种解释。但是，明显跑输沪深300就感觉很难解释了，是因为市场风格发生了变化吗？</p><p>那么如果将rebalance时点比原来提前一周呢？，即调仓的时间点为：</p><ul><li>1季报：4月23日以后的第一个交易日。</li><li>3季报： 10月24日以后的第一个交易日。</li></ul><p>测试结果如下所示：</p><img src="/2020/09/30/screening-improvement/pre_reb.PNG" class=""><p>微弱跑输沪深300。可能是因为没有获取到全部财报的更新数据？</p><p>根据以上描述，可以发现该Screen对rebalance的时点和次数都是非常敏感。这同我的预期形成了鲜明的反差，严重伤害了我的感情！这样的策略不可能应用到实战中，于是开始着手调查。。。</p><h2 id="陷阱"><a href="#陷阱" class="headerlink" title="陷阱"></a>陷阱</h2><p>由于整个回测是自动化完成的，要找到问题并不容易，输出日志也许是为数不多的方法。</p><h3 id="陷阱之一-—-一定是策略出问题了"><a href="#陷阱之一-—-一定是策略出问题了" class="headerlink" title="陷阱之一 — 一定是策略出问题了"></a>陷阱之一 — 一定是策略出问题了</h3><p>对于调整rebalance时间点对回测结果产生重大影响这个问题，我第一反应是很可能策略很有可能在rebalance时间前后会给出差异巨大的输出，这样就可能导致回测结果出现严重的不一致。该如何排查这一点呢？只能通过日志输出来进行人工比较。但是，结果显示，策略的输出并无明显差别，如下所示。下表是策略原来预设的调仓时间点：2017-04-30以后的第一交易日所产生的输出：</p><div class="table-container"><table><thead><tr><th>label</th><th>z_score_sum</th><th>symbol</th><th>industry_name</th></tr></thead><tbody><tr><td>000502.XSHE</td><td>8.890258</td><td>绿景控股</td><td>房地产业</td></tr><tr><td>000004.XSHE</td><td>8.681055</td><td>国农科技</td><td>软件和信息技术服务业</td></tr><tr><td>600338.XSHG</td><td>8.068400</td><td>西藏珠峰</td><td>有色金属矿采选业</td></tr><tr><td>002110.XSHE</td><td>7.868558</td><td>三钢闽光</td><td>黑色金属冶炼和压延加工业</td></tr><tr><td>000036.XSHE</td><td>7.327801</td><td>华联控股</td><td>房地产业</td></tr><tr><td>600052.XSHG</td><td>6.932945</td><td>浙江广厦</td><td>广播、电视、电影和影视录音制作业</td></tr><tr><td>600519.XSHG</td><td>6.889754</td><td>贵州茅台</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>002120.XSHE</td><td>6.812944</td><td>韵达股份</td><td>邮政业</td></tr><tr><td>002508.XSHE</td><td>6.806315</td><td>老板电器</td><td>电气机械和器材制造业</td></tr><tr><td>000011.XSHE</td><td>6.669217</td><td>深物业A</td><td>房地产业</td></tr><tr><td>002372.XSHE</td><td>6.640031</td><td>伟星新材</td><td>橡胶和塑料制品业</td></tr><tr><td>002032.XSHE</td><td>6.371474</td><td>苏泊尔</td><td>金属制品业</td></tr><tr><td>002352.XSHE</td><td>6.352925</td><td>顺丰控股</td><td>邮政业</td></tr><tr><td>600681.XSHG</td><td>6.345977</td><td>百川能源</td><td>燃气生产和供应业</td></tr><tr><td>002558.XSHE</td><td>6.327748</td><td>巨人网络</td><td>互联网和相关服务</td></tr><tr><td>600641.XSHG</td><td>6.267760</td><td>万业企业</td><td>房地产业</td></tr><tr><td>002035.XSHE</td><td>6.266626</td><td>华帝股份</td><td>电气机械和器材制造业</td></tr><tr><td>002468.XSHE</td><td>6.229671</td><td>申通快递</td><td>邮政业</td></tr><tr><td>600477.XSHG</td><td>6.075676</td><td>杭萧钢构</td><td>金属制品业</td></tr><tr><td>002466.XSHE</td><td>6.044695</td><td>天齐锂业</td><td>有色金属冶炼和压延加工业</td></tr><tr><td>600887.XSHG</td><td>5.964935</td><td>伊利股份</td><td>食品制造业</td></tr><tr><td>002597.XSHE</td><td>5.962833</td><td>金禾实业</td><td>化学原料及化学制品制造业</td></tr><tr><td>600167.XSHG</td><td>5.836436</td><td>联美控股</td><td>电力、热力生产和供应业</td></tr><tr><td>002677.XSHE</td><td>5.706263</td><td>浙江美大</td><td>电气机械和器材制造业</td></tr><tr><td>600779.XSHG</td><td>5.639503</td><td>水井坊</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>600746.XSHG</td><td>5.600572</td><td>江苏索普</td><td>化学原料及化学制品制造业</td></tr><tr><td>002647.XSHE</td><td>5.583226</td><td>仁东控股</td><td>其他金融业</td></tr><tr><td>300268.XSHE</td><td>5.565489</td><td>佳沃股份</td><td>农副食品加工业</td></tr><tr><td>300136.XSHE</td><td>5.494172</td><td>信维通信</td><td>计算机、通信和其他电子设备制造业</td></tr><tr><td>600688.XSHG</td><td>5.400361</td><td>上海石化</td><td>石油加工、炼焦和核燃料加工业</td></tr><tr><td>002233.XSHE</td><td>5.293639</td><td>塔牌集团</td><td>非金属矿物制品业</td></tr><tr><td>002136.XSHE</td><td>5.285238</td><td>安纳达</td><td>化学原料及化学制品制造业</td></tr><tr><td>002460.XSHE</td><td>5.247013</td><td>赣锋锂业</td><td>有色金属冶炼和压延加工业</td></tr><tr><td>603288.XSHG</td><td>5.194811</td><td>海天味业</td><td>食品制造业</td></tr><tr><td>600132.XSHG</td><td>5.166631</td><td>重庆啤酒</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>002043.XSHE</td><td>5.161986</td><td>兔宝宝</td><td>木材加工和木、竹、藤、棕、草制品业</td></tr><tr><td>600507.XSHG</td><td>5.078334</td><td>方大特钢</td><td>黑色金属冶炼和压延加工业</td></tr><tr><td>002555.XSHE</td><td>4.955648</td><td>三七互娱</td><td>互联网和相关服务</td></tr><tr><td>002636.XSHE</td><td>4.927382</td><td>金安国纪</td><td>计算机、通信和其他电子设备制造业</td></tr><tr><td>002133.XSHE</td><td>4.854489</td><td>广宇集团</td><td>房地产业</td></tr><tr><td>300176.XSHE</td><td>4.773486</td><td>派生科技</td><td>汽车制造业</td></tr><tr><td>600309.XSHG</td><td>4.762293</td><td>万华化学</td><td>化学原料及化学制品制造业</td></tr><tr><td>002713.XSHE</td><td>4.732748</td><td>东易日盛</td><td>建筑装饰和其他建筑业</td></tr><tr><td>000568.XSHE</td><td>4.716226</td><td>泸州老窖</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>000910.XSHE</td><td>4.704433</td><td>大亚圣象</td><td>木材加工和木、竹、藤、棕、草制品业</td></tr><tr><td>002507.XSHE</td><td>4.697732</td><td>涪陵榨菜</td><td>食品制造业</td></tr><tr><td>600211.XSHG</td><td>4.618739</td><td>西藏药业</td><td>医药制造业</td></tr><tr><td>002572.XSHE</td><td>4.540608</td><td>索菲亚</td><td>家具制造业</td></tr><tr><td>000930.XSHE</td><td>4.525929</td><td>中粮科技</td><td>化学原料及化学制品制造业</td></tr><tr><td>000813.XSHE</td><td>4.461262</td><td>德展健康</td><td>医药制造业</td></tr></tbody></table></div><p>而下表为推后的调仓时间点：2017-05-16这个交易日所产生的输出，比策略原来预设的调仓时间点晚了2周：</p><div class="table-container"><table><thead><tr><th>label</th><th>z_score_sum</th><th>symbol</th><th>industry_name</th></tr></thead><tbody><tr><td>000502.XSHE</td><td>8.778548</td><td>绿景控股</td><td>房地产业</td></tr><tr><td>000004.XSHE</td><td>8.597785</td><td>国农科技</td><td>软件和信息技术服务业</td></tr><tr><td>002110.XSHE</td><td>7.754317</td><td>三钢闽光</td><td>黑色金属冶炼和压延加工业</td></tr><tr><td>002120.XSHE</td><td>7.576107</td><td>韵达股份</td><td>邮政业</td></tr><tr><td>600519.XSHG</td><td>7.571283</td><td>贵州茅台</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>600338.XSHG</td><td>7.553469</td><td>西藏珠峰</td><td>有色金属矿采选业</td></tr><tr><td>000036.XSHE</td><td>7.347328</td><td>华联控股</td><td>房地产业</td></tr><tr><td>002508.XSHE</td><td>7.269823</td><td>老板电器</td><td>电气机械和器材制造业</td></tr><tr><td>000011.XSHE</td><td>7.180023</td><td>深物业A</td><td>房地产业</td></tr><tr><td>002352.XSHE</td><td>7.168590</td><td>顺丰控股</td><td>邮政业</td></tr><tr><td>002035.XSHE</td><td>7.091673</td><td>华帝股份</td><td>电气机械和器材制造业</td></tr><tr><td>002032.XSHE</td><td>7.063430</td><td>苏泊尔</td><td>金属制品业</td></tr><tr><td>002372.XSHE</td><td>7.029911</td><td>伟星新材</td><td>橡胶和塑料制品业</td></tr><tr><td>600052.XSHG</td><td>6.886197</td><td>浙江广厦</td><td>广播、电视、电影和影视录音制作业</td></tr><tr><td>002468.XSHE</td><td>6.820134</td><td>申通快递</td><td>邮政业</td></tr><tr><td>600477.XSHG</td><td>6.657167</td><td>杭萧钢构</td><td>金属制品业</td></tr><tr><td>002597.XSHE</td><td>6.645728</td><td>金禾实业</td><td>化学原料及化学制品制造业</td></tr><tr><td>600887.XSHG</td><td>6.407632</td><td>伊利股份</td><td>食品制造业</td></tr><tr><td>002466.XSHE</td><td>6.316711</td><td>天齐锂业</td><td>有色金属冶炼和压延加工业</td></tr><tr><td>300136.XSHE</td><td>6.279457</td><td>信维通信</td><td>计算机、通信和其他电子设备制造业</td></tr><tr><td>600779.XSHG</td><td>6.244783</td><td>水井坊</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>600641.XSHG</td><td>6.199704</td><td>万业企业</td><td>房地产业</td></tr><tr><td>002677.XSHE</td><td>6.016379</td><td>浙江美大</td><td>电气机械和器材制造业</td></tr><tr><td>002460.XSHE</td><td>5.974417</td><td>赣锋锂业</td><td>有色金属冶炼和压延加工业</td></tr><tr><td>603288.XSHG</td><td>5.783055</td><td>海天味业</td><td>食品制造业</td></tr><tr><td>000568.XSHE</td><td>5.741317</td><td>泸州老窖</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>002636.XSHE</td><td>5.690895</td><td>金安国纪</td><td>计算机、通信和其他电子设备制造业</td></tr><tr><td>600681.XSHG</td><td>5.650337</td><td>百川能源</td><td>燃气生产和供应业</td></tr><tr><td>600746.XSHG</td><td>5.632605</td><td>江苏索普</td><td>化学原料及化学制品制造业</td></tr><tr><td>600132.XSHG</td><td>5.505306</td><td>重庆啤酒</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>600688.XSHG</td><td>5.485803</td><td>上海石化</td><td>石油加工、炼焦和核燃料加工业</td></tr><tr><td>300268.XSHE</td><td>5.423325</td><td>佳沃股份</td><td>农副食品加工业</td></tr><tr><td>002507.XSHE</td><td>5.385897</td><td>涪陵榨菜</td><td>食品制造业</td></tr><tr><td>000858.XSHE</td><td>5.205664</td><td>五粮液</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>002555.XSHE</td><td>5.198571</td><td>三七互娱</td><td>互联网和相关服务</td></tr><tr><td>000910.XSHE</td><td>5.184445</td><td>大亚圣象</td><td>木材加工和木、竹、藤、棕、草制品业</td></tr><tr><td>600507.XSHG</td><td>5.169067</td><td>方大特钢</td><td>黑色金属冶炼和压延加工业</td></tr><tr><td>600309.XSHG</td><td>5.164688</td><td>万华化学</td><td>化学原料及化学制品制造业</td></tr><tr><td>002572.XSHE</td><td>5.162698</td><td>索菲亚</td><td>家具制造业</td></tr><tr><td>600167.XSHG</td><td>5.118928</td><td>联美控股</td><td>电力、热力生产和供应业</td></tr><tr><td>002136.XSHE</td><td>5.080895</td><td>安纳达</td><td>化学原料及化学制品制造业</td></tr><tr><td>002043.XSHE</td><td>5.013130</td><td>兔宝宝</td><td>木材加工和木、竹、藤、棕、草制品业</td></tr><tr><td>000049.XSHE</td><td>5.000309</td><td>德赛电池</td><td>电气机械和器材制造业</td></tr><tr><td>002558.XSHE</td><td>4.966376</td><td>巨人网络</td><td>互联网和相关服务</td></tr><tr><td>002304.XSHE</td><td>4.951366</td><td>洋河股份</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>002415.XSHE</td><td>4.854819</td><td>海康威视</td><td>计算机、通信和其他电子设备制造业</td></tr><tr><td>002647.XSHE</td><td>4.782066</td><td>仁东控股</td><td>其他金融业</td></tr><tr><td>300176.XSHE</td><td>4.772607</td><td>派生科技</td><td>汽车制造业</td></tr><tr><td>002713.XSHE</td><td>4.767137</td><td>东易日盛</td><td>建筑装饰和其他建筑业</td></tr><tr><td>600211.XSHG</td><td>4.707598</td><td>西藏药业</td><td>医药制造业</td></tr></tbody></table></div><p>由以上两表对比可见，策略输出的一致性还是相当高的，除了排名发生了些许变化（因为股价改变了），总体来看排名前50的成分股票变化很少（<strong>有贵州茅台哦！！！</strong>）。那么就排除了策略算法上的问题。到底哪里出问题了？感觉没啥方向，已经感觉大伤元气了。。。</p><h3 id="陷阱之二-—-停牌"><a href="#陷阱之二-—-停牌" class="headerlink" title="陷阱之二 — 停牌"></a>陷阱之二 — 停牌</h3><p>既然策略本身没有问题，那很有可能在执行策略的过程中出问题了！于是将排查的重点放到持仓上。果然很快就发现问题了，通过日志可以发现每次rebalance的时候，总是有一些股票卖不出去，同时会有一些股票买不进来。再通过日志发现因为股票停牌了！对于普通投资者来说本来的持仓的股票个数也不会很大，因此很少会碰到股票停牌。但是，对于策略来说，我的portfolio由50只股票组成。几乎每次rebalance时总是会碰到有股票停牌。尤其是在2015年6月份极端行情的那段时间，出现了大面积的股票停牌，这对策略的结果产生了很大的冲击。因此就会出现改变rebalance的时间点，portfolio的持仓会有很大的区别。例如对于通过策略入围的50只股票，在t天有10只股票停牌，而在t+n天可只有3只股票停牌了。那么在t日买入和在t+n日买入portfolio的构成会有很大的区别。由于停牌，导致了我的portfolio在不同时点做rebalance会有不同只数的股票构成，而且股票只数不足50只。</p><p>发现问题以后，又是狂敲一通代码修改策略的回测过程，在rebalance当天：</p><ul><li>如果有股票因停牌无法卖出的，在买入时还是以portfolio的股票到达50只为止。例如当日有10只股票因停牌无法卖出的，那么只能买入40只股票。</li><li>由于停牌无法卖出的股票在后续交易日执行卖出操作，有可能后续交易日继续停牌，或跌停无法卖出的，在下一交易日继续执行卖出，直至全部卖出为止。</li><li>在卖出的同时补入对应数量入围股票。</li></ul><p>一番测试，修改bug以后觉得没啥问题了，结果一跑回测，发现portfolio里面股票的数量还是不对。。。继续排查。。。</p><h3 id="陷阱之三-—-涨跌停"><a href="#陷阱之三-—-涨跌停" class="headerlink" title="陷阱之三 — 涨跌停"></a>陷阱之三 — 涨跌停</h3><p>顺藤摸瓜，发现策略执行过程中没有考虑涨跌停的股票。例如在rebalance当天，需卖出的股票如果碰到跌停，则是无法卖出的，那么只能在后续交易日卖出。后续交易日也可能继续跌停，那我的策略就是一直执行卖出操作，直至卖出为止。同停牌相似，后续卖出以后也必须买入相同只数的股票。例如后续某交易日补卖出3只股票，则必须同时买入3只股票。也就是说，portfolio的构成始终维持在50只股票。</p><p>如果碰到涨停则在rebalance当天无法买入。那么这里的策略同卖出有所<strong>不同</strong>。买入如果碰到涨停则换一只入围股票，直到portfolio达到50只，也就是说，rebalance当天肯定会使portfolio的持股数量达到50只。</p><p>继续修改代码，回测结果如下图所示：</p><img src="/2020/09/30/screening-improvement/equal_w_benchmark_cap_w.PNG" class=""><p>上图的rebalance时间点为预设时间点后移14天，总收益为-1.88%。而预设rebalance的最终收益是-1.96%，两者对比从最终收益角度看差别不大。看上去问题是解决了，但是这收益和基准（沪深300全收益指数）没啥区别，而且很长时间里面还落后基准。难道我设计的策略就只能取得市场收益吗？</p><p>我对取得市场收益没有什么偏见，恰恰相反，我觉得能取得市场收益也很不错了。但是，我设计这个策略的初衷肯定是想跑赢市场，那为何没有跑赢呢？继续排查。。。</p><h3 id="陷阱之四-—-个股权重"><a href="#陷阱之四-—-个股权重" class="headerlink" title="陷阱之四 — 个股权重"></a>陷阱之四 — 个股权重</h3><p>在解决上门几个问题时，已经做了无数次的回测了，每次都会发生同一个现象，那就是：从2017年开始策略就会落后基准，然后同基准的差距越拉越大。初看感觉就是策略上出问题了。但是，检查持仓也没有发现什么。难道是回测框架（RQAlpha）的问题？</p><p>为了验证我的想法，我又设计了一个测试方案。我想，既然我的基准是沪深300全收益指数，那么我干脆再写一个策略。每次调仓从沪深300里面<strong>随机</strong>抽取50只股票，也是等权重。那么，跑出来的收益应该同沪深300指数差不多吧。于是继续一通敲击键盘。执行回测，出结果，见下图：</p><img src="/2020/09/30/screening-improvement/hs300_compare.PNG" class=""><p>What？！同样从2017年开始分叉了。我再将佣金调成了0，结果也一样。。。不会真的是回测框架的bug吧？！当时也真的是两眼一黑，觉得要另找回测框架了，心中真的是一万匹草泥马奔腾啊！</p><p>转念一想，我每次调仓用的是等权重，而沪深300是流通市值权重。那我是不是该找沪深300等权重指数作为基准来回测一下呢？想想觉得有一定道理，反正死马当活马，再跑一边，出结果：</p><img src="/2020/09/30/screening-improvement/hs300_ew_compare.PNG" class=""><p>跑了几遍，基本能验证我的想法。其实用沪深300指数和沪深300等权重指数直接比较一下，就能发现端倪：</p><img src="/2020/09/30/screening-improvement/hs300_vs_300.PNG" class=""><p>等权重指数严重跑输市值指数。说明市值大的股票要比市值小的股票表现更出色。</p><p>Ok，长舒一口气，看来权重决定成败了。那么，接下去就不是排查问题了，目标很明确，对股票权重进行优化。（overfitting?!）</p><h2 id="优化权重"><a href="#优化权重" class="headerlink" title="优化权重"></a>优化权重</h2><p>有了明确的目标，接下来就好办了，不用等权重，换用其他的权重做一下测试。继续猛敲一通键盘（看来应该去买一个手感好一点的键盘了）。</p><h3 id="使用流通市值权重"><a href="#使用流通市值权重" class="headerlink" title="使用流通市值权重"></a>使用流通市值权重</h3><p>首先想到的就是以市值做为权重。那么在入围的50只股票里面，大盘股的权重大而小盘股的权重小。我直接使用“000985.XSHG，中证全指” 里面的权重为基础，对50只股票按比例重新分配权重（即50只股票的权重之和等于1）。举例来说，假如我的portfolio里有2只股票000001.XSHE和000004.XSHE，在2015-06-12的中证全指里：</p><ul><li>000001.XSHE的权重为0.0040</li><li>000004.XSHE的权重为0.0001</li></ul><p>那么经过换算，这两只股票的权重分别为：</p><ul><li>000001.XSHE的权重为0.97561</li><li>000004.XSHE的权重为0.02439</li></ul><p>使用流通市值权重进行回测的结果是：</p><img src="/2020/09/30/screening-improvement/cap_w_no_limit.PNG" class=""><p>Holly Cow… 71.5%的收益而基准收益为-3%！！！我整个人为之一振啊，这岂止是咸鱼翻身啊。。。（放飞自我了10多分钟以后）我想还是该仔细看一下结果，这确实有点事后诸葛亮的味道，毕竟我看到了等权重指数和市值指数的差异以后再来改我的策略。这有点overfitting的味道了。</p><p>以2019-05-06 rebalance后的持仓前5位为例：</p><div class="table-container"><table><thead><tr><th>label</th><th>position_value</th><th>name</th><th>weight</th></tr></thead><tbody><tr><td>600519.XSHG</td><td>271800.0</td><td>贵州茅台</td><td>0.361408</td></tr><tr><td>000858.XSHE</td><td>128968.0</td><td>五粮液</td><td>0.146703</td></tr><tr><td>600585.XSHG</td><td>50063.0</td><td>海螺水泥</td><td>0.059027</td></tr><tr><td>601888.XSHG</td><td>45606.0</td><td>中国中免</td><td>0.055920</td></tr><tr><td>603288.XSHG</td><td>44250.0</td><td>海天味业</td><td>0.053504</td></tr></tbody></table></div><p>可见光茅台一家就占了31%的仓位。这样的仓位从投资组合角度来说风险暴露程度太高了，茅台一家的涨跌直接影响了整个portfolio。而另一个问题是排在第二大仓位的股票是五粮液，而茅台和五粮液同属一个行业，因此，这样的持仓行业集中度也太高了。可以说这是overfitting了。</p><h3 id="流通市值"><a href="#流通市值" class="headerlink" title="流通市值++"></a>流通市值++</h3><p>那就继续对股票权重进行改进。我想到了一个方案：我设置一个单只股票持仓的阈值，portfolio里的股票持仓不能超过这个阈值。比如我设置20%作为阈值，在根现有权重排序，最大的排在最前。那么，上面持仓中，茅台就超过了，因此茅台的持仓变为20%，而多余的部分按比例分配给其余几家公司。如果排在第二家的权重也超了，那么继续这个过程。</p><p>举例来说，我有如下的仓位:</p><div class="table-container"><table><thead><tr><th>label</th><th>w</th></tr></thead><tbody><tr><td>001</td><td>0.50</td></tr><tr><td>002</td><td>0.40</td></tr><tr><td>005</td><td>0.04</td></tr><tr><td>003</td><td>0.03</td></tr><tr><td>004</td><td>0.03</td></tr></tbody></table></div><p>我的阈值为20%，那么经过处理得到如下的权重：</p><div class="table-container"><table><thead><tr><th>label</th><th>w</th></tr></thead><tbody><tr><td>001</td><td>0.200</td></tr><tr><td>002</td><td>0.160</td></tr><tr><td>003</td><td>0.192</td></tr><tr><td>004</td><td>0.192</td></tr><tr><td>005</td><td>0.256</td></tr></tbody></table></div><p>通过这样处理就好比regularization能将那些出现极端仓位的情况化解掉，防止overfitting。</p><p>那么对于我个人而言，20%是个股的极端仓位了，因此我将阈值设置成20%并回测，结果如下：</p><img src="/2020/09/30/screening-improvement/thresh_20_per.PNG" class=""><p>近60%的收益，同之前71.5%的收益比有所下降。但这样的权重设置在实际应用中会更加可靠。再来比较一下2019-05-06 rebalance后持仓比例的变化</p><div class="table-container"><table><thead><tr><th>label</th><th>position_value</th><th>name</th><th>原weight</th><th>新weight</th></tr></thead><tbody><tr><td>600519.XSHG</td><td>271800.0</td><td>贵州茅台</td><td>0.361408</td><td>0.2</td></tr><tr><td>000858.XSHE</td><td>128968.0</td><td>五粮液</td><td>0.146703</td><td>0.16</td></tr><tr><td>600585.XSHG</td><td>50063.0</td><td>海螺水泥</td><td>0.059027</td><td>0.0768</td></tr><tr><td>601888.XSHG</td><td>45606.0</td><td>中国中免</td><td>0.055920</td><td>0.072758</td></tr><tr><td>603288.XSHG</td><td>44250.0</td><td>海天味业</td><td>0.053504</td><td>0.069614</td></tr></tbody></table></div><p>由上表可见，不光茅台的权重设置成了0.2，茅台+五粮液的权重也明显下降了。个人感觉这个权重分配的算法是比较适合真实应用。由于阈值可以灵活设置，因此可以设置得更加保守，比如15%或10%。下图显示了10%为阈值的回测结果（真的是回测做到吐啊。。。），依旧能获得45.37%的回报。</p><img src="/2020/09/30/screening-improvement/thresh_10_per.PNG" class=""><h2 id="策略回测结果"><a href="#策略回测结果" class="headerlink" title="策略回测结果"></a>策略回测结果</h2><p>最后展示一下策略生成持仓结果，我的设置如下：</p><ul><li>起始时间2015-06-12</li><li>终止时间2020-09-25</li><li>持仓阈值10%</li><li>选股范围：中证全指</li><li>每年rebalance2次，分别为4月30日以及10月31日以后的第一个交易日</li></ul><p>以下展示每年10月31日后第一个交易日rebalance完成后的持仓（top 5）：</p><h3 id="2015"><a href="#2015" class="headerlink" title="2015"></a>2015</h3><div class="table-container"><table><thead><tr><th>label</th><th>position_value</th><th>name</th><th>weight</th></tr></thead><tbody><tr><td>600276.XSHG</td><td>51510.0</td><td>恒瑞医药</td><td>0.088675</td></tr><tr><td>600271.XSHG</td><td>44728.0</td><td>航天信息</td><td>0.077000</td></tr><tr><td>600066.XSHG</td><td>40090.0</td><td>宇通客车</td><td>0.069016</td></tr><tr><td>300017.XSHE</td><td>36174.0</td><td>网宿科技</td><td>0.062274</td></tr><tr><td>600649.XSHG</td><td>28740.0</td><td>城投控股</td><td>0.049476</td></tr></tbody></table></div><h3 id="2016"><a href="#2016" class="headerlink" title="2016"></a>2016</h3><div class="table-container"><table><thead><tr><th>label</th><th>position_value</th><th>name</th><th>weight</th></tr></thead><tbody><tr><td>600519.XSHG</td><td>63336.0</td><td>贵州茅台</td><td>0.104413</td></tr><tr><td>600887.XSHG</td><td>57824.0</td><td>伊利股份</td><td>0.095326</td></tr><tr><td>600276.XSHG</td><td>51579.0</td><td>恒瑞医药</td><td>0.085031</td></tr><tr><td>300072.XSHE</td><td>30821.0</td><td>三聚环保</td><td>0.050810</td></tr><tr><td>000568.XSHE</td><td>28320.0</td><td>泸州老窖</td><td>0.046687</td></tr></tbody></table></div><h3 id="2017"><a href="#2017" class="headerlink" title="2017"></a>2017</h3><div class="table-container"><table><thead><tr><th>label</th><th>position_value</th><th>name</th><th>weight</th></tr></thead><tbody><tr><td>600887.XSHG</td><td>77004.0</td><td>伊利股份</td><td>0.093416</td></tr><tr><td>600276.XSHG</td><td>68510.0</td><td>恒瑞医药</td><td>0.083112</td></tr><tr><td>600519.XSHG</td><td>62301.0</td><td>贵州茅台</td><td>0.075579</td></tr><tr><td>002304.XSHE</td><td>56600.0</td><td>洋河股份</td><td>0.068663</td></tr><tr><td>600309.XSHG</td><td>44820.0</td><td>万华化学</td><td>0.054373</td></tr></tbody></table></div><h3 id="2018"><a href="#2018" class="headerlink" title="2018"></a>2018</h3><div class="table-container"><table><thead><tr><th>label</th><th>position_value</th><th>name</th><th>weight</th></tr></thead><tbody><tr><td>600585.XSHG</td><td>70560.0</td><td>海螺水泥</td><td>0.103942</td></tr><tr><td>601888.XSHG</td><td>63516.0</td><td>中国中免</td><td>0.093566</td></tr><tr><td>603288.XSHG</td><td>58680.0</td><td>海天味业</td><td>0.086442</td></tr><tr><td>600309.XSHG</td><td>52110.0</td><td>万华化学</td><td>0.076764</td></tr><tr><td>600516.XSHG</td><td>29400.0</td><td>方大炭素</td><td>0.043309</td></tr></tbody></table></div><h3 id="2019"><a href="#2019" class="headerlink" title="2019"></a>2019</h3><div class="table-container"><table><thead><tr><th>label</th><th>position_value</th><th>name</th><th>weight</th></tr></thead><tbody><tr><td>000858.XSHE</td><td>93590.0</td><td>五粮液</td><td>0.099662</td></tr><tr><td>002475.XSHE</td><td>91868.0</td><td>立讯精密</td><td>0.097829</td></tr><tr><td>603288.XSHG</td><td>78603.0</td><td>海天味业</td><td>0.083703</td></tr><tr><td>600585.XSHG</td><td>73899.0</td><td>海螺水泥</td><td>0.078694</td></tr><tr><td>300015.XSHE</td><td>54522.0</td><td>爱尔眼科</td><td>0.058060</td></tr></tbody></table></div><h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>最后聊点感想，如果要写一些言之有物的东西真心是需要做大量的工作。这篇文章（其实也包括我写的其他内容）背后是大量的代码和测试。对于那些每天更新的自媒体，我不敢说100%但十之八九是没啥信息量。高质量的文章如果能做到每周更新那真的非常不易。</p><p>本篇把回测过程中碰到的陷阱给逐个解决了，而且还搞定了个股权重问题，下一篇《screen（筛选器）之三》打算着手优化aggregate z-score的权重问题，也就是每个factor该如何分配权重。敬请期待！</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;本文描述了在对screen（股票筛选器）进行回测的过程中所碰到的各种问题以及对应的解决方法。最后，通过对portfolio中个股权重进行优化，获得了一个相当不错的回测结果。回测以股灾顶峰（2015-06-12）为开始时点一直到2020-09-25，并以比较保守的参数设置，期间获得了近45%的总收益或年化7.5%的收益。&lt;/p&gt;
    
    </summary>
    
    
      <category term="量化投资组合管理" scheme="https://www.keepswalking.com/categories/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%BB%84%E5%90%88%E7%AE%A1%E7%90%86/"/>
    
    
  </entry>
  
  <entry>
    <title>一个基于价值的screen（筛选器） -- 大概是最简单的量化投资</title>
    <link href="https://www.keepswalking.com/2020/09/23/screening-in-practice/"/>
    <id>https://www.keepswalking.com/2020/09/23/screening-in-practice/</id>
    <published>2020-09-23T06:13:52.000Z</published>
    <updated>2020-09-29T03:41:45.191Z</updated>
    
    <content type="html"><![CDATA[<p>本文设计了一个能长期跑赢沪深300指数的screen。并通过回测观察了该screen在不同市场环境下的表现。对基于价值的股票投资有一定的指导意义。</p><a id="more"></a><p>量化的第一步通常是确定投资标的池，面对几千只股票，通过初步的筛选，哪些是符合标准并进入池子中。这步工作不太可能人工完成，因为数量实在太大。那么，接下来一个问题的我该如何设计一个screening？这就涉及到你的投资风格问题了，通常来说，有如下这些风格：</p><ul><li>价值股投资；格雷厄姆，巴菲特都是祖师爷。</li><li>成长股投资；贵有贵的道理。。。</li><li>趋势投资；顺势而为。</li><li>逆向投资；人弃我取。</li><li>跟投；别人投啥我投啥，比如跟踪外资策略。</li><li>。。。</li></ul><p>我比较认同价值投资，因此就基于价值投资的理念，设计一个screening。顺便扯一下题外话，买P/E是100倍的股票未必就不是价值投资。价值投资的本质上还是看买入的价格是否低于内在价值，言归正传。既然目标是做一个价值投资的screen，那就来明确一下该目标背后的含义。我希望通过该screen，找到被错误定价的公司，即被低估的公司，价格便宜，但没有明显的负面因素造成这种低估，例如高风险，低增长，或低质量的增长（需要很高的资本投入等）。换句话说，<strong>我希望找到一组股票，在低价格乘数（multiples）区间交易（e.g.低P/E），公司风险低，有高的增长，并且增长的质量好</strong>。这么写出来是不是觉得在做梦啊？！Too good to be true！这就对了，凭啥赚钱那么容易？！你都觉得不可能了说明市场其实在大部分时间还是有效的！但是，虽然觉得概率低，试着找找看这样的股票也没啥坏处，指不定就真在地上找到了皮夹子。</p><h2 id="Screen-维度"><a href="#Screen-维度" class="headerlink" title="Screen 维度"></a>Screen 维度</h2><p>接下来我就从下面几个维度开始设计screening：</p><ul><li>价格</li><li>风险</li><li>成长性</li><li>成长质量</li></ul><h3 id="Screen-for-price"><a href="#Screen-for-price" class="headerlink" title="Screen for price"></a>Screen for price</h3><p>衡量价格一般用价格乘数，相关指标有很多，最常用的P/E，P/B。需要指出一个大原则，如下图所示：</p><img src="/2020/09/23/screening-in-practice/Multiple.jpg" class=""><p>即分子与分母从财务角度必须一致，如果分子是equity value，那分母也必须是equity value。同样，如果分子是enterprise value，那分母也必须是enterprise value。举例来说，P/E 是满足一致性要求的，P（price）是equity value，E(earning, net income)也是equity value。</p><p>由于不同行业有其自身的特征，比如有些行业杠杆率高，为了实现跨行业的可比性，我使用enterprise value 乘数： <strong>EV / EBIT</strong>。其中：</p><ul><li>EV = enterprise value = market value of equity + interest-bearing debt - cash</li><li>EBIT，息税前利润。</li></ul><p>有了价格乘数，那么接下来一个问题是：如何算是便宜？可以有两种方式：</p><ul><li>绝对，设定一个具体的EV / EBIT 标准，超过了就算贵。</li><li>相对，对所有股票EV / EBIT 进行排序，设定一个百分比，比如top 33% 算贵。</li></ul><p>我倾向使用相对方式进行screening。因为，格雷厄姆时代的标准放到今天可能就找不到股票了。</p><h3 id="Screen-for-risk"><a href="#Screen-for-risk" class="headerlink" title="Screen for risk"></a>Screen for risk</h3><p>Risk 可以分为：</p><ul><li>Operating risk，主要是从公司经营角度出发，影响营收或公司正常用作的风险</li><li>Financial risk, 从财务角度出发，例如债务</li><li>Liquidity risk，主要从股票持有人变现角度出发，如买卖spread，公司停牌之类</li></ul><p>对于设计Screen来说，一般比较容易做的是：</p><ul><li>基于价格：如股票的beta，或是standard deviation for returns。</li><li>基于会计：根据财务报表上的数据进行分析，例如公司偿债能力。</li></ul><p>从债务杠杆出发，选用<strong>book debt-to-equity ratio</strong>作为风险度量。当然，并非说债务高就一定不好。但是，“这个世界上没有无缘无故的狠”，便宜的股票通常在财务上面临压力，因此，在此前提下，债务越低越安全。之所以没有使用market value来计算debt-to-equity ratio是因为market value of equity其实是price的一种度量，而EV / EBIT已经度量了价格。</p><p>除了考虑债务杠杆的绝对值，在加入债务杠杆的变化：</p><p><strong>Change in book D/E = Current year’s D/E - prior year’s D/E</strong></p><p>收入容易被操控，因此是一个需要小心的地方。如果net income大于cash flow from operatinos，那么就有可能是一个不好的信号。使用以下指标：</p><p><strong>ACCRUAL = (NI-CFO)/TA</strong></p><p>其中：</p><ul><li>NI = net income before extraordinary items</li><li>CFO = cash flow from operations</li><li>TA = total assets</li></ul><h3 id="Screen-for-growth"><a href="#Screen-for-growth" class="headerlink" title="Screen for growth"></a>Screen for growth</h3><p>对于增长我没有太多好的想法，使用一致性预期应该是一个不错的选择，但是，并非每只股票都有一致性预期，尤其是不受待见的问题股票。因此，我就简单用Revenue growth了：</p><p><strong>Revenue growth = Current year’s Revenue / Prior years’s Revenue - 1</strong></p><p>这里，我还想加入一个技术指标用来表示增长：Momentum，使用3个月的股票价格的return：</p><p><strong>M3M = 3-Month price change</strong></p><h3 id="Screen-for-quality-of-growth"><a href="#Screen-for-quality-of-growth" class="headerlink" title="Screen for quality of growth"></a>Screen for quality of growth</h3><p>我希望入围的公司不光有增长，而且增长的质量比较高。比如，不用靠很高的资本支出。对于这个Screen，我使用return on invested capital （ROIC）。</p><p><strong>ROIC = EBIT(1-t) / (Book value of equity + book value of debt - cash)</strong></p><p>进一步，不光考虑ROIC的绝对水平，还进一步考虑ROIC的变化：</p><p><strong>Change in ROIC = Current year’s ROIC - prior year’s ROIC</strong></p><p>总结一下，我用了一下这些条件对股票进行过滤：</p><ul><li>Price<ul><li>EV / EBIT</li></ul></li><li>Risk<ul><li>book debt-to-equity ratio</li><li>Change in book D/E</li><li>ACCRUAL = (NI-CFO)/TA</li></ul></li><li>Growth<ul><li>Revenue growth</li><li>M3M = 3-Month price change</li></ul></li><li>Quality<ul><li>ROIC</li><li>Change in ROIC</li></ul></li></ul><p>一共8个过滤条件。</p><h2 id="两种不同的过滤方式"><a href="#两种不同的过滤方式" class="headerlink" title="两种不同的过滤方式"></a>两种不同的过滤方式</h2><p>如何使用这8个条件进行筛选并获得目标股票池？一种方式是<strong>顺序过滤</strong>。根据重要性将条件排序。比如，我觉得股票是否便宜是最重要的，那么就将EV / EBIT排在第一位，用这个条件将所有股票进行排序，然后选择top 50%，然后接下来再用次重要的条件对入围的股票再进行排序，依次完成所有的条件。但是，这么做有几个问题：</p><ul><li>如果某两个或多个条件具有相同的重要性，你必须给定一个顺序，这样造成的结果就是会过滤掉你希望保留的股票。</li><li>最后可能没有满足条件的股票，或结果集的数量太少了。</li></ul><p>为了解决以上问题，可以使用<strong>多条件并行过滤（simultaneous screening）</strong>的方法：</p><ul><li>首先将每个条件的值进行标准化处理 — Z-Score</li><li>将各个条件的z-score值按照一定的权重加总</li><li>根据加总后值进行排序，获得过滤结果</li></ul><p>这里需要注意的地方是：</p><ul><li>对条件值进行标准化处理可以有多种方法，我选用z-score。这步是必须的，否则不同的条件值之间的数量级会有很大的差别。汇总后，那些值很大的条件就会对结果产生更大的影响</li><li>不同条件z-score的方向应该有相同的影响。比如，z-score大，代表有正面影响，反之则有负面影响</li></ul><h2 id="模型实现"><a href="#模型实现" class="headerlink" title="模型实现"></a>模型实现</h2><p>到了这步就要拿出我码农的本色！开始撸数据，写代码。目标就是计算出每只股票在对应条件上的z-score。其实，最大的挑战还是数据，包括获取数据，清理数据以及处理outlier。具体细节没必要放在这里（此处省略240行代码。。。）。我主要做以下工作：</p><ul><li>工具方面，基本就是python了，利用numpy，pandas来存储加工数据</li><li>数据利用的是ricequant平台，不得不说，他们在数据的二次加工上做的挺完善，基本上你想要的股票基本面数据他们都提供了。这就极大简化了数据处理的工作，至于数据是否准确，还需要观察一段时间</li><li>扫描全部A股。确保股票至少上市3年才进入我的筛选范围</li><li>对于EBIT &lt; 0的股票不考虑，虽说EBIT &lt; 0不代表这支股票不好，但是，由于我这里的策略还是基于value，而EBIT &lt; 0 的股票有可能是成长型公司，或是公司经营出了问题。另外，如果EBIT &lt; 0，那么EV / EBIT就变得没有意义</li><li>对于outlier，我的定义是z-score &gt; 3 或 z-score &lt; -3，发现outlier，我并不是简单做删除处理，而是将outlier设置成3或-3</li><li>剔除了所有的金融股票，包括银行和非银，原因很简单，你很难定义什么是他们的debt，就更不用说interesting bearing debt了，那该怎么计算他们的debt to equity ratio呢？</li></ul><p>下图所示是数据处理完的结果：</p><img src="/2020/09/23/screening-in-practice/zscore.PNG" class=""><p>上半部分cleaned_df是所有股票的条件值的计算结果，下半部分则是将其转化成了z-score。至此z-score都已计算完成。</p><h2 id="z-score权重"><a href="#z-score权重" class="headerlink" title="z-score权重"></a>z-score权重</h2><p>有了各个条件上z-core，那么接下来我需要加总求和。如何求和？也就是每个条件上z-score对应的权重是多少？这个权重该如何确定？</p><p>最简单的方法：等权重求和了！虽说是简单粗暴，但是，等权重也是有一个明显的好处，那就避免了overfitting！因此是一个不错的benchmark，以后对z-score权重的优化都可以同这个等权重benchmark做比较。再强调一下，每个条件上的z-score在求和的时候必须保证同方向，因此求和操作应如下：</p><p>SUM of Z-Score =  </p><ul><li><em>minus</em> EV / EBIT </li><li><em>minus</em> book debt-to-equity ratio</li><li><em>minus</em> Change in book D/E</li><li><em>minus</em> (NI-CFO)/TA</li><li><em>plus</em> Revenue growth</li><li><em>plus</em> M3M</li><li><em>plus</em> ROIC</li><li><em>plus</em> Change in ROIC</li></ul><p>下表显示了排名前50的股票：</p><div class="table-container"><table><thead><tr><th>label</th><th>z_score_sum</th><th>symbol</th><th>industry_code</th><th>industry_name</th></tr></thead><tbody><tr><td>300677.XSHE</td><td>10.716210</td><td>英科医疗</td><td>C29</td><td>橡胶和塑料制品业</td></tr><tr><td>002869.XSHE</td><td>7.475962</td><td>金溢科技</td><td>C39</td><td>计算机、通信和其他电子设备制造业</td></tr><tr><td>600421.XSHG</td><td>7.123312</td><td>ST仰帆</td><td>C34</td><td>通用设备制造业</td></tr><tr><td>002164.XSHE</td><td>7.034439</td><td>宁波东力</td><td>C35</td><td>专用设备制造业</td></tr><tr><td>601020.XSHG</td><td>6.866158</td><td>华钰矿业</td><td>B09</td><td>有色金属矿采选业</td></tr><tr><td>002838.XSHE</td><td>6.495545</td><td>道恩股份</td><td>C29</td><td>橡胶和塑料制品业</td></tr><tr><td>300552.XSHE</td><td>6.002087</td><td>万集科技</td><td>I65</td><td>软件和信息技术服务业</td></tr><tr><td>002124.XSHE</td><td>5.956577</td><td>天邦股份</td><td>C13</td><td>农副食品加工业</td></tr><tr><td>603606.XSHG</td><td>5.861706</td><td>东方电缆</td><td>C38</td><td>电气机械和器材制造业</td></tr><tr><td>002289.XSHE</td><td>5.485774</td><td>ST宇顺</td><td>C39</td><td>计算机、通信和其他电子设备制造业</td></tr><tr><td>000048.XSHE</td><td>5.417372</td><td>京基智农</td><td>C13</td><td>农副食品加工业</td></tr><tr><td>002286.XSHE</td><td>5.285237</td><td>保龄宝</td><td>C13</td><td>农副食品加工业</td></tr><tr><td>300464.XSHE</td><td>4.960576</td><td>星徽精密</td><td>F52</td><td>零售业</td></tr><tr><td>603129.XSHG</td><td>4.847436</td><td>春风动力</td><td>C37</td><td>铁路、船舶、航空航天和其他运输设备制造业</td></tr><tr><td>300056.XSHE</td><td>4.837722</td><td>中创环保</td><td>C35</td><td>专用设备制造业</td></tr><tr><td>600652.XSHG</td><td>4.782898</td><td>ST游久</td><td>I64</td><td>互联网和相关服务</td></tr><tr><td>002216.XSHE</td><td>4.725449</td><td>三全食品</td><td>C14</td><td>食品制造业</td></tr><tr><td>300246.XSHE</td><td>4.653786</td><td>宝莱特</td><td>C35</td><td>专用设备制造业</td></tr><tr><td>002714.XSHE</td><td>4.440177</td><td>牧原股份</td><td>A03</td><td>畜牧业</td></tr><tr><td>600132.XSHG</td><td>4.402648</td><td>重庆啤酒</td><td>C15</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>002030.XSHE</td><td>4.378498</td><td>达安基因</td><td>C27</td><td>医药制造业</td></tr><tr><td>300274.XSHE</td><td>4.367707</td><td>阳光电源</td><td>C38</td><td>电气机械和器材制造业</td></tr><tr><td>002555.XSHE</td><td>4.361072</td><td>三七互娱</td><td>I64</td><td>互联网和相关服务</td></tr><tr><td>002677.XSHE</td><td>4.335123</td><td>浙江美大</td><td>C38</td><td>电气机械和器材制造业</td></tr><tr><td>300103.XSHE</td><td>4.327513</td><td>达刚控股</td><td>N77</td><td>生态保护和环境治理业</td></tr><tr><td>002312.XSHE</td><td>4.320156</td><td>三泰控股</td><td>C26</td><td>化学原料及化学制品制造业</td></tr><tr><td>601633.XSHG</td><td>4.311244</td><td>长城汽车</td><td>C36</td><td>汽车制造业</td></tr><tr><td>300225.XSHE</td><td>4.307500</td><td>金力泰</td><td>C26</td><td>化学原料及化学制品制造业</td></tr><tr><td>300676.XSHE</td><td>4.304628</td><td>华大基因</td><td>M74</td><td>专业技术服务业</td></tr><tr><td>603416.XSHG</td><td>4.267281</td><td>信捷电气</td><td>C40</td><td>仪器仪表制造业</td></tr><tr><td>603338.XSHG</td><td>4.231131</td><td>浙江鼎力</td><td>C35</td><td>专用设备制造业</td></tr><tr><td>300435.XSHE</td><td>4.172462</td><td>中泰股份</td><td>D45</td><td>燃气生产和供应业</td></tr><tr><td>603906.XSHG</td><td>4.095128</td><td>龙蟠科技</td><td>C26</td><td>化学原料及化学制品制造业</td></tr><tr><td>002285.XSHE</td><td>4.074116</td><td>世联行</td><td>K70</td><td>房地产业</td></tr><tr><td>300411.XSHE</td><td>4.064889</td><td>金盾股份</td><td>C34</td><td>通用设备制造业</td></tr><tr><td>000913.XSHE</td><td>4.055015</td><td>钱江摩托</td><td>C37</td><td>铁路、船舶、航空航天和其他运输设备制造业</td></tr><tr><td>002735.XSHE</td><td>4.049436</td><td>王子新材</td><td>C29</td><td>橡胶和塑料制品业</td></tr><tr><td>603877.XSHG</td><td>3.998039</td><td>太平鸟</td><td>C18</td><td>纺织服装、服饰业</td></tr><tr><td>601216.XSHG</td><td>3.992290</td><td>君正集团</td><td>C26</td><td>化学原料及化学制品制造业</td></tr><tr><td>002706.XSHE</td><td>3.991975</td><td>良信电器</td><td>C38</td><td>电气机械和器材制造业</td></tr><tr><td>603787.XSHG</td><td>3.990077</td><td>新日股份</td><td>C37</td><td>铁路、船舶、航空航天和其他运输设备制造业</td></tr><tr><td>000897.XSHE</td><td>3.988275</td><td>津滨发展</td><td>K70</td><td>房地产业</td></tr><tr><td>601012.XSHG</td><td>3.951803</td><td>隆基股份</td><td>C30</td><td>非金属矿物制品业</td></tr><tr><td>603960.XSHG</td><td>3.926110</td><td>克来机电</td><td>C35</td><td>专用设备制造业</td></tr><tr><td>002730.XSHE</td><td>3.869764</td><td>电光科技</td><td>C35</td><td>专用设备制造业</td></tr><tr><td>002569.XSHE</td><td>3.842822</td><td>ST步森</td><td>C18</td><td>纺织服装、服饰业</td></tr><tr><td>601069.XSHG</td><td>3.841323</td><td>西部黄金</td><td>B09</td><td>有色金属矿采选业</td></tr><tr><td>002568.XSHE</td><td>3.825067</td><td>百润股份</td><td>C15</td><td>酒、饮料和精制茶制造业</td></tr><tr><td>300405.XSHE</td><td>3.803350</td><td>科隆股份</td><td>C26</td><td>化学原料及化学制品制造业</td></tr><tr><td>002833.XSHE</td><td>3.783292</td><td>弘亚数控</td><td>C35</td><td>专用设备制造业</td></tr></tbody></table></div><p>新鲜出炉啊~~~这是根据2020年Q3财报产生的结果。</p><h2 id="回测"><a href="#回测" class="headerlink" title="回测"></a>回测</h2><p>回测其实更为繁琐，借助RQAlpha框架，真的是极大的降低了工作量（此处又省略了296行代码。。。）。在本篇中，我只用最简单粗暴的方式进行回测，不做任何的优化。说一下我在回测过程中做了哪些处理：</p><ul><li>在构建portfolio时，直接用aggregate z-score为top 50的股票；也就是说没有太多考虑分散投资，在下一篇，我会根据行业构建一个相对分散投资的portfolio。</li><li>使用等权重资金投资到每个股票，也就是说，有50只股票，将资金等分成50份，每份投资一只股票。如果以后做优化的话，可以考虑risk parity方法，或根据每只股票的预期收益，做MVO。我觉得sharpe ratio应该是可以提高不少。</li><li>在回测的过程中考虑<strong>forward looking bias</strong>。由于国内财报的披露时间为：<ul><li>1季报：每年4月1日——4月30日。</li><li>2季报（中报）：每年7月1日——8月31日。</li><li>3季报： 每年10月1日——10月31日<br>因此我在回测的过程中，定义获取财报的时间分别为：</li><li>1季报：4月30日以后的第一个交易日。</li><li>2季报（中报）：8月31日以后的第一个交易日。</li><li>3季报： 10月31日以后的第一个交易日。</li></ul></li><li>每年做3次rebalance，分别对应以上三个财报季。rebalance方式也是简单粗暴，第一步全部卖出，第二步再以等权重方式买入新入围的50只股票。因此将来，这步也是有很多的优化可以做。</li><li>考虑了<strong>survival bias</strong>，比如，我从2015年6月12日开始回测，那我会以当时股票市场的全部股票作为我的pool，并以此进行screening（而非今天市场上的全部股票）。而当时的股票到今天可能已经退市了！因此用这种方式进行回测能避免survival bias。</li></ul><p>下面上结果，我先用2年时长进行回测（2018-9-25到2020-9-25）：</p><img src="/2020/09/23/screening-in-practice/backtest1.PNG" class=""><ul><li>基准是沪深300指数</li><li>深红色是screen的净值曲线，蓝色是基准，黄色是超额收益</li><li>2年的周期最后是跑赢了基准！但是，有超过1年多的时间是落后基准，这里想表达的意思是，使用这个screen（包括其他策略）需要有一个相对长期的预期，不能期望时时刻刻都能跑赢基准</li><li>整体来说和沪深300的相关性很高，beta=0.9。screen的收益是46.66%，基准的收益是33.734%。作为未经任何优化的screen能取得这样的结果还是有点出乎我的意料</li></ul><p>然后，我想看看2015年股灾后的表现，用了一个很极端的场景：从2015-6-12开始回测，也就是<strong>从股灾的顶点开始</strong>，一直到2020-9-25。我想看看，这个策略在股灾巨幅下跌时的表现，以及需要多久能重新回到原点。如下图所示：</p><img src="/2020/09/23/screening-in-practice/backtest2015.PNG" class=""><ul><li>首先这段回测超过5年。从刚开始那段暴跌看，似乎screen也没有表现出抗跌的特点，但有意思的是，在其后的反弹过程中大幅跑赢了基准</li><li>最终的结果看screen不仅收复了所有的下跌，还获得了7.288%的收益，而沪深300还亏损了13.88%！其实不能觉得5年多才7.288%，要知道这是很极端的情况，也就是你在泡沫的顶点开始投资！因此对screen的表现也觉得挺不错！</li><li>还有一点比较有意思，就是沪深300代表的大盘股从2016年2月开始稳步上涨一直到2018年1月，而screen在这段时间一直没有表现，甚至在行情结束时被反超。因此，要坚持策略也需要有个强大的内心！</li><li>这里beta只有0.8，我觉得是一个好现象，长期来看同沪深300的相关性变低了</li></ul><p>聊一聊下一步打算，我会对这个screen做进一步的优化：</p><ul><li>在计算aggregate z-score时，不是简单粗暴的使用等权重</li><li>在构建portfolio时，不是简单的选择aggregate z-score为top n的那些股票，而是考虑如何做好分散。因为排在前面的股票可能会集中在某几个行业，这样，你的portfolio就太集中了</li><li>对screen做一些风格方面的调整，比如，我就想追求绝对便宜，那么可以试一下先根据 EV / EBIT 剔除掉最贵的50%的股票，然后在余下的50%里面做aggregate z-score</li><li>rebalance时是否需要将股票全部换掉？可以考虑每次换出aggregate z-score最低的几只股票，并补充新的高分股票等等。。。</li></ul><p>这些测试我将放在下一篇。感觉本篇内容足够干货了! 等以上优化完成以后，我打算在雪球上以此建一个portfolio，作为benchmark长期跟踪，并能分享给有兴趣的朋友。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>最后，想谈谈使用各种类型的screen是否能击败市场获取超额收益。从经验上看是存在这个可能的，比如本文的screen，还有如Joel Greenblatt的神奇公式（更简单）长期也能跑赢SP500。但是，光是这样的跑赢是否足够，我们是否可以要求的更多？我比较认同Damodaran的观点，他认为作为一个投资者，你必须得有一些独特的东西（核心竞争力）才能在这个市场上获得超额收益。换句话说，就好像我们看公司会看它是不是有护城河，那么作为个人投资者，你需要考虑你的竞争优势在哪里。当格雷厄姆在1951年使用screen时，screen可以看作是一种竞争优势，因为：</p><ul><li><strong>首先，要做一个screen在当时并不容易</strong>。那个时代，要获取大量公司的财报，并且还得有自动化的工具来分析数据，对于普通投资者来说是一件相当难的事情，只有极少数实力强悍的投资者才具备这样的能力。</li><li><strong>其次，是纪律性</strong>，投资者必须让自己远离各种诱惑和潮流，并始终如一的关注screen产生的股票。</li><li><strong>第三，是耐心</strong>，投资者必须长期持有screen产生的股票才能获得理想的收益（这同本文的回测结果是相符的）</li></ul><p>今天，人们有各种途径获得股票数据，还有无数的分析工具。因此第一种优势几乎不存在了，（这里我想多说一句，在这一点上我不太认同，个人感觉，第一种优势在当今可能还是发挥着比较关键的作用，因为<strong>高质量的数据通常不会免费</strong>，所以仅此一点，就挡住了绝大部分的散户。其次是技术的使用，有多少投资人懂得python，甚至能熟练使用excel？）那么就剩下纪律和耐心作为你潜在的竞争优势。可以说，自动化的screening以及投资流程可以做到不需要人工介入，因此，这样一套系统从受到情绪化影响的角度来看，即使同最有纪律性且耐心的人来比，也明显胜出一大截！更直白的说，作为一个主动投资者，<strong>如果说所有你能拿得出手的东西仅仅是screen，那你基本不太可能打败机器</strong>。除了用screen武装自己外，你是否能赚到钱还取决于你在screen之后所做工作的质量。如果你在分析股票内在价值或定性研究方面有所专长，你也许能获取更高超额收益。</p><p>参考文献：</p><ul><li>Joseph D. Piotroski. Value Investing: The use of historical financial statement information to separate winners from losers. Journal of accounting Research Vol. 38 Supplement 2000</li><li>Ludwig B. Chincarini, Daehwan Kim. Quantitative Equity Portfolio Management . P89-179</li><li>Aswath Damodaran. Passive Value investing  Screening for bargains. <a href="https://aswathdamodaran.blogspot.com/2012/06/passive-value-investing-screening-for.html" target="_blank" rel="noopener">https://aswathdamodaran.blogspot.com/2012/06/passive-value-investing-screening-for.html</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;本文设计了一个能长期跑赢沪深300指数的screen。并通过回测观察了该screen在不同市场环境下的表现。对基于价值的股票投资有一定的指导意义。&lt;/p&gt;
    
    </summary>
    
    
      <category term="量化投资组合管理" scheme="https://www.keepswalking.com/categories/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%BB%84%E5%90%88%E7%AE%A1%E7%90%86/"/>
    
    
  </entry>
  
  <entry>
    <title>格力电器估值</title>
    <link href="https://www.keepswalking.com/2020/09/21/valuation-gree/"/>
    <id>https://www.keepswalking.com/2020/09/21/valuation-gree/</id>
    <published>2020-09-21T07:01:49.000Z</published>
    <updated>2020-09-21T08:10:24.921Z</updated>
    
    <content type="html"><![CDATA[<p>“2018年底，格力电器董事长兼总裁董明珠提出未来五年实现营业额6000亿元的目标”，董大姐挺会讲故事的。。。</p><p>估值结果：格力电器的内在价值大概为44.16元，而当前价格是56.55元，超过内在价值28%，个人觉得没啥安全边际。该内在价值同高瓴资本给出的价格比较接近。</p><a id="more"></a><p>先来吐槽一下某头部券商的研报，参见下图：</p><img src="/2020/09/21/valuation-gree/tucao1.PNG" class=""><p>永续阶段的ROE是23%。。。我挺无语的，永续阶段的ROE都差不多是腾讯控股现在的水平了。。。一般来说，永续阶段的ROE应该趋近于cost of equity，给个10%应该算挺高了。好了，吐槽完毕，言归正传。</p><h2 id="故事叙述"><a href="#故事叙述" class="headerlink" title="故事叙述"></a>故事叙述</h2><p>从格力电器所处的生命周期来看，目前格力处于成熟增长阶段（Mature Growth）。 格力的主营业务是空调，2018年，我国空调每百户保有量仅111.1台，未来目标每百户保有量水平为204.5 台，还有 84.1%上涨空间。因此市场还有进一步发展的空间（数据来源申万宏源）。我毛估估达到这个保有量需要10年吧，<strong>差不多以每年6.3%的速度增长</strong>。</p><p>主要竞争对手是美的，海尔，奥克斯。空调市场内部竞争激烈，2019年上半年，格力电器空调业务营收比美的高出了接近80亿元，但在今年上半年，美的暖通空调营收640亿元，超出了格力227亿元。主要原因在于格力疏于线上渠道的布局，而疫情恰恰对线下渠道冲击极大，转而有利于线上销售。</p><p>从利好方面来看，格力正在实施渠道改革+股权激励。还有就是：“2018年底，格力电器董事长兼总裁董明珠提出未来五年实现营业额6000亿元的目标”，而2019年的营业收入为1,981.5亿元。还剩下4年要翻3倍，每年要实现30%的增长，呵呵了，大概把美的的空调业吃下来还能看到点希望。最后就是一直被大肆宣传的高瓴资本入主格力，我大致看了一下，高瓴资本管理的资产规模在4200多亿人民币，2019年12月2日公司控股股东格力集团与高瓴资本控制的珠海明骏签署股份转让协议，珠海明骏以 <strong>46.17元/股</strong>（相比较于底价44.17元/股溢价4.5%）的价格，受让格力集团持有的格力电器15%股权，合计转让价款为416.62 亿元。那差不多占到高瓴资本的10%，数目也不能算小。</p><p>一致性预期显示：</p><div class="table-container"><table><thead><tr><th>年份</th><th>2020E</th><th>2021E</th><th>2022E</th></tr></thead><tbody><tr><td>营业总收入(百万元)</td><td>181,178.81</td><td>203,728.26</td><td>222,818.10</td></tr><tr><td>增长率(%)</td><td>-9.64</td><td>12.45</td><td>9.37</td></tr></tbody></table></div><h2 id="无风险利率"><a href="#无风险利率" class="headerlink" title="无风险利率"></a>无风险利率</h2><p>10年期国债：<strong>3.12%</strong></p><h2 id="市场风险溢价"><a href="#市场风险溢价" class="headerlink" title="市场风险溢价"></a>市场风险溢价</h2><p>对于中国市场，使用最新的Implied Risk Premium = 6.37%，参见：<a href="/2020/07/21/CN-implied-RP/" title="A股市场隐含风险溢价">A股市场隐含风险溢价</a>。</p><p>由于格力有部分营收来自海外市场，因此需要考虑海外市场的Risk Premium。但是，格力的财报里面没有披露海外市场的营收细节，统一归为“外销”！再根据中报，内销占比76%，但是，这个数据由于受到疫情的影响，可能是偏低的。因此，我查看了2019，2018的年报数据，这个比例还是比较稳定。内销占比87%，外销13%。我觉得格力的海外市场份额会逐步扩大，因此我试用80%，20%。</p><p>那么接下来的问题就是这些外销市场到底在哪里，我只能假设以东南亚为主了。那么由Damodaran的数据可得亚洲风险溢价的加权平均=7.29%，那么由下表：</p><div class="table-container"><table><thead><tr><th>地区</th><th>销售额</th><th>Risk Premium</th></tr></thead><tbody><tr><td>中国</td><td>80%</td><td>6.37%</td></tr><tr><td>亚洲（除中国）</td><td>20%</td><td>7.29%</td></tr></tbody></table></div><p>那么根据销售额加权平均可得格力电器对应的<strong>市场风险溢价为：6.55%</strong>。</p><h2 id="Estimate-bottom-up-unlevered-beta"><a href="#Estimate-bottom-up-unlevered-beta" class="headerlink" title="Estimate bottom-up unlevered beta"></a>Estimate bottom-up unlevered beta</h2><p>在相似行业内，过滤出54家公司。我使用了2种行业分类，一种是申万行业，选择“家用电器”（一级行业）；另一个使用GICS行业，选择“非日常生活消费品-耐用消费品与服装-家庭耐用消费品-家用电器”。一个获得57家公司。<strong>beta中值=0.9228</strong>。</p><p>然后，根据这些样本公司可以获得一下数据：</p><ul><li><strong>D/E 中值 = 0.107</strong></li><li><strong>cash / firm value 中值 = 0.1</strong>，其中Firm value = Market value of Equity + Market value of Debt</li><li>税率为25% （中国企业所得税）</li></ul><p>那么Unlevered beta = Regression beta / (1 + (1-tax rate) D/E) = 0.9228 / (1+(1-25%)0.107) = 0.854</p><p>Cash-adjusted beta = Unlevered beta / (1 – Cash/ Firm Value) = 0.854 / (1 - 0.1) = 0.949</p><h2 id="Estimate-market-value-of-equity-and-debt"><a href="#Estimate-market-value-of-equity-and-debt" class="headerlink" title="Estimate market value of equity and debt"></a>Estimate market value of equity and debt</h2><p>2020年中报第150页给出了有息债务的详情：</p><div class="table-container"><table><thead><tr><th>报表项目</th><th>金额（元）</th><th>利率区间 </th></tr></thead><tbody><tr><td>短期借款</td><td>20,437,330,880.32</td><td>1.35%-3.35%</td></tr><tr><td>向中央银行借款</td><td>47,253,790.52</td><td>2.25%</td></tr><tr><td>吸收存款及同业存放</td><td>228,625,054.88</td><td>0.35%-4.13%</td></tr><tr><td>拆入资金</td><td>1,500,163,611.11</td><td>2.25%-2.78%</td></tr><tr><td>卖出回购金融资产款</td><td>294,016,753.97</td><td>2.08%</td></tr><tr><td>长期借款</td><td>1,233,576,700.78</td><td>0.41%-6.18%</td></tr><tr><td>其他流动负债</td><td>3,008,591,296.02</td><td>1.39%</td></tr><tr><td>合计</td><td>26,749,558,087.60</td><td></td></tr></tbody></table></div><p>《表1》</p><p>即26749.55809百万元</p><p>equity = </p><ul><li>2020/9/9 收盘价 = 54.5</li><li>总股本 = 6,015,730,878</li></ul><p>可得：327857.3329 百万元人民币</p><p>因此，可得格力电器的<strong>D/E</strong> = 26749.55809 / 327857.3329 = <strong>0.0816</strong></p><h2 id="Estimate-bottom-up-levered-beta"><a href="#Estimate-bottom-up-levered-beta" class="headerlink" title="Estimate bottom-up levered beta"></a>Estimate bottom-up levered beta</h2><p>由格力 D/E=0.0816， Cash-adjusted beta = 0.949 可得 <strong>levered beta</strong> = Cash-adjusted beta (1 + (1-tax rate) D/E) = 0.931 (1+(1-25%)0.0816) = <strong>1.007</strong></p><h2 id="Estimate-pre-tax-cost-of-debt"><a href="#Estimate-pre-tax-cost-of-debt" class="headerlink" title="Estimate pre-tax cost of debt"></a>Estimate pre-tax cost of debt</h2><p>由《表1》做一些加工，下表中利率区间由中报直接给出：</p><div class="table-container"><table><thead><tr><th>报表项目</th><th>金额</th><th>利率区间</th><th>利率中值</th><th>weight</th></tr></thead><tbody><tr><td>短期借款</td><td>20,437,330,880.32</td><td>1.35%-3.35%</td><td>2.35%</td><td>76.40%</td></tr><tr><td>向中央银行借款</td><td>47,253,790.52</td><td>2.25%</td><td>2.25%</td><td>0.18%</td></tr><tr><td>吸收存款及同业存放</td><td>228,625,054.88</td><td>0.35%-4.13%</td><td>2.24%</td><td>0.85%</td></tr><tr><td>拆入资金</td><td>1,500,163,611.11</td><td>2.25%-2.78%</td><td>2.52%</td><td>5.61%</td></tr><tr><td>卖出回购金融资产款</td><td>294,016,753.97</td><td>2.08%</td><td>2.08%</td><td>1.10%</td></tr><tr><td>长期借款</td><td>1,233,576,700.78</td><td>0.41%-6.18%</td><td>3.30%</td><td>4.61%</td></tr><tr><td>其他流动负债</td><td>3,008,591,296.02</td><td>1.39%</td><td>1.39%</td><td>11.25%</td></tr><tr><td>合计</td><td>26,749,558,087.60</td><td></td><td></td><td></td></tr></tbody></table></div><p>可见，格力电器大部分的有息债务为短期债务。由于财报里只给出了利率范围，我只能用利率中值作为估计值，最后根据加权平均可得格力电器的<strong>pre-tax costs of debt = 2.29%</strong>。</p><h2 id="Estimate-a-tax-rate"><a href="#Estimate-a-tax-rate" class="headerlink" title="Estimate a tax rate"></a>Estimate a tax rate</h2><p>根据最近5年年报数据，<strong>effective tax rate = 15.5%</strong>。</p><p>而<strong>marginal tax rate 应该为25%</strong>。</p><h2 id="Estimate-a-cost-of-capital"><a href="#Estimate-a-cost-of-capital" class="headerlink" title="Estimate a cost of capital"></a>Estimate a cost of capital</h2><p>先计算cost of equity:</p><ul><li>levered beta = 1.007</li><li>risk free rate = 3.12%</li><li>equity risk premium = 6.55%</li></ul><p>可得 r = 3.12% + 1.007*6.55% = 9.71%</p><p>由：</p><ul><li>pre-tax costs of debt = 2.29%</li><li>Market value of equity = 327857.3329 百万元人民币</li><li>Book value of debt = 26749.55809百万元人民币 （近似认为是market value）</li><li>Tax rate = 25%</li></ul><p>可得WACC = 9.11%</p><h2 id="资本化研发费用"><a href="#资本化研发费用" class="headerlink" title="资本化研发费用"></a>资本化研发费用</h2><p>首先一个问题是有没有必要对格力电器的研发费用进行资本化？对比腾讯来看，2019年腾讯的研发费用占销售额为8%，而格力电器的研发费用占比3%。对于格力这样的重资产公司，我觉得暂时可以不用考虑研发费用的资本化。</p><h2 id="Estimate-an-adjusted-operating-income"><a href="#Estimate-an-adjusted-operating-income" class="headerlink" title="Estimate an adjusted operating income"></a>Estimate an adjusted operating income</h2><p>根据一致性预期：</p><div class="table-container"><table><thead><tr><th>年份</th><th>2020E</th><th>2021E</th><th>2022E</th></tr></thead><tbody><tr><td>营业总收入(百万元)</td><td>181,178.81</td><td>203,728.26</td><td>222,818.10</td></tr><tr><td>增长率(%)</td><td>-9.64</td><td>12.45</td><td>9.37</td></tr></tbody></table></div><p>注：以上数据是总收入，包括了利息收入还有手续费及佣金。</p><p>个人觉得这个预期偏乐观，我自己的预期是，以2019年的销售额为基准（198,156.86<br>百万元，该数据不包括利息收入），<strong>到2021年才能回到这个水平。由于最近几年在多元化方面投入，接下来的3年得以在营收上保持较高速的增长：25%~15%，最后每年以6.3%的速度增长直至第10年</strong>。</p><p>由财报上看到最近5年EBIT/Revenue维持在高位，平均在15.3%。但是，接下来面对美的的竞争，打折促销免不了，随着销售费用的上升，EBIT/Revenue肯定会下降。因此，推测，<strong>最近2年EBIT/Revenue分别为8%， 7%；之后3年回升到15.3%</strong>；然后逐渐回归到行业平均水平，大概在6%样子（数据来源Damodaran）。</p><img src="/2020/09/21/valuation-gree/ebit.PNG" class=""><p>空调营收的占比在2019年为70%。格力电器有意拓展不同方向上的业务，包括生活电器，智能装备，但是目前的营收占比很小，以前也做过手机，但是失败了。如果说，格力电器能够在其他业务上实现突破，那么，营收的高增长和高EBIT/Revenue是有可能的。格力为了实现多元化应该会在兼并收购上增加投入，从现金流量表来看，近几年在投资这块确实增加了不少。</p><h2 id="Estimate-net-capital-expenditures"><a href="#Estimate-net-capital-expenditures" class="headerlink" title="Estimate net capital expenditures"></a>Estimate net capital expenditures</h2><p>Net Capex 包括2部分：</p><ul><li>Capex，这部分包括如下科目：<ul><li>处置固定资产、无形资产和其他长期资产收回的现金净额（-）</li><li>购建固定资产、无形资产和其他长期资产支付的现金(+)</li><li><strong>兼并收购</strong>，而这部分包括如下科目：<ul><li>投资支付的现金(+)</li><li>取得子公司及其他营业单位支付的现金净额(+)</li><li>支付其他与投资活动有关的现金(+)</li><li>收到其他与投资活动有关的现金(-)</li><li>处置子公司及其他营业单位收到的现金净额(-)</li><li>收回投资收到的现金(-)</li></ul></li></ul></li><li>折旧摊销，这部分包括如下科目：<ul><li>固定资产和投资性房地产折旧(+)</li><li>无形资产摊销(+)</li></ul></li></ul><p>由于资本性支出和折旧摊销的数据是很难准确估计，尤其是关于兼并收购。根据过去10年的财务数据，我估计Capex/Revenue （不包括兼并收购） = 2.57%；并购/Revenue = 8.23%，两者合计即<strong>Capex/Revenue （包括兼并收购）= 10.8%</strong>。</p><p>同时，根据近10年数据估计：<strong>Depreciation/Revenue = 1.28%</strong>。</p><p>因此，可得<strong>net capex / Revenue = 10.8% - 1.28% = 9.53%</strong>。</p><p>还是需要指出，这块数据的估计存在很大的变数，如果例如，格力电器加大多元化的力度，那么对应的资本开支肯定会大幅增加，这降导致自由现金流的减少，但与此同时，公司的增长速度可能变得更高。是否需要对Net Capex做调整需要后续数据的观察。</p><h2 id="Estimate-non-cash-working-capital"><a href="#Estimate-non-cash-working-capital" class="headerlink" title="Estimate non-cash working capital"></a>Estimate non-cash working capital</h2><p>注意，这里其实是要估计non-cash working capital的change。同Capex一样，working capital也很难估计，每年的变化很大。因此，通过拉长时间做平滑处理。从change in working capital的历史数据看存在着明显的周期性！在去库存周期，如：13年至15年，change in working capital是大于零的，即working capital变大，也就是应收增加而应付减少，可以理解为给渠道供应商提供更多的信用。而在补库存周期，如：16年至19年，change in working capital是小于零的，即working capital变小，也就是应收减少而应付增加，可以理解为给收紧给渠道供应商的信用。</p><img src="/2020/09/21/valuation-gree/change_in_wc.PNG" class=""><p>对于这样存在明显周期性特征的行业，只能通过平滑处理，我实在是没有能力估计接下来5到10年到底是什么周期。根据最近10年的数据，预测<strong>change in working capital 为 0.5%</strong>。</p><h2 id="Estimate-Free-Cash-Flow-to-Firm"><a href="#Estimate-Free-Cash-Flow-to-Firm" class="headerlink" title="Estimate Free Cash Flow to Firm"></a>Estimate Free Cash Flow to Firm</h2><p>参见 Value the firm/stock</p><h2 id="Estimate-a-historical-growth-rate-in-earnings"><a href="#Estimate-a-historical-growth-rate-in-earnings" class="headerlink" title="Estimate a historical growth rate in earnings"></a>Estimate a historical growth rate in earnings</h2><p>参见 Value the firm/stock</p><h2 id="Estimate-growth-in-earnings-from-fundamentals"><a href="#Estimate-growth-in-earnings-from-fundamentals" class="headerlink" title="Estimate growth in earnings from fundamentals"></a>Estimate growth in earnings from fundamentals</h2><p>参见 Value the firm/stock</p><h2 id="Choose-a-lenght-for-high-growth-period"><a href="#Choose-a-lenght-for-high-growth-period" class="headerlink" title="Choose a lenght for high growth period"></a>Choose a lenght for high growth period</h2><p>参见 Value the firm/stock</p><h2 id="Choose-a-DCF-model"><a href="#Choose-a-DCF-model" class="headerlink" title="Choose a DCF model"></a>Choose a DCF model</h2><p>三段式：前5年为高增长期，后5年为过渡期，最后为永续增长期。永续增长率为设定为无风险利率</p><h2 id="期权处理"><a href="#期权处理" class="headerlink" title="期权处理"></a>期权处理</h2><p>格力电器目前没有期权激励计划，但是通过回购股票用于股权激励。回购的股票不影响share outstanding。</p><h2 id="Value-the-firm-stock"><a href="#Value-the-firm-stock" class="headerlink" title="Value the firm/stock"></a>Value the firm/stock</h2><p>参见下图：</p><img src="/2020/09/21/valuation-gree/fcff.PNG" class=""><p><strong>以下的这些假设将直接影响到估值的结果</strong>：</p><ul><li>以2019年的销售额为基准（198,156.86百万元，该数据不包括利息收入），到2021年才能回到这个水平。（base year是指2020年中）</li><li>第3，4，5年营销增长分别为：25%，20%，15%。主要是因为格力电器在兼并收购方面的资本性支出，以实现营收多元化。</li><li>operating margin最近2年会比较低，原因是考虑到市场竞争加剧，最终趋向6%，包括永续阶段。</li><li>Tax rate最近使用有效税率15.5%，后期趋向边际税率25%。</li><li>Reinvestment包括net Capex和Change in working capital，具体假设参见相关章节。这块的变数也会比较多</li></ul><p>最终计算结果参见下图：</p><img src="/2020/09/21/valuation-gree/results.PNG" class=""><ul><li>格力的股权结构还是比较简单，没有期权或Restricted Stock Grants之类。</li><li><strong>最终计算的结果是44.16元</strong>，而当前价格是56.55元（2020/9/21），超过内在价值28%，个人觉得没啥安全边际了。</li><li>我计算出来的内在价值同高瓴资本给出的价格比较接近。</li></ul><p>最后吐槽一下格力电器的网站，上面的年报信息是不全的。比如没有2019年的年报，很多年报的链接是无效的，，，作为一个大公司这太不应该了！</p><img src="/2020/09/21/valuation-gree/no_2019.PNG" class="">]]></content>
    
    <summary type="html">
    
      &lt;p&gt;“2018年底，格力电器董事长兼总裁董明珠提出未来五年实现营业额6000亿元的目标”，董大姐挺会讲故事的。。。&lt;/p&gt;
&lt;p&gt;估值结果：格力电器的内在价值大概为44.16元，而当前价格是56.55元，超过内在价值28%，个人觉得没啥安全边际。该内在价值同高瓴资本给出的价格比较接近。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
      <category term="格力电器" scheme="https://www.keepswalking.com/tags/%E6%A0%BC%E5%8A%9B%E7%94%B5%E5%99%A8/"/>
    
  </entry>
  
  <entry>
    <title>基于FCFE重新计算中国市场隐含风险溢价</title>
    <link href="https://www.keepswalking.com/2020/09/04/cn-market-implied-RP-with-FCFE/"/>
    <id>https://www.keepswalking.com/2020/09/04/cn-market-implied-RP-with-FCFE/</id>
    <published>2020-09-04T02:05:16.000Z</published>
    <updated>2020-09-04T11:37:52.885Z</updated>
    
    <content type="html"><![CDATA[<p>原来根据分红数据来计算中国市场的隐含风险溢价，但是得出的结果不太合理。现在改用FCFE（free cash flow to equity）重新计算，所得结果为Implied Risk Premium = 7.37%。</p><a id="more"></a><p>之前根据Damodaran的方法计算了中国市场的隐含风险溢价（参考：<a href="/2020/07/14/cn-market-rp/" title="中国股票市场的风险溢价">中国股票市场的风险溢价</a>），但是发现计算出来的风险溢价肯定是偏低的，和美国市场也差不多，也就是说我们这里的风险偏好极大，而且有点大到不合情理。所以只能通过拍脑袋，调高永续增长率，调高分红比例来拉高，但这样计算出来的风险溢价肯定不靠谱，因此就想办法改进计算方法。经过分析，发现原因所在，是因为，美国这样的成熟市场分红+回购是接近FCFE（free cash flow to equity）。因此，对于美国这样的成熟市场使用分红和回购就能获得比较准确的风险溢价。但是，在中国这样的发展中市场，分红和FCFE是有很大差别的。这个差别有多大？我们通过数据来说明：</p><ul><li>中证800指数在2020/8/31的股息率为1.63%</li><li>而同为中证800，在同一时间的FCFE率为4.058%</li></ul><p>显然对于中国市场，通过FCFE才能计算得到准确的隐含风险溢价。比较麻烦的是如何获取市场（中证800）的FCFE。下面我就罗列一下具体的改进和对应的数据。</p><p>首先是FCFE的计算，计算公式我使用的是：$ FCFE = NI-(1-DR)(FCInv-Dep)-(1-DR)WCInv $。使用该公式分别计算每一家中证800成分公司（金融机构除外）的FCFE。其中：</p><ul><li>NI为net income。采集数据的时候使用TTM方式获得最新net income。</li><li>DR为Debt to asset ratio。asset使用最新资产负债表季报数据。而Debt的计算使用了长期借款，短期借款，应付债券，租赁负债，应付短期债券这几个科目。</li><li>FCInv为fixed capital investment 即 CAPEX。根据现金流量表里：购建固定资产、无形资产和其他长期资产支付的现金，处置固定资产、无形资产和其他长期资产收回的现金净额这两个科目，并使用TTM方式获得最新的FCInv。</li><li>Dep为depreciation，根据资产负债表，固定资产—累计折旧，无形资产—累计摊销的期初和期末值来计算最新的折旧。</li><li>WCInv为change in non cash working capital investment，使用流动资产合计减货币资金获得current asset。使用流动负债合计减短期借款，减应付短期债券获得current liability。然后用current asset 减去 current liability。</li></ul><p>该公式假设公司的杠杆率是稳定的，因为需对近800家公司分别计算他们的自由现金流，作为一个整体，这个假设可认为是成立里的（law of large number）。</p><p>金融机构（包含银行和非银）的FCFE直接使用分红数据，没有分红的则认为FCFE为0</p><p>其实难点在收集整理数据。我使用Choice，但即使是付费的软件，还是发现有很多缺失的数据。整个数据的收集，清理大概花去一整天。</p><img src="/2020/09/04/cn-market-implied-RP-with-FCFE/fcfe.PNG" class=""><p>如上图所示，还需要以下这些输入：</p><ul><li>无风险利率，直接使用10年期国债的YTM。</li><li>一致性预期是通过卖方对中证800里成分公司未来三年的盈利预测计算获得。我通过加权平均得到一个增长率。但是，我不直接使用这个值，原因是像这样自底而上的增长率估算通常偏乐观。一般卖方总是给出偏乐观的预测。因此我做了处理，参见预期高速增长率。</li><li>GDP预期，是对中国GDP增长的预测，数据来自tradingeconomics.com。该值也是用来估计FCFE的增长率的。GDP作为一个宏观数据，来的更加客观。</li><li>预期高速增长率， 该值用于FCFE在近期的增长率。通过一致性预期和GDP增长率加权平均获得，权值分别是一致性预期占40%，GDP占60%。</li><li>永续增长率，直接使用无风险利率。</li></ul><p>在计算Implied Risk Premium的时候使用三段式DCF model，即高速增长阶段，过渡阶段和永续增长阶段。</p><p>最后，得到Implied Risk Premium = 7.37%，结合无风险利率可得discount rate=10.48%。个人认为这个值还是比较和合理的。相当于说长期来看中证800的收益率为10.48%。那么也从另一方面反应了当前股市的估值还算合理。当然，由于金融所占比重比较高，因此从更微观的角度来看，可能是一种结构性的分化，金融大盘股比较便宜，而中小盘（成长股）则比较贵了。但综合来看，这个风险溢价还是让我觉得A股的估值处在合理区间。</p><p>再来验证一下这个模型以及收集的数据是否合理。我测试了两个场景：</p><ul><li>市场跌30%，那么Implied Risk Premium = 10.21%，这个风险溢价比较有吸引力。</li><li>市场涨30%，那么Implied Risk Premium = 5.78%，这个风险溢价感觉上不足以补偿投资者承担的风险。要使得这个溢价上升至一个合理的水平，要么FCFE变大（企业有护城河，也就是中证800成分公司的质量变好），要么增长率变高（多数企业处于高速发展阶段，也就是总体经济变好，经济处于上升周期）。</li></ul><p>个人觉得这个模型给出的结果还是符合common sense的。接下来我每周都会更新中国市场的Implied Risk Premium。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;原来根据分红数据来计算中国市场的隐含风险溢价，但是得出的结果不太合理。现在改用FCFE（free cash flow to equity）重新计算，所得结果为Implied Risk Premium = 7.37%。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
  </entry>
  
  <entry>
    <title>招商银行估值（DDM法）</title>
    <link href="https://www.keepswalking.com/2020/08/30/valuation-cmbchina/"/>
    <id>https://www.keepswalking.com/2020/08/30/valuation-cmbchina/</id>
    <published>2020-08-30T13:30:26.000Z</published>
    <updated>2020-08-31T12:56:09.093Z</updated>
    
    <content type="html"><![CDATA[<p>没事别去重仓银行股，一笔糊涂账，虽然它已经成了价值投资的代名词。。。</p><p><em>先上结论：招行的内在价值大约为：44元。目前交易价格为38元(2020/8/31)，比内在价值低了14%，有一定的安全边际。</em></p><a id="more"></a><p>银行包括其他的金融服务机构是一个很特殊的群体，通常smart beta策略，还包括一些screening都是将他们排除在外的。原因是：</p><ul><li>银行的debt很难定义同时也很难统计，比如短期债务对银行来说其实是“原材料”而非债务！既然不知道debt，那就无法知晓enterprise value了。因此，对于银行来说，一般直接估算equity。</li><li>对于银行来说，资本性支出和working capital很难估计，因此也就难以计算自由现金流了。</li></ul><p>因为以上原因，反倒是让我解脱了！直接使用DDM（dividend discount model）就解决问题了。面对银行的财报我承认太复杂了，很难分析出个所以然来，对我而言所需要的信息其实就是分红率，ROE，净利润。That’s it!</p><h2 id="故事叙述"><a href="#故事叙述" class="headerlink" title="故事叙述"></a>故事叙述</h2><p>众所周知的一些情况是：招行的零售业务很强是特色，因此，对经济周期敏感性较其他银行来得低，但毕竟还是银行，因此也算是周期性行业；另外，招行的资产质量高，拨备充分。</p><p>从2020半年报看，营业收入同比增长了7.27%但是扣非净利润却录得负增长为-0.88%，主要原因：</p><ul><li>一是业务及管理费同比增加9.7%。这部分用于公司深入推进数字化经营<br>模式探索，可以认为是一种投资活动</li><li>另一为信用减值损失，同比增长22.32%，主要是受疫情的影响</li></ul><p>可以看出疫情对银行业的影响开始逐步显现，2020Q1的数据还是非常“靓丽”。从目前情况看，我个人的预计，疫情的影响持续时间至少2年。</p><p>由于净利润的负增长，扣非后ROE为16.92%，同比减少了2.38%。这个ROE同前几年比也不能算差。</p><p>我整理了招行相关的历史数据：</p><img src="/2020/08/30/valuation-cmbchina/hisdata.PNG" class=""><p>基于以上2020半年报的数据结合历史数据，做出如下假设：</p><ul><li>今后3年净利润不增长</li><li>第4年到第5年净利润以10.5%的速度增长</li><li>近5年dividend payout ratio维持30%</li></ul><h2 id="无风险收益率"><a href="#无风险收益率" class="headerlink" title="无风险收益率"></a>无风险收益率</h2><p>老样子，直接使用10年期国债的YTM了，当前值为3.0672%。这里需要指出，根据Damodaran的方法，risk free rate应该是真正的risk free rate（不是废话吗？！），意思是比如津巴布韦央行发行国债，但你肯定不信他100%不会违约。因此，准确的做法是将某国的risk free rate再减去该国的country default spread。其实呢，China作为发展中国家也是有country default spread滴，要获得这个数据还是有一点麻烦，我这里就偷懒了（也可以直接去Damodaran的博客获得比较新的数据<a href="http://pages.stern.nyu.edu/~adamodar/New_Home_Page/datafile/ctryprem.html）。" target="_blank" rel="noopener">http://pages.stern.nyu.edu/~adamodar/New_Home_Page/datafile/ctryprem.html）。</a> </p><h2 id="Estimate-market-risk-premium"><a href="#Estimate-market-risk-premium" class="headerlink" title="Estimate market risk premium"></a>Estimate market risk premium</h2><p>使用6.1%作为A股的equity risk premium。这里多说两句，之前自己根据Damodaran的方法基于沪深300计算了A股的RP(risk primium)，但是，后来发现这个方法出来的RP是很低的，原因是对于S&amp;P500这样成熟的市场来说，期股票的分红+回购是接近自由现金流的，但是，对于emerging market，如中国市场，公司基本很少分红，因此，分红同自由现金流比还是有很大差距的。最近自己开始使用自由现金流的形式计算RP，并会公布到网上。6.1%是直接使用Damodaran的数据。</p><h2 id="估计beta"><a href="#估计beta" class="headerlink" title="估计beta"></a>估计beta</h2><p>使用bottom-up beta，首先确定可类比公司。招行是综合银行，然后从综合性银行里剔除那些庞然大物，包括：中，农，工，建，邮储。最后得到下面列表：</p><div class="table-container"><table><thead><tr><th>股票代码</th><th>股票名称</th><th>beta</th></tr></thead><tbody><tr><td>000001.SZ</td><td>平安银行</td><td>1.1927</td></tr><tr><td>600000.SH</td><td>浦发银行</td><td>0.6773</td></tr><tr><td>600015.SH</td><td>华夏银行</td><td>0.7173</td></tr><tr><td>600016.SH</td><td>民生银行</td><td>0.6821</td></tr><tr><td>601166.SH</td><td>兴业银行</td><td>0.8381</td></tr><tr><td>601818.SH</td><td>光大银行</td><td>0.7181</td></tr><tr><td>601916.SH</td><td>浙商银行</td><td>0.8422</td></tr><tr><td>601998.SH</td><td>中信银行</td><td>0.7625</td></tr><tr><td>600036.SH</td><td>招商银行</td><td>0.9839</td></tr></tbody></table></div><p>计算beta的平均值，可得招行的beta=0.74</p><h2 id="Estimate-a-cost-of-equity"><a href="#Estimate-a-cost-of-equity" class="headerlink" title="Estimate a cost of equity"></a>Estimate a cost of equity</h2><p>容易得出 r = 3.0672% + 0.74 * 6.1% = 7.58%</p><h2 id="估算TTM净利润"><a href="#估算TTM净利润" class="headerlink" title="估算TTM净利润"></a>估算TTM净利润</h2><p>参见以下数据：</p><div class="table-container"><table><thead><tr><th>时间</th><th>2019</th><th>2020年1-6月</th><th>2019年1-6月</th><th>TTM</th></tr></thead><tbody><tr><td>扣非每股净利润（元）</td><td>3.59</td><td>1.97</td><td>1.99</td><td>3.57</td></tr></tbody></table></div><p>因此，TTM每股净利润为3.57 元。</p><h2 id="模型"><a href="#模型" class="headerlink" title="模型"></a>模型</h2><p>使用DDM。前10年的增长率灵活设置，再加最后永续增长阶段。</p><h2 id="内在价值计算"><a href="#内在价值计算" class="headerlink" title="内在价值计算"></a>内在价值计算</h2><img src="/2020/08/30/valuation-cmbchina/value.PNG" class=""><ul><li>根据假设，今后三年的净利润不增长，因此为0%</li><li>永续增长率等于无风险利率=3.07%</li><li>第四第五年10.5%的增长率是根据ROE=15%，payout ratio=30% 推算获得</li><li>terminal year’s payout ratio是根据g=3.07%, ROE=cost of equity=9.17% 推算获得</li><li>永续增长阶段可假设ROE趋近于cost of equity</li><li>永续阶段的cost of equity不同于前10年，使用beta=1计算得到</li></ul><p>据此，获得招行的内在价值大约为：44元。目前交易价格为38元，比内在价值低了14%。个人觉得还是有足够的安全边际。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;没事别去重仓银行股，一笔糊涂账，虽然它已经成了价值投资的代名词。。。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;先上结论：招行的内在价值大约为：44元。目前交易价格为38元(2020/8/31)，比内在价值低了14%，有一定的安全边际。&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
      <category term="招商银行" scheme="https://www.keepswalking.com/tags/%E6%8B%9B%E5%95%86%E9%93%B6%E8%A1%8C/"/>
    
  </entry>
  
  <entry>
    <title>关于自底向上贝塔(bottom-up beta)的10个常见问题</title>
    <link href="https://www.keepswalking.com/2020/08/27/ten-question-about-bottom-up-betas/"/>
    <id>https://www.keepswalking.com/2020/08/27/ten-question-about-bottom-up-betas/</id>
    <published>2020-08-27T07:28:59.000Z</published>
    <updated>2020-08-27T07:45:10.052Z</updated>
    
    <content type="html"><![CDATA[<p>本翻译获得Damodaran教授授权，转载请注明出处。原文链接：<a href="http://people.stern.nyu.edu/adamodar/New_Home_Page/TenQs/TenQsBottomupBetas.htm" target="_blank" rel="noopener">http://people.stern.nyu.edu/adamodar/New_Home_Page/TenQs/TenQsBottomupBetas.htm</a></p><a id="more"></a><h3 id="1-什么是bottom-up-beta？"><a href="#1-什么是bottom-up-beta？" class="headerlink" title="1. 什么是bottom-up beta？"></a>1. 什么是bottom-up beta？</h3><p>bottom-up beta 的估算首先从分析公司所处行业/业务出发，通过估算各个业务的基本风险或beta，然后将这些风险进行加权平均最终获得。</p><h3 id="2-估算bottom-up-beta包括哪些步骤？"><a href="#2-估算bottom-up-beta包括哪些步骤？" class="headerlink" title="2. 估算bottom-up beta包括哪些步骤？"></a>2. 估算bottom-up beta包括哪些步骤？</h3><p>一共包括4个步骤：</p><p>步骤1：将目标公司的业务做一定的拆分。GE有26种业务，而沃尔玛则是单一业务的公司。不要将业务拆分的过细，因为到了步骤2会碰到问题。</p><p>步骤2：分别估算每种业务的风险（beta）。这里的beta成为资产（asset）beta或无杠杆（unlevered）beta。</p><p>步骤3：将上一步获得的无杠杆beta进行加权平均，权值是根据某业务的价值（value）对比所有业务的价值加总来确定的。</p><p>步骤4：根据目标公司的财务杠杆（debt to equity 比值）计算最终的beta。</p><h3 id="3-如何选择可类比的公司？"><a href="#3-如何选择可类比的公司？" class="headerlink" title="3. 如何选择可类比的公司？"></a>3. 如何选择可类比的公司？</h3><p>一个比较侠义的定义是和目标公司业务相同的公司，而比较广义的定义则包括了那些因目标公司经营情况的好坏而受到影响的公司。反之亦然，即那些可类比公司的经营情况会影响到目标公司。从实际应用角度出发，你可以将可类比公司定义为非常相似的公司，例如目标公司生产游戏软件，那么你就找其他生产游戏软件的公司。如果你能找到足够多的样本（参见问题4），那么这步就结束了。否则，可以试着使用下面的方法来拓展你的搜索范围：</p><p>i. 将可类比公司的定义放宽（例如：所有的软件公司而非仅仅是游戏软件公司）</p><p>ii. 从全球范围查找业务相同的公司。例如：全球所有的游戏软件公司。</p><p>iii. 从目标公司所在供应链的上下游查找可类比的公司。例如查找那些收入大头为游戏软件的软件零售公司</p><h3 id="4-我们至少需要多样本公司？"><a href="#4-我们至少需要多样本公司？" class="headerlink" title="4. 我们至少需要多样本公司？"></a>4. 我们至少需要多样本公司？</h3><p>我们这么来思考这个问题，任何大于1的样本数量都能提高回归beta（regression beta。直接使用market return和个股的return通过线性回归获得的beta）的精度。然而，可比公司的样本越多则消除误差的效果就越明显。如果有4个样本，那么标准差（standard error）将减少一半；如果有9个样本，那么标准差将减少2/3；16个样本则减少75%…。如有可能，尽量获取2位数的样本数量。如果做不到，那么争取获取6~8个可类比公司，这样的话你也能将beta估算的误差降低很多。</p><p>当然， 在可类比公司的定义的宽松程度以及样本数量之间需要权衡。如果你对可类比公司的定义比较严格（可类比公司的规模和业务必须要同目标公司一致），那么你能获得的样本数量肯定比较少。如果这样严格的定义能让你获得2位数的样本，那就使用这些样本。如果你的样本数量太少了，那就试着使用问题3里面的方法来扩充你的样本数量。</p><h3 id="5-一旦我们获得了可类比公司，那接下来该如何估算无杠杆beta（或叫资产beta）？"><a href="#5-一旦我们获得了可类比公司，那接下来该如何估算无杠杆beta（或叫资产beta）？" class="headerlink" title="5. 一旦我们获得了可类比公司，那接下来该如何估算无杠杆beta（或叫资产beta）？"></a>5. 一旦我们获得了可类比公司，那接下来该如何估算无杠杆beta（或叫资产beta）？</h3><p>简单来说，获取这些回归beta的平均值并剔除财务杠杆以及现金的影响。实际是，还是会碰到一些问题：</p><p>a. 在获取每个可类比公司的回归beta时，必须使用同一时间段，并基于同一指数吗？</p><p>如果在一个完美的世界里，回答是yes！但是，随着样本数量的增加，你就不需要太关注这些细节了，因为大数定律（law of large numbers）会拯救你。因此，如果在你的样本里有100家来自世界各地的公司，而这些公司的回归beta都是基于本国股票市场的指数，你还是可以将这100家公司的beta做平均，因为有些beta可能被高估了而另一些则可能被低估。</p><p>b. 当我们获得了样本公司的回归beta，那接下来该使用简单平均还是加权平均？</p><p>使用简单平均。否则，你得到的beta会趋近于你样本里面最大的一家或几家公司的beta。比如，微软的beta变成了所有软件公司的beta。</p><p>c. 为何我们要剔除财务杠杆的影响？</p><p>目标公司在负债方面的政策可能和样本公司有非常大的区别。样本公司的回归beta是带杠杆的beta，它反应了样本公司的财务杠杆（而非目标公司的）。你必须剔除财务杠杆的影响（剔除掉回归beta的杠杆）以获得单一（pure play）的，或叫业务beta。</p><p>Unlevered beta = Regression beta / (1 + (1-tax rate) D/E)</p><p>d. 是该先剔除每家样本公司的回归beta的杠杆再平均呢，还是先获得各家样本公司回归beta的平均值再剔除杠杆？</p><p>我倾向先平均再剔除杠杆。单个样本公司的回归beta带有大量的噪音（标准差很大），如果先剔除杠杆，那无疑将叠加噪音的影响。如果先平均则将减少噪音，从而能获得更准确的beta估算。</p><p>e. 针对某个业务对应的样本公司，我该使用哪个税率以及debt to equity比？</p><p>保险起见，使用边际税率；使用D/E比的中值或聚合的D/E比(加总所有的D，加总所有的E再获得D/E)。D/E比经常出现异常值，这会导致简单平均失去代表性。</p><p>f. 为何需要调整现金对beta的影响，具体该怎么作？</p><p>回归beta反应了公司所有的资产包括现金。因此，如果一家公司的资产包含了60%的软件还有40%的现金，那么它的回归beta会比较低，因为现金是无风险的。由于我们希望获得纯粹的软件业务的beta，我们就需要去除现金对beta的影响。假设现金的beta为零，那么很容易可得：</p><p>Cash-adjusted beta = Unlevered beta / (1 – Cash/ Firm Value)</p><p>Firm value = Market value of Equity + Market value of Debt</p><h3 id="6-是否可能对无杠杆beta进一步调整经营杠杆（operating-leverage）？"><a href="#6-是否可能对无杠杆beta进一步调整经营杠杆（operating-leverage）？" class="headerlink" title="6. 是否可能对无杠杆beta进一步调整经营杠杆（operating leverage）？"></a>6. 是否可能对无杠杆beta进一步调整经营杠杆（operating leverage）？</h3><p>是有这个可能，前提是你知道目标公司以及所有样本公司的固定成本以及可变成本。如果你能获取这些信息，你就可以将无杠杆beta再分割成业务部分（体现了对目标公司需求的弹性）和经营杠杆部分：</p><p>Business Risk beta = Unlevered beta/ (1 +Fixed Costs/ Variable Costs)</p><p>实践中碰到的困难是获取固定成本和可变成本。</p><h3 id="7-如果已获得了目标公司对应各业务的无杠杆beta，那该如何分配权重以获得目标公司的无杠杆beta？"><a href="#7-如果已获得了目标公司对应各业务的无杠杆beta，那该如何分配权重以获得目标公司的无杠杆beta？" class="headerlink" title="7. 如果已获得了目标公司对应各业务的无杠杆beta，那该如何分配权重以获得目标公司的无杠杆beta？"></a>7. 如果已获得了目标公司对应各业务的无杠杆beta，那该如何分配权重以获得目标公司的无杠杆beta？</h3><p>理论上权重应该是基于目标公司各业务的市场价值。然而，现实情况是这些业务并无法交易（例如GE Capital并没有单独上市），因此需要估算各业务的市场价值。一种简便的做法是使用各业务的销售收入或利润来分配权重，但这样就等于假设1美元的销售收入（或利润）对不同的业务来说具有相同的价值。另一种方法是使用销售收入（或利润）的乘数来大致计算每个业务的价值。这些乘数可以通过可类比公司（就是前面用来计算beta平均数的样本公司）的乘数计算获得。因为我们关心的是业务的价值（而非权益的价值），因此我们应该使用EV（enterprise value）乘数（而非权益乘数）。如果使用销售收入，那就用EV/Sales乘数。</p><h3 id="8-如何调整财务杠杆？"><a href="#8-如何调整财务杠杆？" class="headerlink" title="8. 如何调整财务杠杆？"></a>8. 如何调整财务杠杆？</h3><p>调整财务杠杆的标准做法是假设有息债务（debt）的市场风险为0（beta=0）并使用所谓的“Hamada”调整：</p><p>Levered Beta = Unlevered beta (1 + (1- tax rate) (Debt/Equity))</p><p>可以使用目标公司当前的debt to equity比，也可以使用预期的debt to equity比（如果你觉得这个变化很快就会发生）来进行该调整的计算。</p><p>如果你觉得有息债务没有市场风险这个假设不对，那么你需要获得有息债务的beta，并使用以下公式计算：</p><p>Levered Beta = Unlevered Beta (1 + (1-t)(D/E)) – Beta of debt (1-t)(D/E)</p><p>比较棘手的问题是如何估计有息债务的beta。</p><h3 id="9-一家公司的自底向上的beta会随着时间改变吗？"><a href="#9-一家公司的自底向上的beta会随着时间改变吗？" class="headerlink" title="9. 一家公司的自底向上的beta会随着时间改变吗？"></a>9. 一家公司的自底向上的beta会随着时间改变吗？</h3><p>是的，有2个原因。一个是公司的业务组成会随着时间改变，导致无杠杆beta发生改变。另一个是公司的debt to equity比会随着时间改变，这导致了杠杆beta（回归beta）发生改变。</p><h3 id="10-为何使用自底向上的beta比使用回归beta好？"><a href="#10-为何使用自底向上的beta比使用回归beta好？" class="headerlink" title="10. 为何使用自底向上的beta比使用回归beta好？"></a>10. 为何使用自底向上的beta比使用回归beta好？</h3><p>主要有3方面的原因：</p><ul><li><p><em>更精确。</em> 自底向上的beta的标准差更小，因为它通过众多的回归beta取平均值获得。提高的精度大致等于1/SQRT(样本公司数量)。因此，即使目标公司只有一种业务且长时间保持debt to equity比稳定，你还是能从自底向上的beta获得好处。</p></li><li><p>如果目标公司<em>改变了业务组成</em>，你可以很容易地根据改变后的业务组成计算获取自底向上的beta，因为你可以设置不同业务的权重。而回归beta只能反应过去的业务组成。</p></li><li><p>如果目标公司<em>改变了debt to equity比</em>，可以通过调整自底向上的beta，就能很容易地反应这些改变。而回归beta只能反应过去的debt to equity比。</p></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;本翻译获得Damodaran教授授权，转载请注明出处。原文链接：&lt;a href=&quot;http://people.stern.nyu.edu/adamodar/New_Home_Page/TenQs/TenQsBottomupBetas.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://people.stern.nyu.edu/adamodar/New_Home_Page/TenQs/TenQsBottomupBetas.htm&lt;/a&gt;&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
  </entry>
  
  <entry>
    <title>腾讯估值 DCF 方法</title>
    <link href="https://www.keepswalking.com/2020/08/21/valuation-tencent/"/>
    <id>https://www.keepswalking.com/2020/08/21/valuation-tencent/</id>
    <published>2020-08-21T06:38:19.000Z</published>
    <updated>2020-08-25T06:12:07.908Z</updated>
    
    <content type="html"><![CDATA[<p>先说结论吧，根据2020半年报的数据，腾讯的内在价值为510 HKD，当前股价为548HKD， 比内在价值高出7.4%，可以认为当前股价处于合理区域内。</p><a id="more"></a><h2 id="Story-Naritive"><a href="#Story-Naritive" class="headerlink" title="Story Naritive"></a>Story Naritive</h2><p>腾讯的收入分为以下几块：</p><ul><li>增值服务</li><li>网络广告</li><li>金融科技及企业服务</li><li>其它</li></ul><p>增值服务包括网络游戏和社交网络两部分业务，网络游戏国内增长总体放缓，增量时代向存量时代，而且竞争对手也开始不断成长，竞争加剧。可能在海外市场获得新的增长。社交网络业务包括QQ VIP、视频会员、版权音乐、数字阅读，所有非游戏类的付费收入，这个块业务随着内容付费在国内接受度提高，可能继续保持稳步增长。对于增值服务的预期是：今后5年保持总体10%的增长。</p><p>网络广告在经过业务整合以后（腾讯广告和微信广告整合）有可能继续保持比较高速的增长。预计今后5年保持20%的增长。</p><p>金融科技及企业服务方面，前者会成为腾讯继游戏以后另一大支柱业务，而企业服务方面，目前来看竞争激烈，虽然腾讯有发展to B的愿望，但是最近几年很难找到突破口。综合来看今后5年保持30%的增长。</p><p>而其它业务年报里面也没有披露具体信息，并且也只占总收入的2%，对股价影响非常小，按30%的增长来估算。</p><h2 id="Risk-free-rate"><a href="#Risk-free-rate" class="headerlink" title="Risk free rate"></a>Risk free rate</h2><p>由于腾讯年报里用的是人民币，因此为方便估算，整个过程全部使用人民币。以10年期国债作为无风险利率。最新的值为2.9921%</p><h2 id="Estimate-market-risk-premium"><a href="#Estimate-market-risk-premium" class="headerlink" title="Estimate market risk premium"></a>Estimate market risk premium</h2><p>根据腾讯2019年年报显示，海外收入占比只有4%，因此，只需要考虑国内市场的风险溢价就行了。而根据我目前的测算，<a href="https://www.keepswalking.com/2020/07/21/CN-implied-RP/">参见A股市场隐含风险溢价</a>，国内市场风险溢价为5.17%，个人觉得这个溢价有点低，说明整个市场有些高估了。那么，我觉得理想情况下的风险溢价水平在6.1%，后面可以根据这2个值分别计算腾讯的价值。</p><h2 id="Estimate-bottom-up-unlevered-beta"><a href="#Estimate-bottom-up-unlevered-beta" class="headerlink" title="Estimate bottom-up unlevered beta"></a>Estimate bottom-up unlevered beta</h2><p>unlevered beta的具体计算可参见<a href="https://www.keepswalking.com/2020/07/18/bottom-up-beta/">Bottom-up Beta方法 — 试算腾讯的beta</a>。这里我就直接引用Professor Damodaran的global beta数据，unlevered beta = 1.15</p><h2 id="Estimate-market-value-of-equity-and-debt"><a href="#Estimate-market-value-of-equity-and-debt" class="headerlink" title="Estimate market value of equity and debt"></a>Estimate market value of equity and debt</h2><p>最新港元人民币汇率：1港元：0.89人民币</p><p>最近20天均价：529 港元</p><p>总股本：95.82亿</p><p>最新股票市值：45113.0142 亿人民币</p><p>以下计算book value of debt，根据2020年Q2数据：</p><div class="table-container"><table><thead><tr><th>项目</th><th>金额（人民币百万元）</th></tr></thead><tbody><tr><td>非流动负债</td><td></td></tr><tr><td>借款</td><td>131,988</td></tr><tr><td>应付票据</td><td>126,785</td></tr><tr><td>其他金融负债</td><td>7,016</td></tr><tr><td>租赁负债</td><td>8,143</td></tr><tr><td>流动负债</td><td></td></tr><tr><td>借款</td><td>15,101</td></tr><tr><td>应付票据</td><td>0</td></tr><tr><td>其他金融负债</td><td>5,746</td></tr><tr><td>租赁负债</td><td>3,474</td></tr><tr><td>合计</td><td>298,253</td></tr></tbody></table></div><h2 id="Estimate-bottom-up-levered-beta"><a href="#Estimate-bottom-up-levered-beta" class="headerlink" title="Estimate bottom-up levered beta"></a>Estimate bottom-up levered beta</h2><p>根据 debt和equity的市值，可得debt-to-equity ratio为：</p><p>D/E = 2982.53/45113.0142 = 0.066。</p><p>根据腾讯2019年财报，可计算effective tax rate = 12.35% ，由unlevered beta可计算出levered beta = 1.15 * (1 + (1-12.35%) * 0.066) = 1.22</p><h2 id="Estimate-pre-tax-cost-of-debt"><a href="#Estimate-pre-tax-cost-of-debt" class="headerlink" title="Estimate pre-tax cost of debt"></a>Estimate pre-tax cost of debt</h2><p>根据2019年财报第149页显示：“于二零一九年一月一日应用于租赁负债的加权平均承租人增量借款利率为4.58%”，那么可以推断腾讯的pre-tax cost of debt 为 4.58%</p><h2 id="convert-operating-leases-into-debt"><a href="#convert-operating-leases-into-debt" class="headerlink" title="convert operating leases into debt"></a>convert operating leases into debt</h2><p>这个数据是用来估算operating lease的value，由于2019年财报已经使用了新的会计准则（IFRS16），因此这块计算可以省略。</p><h2 id="Estimate-a-tax-rate"><a href="#Estimate-a-tax-rate" class="headerlink" title="Estimate a tax rate"></a>Estimate a tax rate</h2><p>根据腾讯2019年财报，可计算effective tax rate = 12.35%</p><h2 id="Estimate-a-cost-of-capital"><a href="#Estimate-a-cost-of-capital" class="headerlink" title="Estimate a cost of capital"></a>Estimate a cost of capital</h2><p>cost of equity = 2.9921% + 1.22*6.1% = 10.43%</p><p>WACC = 10.43% * 45113.0142/(45113.0142+2982.53) + (1-12.35%) * 4.58% * 2982.53/(45113.0142+2982.53) = 10.03%</p><h2 id="Capitalize-R-amp-D-expenses"><a href="#Capitalize-R-amp-D-expenses" class="headerlink" title="Capitalize R&amp;D expenses"></a>Capitalize R&amp;D expenses</h2><p>对于腾讯这样的科技公司，将研发费用资本化能更加准确的反应经营性收入(operating income)。根据腾讯2019年年报可查得研发费用，用3年折旧，见下表：</p><div class="table-container"><table><thead><tr><th>year</th><th>index</th><th>研发开支（亿元rmb）</th><th>折旧</th></tr></thead><tbody><tr><td>2019</td><td>current</td><td>303.87</td><td>0</td></tr><tr><td>2018</td><td>-1</td><td>229.36</td><td>76.45</td></tr><tr><td>2017</td><td>-2</td><td>174.56</td><td>58.19</td></tr><tr><td>2016</td><td>-3</td><td>118.45</td><td>39.48</td></tr><tr><td></td><td></td><td>Total</td><td>174.12</td></tr></tbody></table></div><p>因此，当年研发折旧为：174.12 亿元RMB。</p><p>那么，对当年operating income的调整为：303.87-174.12 = 129.75 亿元RMB</p><h2 id="Estimate-an-adjusted-operating-income"><a href="#Estimate-an-adjusted-operating-income" class="headerlink" title="Estimate an adjusted operating income"></a>Estimate an adjusted operating income</h2><p>腾讯刚发布2020年中报，因此，结合2019年年报可以计算出TTM (trailing 12 month)的经营性收入。计算如下：</p><div class="table-container"><table><thead><tr><th>项目</th><th>2019</th><th>2020MID</th><th>2019MID</th><th>TTM</th><th>TTM/2019</th></tr></thead><tbody><tr><td>Revenues</td><td>377,289</td><td>222,948</td><td>174,286</td><td>425,951</td><td>13%</td></tr><tr><td>EBIT</td><td>118,694</td><td>76,571</td><td>64,263</td><td>131,002</td><td>10%</td></tr></tbody></table></div><p>以上单位为人民币百万元</p><p>由于将研发费用资本化，因此需要对EBIT进行调整，调整后的EBIT为：</p><p>131,002 + 12,975 = 143,977 </p><p><strong>注意：</strong> 这里的数据是需要进行标准化的，原因是2020年上半年由于新冠疫情的原因，使得游戏业务意外受益。从2020年半年报可知，半年的收入同比增长了28%！而2019年的收入比2018年增长了21%，那么，可以假设如果没有疫情影响，2020年上半年销售额同比增长为21%</p><h2 id="Estimate-net-capital-expenditures"><a href="#Estimate-net-capital-expenditures" class="headerlink" title="Estimate net capital expenditures"></a>Estimate net capital expenditures</h2><p>Net capital expenditures = capital expenditures - depreciation。从公司治理角度来看，净资本支出必须大于零，就是说资本支出要高于折旧，公司才可能有增长。</p><p>我整理了2015年~2019年年报里的数据：</p><div class="table-container"><table><thead><tr><th>资本性支出</th><th>2019</th><th>2018</th><th>2017</th><th>2016</th><th>2015</th></tr></thead><tbody><tr><td>購買物業、設備及器材、在建工程與投資物業</td><td>-22,766</td><td>-19,743</td><td>-12,108</td><td>-8,399</td><td>-5,440</td></tr><tr><td>處置物業、設備及器材</td><td>4</td><td>33</td><td>28</td><td>31</td><td>70</td></tr><tr><td>購買無形資產的付款╱預付款項</td><td>-29,866</td><td>-31,877</td><td>-19,850</td><td>-8,849</td><td>-4,505</td></tr><tr><td>購買土地使用權的付款╱預付款項</td><td>-4,356</td><td>-2,441</td><td>-46</td><td>-1,506</td><td>-3,045</td></tr><tr><td>對聯營公司的投資</td><td>-14,904</td><td>-37,776</td><td>-33,912</td><td>-12,258</td><td>-13817</td></tr><tr><td>處置於聯營公司的投資</td><td>667</td><td>429</td><td>1115</td><td>1,373</td><td>1,106</td></tr><tr><td>對合營公司的投資</td><td>-720</td><td>-2,352</td><td>-7082</td><td>-59</td><td>-500</td></tr><tr><td>total - without acquisition</td><td>-56,984</td><td>-54,028</td><td>-31,976</td><td>-18,723</td><td>-12,920</td></tr><tr><td>total - with acquisition</td><td>-71,941</td><td>-93,727</td><td>-71,855</td><td>-29,667</td><td>-26,131</td></tr></tbody></table></div><p>以下是折旧/摊销的数据：</p><div class="table-container"><table><thead><tr><th>折旧/摊销</th><th>2019</th><th>2018</th><th>2017</th><th>2016</th><th>2015</th></tr></thead><tbody><tr><td>無形資產攤銷</td><td>28,954</td><td>25,616</td><td>18,622</td><td>8,930</td><td>3,515</td></tr><tr><td>物業、設備及器材、投資物業以及使用權資產折舊</td><td>15,623</td><td>8,423</td><td>4,850</td><td>3,699</td><td>3,159 </td></tr><tr><td>土地使用權攤銷</td><td>211</td><td>353</td><td>109</td><td>95</td><td>0</td></tr><tr><td>Total</td><td>44,788</td><td>34,392</td><td>23,581</td><td>12,724</td><td>6,674</td></tr><tr><td>研发调整</td><td>129.7</td><td>101.6</td><td>79.7</td><td>46.1</td><td>34.2</td></tr><tr><td>Adj Net CAPEX with ac</td><td>27,283</td><td>59,437</td><td>48,354</td><td>16,989</td><td>19,491</td></tr><tr><td>Adj Net CAPEX without ac</td><td>12,325.7</td><td>19,737.6</td><td>8,474.7</td><td>6,045.1</td><td>6,280.2 </td></tr></tbody></table></div><ul><li>上表中，2015年土地使用权摊销已包含在无形资产摊销内，因此设置成0。</li><li>对于腾讯这样的科技公司将研发费用资本化</li><li>研发调整 = 当年研发支出-历年研发摊销，使用3年摊销。</li><li>Adj Net CAPEX = CAPEX - Depreciation + 研发调整</li></ul><p>由以上数据进行一些统计：</p><div class="table-container"><table><thead><tr><th>统计项目</th><th>2019</th><th>2018</th><th>2017</th><th>2016</th><th>2015</th></tr></thead><tbody><tr><td>Revenue</td><td>377,289</td><td>312,694</td><td>237,760</td><td>151,938</td><td>102,863</td></tr><tr><td>capex without ac / Rev</td><td>15.1%</td><td>17.3%</td><td>13.4%</td><td>12.3%</td><td>12.6%</td></tr><tr><td>adj net capex without ac / Rev</td><td>3.3%</td><td>6.3%</td><td>3.6%</td><td>4.0%</td><td>6.1%</td></tr><tr><td>adj net capex with ac / Rev</td><td>7.2%</td><td>19.0%</td><td>20.3%</td><td>11.2%</td><td>18.9%</td></tr></tbody></table></div><ul><li>上表第一行为历年销售收入</li><li>由第二行capex without ac / Rev 可见，腾讯每年的资本支出同销售收入之间的关系还是比较稳定的，基本在13% 到 17% 之间</li><li>由第三行adj net capex without ac / Rev可见，不包括并购投资的净资本支出在3.3% 到 6.1%之间浮动</li><li>第四行adj net capex with ac / Rev 包括了并购支出。并购投资通常来说不是一种稳定的行为，因此需要对此作一些平滑处理</li></ul><p>经平滑处理后，可得每年并购活动占销售额（ac/rev）为10%；而adj net capex without ac / Rev 的平均值为4.6%；因此推测<strong>总的资本性支出占销售额为14.6%</strong></p><h2 id="Estimate-non-cash-working-capital"><a href="#Estimate-non-cash-working-capital" class="headerlink" title="Estimate non-cash working capital"></a>Estimate non-cash working capital</h2><p>non-cash working capital 的定义：non-cash working capital = non-cash current asset - non-debt current liabilities</p><p>收集历年的年报数据：</p><div class="table-container"><table><thead><tr><th>项目</th><th>2019</th><th>2018</th><th>2017</th><th>2016</th><th>2015</th><th>2014</th></tr></thead><tbody><tr><td>current asset</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>存貨</td><td>718</td><td>324</td><td>295</td><td>263</td><td>222</td><td>244</td></tr><tr><td>應收賬款</td><td>35,839</td><td>28,427</td><td>16,549</td><td>10,152</td><td>7,061</td><td>4,588</td></tr><tr><td>預付款項、按金及其他資產</td><td>27,840</td><td>18,493</td><td>17,110</td><td>14,118</td><td>11,397</td><td>7,804</td></tr><tr><td>current liabilities</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>應付賬款</td><td>80,690</td><td>73,735</td><td>50,085</td><td>27,413</td><td>15,700</td><td>8,683</td></tr><tr><td>其他應付款項及預提費用</td><td>45,174</td><td>33,312</td><td>29,433</td><td>20,873</td><td>70,199</td><td>19,123</td></tr><tr><td>流動所得稅負債</td><td>9,733</td><td>10,210</td><td>8,708</td><td>5,219</td><td>1,608</td><td>461</td></tr><tr><td>其他稅項負債</td><td>1,245</td><td>1,049</td><td>934</td><td>745</td><td>462</td><td>566</td></tr><tr><td>遞延收入</td><td>60,949</td><td>42,375</td><td>42,132</td><td>31,203</td><td>21,122</td><td>16,153</td></tr><tr><td>non-cash working cap</td><td>-133,394</td><td>-113,437</td><td>-97,338</td><td>-60,920</td><td>-90,411</td><td>-32,350</td></tr><tr><td>change in working cap</td><td>-19,957</td><td>-16,099</td><td>-36,418</td><td>29,491</td><td>-58,061</td><td></td></tr><tr><td>change in working cap / rev</td><td>-5%</td><td>-5%</td><td>-15%</td><td>19%</td><td>-56%</td><td></td></tr></tbody></table></div><ul><li>从上表可见，腾讯的working capital是负的，也就是说腾讯从供应商处获得信用作为自己的资本发展业务。</li><li>另外，腾讯的change in working capital也是负的，说明随着公司不断增长，其从供应商处获得信用的能力也越来越强。但是，从长期来看，working capital变得越来越负是不现实的。从数据上看，最近3年change in working cap / rev的值不断向0的方向增加。</li></ul><p>因此，<strong>推测change in working cap占销售额</strong> 为-5%，并且不断趋向0</p><h2 id="Estimate-Free-Cash-Flow-to-Firm"><a href="#Estimate-Free-Cash-Flow-to-Firm" class="headerlink" title="Estimate Free Cash Flow to Firm"></a>Estimate Free Cash Flow to Firm</h2><p>参见 Value the firm/stock</p><h2 id="Estimate-a-historical-growth-rate-in-earnings"><a href="#Estimate-a-historical-growth-rate-in-earnings" class="headerlink" title="Estimate a historical growth rate in earnings"></a>Estimate a historical growth rate in earnings</h2><p>参见 Value the firm/stock</p><h2 id="Estimate-growth-in-earnings-from-fundamentals"><a href="#Estimate-growth-in-earnings-from-fundamentals" class="headerlink" title="Estimate growth in earnings from fundamentals"></a>Estimate growth in earnings from fundamentals</h2><p>参见 Value the firm/stock</p><h2 id="Choose-a-lenght-for-high-growth-period"><a href="#Choose-a-lenght-for-high-growth-period" class="headerlink" title="Choose a lenght for high growth period"></a>Choose a lenght for high growth period</h2><p>最近5年为高增长期，销售收入增长率为：19%</p><h2 id="Choose-a-DCF-model"><a href="#Choose-a-DCF-model" class="headerlink" title="Choose a DCF model"></a>Choose a DCF model</h2><p>三段式：前5年为高增长期，后5年为过渡期，最后为永续增长期。永续增长率为：5.98%。</p><h2 id="期权处理"><a href="#期权处理" class="headerlink" title="期权处理"></a>期权处理</h2><p>根据2020年中报，期权信息显示如下：</p><img src="/2020/08/21/valuation-tencent/option.PNG" class=""><p>根据年报信息显示，这2个计划发出的期权期限都为7年。计划II已于2017年5月16日结束。那么计划II发出的期权最晚可能于2024年5月16日到期。因此假设计划II期权到期时间为2年。</p><p>计划IV是从2017年5月17日起十年內有效，那么该计划里最早的期权将于2024年5月17日到期。因此假设计划IV期权到期时间为3.5年。</p><p>根据以下输入参数：</p><div class="table-container"><table><thead><tr><th>参数</th><th>计划II</th><th>计划IV</th></tr></thead><tbody><tr><td>当前股价</td><td>529 港元</td><td>529 港元</td></tr><tr><td>期权执行价</td><td>185.86港元</td><td>374.84港元</td></tr><tr><td>到期时间（年）</td><td>2</td><td>3.5</td></tr><tr><td>波动率</td><td>30%</td><td>30%</td></tr><tr><td>股息率</td><td>0.23%</td><td>0.23%</td></tr><tr><td>无风险利率</td><td>0.5%</td><td>0.5%</td></tr><tr><td>期权数量</td><td>48,841,295</td><td>67,983,454</td></tr><tr><td>期权单位价值</td><td>341.90</td><td>193.24 </td></tr><tr><td>所有期权价值</td><td>16,698,627,876</td><td>13,137,208,432</td></tr></tbody></table></div><p>因此，截至2020/6/30 全部期权价值为：16,698,627,876 + 13,137,208,432 = 29,835.836,308 港元 = 26,553.89 百万人民币</p><h2 id="Value-the-firm-stock"><a href="#Value-the-firm-stock" class="headerlink" title="Value the firm/stock"></a>Value the firm/stock</h2><p>参见下图：</p><img src="/2020/08/21/valuation-tencent/FCFF.PNG" class=""><p>上表中有几点需要注意：</p><ul><li>terminal year的reinvestment是通过growth equation计算获得的，即 reinvestment = (perpetual growth / ROIC) * after tax operating income</li><li>base year revenue 使用TTM，但因为疫情原因使得游戏业务意外收益，因此没有直接使用TTM，而是做了标准化</li></ul><p>最后需要计算shares outstanding。截至2020-07-6，腾讯有9,555,165,469股（数据来源choice金融终端）。根据2020年中报显示，股份奖励计划将发行80,064,689股，因此稀释后的股份数= 9,555,165,469+80,064,689 = 9,635,230,158。</p><img src="/2020/08/21/valuation-tencent/result.PNG" class=""><ul><li>最后的每股内在价值考虑了股份奖励计划以及期权对股价的稀释</li><li>目前的股价比计算出来的内在价值高7.4%，可以认为处在合理范围内</li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;先说结论吧，根据2020半年报的数据，腾讯的内在价值为510 HKD，当前股价为548HKD， 比内在价值高出7.4%，可以认为当前股价处于合理区域内。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
      <category term="腾讯" scheme="https://www.keepswalking.com/tags/%E8%85%BE%E8%AE%AF/"/>
    
  </entry>
  
  <entry>
    <title>从debt和liabilities的翻译想到的</title>
    <link href="https://www.keepswalking.com/2020/08/03/debt-definition/"/>
    <id>https://www.keepswalking.com/2020/08/03/debt-definition/</id>
    <published>2020-08-03T06:40:41.000Z</published>
    <updated>2020-09-30T02:34:09.561Z</updated>
    
    <content type="html"><![CDATA[<p>前些时间在计算上市公司unlevered beta的时候需要用到debt to equtiy ratio（负债股权比率），于是就去找相关的数据来计算，找着找着自己就迷茫了。到底什么负债？我发现中文里面debt和liability都翻译成负债，债务。这就很误导我这种非会计出生的半吊子了。想想，作为母语是英语的同学就不会有这样的疑惑了。</p><a id="more"></a><p>首先，从大方向上看看liability和debt的区别：</p><ul><li>liability包括debt，而debt是liability的子类。</li><li>Debt总是以钱的形式存在的，而liability的形式就很广了，任何需要公司支出的都算</li><li>Debt比liability具有更为严重的法律后果（如果违约）</li></ul><p>知道了这一层似乎就不那么迷茫了，那么从财报分析的角度看，到底什么是debt呢？也就是debt的定义：</p><ul><li>承诺在未来的某一时点支付某个约定的金额</li><li>该支出可以获得税收上的减免</li><li>如果没有兑现该支出，则导致违约，或失去对公司的控制，并由债权人获得控制权</li></ul><p>有了以上的定义，我们就比较容易区分哪些是debt而哪些是liability了，虽然中文都叫负债。。。</p><p>具体来说，所有的有息债务不管是长期还是短期，都算debt。租赁，包括经营租赁(operating lease)和资本租赁(capital lease)都认为是debt；而应付账款以及卖方信贷(supplier credit)则不是debt。下图表述了debt和equity的一些特征：</p><img src="/2020/08/03/debt-definition/DebtvsEquity.jpg" class=""><p>那么，再进一步，如何计算debt。是否直接拿财报上的数值就行了呢？往下细挖一下，发现其实还是有很多弯弯需要绕的。那么，先从一些具体的应用开始：</p><ul><li>通过FCFF (free cash flow for the firm) discount方式获得企业价值(Enterprise value — EV)后，需要推算出equity value。而EV = market value of equity + market value of debt - cash。这里显然需要debt的市值，而非报表上的book value（账面价值）。</li><li>再来，Debt to equity ratio (D/E)，比如我们在使用pure play方法计算unlevered beta时需要使用到D/E，那这里使用的是市值还是账面价值呢？其实，仔细分析一下，我们计算beta是为了进一步计算requried return，作为投资者，他们投资是账面价值还是市场价值呢？显然是后者。因此，这里的D/E应该用市值来计算</li></ul><p>由以上两例可见，很多情况下我们需要用到debt的市值！那么企业的debt未必都是以公开发行债券的方式。另外，还有些debt，如operating lease甚至看上去都不是debt，那该如何计算市值呢？</p><p>那么，我们就以腾讯控股为例，试着算算她的debt的市值是多少。翻开腾讯2019年的年报，第141，142页展示了负债部分，如下图所示：</p><img src="/2020/08/03/debt-definition/tencent_debt1.PNG" class=""><img src="/2020/08/03/debt-definition/tencent_debt2.PNG" class=""><p>先来确定哪几项可以归入debt的范畴，对于非流动负债部分：</p><div class="table-container"><table><thead><tr><th>项目</th><th>是否计入debt？</th><th>金额（人民币百万元）</th><th>说明</th></tr></thead><tbody><tr><td>借款</td><td>是</td><td>104,257</td><td>根据说明，借款是指向银行的长期借款</td></tr><tr><td>应付票据</td><td>是</td><td>83,327</td><td>根据说明，应付票据是指浮动利率债</td></tr><tr><td>长期应付款项</td><td>否</td><td>3,577</td><td></td></tr><tr><td>其他金融负债</td><td>是</td><td>5,242</td><td></td></tr><tr><td>递延所得税负债</td><td>否</td><td>12,841</td><td></td></tr><tr><td>租赁负债</td><td>是</td><td>8,428</td><td></td></tr><tr><td>递延收入</td><td>否</td><td>7,334</td><td></td></tr></tbody></table></div><p>对于流动负债部分：</p><div class="table-container"><table><thead><tr><th>项目</th><th>是否计入debt？</th><th>金额（人民币百万元）</th><th>说明</th></tr></thead><tbody><tr><td>应付账款</td><td>否</td><td>80,690</td><td></td></tr><tr><td>其他应付款项及预提费用</td><td>否</td><td>45,174</td></tr><tr><td>借款</td><td>是</td><td>22,695</td><td>银行借款</td></tr><tr><td>应付票据</td><td>是</td><td>10,534</td><td></td></tr><tr><td>流动所得税负债</td><td>否</td><td>9,733</td><td></td></tr><tr><td>其他税项负债</td><td>否</td><td>1,245</td><td></td></tr><tr><td>其他金融负债</td><td>是</td><td>5,857</td><td></td></tr></tbody></table></div><p>因此可得debt的总额为285,514。此金额是账面价值而非市场价值。在实践中，这个账面价值可以近似认为是市场价值。因为，要得出市场价值还是有很多困难，一般来说，需要将公司的debt当作一只债券，需要知道债券的yeild to maturity，期限，每年支付的利息，到期的面额，这些都是需要进行估算。从腾讯的财报中可知，应付票据是按照市场价格来计算的，再加上腾讯本事偿债能力非常强，因此，可以将报表上的金额近似认为是市场价值。</p><p>对公司进行估值的时候很多数据是不能拿来直接用的，以上debt就是一例，如果直接拿债务(liability)那就会出现很大的偏差。进一步，对于腾讯这样的大型公司，她进行了很多的并购，而其中有些被并购的公司是并表的，而有些是以equity method方式计入报表的，如果需要知道腾讯真实的价值，还需要对这些并购的公司分别进行估值才行。所以，常常觉得对公司进行估值不是一件容易的事情，真的是需要具备方方面面的知识。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;前些时间在计算上市公司unlevered beta的时候需要用到debt to equtiy ratio（负债股权比率），于是就去找相关的数据来计算，找着找着自己就迷茫了。到底什么负债？我发现中文里面debt和liability都翻译成负债，债务。这就很误导我这种非会计出生的半吊子了。想想，作为母语是英语的同学就不会有这样的疑惑了。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
  </entry>
  
  <entry>
    <title>A股市场隐含风险溢价(Implied Equity Risk Premium)</title>
    <link href="https://www.keepswalking.com/2020/07/21/CN-implied-RP/"/>
    <id>https://www.keepswalking.com/2020/07/21/CN-implied-RP/</id>
    <published>2020-07-21T02:42:08.000Z</published>
    <updated>2020-09-22T05:40:07.080Z</updated>
    
    <content type="html"><![CDATA[<p>说明：</p><ol><li>隐含风险溢价(Implied Equity Risk Premium)的具体计算参见：<a href="/2020/07/14/cn-market-rp/" title="中国股票市场的风险溢价">中国股票市场的风险溢价</a></li><li>市场参照对象为沪深300指数</li><li>每周更新</li></ol><a id="more"></a><div class="table-container"><table><thead><tr><th>时间</th><th>Implied RP</th><th>HS800点位</th><th>FCFE</th><th>高速增长率%</th><th>无风险收益率%</th><th>永续增长率%</th><th>说明</th></tr></thead><tbody><tr><td>2020/9/2</td><td>7.37%</td><td>5153.16</td><td>151.14</td><td>15.1%</td><td>3.11%</td><td>3.11%</td><td>计算方法从分红改为自由现金流<br>无风险利率持续走高，体现了对通胀的预期</td></tr></tbody></table></div>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;说明：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;隐含风险溢价(Implied Equity Risk Premium)的具体计算参见：&lt;a href=&quot;/2020/07/14/cn-market-rp/&quot; title=&quot;中国股票市场的风险溢价&quot;&gt;中国股票市场的风险溢价&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;市场参照对象为沪深300指数&lt;/li&gt;
&lt;li&gt;每周更新&lt;/li&gt;
&lt;/ol&gt;
    
    </summary>
    
    
      <category term="Data" scheme="https://www.keepswalking.com/categories/Data/"/>
    
    
  </entry>
  
  <entry>
    <title>Bottom-up Beta方法 -- 试算腾讯的beta</title>
    <link href="https://www.keepswalking.com/2020/07/18/bottom-up-beta/"/>
    <id>https://www.keepswalking.com/2020/07/18/bottom-up-beta/</id>
    <published>2020-07-18T13:03:53.000Z</published>
    <updated>2020-07-19T07:19:24.049Z</updated>
    
    <content type="html"><![CDATA[<p>Beta是一个非常流行的个股风险度量尺度，通过大名鼎鼎的CAPM广为传播。当需要确定某个股的discount rate的时候最常用的方式就是通过CAPM：$ E(R)=R_f + \beta * (R_m-R_f) $ 。其中$R_m$ 是 expected market return。 </p><a id="more"></a><p>那么该如何获取beta呢？一种方式就是通过linear regression。将independent variables:$ R_m, R_f $ 以及dependent variable E(R) 通过linear regression便可获取参数beta了。但是，很多终端包括在网上找到的所有例子，在计算beta时不考虑$R_f$，直接通过$ E(R) = \beta*(R_m) $ 来确定beta；这种做法可能有一定的道理，由于$R_f$本身很小，比如国内10年期国债的yield在3%左右，如果以weekly return计算的话，对应的return才0.0577%，而国外的$R_f$就更不用说了，因此可以近似忽略。另外，如何选择risk free rate本身又是一件不太简单的事情。例如，对于成熟市场来说如美国来说，就可以有多种选择，除了国债外（10年期或其他？）还有Overnight Index Swap (OIS)等。</p><p>接下来通过linear regression方法来计算腾讯的beta。因为腾讯在香港上市，因此，market return使用恒生指数。$ R_f $使用香港政府10年期国债。仿照Bloomberg计算beta的方法，使用最近2年的weekly return数据。我自己计算获得的结果是：</p><ul><li>不包含$ R_f $，使用regression 计算得出的beta = 1.219</li><li>包含$ R_f $，使用regression 计算得出的beta = 1.22</li><li>直接使用公式：$Covariance(market<em>{rt}, stock</em>{rt}) / Var(market_{rt})$，计算得出的beta = 1.231</li></ul><p>可见，risk free rate对于beta的影响确实很小。另外，我在Choice终端上，使用同样的周期得到的结果是1.2123。而yahoo finance上，5 年，月return显示的beta是1.02，我用yahoo的数据自己算了一下，发现它的结果是不对的！应该是1.2471，接近我上面的计算结果。看来大网站的数据也不能相信。</p><p>当然，本文不是讨论regression beta如何计算，从上面可以看出来，单个股票的beta其实是一个含有大量噪音的数据，如果直接就这么用，那心里肯定没底，十有八九这个beta的值是有问题的。因此，有一种“bottom-up Betas”的方法可以比较好的消除单只股票的beta的噪音。</p><p>什么是“bottom-up beta”？就是根据目标公司所在的行业，在这些行业里找到同目标公司相似的一堆公司，用这些公司的beta计算平均值获得一个比较准确的beta。bottom-up beta的一大好处就是，当你找到足够多的样本公司，你估算出来的目标公司beta的standaerd error会大大降低。另一个好处就是即使当目标公司没有很多历史数据的情况下，你一样可以通过bottom-up beta计算得到目标公司的beta。</p><p>以下是bottom-up beta的具体计算方法：</p><ol><li>确定目标公司所处的行业，目标公司有可能是单一行业，也有可能是跨多个行业。</li><li>在每个行业里找到相似的公司，当然多多益善。如果是跨行业的公司，则需要分别在每个行业里面找到相似的公司，并获得这些公司的beta。然后分别按行业计算这些公司beta的平均值。</li><li>计算unlevered beta。$ \beta_u = \beta_r / (1 + (1-tax) D/E) $ 。其中D/E是debt to equity ratio，这里指相似公司的平均D/E。</li><li>确定目标公司在各业务上的比重，通常可以按照销售收入或opterating income来确定比重。当然最理想的方式是估算各业务的价值，以价值来确定比重。</li><li>计算目标公司unlevered beta的加权平均值。个业务unlevered beta来自第3步，权重来自第4步。</li><li>最后计算levered beta，$ \beta_{bottomup} = \beta_u (1+ (1-tax) (D/E))$，这里的D/E是目标公司的D/E。</li></ol><p>方法讲完了，接下来就以腾讯控股为例来确定她的bottom-up beta。按照以上第1步，先确定腾讯所在行业即她涉及哪些业务。腾讯的收入包括如下几块：</p><ul><li>网络游戏</li><li>数字内容，包括：视频（传统+短视频），音乐，阅读</li><li>网络广告</li><li>金融科技</li><li>云及企业服务</li></ul><p>而从GICS分类来看腾讯属于：信息技术-软件与服务-信息技术服务-互联网服务与基础设施。显然这样的分类不能体现腾讯的全部业务。一种比较仔细的做法是根据腾讯的业务，分别找到对应的公司。这里，我就比较粗粒度的找到一些我觉得相关的在香港上市的公司，见下表：</p><div class="table-container"><table><thead><tr><th>证券代码</th><th>证券名称</th><th>所属GICS行业</th><th>Beta</th><th>总市值（亿元）</th><th>D/E</th></tr></thead><tbody><tr><td>09988.HK</td><td>阿里巴巴-SW</td><td>非日常生活消费品-零售业-互联网与直销零售-互联网与直销零售</td><td>0.9181</td><td>51,250.7415</td><td>0.493</td></tr><tr><td>03690.HK</td><td>美团点评-W</td><td>信息技术-软件与服务-软件-应用软件</td><td>0.8307</td><td>11,231.8189</td><td>0.339</td></tr><tr><td>01810.HK</td><td>小米集团-W</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>1.1003</td><td>3,733.3914</td><td>1.070</td></tr><tr><td>00268.HK</td><td>金蝶国际</td><td>信息技术-软件与服务-软件-应用软件</td><td>1.5451</td><td>598.9131</td><td>0.370</td></tr><tr><td>08083.HK</td><td>中国有赞</td><td>非日常生活消费品-零售业-互联网与直销零售-互联网与直销零售</td><td>1.1385</td><td>282.5032</td><td>1.693</td></tr><tr><td>02013.HK</td><td>微盟集团</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>1.9174</td><td>252.0400</td><td>0.660</td></tr><tr><td>00136.HK</td><td>恒腾网络</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>0.7934</td><td>182.7986</td><td>0.347</td></tr><tr><td>01686.HK</td><td>新意网集团</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>1.1249</td><td>136.7236</td><td>2.696</td></tr><tr><td>00777.HK</td><td>网龙</td><td>信息技术-软件与服务-软件-应用软件</td><td>1.4445</td><td>127.7308</td><td>0.447</td></tr><tr><td>00799.HK</td><td>IGG</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>1.5530</td><td>93.0871</td><td>0.272</td></tr><tr><td>01089.HK</td><td>乐游科技控股</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>0.6488</td><td>92.4880</td><td>0.282</td></tr><tr><td>00302.HK</td><td>中手游</td><td>信息技术-软件与服务-软件-应用软件</td><td>1.0677</td><td>77.5940</td><td>0.403</td></tr><tr><td>01675.HK</td><td>亚信科技</td><td>信息技术-软件与服务-软件-应用软件</td><td>0.4815</td><td>71.0940</td><td>0.244</td></tr><tr><td>01357.HK</td><td>美图公司</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>1.3548</td><td>68.5665</td><td>0.236</td></tr><tr><td>01137.HK</td><td>香港电视</td><td>通讯服务-媒体与娱乐-娱乐-电影与娱乐</td><td>1.1290</td><td>56.4704</td><td>0.656</td></tr><tr><td>01806.HK</td><td>汇付天下</td><td>金融-综合金融-综合金融服务-其它综合性金融服务</td><td>0.8373</td><td>39.5487</td><td>3.959</td></tr><tr><td>BIDU.O</td><td>百度</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>1.4500</td><td>423.1467</td><td>0.751</td></tr><tr><td>NTES.O</td><td>网易</td><td>信息技术-软件与服务-信息技术服务-互联网服务与基础设施</td><td>0.7400</td><td>631.9686</td><td>0.599</td></tr></tbody></table></div><p>以上数据来自东方财富Choice数据。</p><p>一共12家上市公司。在查找这些公司的时候首先我考虑市值，毕竟腾讯的体量摆在那里，找对应的公司市值也不能太小，否则就没有参考意义了；另外，还得考虑上市时间，像网易，京东这样的公司虽然比较匹配，但是上市时间实在太短，历史数据太少，因此也没参考意义，我就直接拿美股的数据过来了（虽然跨市场，但只要样本足够多，通过大数定律还是可以得到比较准确的结果）。</p><p>有了参照数据，很容易就得到了beta的平均值：1.115。然后计算unlevered beta，需要先获得相似公司的D/E，我这里将所有相关公司的detb和equity分别加总，再用这两个总和求得D/E = 0.573。然后还需要确定tax rate，根据国家政策，高新技术企业税率是15%，代入这些数据可得：</p><p>$\beta_u$ = 1.115/(1+(1-0.15) * 0.573) = 0.75</p><p>最后，为了获取腾讯的bottom-up beta，我们还需要确定腾讯的D/E，根据腾讯的财报，可得到她的D/E = 0.976。那么，对应的beta应该为：</p><p>$\beta_{bottomup}$ = 0.75*(1+(1-0.15)*0.976) = 1.372</p><p>这就是腾讯的beta。那么，将这个bottom-up beta同腾讯的regressison beta（=1.22）比大了一点（12.5%）。但1.372也是有一定道理的，因为，从D/E比来看，网易，百度，阿里都比腾讯低。因此，我个人觉得1.372这个值还是比较靠谱。确定beta作为股票估值的重要的一步到此完成。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Beta是一个非常流行的个股风险度量尺度，通过大名鼎鼎的CAPM广为传播。当需要确定某个股的discount rate的时候最常用的方式就是通过CAPM：$ E(R)=R_f + \beta * (R_m-R_f) $ 。其中$R_m$ 是 expected market return。 &lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
  </entry>
  
  <entry>
    <title>中国股票市场的风险溢价</title>
    <link href="https://www.keepswalking.com/2020/07/14/cn-market-rp/"/>
    <id>https://www.keepswalking.com/2020/07/14/cn-market-rp/</id>
    <published>2020-07-14T13:11:41.000Z</published>
    <updated>2020-09-04T11:34:33.178Z</updated>
    
    <content type="html"><![CDATA[<p>所谓的Risk Premium（以下简写成RP）是值市场的预期收益(expected return)减去无风险收益率（risk free rate）$ r_f $。RP是估值的关键，当对某只股票进行估值的时候，你首先需要确定其required return（或称discount rate）r。而$ r = r_f + \beta*RP $。那么中国市场的RP是多少呢？作为emerging market，中国市场的RP是否就比成熟市场高呢？</p><a id="more"></a><p>RP的确定通常有2种方式。Historical Premium 和 Implied Premium。Historical Premium其实就是根据历史数据计算市场的平均收益率（算数或几何平均）。这里以沪深300指数来代表中国股票市场整体。那么，先来看看Historical Premium是多少？参见下表：</p><div class="table-container"><table><thead><tr><th>时间</th><th>开盘</th><th>收盘</th><th>收益</th></tr></thead><tbody><tr><td> 2005/12/30</td><td>994.76</td><td>923.45</td><td>-7.17%</td></tr><tr><td> 2006/12/29</td><td>926.56</td><td>2041.05</td><td>121.02%</td></tr><tr><td> 2007/12/28</td><td>2073.25</td><td>5338.27</td><td>161.55%</td></tr><tr><td> 2008/12/31</td><td>5349.76</td><td>1817.72</td><td>-65.95%</td></tr><tr><td> 2009/12/31</td><td>1848.33</td><td>3575.68</td><td>96.71%</td></tr><tr><td> 2010/12/31</td><td>3592.47</td><td>3128.26</td><td>-12.51%</td></tr><tr><td> 2011/12/30</td><td>3155.56</td><td>2345.74</td><td>-25.01%</td></tr><tr><td> 2012/12/31</td><td>2361.5</td><td>2522.95</td><td>7.55%</td></tr><tr><td> 2013/12/31</td><td>2551.81</td><td>2330.03</td><td>-7.65%</td></tr><tr><td> 2014/12/31</td><td>2323.43</td><td>3533.71</td><td>51.66%</td></tr><tr><td> 2015/12/31</td><td>3566.09</td><td>3731</td><td>5.58%</td></tr><tr><td> 2016/12/30</td><td>3725.86</td><td>3310.08</td><td>-11.28%</td></tr><tr><td> 2017/12/29</td><td>3313.95</td><td>4030.86</td><td>21.78%</td></tr><tr><td> 2018/12/28</td><td>4045.21</td><td>3010.65</td><td>-25.31%</td></tr><tr><td> 2019/12/31</td><td>3017.07</td><td>4096.58</td><td>36.07%</td></tr><tr><td> 2020/07/14</td><td>4121.35</td><td>4806.69</td><td>17.33%</td></tr></tbody></table></div><p>一共才16条数据，数据样本很小，未必能揭示真实的RP。如果以算数平均计算，可得沪深300的预期收益是：22.77%。而以几何平均计算，预期收益是：10.35%，几何平均更合理，通常来说几何平均是会小于算数平均。对于无风险收益率来说，选取10年期国债的收益率：3.06%，由此可得RP=10.35%-3.06% = 7.29%。看上去好像还蛮不错的哦！</p><p>当然，使用historical premium的问题也很明显，你需要有大量的历史数据，对于成熟市场，如果美国股市，可以得到相对可靠的数据（其实方差也很大），而对于中国这样的emerging market，historical premium的准确性更是值得怀疑。另外一个问题，历史数据只能反应历史，而很多新的变化就无法体现在结果中，就好比看着后视镜开车。</p><p>Implied Premium，在计算过程中使用了“未来数据”，将最新的预期加入计算，因此更加能反应未来的变化。那么，如何计算implied premium呢？简单来说就是根据dividend discount model (DDM) 来推算出r—required return, 我们知道DDM的简单形式可以写成：</p><script type="math/tex; mode=display">P = D_1/(r-g)</script><p>其中，P对应现在的指数，D1=下一年的分红，g=收入增长率。那么，如果知道P，D1，g就可以推算出r来了。而D1，g都是预测值，是对未来的预期。通过这种方式计算出来的r对估值具有更好的效果。</p><p>接下来还是以沪深300为例来计算Implied Premium。在本例中使用两段式的DDM， 即一开始的5年为高速增长期，5年以后为稳定增长期。输入参数如下：</p><div class="table-container"><table><thead><tr><th>参数</th><th>值</th><th>说明</th></tr></thead><tbody><tr><td>当前指数</td><td>4806.69</td><td>这个很容获取，直接填上最新的指数值，我这里填的式2020/7/14日沪深300的收盘价</td></tr><tr><td>分红和回购率</td><td>2.07%</td><td>这个要花一点功夫了，不得不说中证指数有限公司工作很粗糙，照理这些数据应该提供的，我在他们网站上找了好久也没找到，而S&amp;P以及恒生指数都提供这些数据的。最后只能自己计算了，将300只成分股一个一个数据汇集起来。最终的结果也符合直觉，国内红率不是很高，尤其对应这几天的大涨，分红率就更低了。</td></tr><tr><td>今后5年收入增加率</td><td>14.364%</td><td>这个数据也挺难弄。我从Choice终端上查找一致性预期获得的。原始数据是今后2年复合增长率21.9%，但是感觉这数据太高了。有可能是疫情的原因。我自己作了调整。</td></tr><tr><td>五年以后增长率</td><td>3.06%</td><td>这个值代表了永续增长率，我取和无风险收益保持一致</td></tr><tr><td>10年期国债收益率</td><td>3.06%</td><td>无风险收益率</td></tr></tbody></table></div><p>然后，利用MS Excel的规划求解就能得到implied risk premium，参见下图：</p><img src="/2020/07/14/cn-market-rp/irp.PNG" class=""><p>expected dividend是根据今后5年收入增长率推算得到。terminal value根据DDM公式计算得到。应用规划求解，可变单元格的值设置为Implied Risk Premium，最后的结果为3.49%，同historical premium的7.29%比低了好多啊！！！至于说哪个值更加符合市场实际情况呢？我个人觉得3.49%似乎比较符合直观感受。我大哀股如同绞肉机，说直白一点，就是收益和风险不对称，股民承担了很高的风险却为了不太理想的收益。</p><p>为何implied premium会那么低？首先，分红+回购比例很低！这也导致了terminal value很低，而另一方面，指数本身又很高。这就进一步解释了高风险低收益的市场状况。假设市场跌去50%，而分红绝对值保持不变，那么implied premium就变成了6.81%，相对来说就改善了很多。</p><p>所以，implied premium能从风险收益比较的角度来提供我们观察市场的一种方法。那么，究竟该使用historical premium还是implied premium呢？</p><p>下表是Damodaran教授提供的美国市场的数据：</p><img src="/2020/07/14/cn-market-rp/which_to_use.PNG" class=""><p>显然implied premium效果好很多了。不过需要指出的一点，implied premium需要高质量的预期数据，例如今后几年的盈利增长率，分红率。获得高质量的一致性预期数据就显得尤为重要。当然还需要指出的是implied premium并没有一个客观正确的值，每个人可以有自己预期，并得到对应的值，就好像每个人对市场都可以有自己的看法一样。RP是一项很关键的数据，后面的股票估值直接需要RP的参与。我打算每周都会更新implied risk premium。</p><p>：：：更新（2020/9/4）：：：</p><p>更新了模型的数据：</p><ul><li>使用FCFE而非原来的分红+回购来计算implied risk premium。</li><li>具体更新说明参见：<a href="/2020/09/04/cn-market-implied-RP-with-FCFE/" title="基于FCFE重新计算中国市场隐含风险溢价">基于FCFE重新计算中国市场隐含风险溢价</a></li></ul><p>结果参见：<a href="/2020/07/21/CN-implied-RP/" title="A股市场隐含风险溢价(Implied Risk Premium)">A股市场隐含风险溢价(Implied Risk Premium)</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;所谓的Risk Premium（以下简写成RP）是值市场的预期收益(expected return)减去无风险收益率（risk free rate）$ r_f $。RP是估值的关键，当对某只股票进行估值的时候，你首先需要确定其required return（或称discount rate）r。而$ r = r_f + \beta*RP $。那么中国市场的RP是多少呢？作为emerging market，中国市场的RP是否就比成熟市场高呢？&lt;/p&gt;
    
    </summary>
    
    
      <category term="Valuation" scheme="https://www.keepswalking.com/categories/Valuation/"/>
    
    
  </entry>
  
  <entry>
    <title>vanishing gradients</title>
    <link href="https://www.keepswalking.com/2020/06/02/vanishing-gradients/"/>
    <id>https://www.keepswalking.com/2020/06/02/vanishing-gradients/</id>
    <published>2020-06-02T09:13:32.000Z</published>
    <updated>2020-06-02T09:37:34.701Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Vanishing-Gradients"><a href="#Vanishing-Gradients" class="headerlink" title="Vanishing Gradients"></a>Vanishing Gradients</h1><p>这里只使用numpy来实现一个neural network，而非借助pytorch这样的框架，如此，可以更好的帮助我理解neural network以及vanishing gradients.</p><a id="more"></a><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line">%matplotlib inline</span><br><span class="line">plt.rcParams[<span class="string">'figure.figsize'</span>] = (<span class="number">10.0</span>, <span class="number">8.0</span>) <span class="comment"># set default size of plots</span></span><br><span class="line">plt.rcParams[<span class="string">'image.interpolation'</span>] = <span class="string">'nearest'</span></span><br><span class="line">plt.rcParams[<span class="string">'image.cmap'</span>] = <span class="string">'gray'</span></span><br><span class="line"></span><br><span class="line">%load_ext autoreload</span><br><span class="line">%autoreload <span class="number">2</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># generate random data -- not linearly separable</span></span><br><span class="line">np.random.seed(<span class="number">0</span>)</span><br><span class="line">N = <span class="number">100</span> <span class="comment"># number of points per class</span></span><br><span class="line">D = <span class="number">2</span> <span class="comment"># dimensionality (向量维度)</span></span><br><span class="line">K = <span class="number">3</span> <span class="comment"># number of classes</span></span><br><span class="line">X = np.zeros((N*K, D))</span><br><span class="line">num_train_examples = X.shape[<span class="number">0</span>]</span><br><span class="line">y = np.zeros(N*K, dtype=<span class="string">'uint8'</span>)  <span class="comment"># 无符号整数</span></span><br><span class="line"><span class="keyword">for</span> j <span class="keyword">in</span> range(K):</span><br><span class="line">    ix = range(N*j, N*(j+<span class="number">1</span>))</span><br><span class="line">    r = np.linspace(<span class="number">0.0</span>, <span class="number">1</span>, N) <span class="comment"># radius, evenly spaced numbers</span></span><br><span class="line">    t = np.linspace(j*<span class="number">4</span>, (j+<span class="number">1</span>)*<span class="number">4</span>, N) + np.random.randn(N)*<span class="number">0.2</span> <span class="comment"># theta</span></span><br><span class="line">    X[ix] = np.c_[r*np.sin(t), r*np.cos(t)] <span class="comment"># 变成2列的matrix</span></span><br><span class="line">    y[ix] = j</span><br><span class="line">fig = plt.figure()</span><br><span class="line">plt.scatter(X[:,<span class="number">0</span>], X[:,<span class="number">1</span>], c=y, s=<span class="number">40</span>, cmap=plt.cm.Spectral)</span><br><span class="line">plt.xlim([<span class="number">-1</span>,<span class="number">1</span>])</span><br><span class="line">plt.ylim([<span class="number">-1</span>,<span class="number">1</span>])</span><br></pre></td></tr></table></figure><p><img src="1.svg" alt="svg"></p><p>sigmoid 函数的值在0,1之间，尤其是在输入值的绝对值很大的情况下，两端会无限接近0或1，因此变得很扁平，由此，对应的梯度（Gradient）就会无限逼近0。这就导致了所谓的梯度消失（vanishing gradients）的现象。因为梯度消失使得神经网络无法进行有效的学习（因为每次迭代对参数W的修正几乎都是0）。</p><p>而另一方面，relu函数不会出现因为输入参数变大而输出变得不敏感。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">sigmoid</span><span class="params">(x)</span>:</span></span><br><span class="line">    x = <span class="number">1</span>/(<span class="number">1</span>+np.exp(-x))</span><br><span class="line">    <span class="keyword">return</span> x</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">sigmoid_grad</span><span class="params">(x)</span>:</span> <span class="comment"># sigmoid函数的导数</span></span><br><span class="line">    <span class="keyword">return</span> (x)*(<span class="number">1</span>-x)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">relu</span><span class="params">(x)</span>:</span></span><br><span class="line">    <span class="keyword">return</span> np.maximum(<span class="number">0</span>,x)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># plot the 2 function</span></span><br><span class="line">x = np.linspace(<span class="number">-3</span>,<span class="number">3</span>,<span class="number">100</span>)</span><br><span class="line">y_sigmoid = sigmoid(x)</span><br><span class="line">y_relu = relu(x)</span><br><span class="line"></span><br><span class="line">plt.plot(x, y_sigmoid, <span class="string">'b-'</span>, x, y_relu, <span class="string">'r-'</span>)</span><br></pre></td></tr></table></figure><p><img src="2.svg" alt="svg"></p><p>接下来让我们看一下2种不同的非线性函数（sigmoid和relu）对神经网络在训练时的影响。以下，我们会创建一个简单的3层神经网路（2 hidden layers）。 通过使用sigmoid和relu我们可以比较在训练过程中的区别。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># function to train a 3 layer neural net with either relu or sigmoid nonlinearity via vanilla grad decent.</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">three_layer_net</span><span class="params">(NONLINEARITY, X, y, model, step_size, reg)</span>:</span></span><br><span class="line">    <span class="comment"># param init</span></span><br><span class="line">    h = model[<span class="string">'h'</span>]</span><br><span class="line">    h2 = model[<span class="string">'h2'</span>]</span><br><span class="line">    W1 = model[<span class="string">'W1'</span>]</span><br><span class="line">    W2 = model[<span class="string">'W2'</span>]</span><br><span class="line">    W3 = model[<span class="string">'W3'</span>]</span><br><span class="line">    b1 = model[<span class="string">'b1'</span>]</span><br><span class="line">    b2 = model[<span class="string">'b2'</span>]</span><br><span class="line">    b3 = model[<span class="string">'b3'</span>]</span><br><span class="line"></span><br><span class="line">    <span class="comment"># some hyperparameters</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># gradient descent loop</span></span><br><span class="line">    num_examples = X.shape[<span class="number">0</span>]</span><br><span class="line">    plot_array_1 = []</span><br><span class="line">    plot_array_2 = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">50000</span>):</span><br><span class="line">        <span class="comment"># forward prop</span></span><br><span class="line">        <span class="comment"># 假设有X的维度[N, M], 即有N条training 数据，每条数据有M个feature</span></span><br><span class="line">        <span class="keyword">if</span> NONLINEARITY == <span class="string">'RELU'</span>:</span><br><span class="line">            <span class="comment"># 从X到hidden layer 1, X=[N*2], W1=[2*50] --&gt; hidden layer=[N*50]</span></span><br><span class="line">            hidden_layer = relu(np.dot(X,W1) + b1)  </span><br><span class="line">            <span class="comment"># 从 hidden layer 1 到 layer2. hidden 1 = [N*50], W2=[50*50]--&gt;hidden2 = [N*50]</span></span><br><span class="line">            hidden_layer2 = relu(np.dot(hidden_layer, W2) + b2)  </span><br><span class="line">            <span class="comment"># 从 hidden 2 到 最总output layer， hidden 2 = [1*50], W3=[50*3] --&gt; output = [3] </span></span><br><span class="line">            scores = np.dot(hidden_layer2, W3) + b3  <span class="comment"># scores的维度是[N,3]</span></span><br><span class="line">        </span><br><span class="line">        <span class="keyword">elif</span> NONLINEARITY == <span class="string">'SIGM'</span>:</span><br><span class="line">            hidden_layer = sigmoid(np.dot(X,W1) + b1)  <span class="comment"># 从X到hidden layer 1</span></span><br><span class="line">            hidden_layer2 = sigmoid(np.dot(hidden_layer, W2) + b2)  <span class="comment"># 从 hidden layer 1 到 layer2</span></span><br><span class="line">            scores = np.dot(hidden_layer2, W3) + b3</span><br><span class="line"></span><br><span class="line">        exp_scores = np.exp(scores) <span class="comment"># [N*K], K=3</span></span><br><span class="line">        <span class="comment"># keepdims=True 意思是np.sum被sum的维度变为1，另一个维度保持不变。</span></span><br><span class="line">        probs = exp_scores / np.sum(exp_scores, axis=<span class="number">1</span>, keepdims=<span class="literal">True</span>) <span class="comment"># normalize，行方向sum</span></span><br><span class="line"></span><br><span class="line">        <span class="comment"># compute the loss: average cross-entropy loss and regularization</span></span><br><span class="line">        corect_logprobs = -np.log(probs[range(num_examples), y]) <span class="comment"># y的取值范围0，1，2。结果[N*1]</span></span><br><span class="line">        data_loss = np.sum(corect_logprobs)/num_examples</span><br><span class="line">        <span class="comment"># regularization项</span></span><br><span class="line">        reg_loss = <span class="number">0.5</span>*reg*np.sum(W1*W1) + <span class="number">0.5</span>*reg*np.sum(W2*W2)+<span class="number">0.5</span>*reg*np.sum(W3*W3)</span><br><span class="line">        loss = data_loss + reg_loss</span><br><span class="line">        <span class="comment"># if i % 1000 == 0:</span></span><br><span class="line">        <span class="comment">#     print("iteration &#123;0&#125;: loss &#123;1&#125;".format(i, loss))</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment"># comput the gradient on scores</span></span><br><span class="line">        dscores = probs  <span class="comment">#  -- [N*K]</span></span><br><span class="line">        dscores[range(num_examples), y] -= <span class="number">1</span>  <span class="comment"># error value -- [N*K]</span></span><br><span class="line">        dscores /= num_examples</span><br><span class="line"></span><br><span class="line">        <span class="comment"># backprop here</span></span><br><span class="line">        <span class="comment"># 从output layer back prop 到 hidden layer2, 由于该层没有nonlinearity</span></span><br><span class="line">        <span class="comment"># 即 hidden2*W3 = s, ds/dW3 = hidden2 (local gradient), 因此back prop error</span></span><br><span class="line">        <span class="comment"># 只需要将error * local gradient，即hidden2.</span></span><br><span class="line">        dW3 = (hidden_layer2.T).dot(dscores)  <span class="comment"># [50*N] * [N*3] = [50*3]</span></span><br><span class="line">        db3 = np.sum(dscores, axis=<span class="number">0</span>, keepdims=<span class="literal">True</span>) <span class="comment"># [3]</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> NONLINEARITY == <span class="string">'RELU'</span>:</span><br><span class="line">            <span class="comment"># backprop Relu nonlinearity here</span></span><br><span class="line">            dhidden2 = np.dot(dscores, W3.T)</span><br><span class="line">            dhidden2[hidden_layer2 &lt;= <span class="number">0</span>] = <span class="number">0</span></span><br><span class="line">            dW2 = np.dot(hidden_layer.T, dhidden2)</span><br><span class="line">            plot_array_2.append(np.sum(np.abs(dW2))/np.sum(np.abs(dW2.shape)))</span><br><span class="line">            db2 = np.sum(dhidden2, axis=<span class="number">0</span>)</span><br><span class="line">            dhidden = np.dot(dhidden2, W2.T)</span><br><span class="line">            dhidden[hidden_layer &lt;= <span class="number">0</span>] = <span class="number">0</span></span><br><span class="line">        </span><br><span class="line">        <span class="keyword">elif</span> NONLINEARITY == <span class="string">'SIGM'</span>:</span><br><span class="line">            <span class="comment"># backprop sigmoid nonlinearity there</span></span><br><span class="line">            <span class="comment"># hidden layer 2 是 sigmoid的输出，因此需要乘以一个local gradiant</span></span><br><span class="line">            dhidden2 = dscores.dot(W3.T)*sigmoid_grad(hidden_layer2) </span><br><span class="line">            dW2 = (hidden_layer.T).dot(dhidden2)</span><br><span class="line">            plot_array_2.append(np.sum(np.abs(dW2))/np.sum(np.abs(dW2.shape)))</span><br><span class="line">            db2 = np.sum(dhidden2, axis=<span class="number">0</span>)</span><br><span class="line">            dhidden = dhidden2.dot(W2.T)*sigmoid_grad(hidden_layer)</span><br><span class="line"></span><br><span class="line">        dW1 = np.dot(X.T, dhidden)</span><br><span class="line">        plot_array_1.append(np.sum(np.abs(dW1))/np.sum(np.abs(dW1.shape)))</span><br><span class="line">        db1 = np.sum(dhidden, axis=<span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">        <span class="comment"># add regularization</span></span><br><span class="line">        dW3 += reg * W3</span><br><span class="line">        dW2 += reg * W2</span><br><span class="line">        dW1 += reg * W1</span><br><span class="line"></span><br><span class="line">        <span class="comment"># option to return loss, grads, </span></span><br><span class="line">        <span class="comment"># grads = &#123;&#125;</span></span><br><span class="line">        <span class="comment"># grads['W1'] = dW1</span></span><br><span class="line">        <span class="comment"># grads['W2'] = dW2</span></span><br><span class="line">        <span class="comment"># grads['W3'] = dW3</span></span><br><span class="line">        <span class="comment"># grads['b1'] = db1</span></span><br><span class="line">        <span class="comment"># grads['b2'] = db2</span></span><br><span class="line">        <span class="comment"># grads['b3'] = db3</span></span><br><span class="line"></span><br><span class="line">        <span class="comment"># update grads</span></span><br><span class="line">        W1 += -step_size * dW1</span><br><span class="line">        b1 += -step_size * db1</span><br><span class="line">        W2 += -step_size * dW2</span><br><span class="line">        b2 += -step_size * db2        </span><br><span class="line">        W3 += -step_size * dW3</span><br><span class="line">        b3 += -step_size * db3</span><br><span class="line">    <span class="comment"># evaluate training set accuracy， 使用training出来的W1，W2,W3,b1,b2,b3</span></span><br><span class="line">    <span class="comment"># 来计算结果。</span></span><br><span class="line">    <span class="keyword">if</span> NONLINEARITY == <span class="string">'RELU'</span>:</span><br><span class="line">        hidden_layer = relu(np.dot(X, W1) + b1)</span><br><span class="line">        hidden_layer2 = relu(np.dot(hidden_layer, W2) + b2)</span><br><span class="line">    <span class="keyword">elif</span> NONLINEARITY == <span class="string">'SIGM'</span>:</span><br><span class="line">        hidden_layer = sigmoid(np.dot(X, W1) + b1)</span><br><span class="line">        hidden_layer2 = sigmoid(np.dot(hidden_layer, W2) + b2)</span><br><span class="line"></span><br><span class="line">    scores = np.dot(hidden_layer2, W3) + b3</span><br><span class="line">    predicted_class = np.argmax(scores, axis=<span class="number">1</span>)  <span class="comment"># 找出每一行的最大值的index</span></span><br><span class="line">    print(<span class="string">'training accuracy: &#123;0&#125;'</span>.format(np.mean(predicted_class==y)))</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> plot_array_1, plot_array_2, W1, W2, W3, b1, b2, b3</span><br></pre></td></tr></table></figure><p>关于back propagation 的计算参见下图。 其实就是对chain rule的应用。</p><img src="/2020/06/02/vanishing-gradients/8.jpg" class=""><h3 id="Train-net-with-sigmoid-nonlinearity-first"><a href="#Train-net-with-sigmoid-nonlinearity-first" class="headerlink" title="Train net with sigmoid nonlinearity first"></a>Train net with sigmoid nonlinearity first</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Initialize toy model, train sigmoid net </span></span><br><span class="line"></span><br><span class="line">N = <span class="number">100</span>  <span class="comment"># number of points per class</span></span><br><span class="line">D = <span class="number">2</span>  <span class="comment"># dimensionality</span></span><br><span class="line">K = <span class="number">3</span>  <span class="comment"># number of classes</span></span><br><span class="line">h = <span class="number">50</span>  <span class="comment"># hidden layer 1 size</span></span><br><span class="line">h2 = <span class="number">50</span>  <span class="comment"># hidden layer 2 size</span></span><br><span class="line">num_train_examples = X.shape[<span class="number">0</span>]</span><br><span class="line"></span><br><span class="line">model = &#123;&#125;</span><br><span class="line">model[<span class="string">'h'</span>] = h</span><br><span class="line">model[<span class="string">'h2'</span>] = h2</span><br><span class="line">model[<span class="string">'W1'</span>] = <span class="number">0.1</span> * np.random.randn(D, h)</span><br><span class="line">model[<span class="string">'b1'</span>] = np.zeros((<span class="number">1</span>,h))</span><br><span class="line">model[<span class="string">'W2'</span>] = <span class="number">0.1</span> * np.random.randn(h, h2)</span><br><span class="line">model[<span class="string">'b2'</span>] = np.zeros((<span class="number">1</span>,h2))</span><br><span class="line">model[<span class="string">'W3'</span>] = <span class="number">0.1</span> * np.random.randn(h2, K)</span><br><span class="line">model[<span class="string">'b3'</span>] = np.zeros((<span class="number">1</span>,K))</span><br><span class="line"></span><br><span class="line">(sigm_array_1, sigm_array_2, s_W1, s_W2, s_W3, s_b1, s_b2, s_b3) = three_layer_net(<span class="string">'SIGM'</span>, X, y, model, step_size=<span class="number">1e-1</span>, reg=<span class="number">1e-3</span>)</span><br></pre></td></tr></table></figure><p>training accuracy: 0.97</p><h3 id="Now-train-net-with-ReLU-nonlinearity"><a href="#Now-train-net-with-ReLU-nonlinearity" class="headerlink" title="Now train net with ReLU nonlinearity"></a>Now train net with ReLU nonlinearity</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Re-initialize model, train relu net</span></span><br><span class="line">model = &#123;&#125;</span><br><span class="line">model[<span class="string">'h'</span>] = h</span><br><span class="line">model[<span class="string">'h2'</span>] = h2</span><br><span class="line">model[<span class="string">'W1'</span>] = <span class="number">0.1</span> * np.random.randn(D, h)</span><br><span class="line">model[<span class="string">'b1'</span>] = np.zeros((<span class="number">1</span>,h))</span><br><span class="line">model[<span class="string">'W2'</span>] = <span class="number">0.1</span> * np.random.randn(h, h2)</span><br><span class="line">model[<span class="string">'b2'</span>] = np.zeros((<span class="number">1</span>,h2))</span><br><span class="line">model[<span class="string">'W3'</span>] = <span class="number">0.1</span> * np.random.randn(h2, K)</span><br><span class="line">model[<span class="string">'b3'</span>] = np.zeros((<span class="number">1</span>,K))</span><br><span class="line"></span><br><span class="line">(relu_array_1, relu_array_2, r_W1, r_W2, r_W3, r_b1, r_b2, r_b3) = three_layer_net(<span class="string">'RELU'</span>, X, y, model, step_size=<span class="number">1e-1</span>, reg=<span class="number">1e-3</span>)</span><br></pre></td></tr></table></figure><p>training accuracy: 0.9933333333333333</p><h2 id="The-Vanishing-Gradient-Issue-—-梯度消失的问题"><a href="#The-Vanishing-Gradient-Issue-—-梯度消失的问题" class="headerlink" title="The Vanishing Gradient Issue — 梯度消失的问题"></a>The Vanishing Gradient Issue — 梯度消失的问题</h2><p>我们可以对某一hidden层W的梯度（dW）进行加总，用这个简单的指标来衡量学习的速度，显然，sum(dW)越大，说明神经网络的学习速度越快。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">plt.plot(np.array(sigm_array_1))</span><br><span class="line">plt.plot(np.array(sigm_array_2))</span><br><span class="line">plt.title(<span class="string">'Sum of magnitudes of gradients -- SIGM weights'</span>)</span><br><span class="line">plt.legend((<span class="string">"sigm first layer"</span>, <span class="string">"sigm second layer"</span>))</span><br></pre></td></tr></table></figure><p><img src="3.svg" alt="svg"></p><p>由上图可见，第二层的梯度显著大于第一层。说明在进行back prop的时候，hidden层越多，那么排在最前的hidden层对应的梯度（dW）就会变得越来越小。直观的讲，因为chain rule的原因，hidden层越多，则chain rule里乘的local gradient越多，而另一方面，由于nonlinearity使用的是sigmod，sigmoid grad = δ*(1-δ)，输出必在[0,1]之间。所以local gradient的值都落在[0，1]，那么随着hidden层的增加，排在最前的hidden层对应的梯度（dW）就会变得越来越小。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">plt.plot(np.array(relu_array_1))</span><br><span class="line">plt.plot(np.array(relu_array_2))</span><br><span class="line">plt.title(<span class="string">'Sum of magnitudes of gradients -- ReLU weights'</span>)</span><br><span class="line">plt.legend((<span class="string">"relu first layer"</span>, <span class="string">"relu second layer"</span>))</span><br></pre></td></tr></table></figure><p><img src="4.svg" alt="svg"></p><p>由上图可见，ReLU收敛的速度比sigmoid快很多，而且收敛后就很稳定。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># overlaying the 2 plots to compare</span></span><br><span class="line">plt.plot(np.array(sigm_array_1))</span><br><span class="line">plt.plot(np.array(sigm_array_2))</span><br><span class="line">plt.plot(np.array(relu_array_1))</span><br><span class="line">plt.plot(np.array(relu_array_2))</span><br><span class="line">plt.title(<span class="string">'Sum of magnitudes of gradients -- hidden layer neurons'</span>)</span><br><span class="line">plt.legend((<span class="string">"sigm first layer"</span>, <span class="string">"sigm second layer"</span>, <span class="string">"relu first layer"</span>, <span class="string">"relu second layer"</span>))</span><br></pre></td></tr></table></figure><p><img src="5.svg" alt="svg"></p><p>上图可以更明显的看到，ReLU的收敛速度快，一开始的gradient更高。</p><p>最后，看看2种分类器的表现，由于ReLU训练速度更快，因此用同样的epochs，ReLU表现的更好。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># plot the classifiers -- SIGMOID</span></span><br><span class="line">h = <span class="number">0.02</span></span><br><span class="line">x_min, x_max = X[:, <span class="number">0</span>].min() - <span class="number">1</span>, X[:, <span class="number">0</span>].max() + <span class="number">1</span></span><br><span class="line">y_min, y_max = X[:, <span class="number">1</span>].min() - <span class="number">1</span>, X[:, <span class="number">1</span>].max() + <span class="number">1</span></span><br><span class="line">xx, yy = np.meshgrid(np.arange(x_min, x_max, h),</span><br><span class="line">                     np.arange(y_min, y_max, h))</span><br><span class="line">Z = np.dot(sigmoid(np.dot(sigmoid(np.dot(np.c_[xx.ravel(), yy.ravel()], s_W1) + s_b1), s_W2) + s_b2), s_W3) + s_b3</span><br><span class="line">Z = np.argmax(Z, axis=<span class="number">1</span>)</span><br><span class="line">Z = Z.reshape(xx.shape)</span><br><span class="line">fig = plt.figure()</span><br><span class="line">plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=<span class="number">0.8</span>)</span><br><span class="line">plt.scatter(X[:, <span class="number">0</span>], X[:, <span class="number">1</span>], c=y, s=<span class="number">40</span>, cmap=plt.cm.Spectral)</span><br><span class="line">plt.xlim(xx.min(), xx.max())</span><br><span class="line">plt.ylim(yy.min(), yy.max())</span><br></pre></td></tr></table></figure><p><img src="6.svg" alt="svg"></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># plot the classifiers-- RELU</span></span><br><span class="line">h = <span class="number">0.02</span></span><br><span class="line">x_min, x_max = X[:, <span class="number">0</span>].min() - <span class="number">1</span>, X[:, <span class="number">0</span>].max() + <span class="number">1</span></span><br><span class="line">y_min, y_max = X[:, <span class="number">1</span>].min() - <span class="number">1</span>, X[:, <span class="number">1</span>].max() + <span class="number">1</span></span><br><span class="line">xx, yy = np.meshgrid(np.arange(x_min, x_max, h),</span><br><span class="line">                     np.arange(y_min, y_max, h))</span><br><span class="line">Z = np.dot(relu(np.dot(relu(np.dot(np.c_[xx.ravel(), yy.ravel()], r_W1) + r_b1), r_W2) + r_b2), r_W3) + r_b3</span><br><span class="line">Z = np.argmax(Z, axis=<span class="number">1</span>)</span><br><span class="line">Z = Z.reshape(xx.shape)</span><br><span class="line">fig = plt.figure()</span><br><span class="line">plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=<span class="number">0.8</span>)</span><br><span class="line">plt.scatter(X[:, <span class="number">0</span>], X[:, <span class="number">1</span>], c=y, s=<span class="number">40</span>, cmap=plt.cm.Spectral)</span><br><span class="line">plt.xlim(xx.min(), xx.max())</span><br><span class="line">plt.ylim(yy.min(), yy.max())</span><br></pre></td></tr></table></figure><p><img src="7.svg" alt="svg"></p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;Vanishing-Gradients&quot;&gt;&lt;a href=&quot;#Vanishing-Gradients&quot; class=&quot;headerlink&quot; title=&quot;Vanishing Gradients&quot;&gt;&lt;/a&gt;Vanishing Gradients&lt;/h1&gt;&lt;p&gt;这里只使用numpy来实现一个neural network，而非借助pytorch这样的框架，如此，可以更好的帮助我理解neural network以及vanishing gradients.&lt;/p&gt;
    
    </summary>
    
    
      <category term="Financial Machine Learning" scheme="https://www.keepswalking.com/categories/Financial-Machine-Learning/"/>
    
    
  </entry>
  
  <entry>
    <title>Bars part 1</title>
    <link href="https://www.keepswalking.com/2020/03/28/bars-part-1/"/>
    <id>https://www.keepswalking.com/2020/03/28/bars-part-1/</id>
    <published>2020-03-28T09:51:32.000Z</published>
    <updated>2020-03-28T12:26:36.820Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Financial-Machine-Learning-Bars"><a href="#Financial-Machine-Learning-Bars" class="headerlink" title="Financial Machine Learning - Bars"></a>Financial Machine Learning - Bars</h1><p>最近在啃Marcos Lopez de Prado的 Advances in Financial Machine Learning，感觉很有难度，我想通过笔记的形式将自己的理解慢慢记录下来。总体讲这本书给我很多的启发。个人感觉，网上很多所谓machine learning在finance和investment上的应用都是谬误的，其实这本书并不会讨论具体的算法，而更多的是提供一种machine learning在finance 应用上的标准流程或者说是方法论，懂得了这些流程/方法论并不能保证你就能写出赚钱的模型来，但是，可以帮助你避免很多错误和陷阱，从而节约了你很多的时间。本书的观点认为，ML在投资领域的应用犹如一种工业化的生产过程，在当今市场的有效性条件下，企图靠某个个人所谓的深厚功力写出一个盈利可观的模型变得越来越不切实际了，只有依靠大量的人力，标准化的流程才可能在高度有效的市场环境下生存。</p><a id="more"></a><p>该书首先从数据准备讲起。他的观点是，如果某项数据所有人都在用，那这个数据的价值就不大了。比如财报数据，当然，传统bar（K线）数据的价值也不大，一方面人人都在用，另外一方k线数据的采样是有缺陷的。举例来说，假如我们使用5分钟线，那么通常在每天开盘和收盘的时间段成交比较密集，也就意味着这段时间包含的信息量比较多。但是，传统的k线只做定期采样，造成的结果就是，各个5分钟k线包含的信息量是不等的，导致很多的信息量无法被体现出来。为了避免这样的缺陷，该书提出了以下几种bar：</p><ul><li><p>Tick Bars</p></li><li><p>Volume Bars</p></li><li><p>Dollar Bars</p></li><li><p>Imbalance Bars</p></li></ul><p>接下来我以沪深300指数的1分钟k线为基础，分别来看这些Bar有什么区别。</p><h2 id="Time-Bars"><a href="#Time-Bars" class="headerlink" title="Time Bars"></a>Time Bars</h2><p>Time bars就是指最常见的k线了。原始数据是1分钟k线，我可以将其合成为15分钟k线</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># load data</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> datetime <span class="keyword">import</span> datetime</span><br><span class="line"></span><br><span class="line">data = pd.read_csv(<span class="string">"hs300.csv"</span>) <span class="comment">#沪深300 1分钟k线</span></span><br><span class="line"><span class="comment"># change column name</span></span><br><span class="line">data.rename(columns=&#123;data.columns[<span class="number">0</span>]:<span class="string">"timestamp"</span>&#125;, inplace=<span class="literal">True</span>)</span><br><span class="line">data[<span class="string">'timestamp'</span>] = pd.to_datetime(data[<span class="string">'timestamp'</span>])</span><br><span class="line"><span class="comment"># data['timestamp'] = data.timestamp.map(lambda t: datetime.strptime(t, "%Y-%m-%d %H:%M:%S"))</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">compute_vwap</span><span class="params">(df)</span>:</span></span><br><span class="line">    <span class="comment"># 因为groupby有upsampling的问题，所以，必须剔出这些额外增加出来的非交易时段的ts</span></span><br><span class="line">    <span class="keyword">if</span> df.isna().to_numpy().any():</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    q = df[<span class="string">'volume'</span>]</span><br><span class="line">    p = df[<span class="string">'close'</span>] <span class="comment"># use close price</span></span><br><span class="line">    vwap = np.sum(p * q) / np.sum(q)</span><br><span class="line">    df[<span class="string">'vwap'</span>] = vwap</span><br><span class="line">    <span class="comment"># print(df.head())</span></span><br><span class="line">    <span class="keyword">return</span> df</span><br><span class="line"></span><br><span class="line">data_timeidx = data.set_index(<span class="string">'timestamp'</span>)</span><br><span class="line"></span><br><span class="line">sub_data = data_timeidx[<span class="string">'2015-05'</span>] <span class="comment">#选取2015年5月的数据</span></span><br><span class="line">data_time_grp = sub_data.groupby(pd.Grouper(freq=<span class="string">'15Min'</span>, closed=<span class="string">'right'</span>))</span><br><span class="line">num_time_bars = <span class="number">1</span></span><br><span class="line"><span class="comment"># 计算groupby以后一共有多少跟k线</span></span><br><span class="line"><span class="keyword">for</span> name, group <span class="keyword">in</span> data_time_grp:</span><br><span class="line">    <span class="keyword">if</span> group.empty == <span class="literal">False</span>:</span><br><span class="line">        num_time_bars += <span class="number">1</span></span><br><span class="line"></span><br><span class="line">data_time_vwap = data_time_grp.apply(compute_vwap)    </span><br><span class="line">sub_df = data_time_vwap.copy()</span><br><span class="line">sub_df.index = sub_df.index.map(str)</span><br><span class="line">sub_df[<span class="string">'vwap'</span>].plot()</span><br></pre></td></tr></table></figure><pre><code>&lt;matplotlib.axes._subplots.AxesSubplot at 0x180d0b81f88&gt;</code></pre><p><img src="bars_4_1.svg" alt="svg"></p><h2 id="Tick-Bars"><a href="#Tick-Bars" class="headerlink" title="Tick Bars"></a>Tick Bars</h2><p>为了避免上述Time bar的问题，一种方法是构建tick bar。 所谓tick bar是以某个固定的tick数量来切分并生成对应的bar，例如：每个tick bar包含50个tick。这样做的好显而易见，就是当市场的某些时段交易很活跃的时候，就有更多的tick bar生成出来即更多的采样，反之，生成的tick bar的数量减少。因此，相较于传统的time bar，每个tick bar包含的信息更加均衡。</p><p>但是tick bar也有一个缺点，例如：一个tick对应10手买单，和10个tick，每个tick分别对应1手买单。但是，他们包含的信息量显然不一样，简单来说，前者可能是掌握了某些信息的市场参与者的行为，而后者可能更多的是一种随机行为。按照tick bar的生成方式，前者就无法被及时采样，并容易被其他低信息量的tick淹没。</p><p>由于我的原始数据是1分钟k线而非tick数据，因此无法合成tick bar。</p><h2 id="Volume-Bars"><a href="#Volume-Bars" class="headerlink" title="Volume Bars"></a>Volume Bars</h2><p>所谓的volume bar就是以某个固定的成交量来切分并生成对应的bar。例如：每个bar包含10000股的成交量。这样就改进了tick bar存在的问题，使得每个volume bar所含的信息量更为平均</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">data_cm_vol = sub_data.assign(cmVol=sub_data[<span class="string">'volume'</span>].cumsum())  <span class="comment">#计算总成交量</span></span><br><span class="line">total_vol = data_cm_vol.cmVol.values[<span class="number">-1</span>]</span><br><span class="line"><span class="comment"># 令volume bar的数量和time bar的数量相同，便于显示的时候做比较</span></span><br><span class="line">vol_per_bar = total_vol / num_time_bars</span><br><span class="line">vol_per_bar = round(vol_per_bar, <span class="number">0</span>) </span><br><span class="line">data_vol_grp = data_cm_vol.assign(grpId=<span class="keyword">lambda</span> row: row.cmVol // vol_per_bar)</span><br><span class="line">data_vol_vwap =  data_vol_grp.groupby(<span class="string">'grpId'</span>).apply(compute_vwap)</span><br><span class="line"><span class="comment"># plot</span></span><br><span class="line">sub_df1 = data_vol_vwap.copy()</span><br><span class="line">sub_df1.index = sub_df1.index.map(str)</span><br><span class="line">plot_data = &#123;<span class="string">'time'</span>: sub_df[<span class="string">'vwap'</span>], <span class="string">'volume'</span>:sub_df1[<span class="string">'vwap'</span>]&#125;</span><br><span class="line">plot_df = pd.DataFrame(plot_data)</span><br><span class="line">plot_df.plot(alpha=<span class="number">0.6</span>)</span><br></pre></td></tr></table></figure><pre><code>&lt;matplotlib.axes._subplots.AxesSubplot at 0x180ce3cf788&gt;</code></pre><p><img src="bars_7_1.svg" alt="svg"></p><p>由上图可见volume bar在一些波峰和波谷的位置更加的显著，说明在偏极端的行情的环境下，volume bar保存的信息更多。如下所示的放大图。</p><img src="/2020/03/28/bars-part-1/enlarge1.PNG" class=""><h2 id="Dollar-Bars"><a href="#Dollar-Bars" class="headerlink" title="Dollar Bars"></a>Dollar Bars</h2><p>同Volume bar类似，所谓的Dollar bar就是以某个固定的成交金额来切分并生成对应的bar。例如：每个bar包含100000元。一个比较直观想法是：当上证综合指数在6000点买入100手股票同在1000点买入100手股票是完全不同的概念，由于在资金量上的巨大的差异，虽然手数相同，但是这两个决定所包含的信息应该是差异很大。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">data_cm_dollar = sub_data.assign(cmDollar=sub_data[<span class="string">'total_turnover'</span>].cumsum()) </span><br><span class="line">total_dollar = data_cm_dollar.cmDollar.values[<span class="number">-1</span>]</span><br><span class="line">dollar_per_bar = total_dollar / num_time_bars</span><br><span class="line">dollar_per_bar = round(dollar_per_bar, <span class="number">0</span>) </span><br><span class="line">data_dollar_grp = data_cm_dollar.assign(grpId=<span class="keyword">lambda</span> row: row.cmDollar // dollar_per_bar)</span><br><span class="line">data_dollar_vwap =  data_dollar_grp.groupby(<span class="string">'grpId'</span>).apply(compute_vwap)</span><br><span class="line"><span class="comment"># plot</span></span><br><span class="line">sub_df2 = data_dollar_vwap.copy()</span><br><span class="line">sub_df2.index = sub_df2.index.map(str)</span><br><span class="line"></span><br><span class="line">plot_data = &#123;<span class="string">'dollar'</span>: sub_df2[<span class="string">'vwap'</span>], <span class="string">'volume'</span>:sub_df1[<span class="string">'vwap'</span>]&#125;</span><br><span class="line">plot_df = pd.DataFrame(plot_data)</span><br><span class="line">plot_df.plot(alpha=<span class="number">0.6</span>)</span><br></pre></td></tr></table></figure><pre><code>&lt;matplotlib.axes._subplots.AxesSubplot at 0x180d1e57988&gt;</code></pre><p><img src="bars_10_1.svg" alt="svg"></p><p>上图是dollar bar 和 volume bar的比较。区别不是很大。可以看出，在一些比较极端的走势图形上，dollar bar和volume bar的采样还是有一定区别。如下图所示：</p><img src="/2020/03/28/bars-part-1/enlarge2.PNG" class=""><p>除了以上这些bar外，还有一种bar叫做Imbalance bar，由于相对比较复杂，所以会单独开一篇来介绍。</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;Financial-Machine-Learning-Bars&quot;&gt;&lt;a href=&quot;#Financial-Machine-Learning-Bars&quot; class=&quot;headerlink&quot; title=&quot;Financial Machine Learning - Bars&quot;&gt;&lt;/a&gt;Financial Machine Learning - Bars&lt;/h1&gt;&lt;p&gt;最近在啃Marcos Lopez de Prado的 Advances in Financial Machine Learning，感觉很有难度，我想通过笔记的形式将自己的理解慢慢记录下来。总体讲这本书给我很多的启发。个人感觉，网上很多所谓machine learning在finance和investment上的应用都是谬误的，其实这本书并不会讨论具体的算法，而更多的是提供一种machine learning在finance 应用上的标准流程或者说是方法论，懂得了这些流程/方法论并不能保证你就能写出赚钱的模型来，但是，可以帮助你避免很多错误和陷阱，从而节约了你很多的时间。本书的观点认为，ML在投资领域的应用犹如一种工业化的生产过程，在当今市场的有效性条件下，企图靠某个个人所谓的深厚功力写出一个盈利可观的模型变得越来越不切实际了，只有依靠大量的人力，标准化的流程才可能在高度有效的市场环境下生存。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Financial Machine Learning" scheme="https://www.keepswalking.com/categories/Financial-Machine-Learning/"/>
    
    
  </entry>
  
  <entry>
    <title>AdaBoost Example</title>
    <link href="https://www.keepswalking.com/2020/02/23/AdaBoost-Example/"/>
    <id>https://www.keepswalking.com/2020/02/23/AdaBoost-Example/</id>
    <published>2020-02-23T14:08:03.000Z</published>
    <updated>2020-02-26T08:50:10.899Z</updated>
    
    <content type="html"><![CDATA[<p>我终于想到自己应该滚过来更新了。实在是因为考完CFA以后，整个人生好像没有了明确的目标，导致自己什么都想做，结果什么都做不好。这段时间自己的状态一直保持低迷，原因肯定是对自己各种的放纵。前阵子，德约科维奇又拿下来澳网的冠军，我就顺便看了一本他的自传，印象最深的是极度的自律。在拿到某次冠军后（好像也是澳网），他说他想吃一块巧克力庆祝一下（因为平时绝对不会碰这种东西，怕影响状态），结果就吃了一小口。只有能做到这样的自律，才能取得不平凡的成绩。</p><p>说了一堆废话，还是言归正传。前段时间正好用到random forrest就想顺便把AdaBoost也看一下，李航《统计学习方法》里有一个例子，但是我怎么都没看懂（智商不够用，顺便吐槽一下这本书，虽然很多人推荐，但我一直没觉得这本书好在哪里），于是就到网上找例子，到油管上看视频，结果发现能把AdaBoost讲明白的例子几乎没有。后来不知道哪天突然开悟了，李航那本书上的例子竟然被我看明白了！</p><a id="more"></a><p>我就直接上例子了，AdaBoost具体的理论还请自行脑补。训练数据如下表：</p><div class="table-container"><table><thead><tr><th>序号</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>10 </th></tr></thead><tbody><tr><td>x</td><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9 </td></tr><tr><td>y</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td><td>-1</td><td>1</td><td>1</td><td>1</td><td>-1</td></tr></tbody></table></div><p>x是特征，y是label。显然根据特征x对y分类，分为2种类型1，-1。我一开始一直没搞明白评价分类结果依据什么？后来才理解了评价分类的依据是各训练数据的权值！我们知道Adaboost会将分类错误的训练数据的权值提高，这样，在下一次弱分类器的训练过程中就可以重点“关照”这些被分错的数据了。那么，也就有可能出现以下这种情况：某个弱分类器可能错误率很高但却被采纳了，因为它可能将权重更高的训练数据进行准确地分类。参见以下训练过程</p><h3 id="m-1-训练第一个弱分类器"><a href="#m-1-训练第一个弱分类器" class="headerlink" title="m=1 (训练第一个弱分类器)"></a>m=1 (训练第一个弱分类器)</h3><p>对于第一个弱分类器而言，每个训练数据的权值w都是一样的，即1/N（初始情况下的默认值），N表示训练数据量。就本例而言，N=10，每个训练数据的权值w为0.1，在此前提下可以训练出一个最优的弱分类器：</p><script type="math/tex; mode=display">    G_1(x) =     \\begin{cases}    1,  & \text{x $<$ 2.5} \\\\    -1, & \text{x $>$ 2.5} \\\\    \\end{cases}</script><p>切分点为x=2.5，因为误差率（分错权值加总）最低，注意这里需要强调的是选择弱分类器的依据是误差率最低的那个，而不是分对的数量最多的那个（当然，权值相同的时候分对数量最高则代表误差率最低），我一开始没看明白就是在这里犯糊涂了。那么有3个数据被错误分类了（x=6，7，8），由于w都为0.1，因此误差率$e_1$（分错权值加总）=0.3。这个误差率是当前权值（w）下最小的。</p><p>计算第一个弱分类器的系数（权重），套用公式了，$ \alpha_1 = \frac{1}{2}log\frac{1-e_1}{e_1} $ = 0.5*ln((1-0.3)/0.3) = 0.4236 ； 直观的理解就是如果这个分类器的误差率越低，则在一系列弱分类器的组合里所占的权重越高。</p><p>更新训练数据的权值，也就是将分对的数据的权值调低，而将分错的数据的权值调高，计算权值的公式为：$w<em>{m+1, i} = w</em>{m, i}exp(-\alpha_m y_i G_m(x_i))$，计算结果如下：</p><div class="table-container"><table><thead><tr><th>序号</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>10 </th></tr></thead><tbody><tr><td>y</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td><td>-1</td><td>1</td><td>1</td><td>1</td><td>-1</td></tr><tr><td>$w_1$</td><td>0.1</td><td>0.1</td><td>0.1</td><td>0.1</td><td>0.1</td><td>0.1</td><td>0.1</td><td>0.1</td><td>0.1</td><td>0.1</td></tr><tr><td>$G_1(x)$</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td><td>-1</td><td>-1</td><td>-1</td><td>-1</td><td>-1</td></tr><tr><td>$ \alpha_1 $</td><td>0.4236</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>$w_2$ without normalized</td><td>0.06547</td><td>0.06547</td><td>0.06547</td><td>0.06547</td><td>0.06547</td><td>0.06547</td><td>0.15275</td><td>0.15275</td><td>0.15275</td><td>0.06547 </td></tr><tr><td>Z</td><td>0.9165</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>$w_2$ normalized</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.16667</td><td>0.16667</td><td>0.16667</td><td>0.07143 </td></tr></tbody></table></div><p>以计算第一个$w_2$为例，原来的$w_2=0.1, \alpha=0.4236, y=1, G_1(x_1)=1$，也就是分类正确，那么可得: 0.1 <em> exp(-0.4236 </em> 1 * 1) = 0.06547<br>，标准化后为0.07143（$w_2$ 需要标准化，也就是$w_2$的sum为1，表中的Z为所有w的加总，那么normalized w = w without normalized / Z），因此权重降低了！。而对$x_7, x_8, x_9$来说，由于分错了，因此权重升高了。至此第一个弱分类器训练完成，可得：</p><script type="math/tex; mode=display">f_1(x) = 0.4236G_1(x)</script><h3 id="m-2-训练第二个弱分类器"><a href="#m-2-训练第二个弱分类器" class="headerlink" title="m=2 (训练第二个弱分类器)"></a>m=2 (训练第二个弱分类器)</h3><p>通过训练可得x=8.5最为最佳切分点，因为误差率最小，即：</p><script type="math/tex; mode=display">    G_2(x) =     \\begin{cases}    1,  & \text{x $<$ 8.5} \\\\    -1, & \text{x $>$ 8.5}    \\end{cases}</script><p>$G_2(x)$的误差率为$e_2 = 0.2143$。因为当以8.5为切分点的时候，4，5，6被错误分类了，而他们对应的权重$w_2$ 分别为：0.07143，0.07143，0.07143，即 0.07143 * 3 = 0.2143。如果选择8.5以外的切分点，误差率都比0.2143高。</p><p>同样的计算$\alpha_2 = 0.5*LN((1-0.2143)/0.2143) = 0.6496$</p><p>其余数据参见下表：</p><div class="table-container"><table><thead><tr><th>序号</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>10 </th></tr></thead><tbody><tr><td>y</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td><td>-1</td><td>1</td><td>1</td><td>1</td><td>-1</td></tr><tr><td>$w_2$</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.07143</td><td>0.16667</td><td>0.16667</td><td>0.16667</td><td>0.07143 </td></tr><tr><td>$G_2(x)$</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td></tr><tr><td>$ \alpha_2 $</td><td>0.6496</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>$w_3$ without normalized</td><td>0.0373</td><td>0.0373</td><td>0.0373</td><td>0.1368</td><td>0.1368</td><td>0.1368</td><td>0.0870</td><td>0.0870</td><td>0.0870</td><td>0.0373  </td></tr><tr><td>Z</td><td>0.8207</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>$w_3$ normalized</td><td>0.0455</td><td>0.0455</td><td>0.0455</td><td>0.1667</td><td>0.1667</td><td>0.1667</td><td>0.1061</td><td>0.1061</td><td>0.1061</td><td>0.0455 </td></tr></tbody></table></div><p>至此第二个弱分类器训练完成，可得：</p><script type="math/tex; mode=display">f_2(x) = 0.4236G_1(x) + 0.6496G_2(x)</script><p>如果，此时将数据喂给$f_2(x)$，可得以下结果：</p><div class="table-container"><table><thead><tr><th>序号</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>10 </th></tr></thead><tbody><tr><td>x</td><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9 </td></tr><tr><td>y</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td><td>-1</td><td>1</td><td>1</td><td>1</td><td>-1</td></tr><tr><td>$f_2(x)$</td><td>1.0732</td><td>1.0732</td><td>1.0732</td><td>0.226</td><td>0.226</td><td>0.226</td><td>0.226</td><td>0.226</td><td>0.226</td><td>-1.0732</td></tr><tr><td>$sign(f_2(x))$</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td><td>-1</td></tr></tbody></table></div><p>由y同$sign(f_2(x))$比较可知，一共有3个误分类点：4，5，6。</p><h3 id="m-3-训练第三个弱分类器"><a href="#m-3-训练第三个弱分类器" class="headerlink" title="m=3 (训练第三个弱分类器)"></a>m=3 (训练第三个弱分类器)</h3><p>通过训练可得x=5.5最为最佳切分点，因为误差率最小，即：</p><script type="math/tex; mode=display">    G_3(x) =     \\begin{cases}    1,  & \text{x $>$ 5.5} \\\\    -1, & \text{x $<$ 5.5}    \\end{cases}</script><p>$G_3(x)$的误差率为$e_3 = 0.1818$。因为当以5.5为切分点的时候1, 2, 3, 10被错误分类了，而他们对应的权重$w_3$ 分别为：0.0455, 0.0455, 0.0455, 0.0455，即 0.0455 * 4 = 0.1818。</p><p>同样的计算$\alpha_3 = 0.5*LN((1-0.1818)/0.0.1818) = 0.7520$</p><p>至此第三个弱分类器训练完成，可得：</p><script type="math/tex; mode=display">f_3(x) = 0.4236G_1(x) + 0.6496G_2(x) + 0.7520G_3(x)</script><p>如果，此时将数据喂给$f_3(x)$，可得以下结果：</p><div class="table-container"><table><thead><tr><th>序号</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>10 </th></tr></thead><tbody><tr><td>x</td><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9 </td></tr><tr><td>y</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td><td>-1</td><td>1</td><td>1</td><td>1</td><td>-1</td></tr><tr><td>$f_3(x)$</td><td>0.3212</td><td>0.3212</td><td>0.3212</td><td>-0.526</td><td>-0.526</td><td>-0.526</td><td>0.978</td><td>0.978</td><td>0.978</td><td>-0.3212</td></tr><tr><td>$sign(f_3(x))$</td><td>1</td><td>1</td><td>1</td><td>-1</td><td>-1</td><td>-1</td><td>1</td><td>1</td><td>1</td><td>-1</td></tr></tbody></table></div><p>由y同$sign(f_3(x))$比较可知已经无错误分类点！因此，可以认为达到了精度要求，无需再进一步训练。</p><p>以上就是对李航《统计学习方法》里关于AdaBoost例子的详细解释，作此笔记以备今后复习。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;我终于想到自己应该滚过来更新了。实在是因为考完CFA以后，整个人生好像没有了明确的目标，导致自己什么都想做，结果什么都做不好。这段时间自己的状态一直保持低迷，原因肯定是对自己各种的放纵。前阵子，德约科维奇又拿下来澳网的冠军，我就顺便看了一本他的自传，印象最深的是极度的自律。在拿到某次冠军后（好像也是澳网），他说他想吃一块巧克力庆祝一下（因为平时绝对不会碰这种东西，怕影响状态），结果就吃了一小口。只有能做到这样的自律，才能取得不平凡的成绩。&lt;/p&gt;
&lt;p&gt;说了一堆废话，还是言归正传。前段时间正好用到random forrest就想顺便把AdaBoost也看一下，李航《统计学习方法》里有一个例子，但是我怎么都没看懂（智商不够用，顺便吐槽一下这本书，虽然很多人推荐，但我一直没觉得这本书好在哪里），于是就到网上找例子，到油管上看视频，结果发现能把AdaBoost讲明白的例子几乎没有。后来不知道哪天突然开悟了，李航那本书上的例子竟然被我看明白了！&lt;/p&gt;
    
    </summary>
    
    
      <category term="Machine Learning" scheme="https://www.keepswalking.com/categories/Machine-Learning/"/>
    
    
  </entry>
  
  <entry>
    <title>Lasso Regression Notes</title>
    <link href="https://www.keepswalking.com/2019/09/08/lasso-regression-notes/"/>
    <id>https://www.keepswalking.com/2019/09/08/lasso-regression-notes/</id>
    <published>2019-09-08T09:48:58.000Z</published>
    <updated>2019-09-08T12:16:28.512Z</updated>
    
    <content type="html"><![CDATA[<p>这周读了一篇论文《基于LASSO和神经网络的量化交易智能系统构建》，借机看了一下Lasso的概念。做点笔记以备复习。</p><a id="more"></a><p>Lasso 全称Least absolute shrinkage and selection operator。主要的作用是regularization，也就是防止overfitting。通常用在linear regression和logistic regression里。说到regularization，另一种方式是ridge regression。两种表现形式如下：</p><ul><li>Ridge:<img src="/2019/09/08/lasso-regression-notes/ridge.PNG" class=""></li></ul><ul><li>Lasso:<img src="/2019/09/08/lasso-regression-notes/lasso.PNG" class=""></li></ul><p>Ridge和Lasso最重要的区别是，Ridge regression只能将不相关variables的beta减小至接近0；而Lasso regression则可以将beta减小至0。另外，需要注意的是Ridge Regression是无偏的，而Lasso则是有偏的（biased）。</p><p>那为何要用lasso呢？由于Lasso的特性—能够将无关variables的beta减少至0，因此它具有feature selection的能力。它能自动识别出哪些variables对模型的预测起到作用。</p><p>下面这副图解释了为何Lasso能将无关variables的beta减少至0。</p><img src="/2019/09/08/lasso-regression-notes/lasso_ridge.png" class=""><p>右边是Ridge regression，左边是Lasso regression。等高线的中点β hat代表了最优拟合点，但是，这个点通常是会造成overfitting的。为了避免overfitting，必须对beta的取值做出限制。也就是蓝色的区域。由图可见，Lasso区别Ridge的地方在于Lasso的beta取值范围是一个正方形，而Ridge则是圆形。在加入了regularization后的最优点一定落在红色等高线和蓝色区域相切的位置。而Lasso的切点一般会是正方形的顶点。也就是说，某些variables的beta取值为0。因此，Lasso具有feature selection的能力。</p><p>在看下图：</p><img src="/2019/09/08/lasso-regression-notes/lasso-reduce.png" class=""><p>横轴代表了λ（hyper parameter）的取值范围，纵轴代表了variables的数量。从图上可以看到，在λ取值较小的时候，所有的variables都包括在了模型内，而随着λ的增加，模型里的variables不断减少。因此，当遇到variables非常多的情况（模型复杂），Lasso是可以帮助识别出哪些variables对模型影响最大。</p><p>如何确定λ的值？通常使用cross validation的方式。根据不同的λ在cross validation set上所得到的误差来确定合理的值。</p><p>最后还是要吐槽一下国内博士的水平。个人觉得这篇论文质量不怎么样，也许是期刊《投资研究》本身水平不行？该博士第一步用linear regression + lasso 来选择feature（各种股票技术指标），第二步，这些通过lasso筛选出来的featrue被用于神经网络。最后得出的结论是lasso + 神经网络在预测股市涨跌方面的效果最好，sharpe ratio最高。我能看到的一个明显的逻辑上的问题是lasso是用在linear regression上的，也就是说这一步feature selection体现的线性相关性。而神经网络可用于非线性关系的发掘。那么在第一步中筛选出来的是线性显著的技术指标，这一步很可能把非线性的关系给过滤掉了。然后在第二步中，把这些线性显著的技术指标在输入给神经网络，那是希望从已知的线性关系中进一步发掘非线性关系？！觉得逻辑上挺混乱的。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;这周读了一篇论文《基于LASSO和神经网络的量化交易智能系统构建》，借机看了一下Lasso的概念。做点笔记以备复习。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Machine Learning" scheme="https://www.keepswalking.com/categories/Machine-Learning/"/>
    
    
  </entry>
  
  <entry>
    <title>CFA Level III 准备过程 【2019年6月】</title>
    <link href="https://www.keepswalking.com/2019/08/25/How-did-I-prepare-CFA-level-III/"/>
    <id>https://www.keepswalking.com/2019/08/25/How-did-I-prepare-CFA-level-III/</id>
    <published>2019-08-25T09:48:33.000Z</published>
    <updated>2019-08-25T12:14:00.304Z</updated>
    
    <content type="html"><![CDATA[<p>很幸运一次性过了CFA level III, 一二三级连续一次过关，真的是上天保佑了。<br><a id="more"></a><br>先说说考试本身。上午是essay，下午同1，2级一样是选择题。相对一二级来说，我三级的准备不是太充分。有一部分事先准备的复习资料最后也是没有时间去看了。因此上考场的时候心里就有点虚的。上午的essay可谓是悲惨啊，一上来就卡住了，结果花了1个小时前2题都没做完，当时心里就毛了，然后开始赶时间，后面也是有几个地方做不出，最后一大题彻底没时间了，只完成了第一个小问题。考完当时的第一反应就是：我也算是坚持到最后一秒了，没有放弃！但是，心里觉得这次考试很玄了。整个上午可以用梦游或魂不守舍来形容。中午休息的时候，依旧看到很多同学拿着资料在复习，我对这些人的敬佩之心如滔滔江水。已经考了3个小时了，还不休息一下？！下午还有3个小时啊。。。这时候还在复习，下午还有精力吗？反正我是觉得中午还是不要看什么资料了，好好休息休息，迎接下午的考试。下午进入考场的时候，发现原本坐我右边的同学撤了。。。我猜估计上午也遭到打击了！下午的难度明显低了很多，做题的速度因此变的很快。零星碰到一点有难度的题目，反正不是很多。因此，下午整个人的状态就很放松，不如上午来的那么崩溃了。不过还是受到了打击，还是源自上午的essay！我下午做题的时候，突然发现，计算器上计算PV的模式设置成了annuity due!!!当时如五雷轰顶啊～～～上午有2题是需要用到pv计算的，而且只需要普通的模式就行了，当时两眼一黑，想完了，上午肯定是一塌糊涂了。然后我也只能调整心态，不去想这件事了。所以，各位同学，必须要吸取我的教训，一定注意自己计算器的pv模式是否设置对了。</p><h2 id="关于复习资料"><a href="#关于复习资料" class="headerlink" title="关于复习资料"></a>关于复习资料</h2><p>老规矩，官方教材我还是老老实实看了一遍的。不过ethics我这次直接放弃了。因为，我在level II的时候花了很多的时间去复习这部分，结果成绩还是很差！这次我干脆就放弃了。ethics的内容相当多，handbook就有100多页，我觉得通读对提高我的成绩没有帮助，性价比太低了，因此3级复习ethics直接忽略，只是做书后习题+mock上的题目。事实证明这么做是对的，因为，成绩出来ethics考的不错。官方教材的所有习题我做了2变。</p><p>然后的Notes，依旧从网上下的:(  看了一遍。有些章节看了多变。这里需要指出的是3级的复习其实是有陷阱的。粗看好像3级没啥特别难的地方，看教材，看Notes看完了觉得好像不难，但是，看完了又觉得自己好像也没记住什么东西，再看一遍的时候，觉得好像新的内容一样。我觉得之所以会有这样的情况和三级的侧重点有关系。1，2级的考点其实很具体，尤其涉及计算的，一旦你掌握了，基本不会忘记。但是，3级以portfolio manager的视角，关注的是如何给client定制资产管理的方案，里面的知识点都是围绕这个主题。相对high level，概念性的东西偏多。因此，造成了说看完一遍感觉不难，但是，要记住这些概念，并能理解使用这些概念那就非常难了！一方面是内容多，一方面是要会应用，真的不容易的。我到后期觉得再通看notes并不会给我带来多少提升，所以还是以刷题为主。</p><p>再次是Mock题目了，同2级一个道理，历年Mock题目的重复率太高了（下午考试部分），我从网上找了2010年开始的历年mock，做了几套，觉得重复率太高了，再这么做下去没啥意义。而且难度差异巨大。因此，个人觉得Mock的成绩没太多参考价值。我的建议是，Mock题目如果时间充裕那就做，如果不充裕的，那还是挑近几年的做一下了。2019年的mock题目我觉得超级难。。。</p><p>再后是essay真题了（CFA网站提供近3年的），这块强烈建议大家重点关照！！！我找了从2005年开始的essay真题。由于复习时间不够用了，只做了1遍，再回扫了一部分。个人觉得做一遍肯定不够的。因为，essay是新题型，常考的范围是哪些，如何组织你的答案，这些都需要不断练习的。切记不是说你写的多了就安全了！这种想法是危险的，首先是时间，你会发现essay的时间非常紧张的，历年的真题我也基本来不及做，到了考场，我也依旧来不及，最后一大题没时间做。其次，答案如果回答不到点，不给分的。其实essay重点就是回答要简洁，切题！语法无所谓。我建议历年真题最好能反复做个3遍，很有用。虽然不会考同样的题目，但是，真题的难度毋庸置疑，真题的答案是需要自己好好分析总结的，因此绝对有价值。</p><p>最后，我这次花了血本，用了200元买了Kaplan出的practice exam！一共4套题目。我个人也是推荐的。题目的质量真心不错，难度接近考试。更重要的是，答案里提供了分值的计算方式。比如，essay的分值是如何计算的。这对我考试有很大的帮助。有些题目最终答案我不知，但是，我知道把一些相关的分析和计算写上去肯定也是得分的。复习资料就这些了。</p><h2 id="复习"><a href="#复习" class="headerlink" title="复习"></a>复习</h2><p>我没上任何的复习班，还是坚持自己的观点：没必要（估计那些培训机构要吐血了）。时间一定要留足。尤其尤其是刷题的时间！！！一个月刷题是不够的！！！我只留了1.5个月来刷题，事实证明是不够的。essay历年真题最好能做个3遍，Kaplan practice exam至少2遍，再加历年mock选择题，1个月怎么也不够的。试想，一天3个小时复习，也就够做一份essay或下午的选择题（而且3小时肯定不够）。再加上对答案，分析，总结至少2个小时，也就是说一份考卷需要差不多5个小时。光essay就有10多份！需要自己一开始就能估计好刷题的时间。切记留足刷题的时间。</p><p>通读教材和notes的效果不好，有时间可以多读几遍，没时间的话还通过刷题来找自己的弱项吧！</p><p>和1，2级一样，强调笔记的重要性！我的那本笔记本真的是被我翻烂了，literally！</p><h2 id="考试"><a href="#考试" class="headerlink" title="考试"></a>考试</h2><p>这块大家经历了1，2级都经验很丰富了，也没啥好多写的。重点还是合理安排答题时间。我这次essay来不及就是因为一开始的2道大题卡住了。当时，没有很好的调整自己的心态，事后觉得应该马上跳过，做后面。但是，考场上，头脑一热，觉得自己肯定能做出来啊！就一直卡在那里。也有部分原因是因为新题型，如果是选择题，可能也就跳过了。但是，碰到这种新题型，脑子就有点发晕了。</p><p>带个耳塞，因为二级的时候有惨痛的教训，很奇怪，早上开考以后，外面会有隐隐约约广播的声音，严重影响我集中注意力，可能我对噪音比较敏感。这次带了3M的耳塞，效果还不错。由于早上essay是直接做在考卷上的，周围都是翻页的声音，带了耳塞感觉安静很多。</p><h2 id="心路历程"><a href="#心路历程" class="headerlink" title="心路历程"></a>心路历程</h2><p>还是非常幸运的，自己能一口气连过3级！你要问我难不难，我的回答是难！难在哪里？未必说考试本身有多难。但是，要在近3年的时间里，有工作的情况下，每天还需要留出2，3个小时复习，并且是专注地复习，这真的是太难了！！！2，3级准备期间都发生了很多分心的事情，2级的时候差点崩溃，literally，之前很难理解为啥有些人会因为一件事情变成疯子或是自杀，但是考2级的时候接二连三的打击，真真切切感受到自己不堪再承受的临界点，因此也可以理解那些做出极端行为的人，他们的行为真的已经不受自己控制了。3级的阻碍也不少，工作上的烦心事、家人住院、自己又忙装修，还有自己的健康。各种烦心的事情接二连三，导致了复习断断续续。那时内心很挣扎，到底该怎么办？其他准备考试的人肯定比我复习的好很多。后来我对自己说，即使牛人碰到这些事情肯定也是会受影响的，因此我复习受到影响也是很正常的，不能要求自己在这样的客观条件下还能保持专注高效的复习，因此，我可以允许我自己在种情况下不坚持复习，因为即使坚持也没有啥效率。那就干脆安安心心地处理这些烦心事，等处理完成了再回来继续专注复习。鼓励自己不要放弃。也保持弹性。这种情况下复习到哪里是哪里，但是keep walking不要放弃！这里必须感谢家人尤其是妻子。没有她的默默支持，我根本不可能完成考试。自己在压力之下也会脾气失控，更要感谢妻子和家人的包容。</p><p>越是临近考试，越感到自己濒临极限了。有那么几次周末根本连书都不想翻，一开始复习就想吐了。真是强弩之末了。因此干脆也就只能看看电视休息休息。最后两周请假在家复习，也是碰到意外事件，丈母娘紧急送医院。可能是压力太多或是神经衰弱，睡眠也开始出现了问题，只能靠吃安眠药。我承受压力的能力就是这么差。</p><p>这段时间自己一直在调整恢复，也在思考，考CFA的整个过程带给我什么？我想整个过程让我更清楚地知道了我是谁。近3年的压力，回看自己的表现，更清楚自己几斤几两，例如承受压力的能力，体力，智力乃至情商。从而能让自己更加心平气和，接受自己的平庸。清楚看到自己和牛人之间的差距之大。因此，也就不应该对自己有不切实际的期望和要求。就这点来看整个过程还是很值的。在收到考试成绩之前，我也在思考，如果没过要不要继续？我自己也没想好。觉得如果继续，那是有点浪费时间了，因为，我可以将这些时间做更有意义的事情上去，如管理自己的portfolio，看看我有兴趣的书。考完以后，整个人的状态自由落体。什么都不想做，什么都不想看。幸运的是自己通过了level 3，菩萨保佑！接下来我想多花些时间在家人身上，也要规划一下该如何前行了，keep walking！</p><p>最后祝大家复习顺利，考试成功！</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;很幸运一次性过了CFA level III, 一二三级连续一次过关，真的是上天保佑了。&lt;br&gt;
    
    </summary>
    
    
      <category term="CFA" scheme="https://www.keepswalking.com/categories/CFA/"/>
    
    
  </entry>
  
  <entry>
    <title>CFA Level II 准备过程 【2018年6月】</title>
    <link href="https://www.keepswalking.com/2018/08/16/How-did-I-prepare-CFA-level-II/"/>
    <id>https://www.keepswalking.com/2018/08/16/How-did-I-prepare-CFA-level-II/</id>
    <published>2018-08-15T16:00:00.000Z</published>
    <updated>2018-08-25T10:13:21.403Z</updated>
    
    <content type="html"><![CDATA[<p>很幸运一次过了CFA level II，算下来差不多一年半的时间连续过了levelI和level II, 接下来的目标就是level III了，不过说实话觉得好累，对于level III好像没有那么高的passion了，真想好好休息一年。因为考level II的时候真的感觉压力太大了，压力主要来自要同时处理很多的事情。如今准备考试，不像在学校，可以安心看书。我需要同时面对很多事情，不断切换，而且其他事情会影响心情，每次都需要逼着自己去集中注意力在CFA复习上，那是非常非常疲劳和折磨的，而且还是一个长期的过程。我不像网上的有些人花3，4个月就能搞定，我没那么大能力，必须拉长准备的周期。</p><a id="more"></a><p>我差不多从9月份就开始准备了。先说说CFA 2级的难度。我一开始也看到网上考过的人说过二级比一级难很多很多很多，甚至有说难10倍的。当时我觉得那些人就是夸张，能有多难呢？后来自己开始准备的时候就闷逼了。真的是很难很难很难！而且我觉得即使没有难10倍，但难个5倍也是有的！！！所以这里需要提醒大家，如果你觉得自己基础很一般的话，那么真的要多留一些时间的！</p><p>同level I一样，level II我也没参加学习班，我的观点就是没有意义，你也并不知道这些所谓的学习班水平到底如何。而且说白了教材就在那，考试范围也都明确写出来了，我更相信自己。CFA范围很广，靠猜题我更是觉得不靠谱。教材方面依旧是官方的电子版，我成了IPAD的重度用户，说个励志的事情：被我看坏一本IPAD！！！哈哈，是不是真的被我看坏的我不知道，但是确确实实坏掉了，所以，大部分level II的教材阅读是在新的IPAD上完成，够励志吧！教材之外是notes。我是教材看完一遍，一些对我来说很难的地方，教材是看了多遍的，比如Financial Reporting。Notes更是看了无数遍了。。。如果大家没有时间的话那就看Notes吧，很精简。</p><p>二级从教材的内容角度来看，量化部分难度增加了不少，比如如何判断数据间是否相关，如果判断是否有异方差，如何判断unit root，如何判断serial correlation，如何做F test，autoregressive （AR）model等。总之，这部分我自己笔记记了一大把。economics里面汇率的三角套利。corparate finance里关于项目的评估，这部分level I里很简单，就是比较NPV，但是level II里，计算项目的NPV就复杂的多了。Financial reporting这部分我自己觉得是难度增加的最高的一块了。这些topic对我来说都是很高级的，包括了公司间投资，比如一家公司投资另一家公司，可以有三种类型，每种类型在报表上该如何体现。employee compensation是关于年金如何计算并体现在财报上的。还有一大块是关于跨国公司如何将不同的币种收入计入在报表上的。总之，财务报表分析这部分我一直是觉得很迷茫，看了无数遍的教材和notes，慢慢的消化理解。equity这块是level II的大头，但是其实这块从概念上来说没什么新东西，增加了一些新的价值估算的方法，比如free cash flow valuation，residule income valuation等。剩下的fix income, derivatives, alternative investment和portfolio management都难，真的！反正就是不断重复的看notes。</p><p>这里想插一些学习CFA，尤其是level II以后的感想。网上有说CFA没用的。但是，我自己的感觉就是CFA的内容编排贴近实际，对实践很有帮助。尤其是财务报表，corparate finance和equity，对于理解实际股票估值很有帮助。比如我现在看《巴菲特致股东信》就觉得很有收获。看一些价值投资方面的书籍，比如《巴菲特之道》，《聪明的投资者》等觉得也容易理解。总之，我觉得通过学习CFA，对我在理解投资方面的帮助是很明显的，虽然过程很枯燥。CFA关于量化和Portfolio Management方面的知识更是对我有特别的帮助，因为我自己走的是量化的方向，对资产配置的兴趣大过个股分析，我觉得CFA上的这些知识极大的提高了在阅读一些论文和量化专业书籍上的效率。可以这么说，没学CFA之前，我看《QUANTITATIVE EQUITY PORTFOLIO MANAGEMENT》(作者Chincarini)这本书的时间没啥特别感觉，很多东西无法深入理解，但是学了CFA二级以后，再看这本书，真切感觉到对书里的内容理解更深刻了。而且，自己也有机会接触了更多的portfolio management的内容，比如，我也实践了risk parity。可以说，没有在CFA上所投入的时间和精力，就不可能让我形成自己的投资理念，也不会让我更好地看懂各类投资方面的书籍包括量化和价值投资！</p><p>说一下Ethical部分的复习，handbook我看了大概有2～3遍了，但是这次考二级得了个C！我觉得Ethical部分投入的时间是性价比最低的。如果我知道自己花了那么多的精力和时间还是得了C，那我一定是会将时间用到其他部分的。所以，我觉得，对于时间不够的朋友们来说，Ethical不如放弃了。真的性价比太低了。</p><p>还是强调自己的笔记的重要性，将你不懂的部分，容易做错的题目等一一记录到你的笔记本上，我记了有50多页啊！这些是你后期复习的重点。CFA内容那么多，想要从头到尾多看几遍显然不现实，最后阶段就是挑自己最没有把握的部分重点加强，而你的笔记能让你有的放矢。一定一定要记笔记。</p><p>关于考试时间，我上下午都没来得及做完所有题目，尤其是上午，最后一个case就做了一题，其它就只能涂成b应付了事了。下午有2题来不及，也用了同样的方法。而我在做mock的时候基本上能剩余20分钟样子，所以，我上考场的时候有意放慢了节奏，希望自己不要粗心大意，出现低级失误。但是，实际考试的题目难度和mock比，我自己觉得并不会低的。所以，还是要控制自己的节奏，尽量做的快一点，遇到需要思考的题目，或明显没有思路的题目应该先跳过。我没有这么做，导致最后15分钟的时候很慌乱，有些题目根本就没有精力去应付了，反而会造成失误，把一些应该会做的题目都做错了，让我后悔不已！如果最后能有30分钟的时间来处理一些前面遗留的题目，那么心态上就不一样了，放松会让自己更好的来应对这些题目。我在level I的时候就是这样，效果很好。但是这次真的是做的很不好。不过也要提醒一句，那就是二级的题目确实是有难度的。</p><p>准备CFA二级的时候，我也收集了历年mock题目（从2010年开始），原本想复制一级时候的策略。但是，结果告诉我，这样做的效果不大。首先，很明显level I的时候每一年有240题，从概率角度来说题型，知识点会覆盖的比较全面，因此将此作为复习重点是事半功倍的！但是到了二级，情况不一样了，level II每一年只有120题，而知识点和level I比起来一点也不少，甚至更多。所以从覆盖知识点和题型的角度来说肯定没有level I的mock来的效果好。其次，更要命的是，level II每年的mock题目大部分都是相同的！！！所以，我最后还是去重新做了一遍教材上的习题。</p><p>最后，还是应该感谢家人，尤其是妻子的支持与鼓励。今年18年真的是比较难熬的一年，就在考试前一段时间，甚至是离考试只剩下一周的时间，各种烦心事，打击，分心的事情，让我真的有濒临崩溃的感觉。有了妻子和家人的支持，让我熬过来了，至少我走进了考场，完成了考试！很幸运，最终也是过了。我想说，很多事情是必须要熬的，就是坚持。第一遍看教材还觉得可以学到很多新的东西，但是后面就是不断重复，很枯燥，我时常觉得是浪费时间，有这些时间是不是可以做更有意义的事情呢？比如看更多quant方面的书。但是，我后来觉得，其实就是因为这样的重复看教材，看notes，做题，才让我把很多知识掌握扎实。而光靠看一遍教材，很多地方其实是不能理解的。花掉的这些时间其实是在帮我打基础，是非常值得的。制定目标之前先把意义之类的事情想清楚了，最好能写下来，目标一旦定了，就不要犹豫怀疑，想东想西了。就是埋头干，直到达成目标。中间会有怀疑，犹豫和放弃的念头。我觉得有这些想法是很正常的，反正我是有的。比如，得知炒币的都是什么一两百倍的收益，那我是不是该去炒币啊，或者一边复习一遍炒币呢？哈哈！但是，冷静下来想想，我想还是CFA对于我来说更有意义，因此，也就放弃了“加入”币圈的念头。我不知道这样的决定是否正确，但是，我知道，我的能力只适合一步一步走，一口一口吃饭。既要。。。又要。。。还要。。。，臣妾做不到啊！</p><p>每个人情况都不一样，大家还是要结合自己的实际情况，找到最适合自己的复习CFA level II的方法。最后，祝大家复习顺利，考试成功！</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;很幸运一次过了CFA level II，算下来差不多一年半的时间连续过了levelI和level II, 接下来的目标就是level III了，不过说实话觉得好累，对于level III好像没有那么高的passion了，真想好好休息一年。因为考level II的时候真的感觉压力太大了，压力主要来自要同时处理很多的事情。如今准备考试，不像在学校，可以安心看书。我需要同时面对很多事情，不断切换，而且其他事情会影响心情，每次都需要逼着自己去集中注意力在CFA复习上，那是非常非常疲劳和折磨的，而且还是一个长期的过程。我不像网上的有些人花3，4个月就能搞定，我没那么大能力，必须拉长准备的周期。&lt;/p&gt;
    
    </summary>
    
    
      <category term="CFA" scheme="https://www.keepswalking.com/categories/CFA/"/>
    
    
  </entry>
  
</feed>
