《投资者的未来》

1.书籍介绍

       这本书加深了我对股票长期投资方面的认知,作者指出了一些投资陷阱,比如传统观点追求高增长率是合理的,但作者指出这是一件高风险低收益的事。由于作者都是用美股做实验的,出于兴趣,我也测试A股的情况,后面会给出一些A股的测试结果。

      纵览全书,全文分为5个部分,前两部分阐述了投资者容易陷入的两个陷阱:追求高增长率和高估新事物,接着说明股东的收益应该来自哪里,然后展望未来,探讨人口危机和未来全球经济强国的转变,最后给出可供参考的投资组合策略。
       下面按照书籍顺序摘取了作者的重要思想:

1.1 增长率陷阱

        增长率陷阱诱使投资者为那些促进创新并带动经济扩张的产业和公司付出过多的资金。但根据美股过去业绩表明最好的投资往往出现在正在萎缩的产业和发展缓慢的国家。

        为什么呢?因为大家都对创新有过高的热情,导致这样的公司往往容易被高估预期,而且在这些产业里只有极少数的大赢家成功了。即使在成功的情况下,创新带来的高收益也容易流向创业者和帮助销售股票的投资银行家等,当然消费者也获得了更好的产品,而非单个投资者。

        以美股过去70年为例,石油早期占份额最高,而现在却是科技,也就是说科技是新兴行业,石油是萎缩的行业。但是以IBM和新泽西石油两家公司为例,收益增长率方面IBM过去业绩增长率确实一直高于新泽西石油。但是石油的投资者回报收益过去却超过IBM。原因就是IBM定价太高,而新泽西石油却便宜多了,并且股利率也更高,这样每年用获得的股利再投资,长期就可以获得更高的收益。

1.2 高估新事物

作者对过去标普500指数中的股票做了研究,发现以下结论:

  • 不断用新加入的快速成长的新公司取代指数中增长缓慢的老公司,反而会使回报率降低。
  • 只购买最初的500家公司,不再购买新加入的公司,这种情况能超过半世纪里几乎所有的基金经理。
  • 股利很重要,股利的再投资是长期股票获利的关键因素。
  • 股票投资的回报不依赖公司利润增长,而取决于实际的利润增长是否超过了投资者的预期,体现在市盈率上。
  • 首次公开发行的股票在长期中表现糟糕。
  • 增长率不仅存在于单个公司中,对产业部分也同样适用,同样适用于国家。

以上说明不断追求新兴股票却可能降低投资者的收益率,所以投资者应该慎重。

1.3 投资者的收益

        投资者应该能区分这两个概念:市场价值与投资者收益;市场价值是股票数量*每股价格,投资者收益是每股价格变化加上股利。

        对长期投资者来说,股利才是收益的主要来源。从这来说,期间长期持有的股票价格下跌更利于投资者用相同的股利购买到更多的股票。股票的长期收益并不依赖于实际的利润增长情况,而是取决于实际的利润增长与投资者预期的利润增长之间存在的差异。对于获得的股利现金,最好的办法就是再投资,它是熊市保护伞和收益加速器。

1.4 发现并规避市场狂热

  •   最好的办法就是观察市盈率,市盈率过高的,谨慎选择。
  • 定价至关重要,不要选择高估。
  • 不要爱上自己的股票:保持客观,决定卖出的时机。
  • 计算利润存在很多不确定性,所以要密切关注股利。

1.5 未来

       作者在研究了多个国家的股票之后,发现股票收益率是稳定的,尽管在经历了恶性通货膨胀,战争,经济大萧条等,所以未来股票收益也是可期待的。

2. 中国股票收益

        我从baostock抓取了从2007年到2020年的股票情况,用python3.6粗略分析了一下可供大家参考。为什么选择baostock,我看网上说tushare好像要注册,通过积分取数据,对历史数据积分还不太容易得,但是baostock只支持从07年开始的历史数据。

2.1 数据

列名 含义
code 股票代码
code_name 股票名称
2007-01-15股价 取当天闭盘价格
2007-01-15滚动市盈率 取当天闭盘滚动市盈率
2020-09-22股价 取当天闭盘价格
2020-09-22滚动市盈率 取当天闭盘滚动市盈率
股价增长 (20年股价-07年股价)/07年股价
分红回报 转送股+分红现金/派息当天股价
转送股  
投资回报 股价增长+分红回报
季度利润平均增长率 %为单位

 沪深300按照投资回报排序,前20只股票如下:

中证500按照投资回报排序,前20只股票如下:

全部的股票情况可以从以下链接下载:
沪深300:
http://www.offhours365.com/wp-content/uploads/2020/09/hs300_stocks_growth.csv
中证500:
http://www.offhours365.com/wp-content/uploads/2020/09/zz500_stocks_growth.csv

2.2 代码

代码如下(代码可能有些空字段处理有问题,欢迎指出):

import baostock as bs
import pandas as pd

def growthYOYNI(id):
    total = 0.0
    num = 0
    qu = 2
    ye = 2007
    qt = 53
    while num < qt:
        rs_growth = bs.query_growth_data(code=id, year=ye, quarter=qu)
        if rs_growth.error_code != '0':
            print(rs_growth.error_msg)
            return -1
        else:
            row = rs_growth.get_row_data()
            if len(row)<6:
                print('growthYOYNI-{}_{}_{}:{}'.format(id, ye, qu, row))
                qt = qt-1
                num = num-1
            else:
                if row[5]=='':
                    print('growthYOYNI-{}_{}_{}:{}'.format(id, ye, qu, row))
                    qt = qt-1
                    num = num-1
                else:
                    total = total + float(row[5])
        qu = qu +1
        num = num+1
        if qu == 5:
            qu = 1
            ye = ye + 1
    return total/qt


def crashinvest_growth(id, rowreturn):
    ye = 2007
    end = 2020
    stnum = 0.0
    total = 0.0
    while ye <= end:
        rs_dividend = bs.query_dividend_data(code=id, year=ye, yearType="report")
        if rs_dividend.error_code != '0':
            print(rs_dividend.error_msg)
            return -1
        else:
            row = rs_dividend.get_row_data()
            if len(row)<14:
                ye = ye +1
                continue
            if row[13]!="":
                stnum = stnum+ float(row[13])
                total = total+ float(row[13])
            if row[9]!="" :
                if row[7]!="":
                    stdata = bs.query_history_k_data_plus(id, "close", row[7])
                    stdatarow = stdata.get_row_data()
                    cashst = float(row[9])/float(stdatarow[0])
                    total = total+cashst
        ye = ye +1
    rowreturn.append(total)
    rowreturn.append(stnum)
    return total


lg = bs.login()
print('login respond error_code:'+lg.error_code)
print('login respond  error_msg:'+lg.error_msg)

begTime = "2007-01-15"
endTIme = "2020-09-22"

# find zz500 all code and still ok
hs300_stocks = []
rs = bs.query_zz500_stocks(begTime)
while (rs.error_code == '0') & rs.next():
    list = rs.get_row_data()
    stbs = bs.query_stock_basic(code=list[1])
    stbsrow = stbs.get_row_data()
    if (stbsrow[5]=='0'):
        print(list[1])
    else:
        row = []
        row.append(list[1])
        row.append(list[2])
        id = list[1]
        stdata = bs.query_history_k_data_plus(id, "close,peTTM", begTime)
        stdatarow = stdata.get_row_data()
        a = float(stdatarow[0])
        row.append(stdatarow[0])
        row.append(stdatarow[1])
        stdata = bs.query_history_k_data_plus(id, "close,peTTM", endTIme)
        stdatarow = stdata.get_row_data()
        b = float(stdatarow[0])
        row.append(stdatarow[0])
        row.append(stdatarow[1])
        price = (b-a)/a
        row.append(price)
        crash = crashinvest_growth(id, row)
        row.append(price+crash)
        row.append(growthYOYNI(id)*100)      
        hs300_stocks.append(row)
        # print(row)

print ("zz500_stocks length : ", len(hs300_stocks))


result = pd.DataFrame(hs300_stocks, columns=('code', 
    'code_name',
    begTime+'股价',
    begTime+'滚动市盈率',
    endTIme+'股价',
    endTIme+'滚动市盈率', 
    '股价增长',
    '分红回报',
    '转送股',
    '投资回报',
    '季度利润平均增长率'))
result.to_csv("zz500_stocks_growth.csv", encoding="gbk", index=False)
print(result)

bs.logout()

沪深300换成函数bs.query_hs300_stocks函数即可

猜你喜欢

转载自blog.csdn.net/yshhuan/article/details/110469356