“巧妇难为无米之炊”,找不到数据,量化分析、财务报表分析也就无从谈起。对于分析者来说,获取数据是量化分析的第一步。Python的一个强大功能之一就是数据获取(爬虫)。但是对于没时间学爬虫程序的小白来说,python丰富的开源包为我们节省了不少时间精力,只要会用前人的车轮(wheel),就可以造就自己的车(py)。
Tushare是一个免费、开源的python财经数据接口包,可以获取新浪财经、腾讯财经、上交所和深交所提供的数据。如果安装了Anaconda(建议),可以使用Anaconda Prompt或者通过win+R输入cmd调出dos操作界面,输入pip install tushare进行安装。如果没有pip或pip3,可以先用conda install pip (或pip3)安装。
Tushare包可以获取宏观经济数据、股票交易数据、基本面数据(公司盈利能力、业绩报告等)、新闻事件、银行间同业拆放利率等,下面着重介绍使用tushare包获取财务报表数据和可视化分析。
1、引入需要的包(模块module):import xxx
其中,pandas和matplotlib分别是数据处理和画图常用的包,as意味着后面调用这些包将分别使用缩写ts、pd、plt。
import tushare as ts
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import *
from pyecharts import Map, configure
2、获取所需数据
tushare获取数据的接口为pro = ts.pro_api(),很直观。如获取个股每天的股价命令为df = ts.pro.daily(ts_code=‘000001.SZ’, start_date=‘20180701’, end_date=‘20180718’),资产负债表ts.pro.income(ts_code=‘002230.SZ’, start_date=‘20090101’, end_date=‘20181230’),利润表ts.pro.balancesheet(ts_code=‘002230.SZ’, start_date=‘20090101’, end_date=‘20181230’)。下面主要以杜邦分析举例进行分析。
SZZS = pro.index_daily(ts_code='000001.SH', start_date='20090101', end_date='20190130')
SZZS.index = pd.DatetimeIndex(SZZS.trade_date)#获取上证指数十年的数据
print(SZZS.head())
3、读取数据和可视化
可以使用to_csv或者to_excel将数据保存到本地,然后再进行分析,本次以pandas直接对数据进行分析
首先调取全国的上市公司基本数据,ts库所给的基本信息非常全面。
data = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
将当前所有正常上市交易的股票列表存放在变量data里面,下面对公司所在地区进行简单的分析
data_counts = data['area'].value_counts() #对dataframe某一列的数据按照这一列重复值的个数排序,重要
data_counts = pd.DataFrame(data_counts)
attr = list(data_counts.index)
data_counts.area = data_counts.area / 5
val = list(data_counts.area.values)
map = Map("全国上市公司分布", width=1200, height=600)
map.add("",attr,val,maptype="china",is_visualmap=True,visual_text_color="#000",)
map.render("render上市公司分布.html")
最后用 pyecharts中的 Map库进行可视化
如图所示,颜色越深的地方代表上市公司越多,北上广以及江浙等沿海一带占了绝大多数,另外山东和四川也不少。
4、举例分析
看完了全国的分布,重点来了,选择两家比较有代表性的上市公司进行杜邦分析,其一选择这两年非常火热的风口人工智能板块,具有使命意义的科大讯飞和老牌经典永不褪色的国酒茅台。
开始吧,首先利用ts库将近十年两只股票的走势和大盘的趋势对比
KDXF = pro.daily(ts_code='002230.SZ', start_date='20090101', end_date='20190130')#获取科大讯飞十年来股票数据
GZMT = pro.daily(ts_code='600519.SH', start_date='20090101', end_date='20190130')#获取贵州茅台十年来股票数据
KDXF.index = pd.DatetimeIndex(KDXF.trade_date)
GZMT.index = pd.DatetimeIndex(GZMT.trade_date)
SZZS = pro.index_daily(ts_code='000001.SH', start_date='20090101', end_date='20190130')#获取上证指数十年的数据
SZZS.index = pd.DatetimeIndex(SZZS.trade_date)#最后将索引变得一致
plt.subplots_adjust(wspace=0.2, hspace=0.5) # 调整子图间距
plt.subplot(211)
plt.xlabel(u' ', fontproperties=myfont)
plt.ylabel(u'股价', fontproperties=myfont, fontsize=12)
plt.plot(GZMT['close'], label=u'贵州茅台')
plt.legend(prop=myfont)
plt.xticks(year)
plt.title(u'贵州茅台与上证指数走势图对比', fontproperties=myfont, fontsize=12)
plt.subplot(212)
plt.xlabel(u'日期', fontproperties=myfont)
plt.ylabel(u'指数', fontproperties=myfont, fontsize=12)
plt.plot(SZZS['close'], label=u'上证指数')
plt.xticks(year)
plt.legend(prop=myfont)
plt.title(u'', fontproperties=myfont, fontsize=12)
plt.annotate(u'地球顶', size=10, fontproperties=myfont, xy=('2015-05-12', 5300),
xytext=('2016-01-1', 5500), arrowprops=dict(facecolor='red', shrink=0.05))
plt.show()
茅台在2015年牛市表现平平,但是在从2017年之后在大盘表现一般的情况下逆势暴涨,股价一度从200多元被炒到800元一股,可见中国股民对国酒茅台的热爱。
科大讯飞可谓科技股的真实写照,大起大伏,2015年随着牛市暴涨,也随着泡沫破灭暴跌,但是在2017年年中开始随着人工智能和大数据的火热,被投资者疯狂追逐,炒作,超过了2015年牛市的股价,但是好景不长,在2018年下半年经济不景气,互联网寒冬下,被打回了原形,股价一路暴跌,甚至是10年来最低,让投资者从沸点到冰点。
从十年来股价的走势可以大概知道两家公司的基本情况,接下来,用杜邦分析对两家公司的财务报表进行简单描述,首先利用ts库导入数据
#获取科大讯飞的利润表和资产负债表
data_KDXFincome = pro.income(ts_code='002230.SZ', start_date='20090101', end_date='20181230')
data_KDXFbalancesheet = pro.balancesheet(ts_code='002230.SZ', start_date='20090101', end_date='20181230')
数据非常多,并且不全是我们分析需要的数据,现在利用pandas对数据进行简化
def persist_end_date(x):
x['end_date'].at[1] = ""
x['end_date'].at[2] = ""
for i in range(3, 40, 4):
x['end_date'].at[i + 1] = ""
x['end_date'].at[i + 2] = ""
x['end_date'].at[i + 3] = ""
missing = x.loc[x['end_date'] == ""]
x.drop(index=missing.index, inplace=True)
persist_end_date(data_KDXFbalancesheet)
persist_end_date(data_KDXFincome)
data_KDXFbalancesheet = data_KDXFbalancesheet.reset_index(drop=True)
data_KDXFincome = data_KDXFincome.reset_index(drop=True)
数据是按照每季度为报告期,我们只对每年年底的数据分析,由于2018年年底报告未出,以3季度报告为依据,可能会出现误差,但是影响估计不大。
这是一张简单的杜邦分析表,杜邦分析法是一种财务比率分解的方法,能有效反映影响企业获利能力的各指标间的相互联系,对企业的财务状况和经营成果做出合理的分析
简单的计算公式,专业知识有限,不展开讲了,先将上述几个指标一一求解出来
ROE = [] #将求解出来的权益净利率存到列表中
for i in range(1, 9):
x = data_KDXFincome['n_income'].at[i] / [(data_KDXFbalancesheet['total_hldr_eqy_inc_min_int'].at[i] +
data_KDXFbalancesheet['total_hldr_eqy_inc_min_int'].at[i + 1]) / 2]
ROE.append(float('%.4f' % x))
ROE = [i * 100 for i in ROE]
JROA = [] #将求解出来的总资产净利率存到列表
for i in range(1, 9):
x = data_KDXFincome['n_income'].at[i] / [(data_KDXFbalancesheet['total_assets'].at[i] +
data_KDXFbalancesheet['total_assets'].at[i + 1]) / 2]
JROA.append(float('%.4f' % x))
JROA = [i * 100 for i in JROA]
AT = [] #将求解出来的总资产周转率存到列表中
for i in range(1, 9):
x = data_KDXFincome['total_revenue'].at[i] / [(data_KDXFbalancesheet['total_assets'].at[i] +
data_KDXFbalancesheet['total_assets'].at[i + 1]) / 2]
AT.append(float('%.4f' % x))
AT = [i * 100 for i in AT]
EME = [] #权益乘数
for i in range(1, 9):
x = data_KDXFbalancesheet['total_assets'].at[i] / data_KDXFbalancesheet['total_hldr_eqy_inc_min_int'].at[i]
EME.append(float('%.4f' % x))
NOP = [] #营业净利率
for i in range(1, 9):
x = data_KDXFincome['n_income'].at[i] / data_KDXFincome['total_revenue'].at[i]
NOP.append(float('%.4f' % x))
NOP = [i * 100 for i in NOP]
然后将我们需要的数据打印出来,除权益乘数(EME)之外,其他的全部为百分比数据。
再将其可视化
data = pd.DataFrame({"ROE": ROE, "NOP": NOP, "AT":AT, "JROA":JROA, "EME":EME})
data.index = year
line = Line("各种指标走势图", width=1000, height=500, title_pos="left")
print(data.head(10))
year = [str(year) for year in range(2010, 2018)]
for ckey, indexs in zip(data.columns, data.index):
val = list((data[ckey]))
line.add(ckey, year, val, is_smooth=True, line_width=4)
line.render("render8.html")
从权益净利率(ROE)每年下降,影响下降的直接原因主要有总资产净利率和权益乘数,权益乘数(EME)也就是财务杠杆并没有下降,而在2017年还增加了,说明是总资产净利率(JROA)在下降
几乎是等比例下降,那么影响总资产净利率的因素再分解,营业净利率(NOP)和总资产周转率(AT),从下图可以看出,营业净利率下降并不明显,只是在2015-2017下滑的比较严重,总资产周转率年年下滑,但是在2017年反转,引起总资产净利率下降的主要原因是总资产周转率的延缓,对于这个不利因素,今后要通过强化企业管理,优化资源管理。缩短生产经营周期,以加强资金周转来解决。销售净利润的下降总体来看,是消极因素,引起其下降的有利因素主要有三个:销售费用率上升,销售税金率上升和销售管理费用上升,公司今后的工作重点应放在狠抓销售成本率的降低上(仅当前数据说明)。
权益乘数(EME)主要受资产负债率影响。负债比率越大,权益乘数越高,说明企业有较高的负债程度,给企业带来较多地杠杆利益,同时也给企业带来了较多地风险,公司在2015年以后负债程度增加,财务杠杆增加,应该警惕财务风险。
接下来对茅台进行相同的分析,由于操作方式都是一样的,代码就不上了,只需要修改股票代码就行,直接将可视化数据附上
权益净利率和总资产净利率几乎相同变化,权益乘数应该变化不大,从下图可以看出,权益乘数维持在1.2到1.5之间,保持了良好的财务杠杆。
从营业净利率和总资产周转率可以看出,影响权益净利率的主要因素是总资产周转率,2017年暴涨,说明企业资产的营运能力显著提高,生产经营周期缩短,资金周转更强(通俗来说,生意更好了),是影响股价暴涨的因素之一吗?最后不得不说,白酒的利润率真是高,营业净利率常年维持在50%左右。
【结语】
本文主要介绍了如何使用Python的开源包tushare获取上市公司财务数据,以及利用pandas和matplotlib、 pyecharts包对数据进行清洗和可视化分析。只是简单的皮毛而已,对问题的深入分析,还得结合理论(逻辑)+专业的财务分析+统计(数据和计量分析)。Python是我们获取和分析数据的实用工具,为验证分析逻辑或理论的正确与否提供了一个重要维度。