python行业中性_用Python分析指数: 11月16日热门指数Z值表
衡量市场,指数高低是一个难题!
价值投资者很难知道,现在是高估,还是低估? 买的是便宜还是,贵了? 应该现在买/卖,还是再等等?
针对这个问题,我在网上看到了一些量化的处理方法。例如:平均数法,中位数法,比例法等等。这种方法往往过于简单,只能衡量集中度。不能衡量离散度和概率。
也许统计方法中的标准差Z值法更加适合。既可以衡量某个指数的指标的集中度,还可以衡量离散度,和风险情况。尽管指数的数据也不是完美的正态分布,但Z值法依然存在较大参考意义。
我的观点
- Z值越大,越高估。因为大数定理认为:Z>1, Z>2,意味着继续变大的可能性小于16%, 5%。
- Z值越小,越低估。因为大数定理认为:Z<-1, Z<-2,意味着继续变小的可能性小于16%, 5%
- 综观550多只指数的历史数据。绝大部分指数的Z值都在-2,3之间。
- 注:少数的能源,金属类指数曾经出现过短暂疯狂的。Z值法就不太适用
我使用Python的Pandas 和 Matplotlib 等工具,加上一些渠道获得的指数数据(尤其是市盈率),做了这个工具。主要目的是:
- 方便自己定投使用。知道何时开始定投,何时停止定投,何时止盈。 (目前还没有止盈过)
- 结合统计学,熟悉Python的基本数据分析方法。
- 网上分享给愿意参考的人,交流和学习
分享是对自己最好的投资!
欢迎指正。
上个月,文章发表后在雪球和知乎上得到的不少朋友的赞和关注。非常感谢支持。 这个月指数上上下下,貌似熊市来了,又貌似牛市来了。 不同的时间跨度和评估角度看,就有不同的结果。
本月增加了热门指数的Z值高低表,并附上了该指数数据年份跨度的时间
首先,献上截至2017年11月16日的热门指数Z指高低表。
1 Python 基础模块初始化
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
!free -h
# 以下代码是为了显示正文正常
import matplotlib as mpl
import matplotlib.font_manager as font_manager
path_eng = '/usr/share/fonts/chinese/REFSAN.TTF'
path_CHN = "/usr/share/fonts/chinese/simhei.ttf"
prop = font_manager.FontProperties(fname=path_CHN) #Set the microsoft sans serief as default font family. if show chinese test, set path_CHN instead.
#prop.set_weight = 'light'
mpl.rcParams['font.family'] = prop.get_name()
Today = "2017年11月17日"
2 数据库导入
#import data
#数据源:UQer.
#数据采集是另外一套程序,由于UQer中文支持,图形支持不太好,下载数据到本地来进一步处理。
#8月份开始,UQ停止了数据下载功能。现在恢复了,不知道能用多长时间。先用着再说。
sec_map = pd.read_hdf("uqer/sec_map.h5","map") # sec_map 包含了约2800多个指数,实际指数约550只
#sec_map = sec_map.set_index("ticker")
history = pd.read_hdf("uqer/uq_history.h5","history") #hisotry 包含了从2004年到2017年11月16日的指数数据( 大约86万条数据).
print(sec_map.columns)
print(history.columns)
history.info()
3 定义指标-画图函数根据大数定律,在正态分布情况下,Z值=0,左右概率是50% Z值在(-1,+1)左右的概率合计是68%, Z值在(-2,+2)左右区间的概率合计是95%。例例:Z值=1, 其他数据大于1的概率<=84%,小于1的概率>=16%。 可近似认为:目前已经高估了
例:Z值=-1, 其他数据小于-1的概率<=84%,大于-1的概率<=16% 可近似认为:目前已经低估了
def show_KPI(history,ticker ="000001",source="uq",KPI="Close"):
#get the ticker shortName for easy understanding
shortname =sec_map.loc[ticker]["secShortName"] #get the security index chinese name
#check if the request KPI is compatible with database
if source =="uq":
if KPI not in ["Close","TurnoverValue","PE1","PE2"]:
return
elif source =="csi":
if KPI not in ["Close","Turnover","P/E1","D/P1"]:
return
# setup two time span, short for this year(2017),long for full history
timespan={7:"2017",
6:"2016",
5:"2015",
4:"2014",
3:"2013",
2:"2012",
1:"2011",
0:"2007:2016"} #define the time span for each year. 0 is for full range(2007~2017)
history= history.loc[ticker][KPI] #show the selected year KPI performances
history_thisyear =history.loc[timespan[7]]
history_compare =[history,history_thisyear]
#his=history.swaplevel().sort_index().loc["2014"]
#initialize the matplot, chinese font and size and qty of subplots
fig, axes = plt.subplots(1,2, figsize=(10,5),sharey=True)
for i,v_history in enumerate(history_compare): #0 for full histry, 1 for 2017
mean=v_history.mean()
std =v_history.std()
last=v_history.tail(1)
#print(last.index.strftime('%Y-%m-%d'),last.values[0])
fig.axes[i].plot(v_history,"b")
#xticks = v_history.date_range(start=dStart, end=dEnd, freq='W-Tue')
#fig.axes[i].set_xticklabels(rotation=30)
fig.axes[i].legend(loc='best')
if np.isnan(mean) or np.isnan(std):
pass
else:
fig.axes[i].axhline(mean,color="y",label ="mean")
fig.axes[i].axhline(mean + std,color="r",label ="+Z1")
fig.axes[i].axhline(mean - std,color="g",label ="-Z1")
#fig.axes[i].set_title(today)
fig.axes[i].axhline(round(mean +2*std,2), linestyle ="dashed",c="k",label="+Z2",lw=0.5)
fig.axes[i].axhline(round(mean -2*std,2), linestyle ="dashed",c="k",label="-Z2",lw=0.5)
today="{2} {0}:{1:,.2f}".format(KPI,last.values[0],last.index.strftime('%Y-%m-%d'))
fig.suptitle("({0} _{1}) KPI performance \n {2} ".format(shortname, ticker,today))
fig.autofmt_xdate(rotation=45, ha='right')
plt.subplots_adjust(wspace=0, hspace=0.5)
plt.show()
4 历史数据分组正态化处理 -获得Z值
infolist = ["Close","PE1","PE2","PB1","PB2","TurnoverValue","TurnoverVol"]
UQ_Stat=pd.DataFrame()
def COEV(x):
return( x.std()/x.mean())
def init(data_grp,column):
#print(df.head(2))
#df_grp =df.groupby(level="ticker")
df_Stat = data_grp[column].agg(['count',np.mean, np.std,COEV,'last'])
df_Stat["Zscore"]=(df_Stat["last"]-df_Stat["mean"])/df_Stat["std"]
df_Stat["Group_Type"]=column
#print(df_Stat.columns)
return df_Stat.sort_values(by="Zscore")
History_grp=history.groupby(level="ticker")
for info in infolist:
UQ_Stat=UQ_Stat.append(init(History_grp,info))
print("{0} 只指数将被分析".format(UQ_Stat.groupby(level=0).count().shape[0]))
5 热门指数当日和历史图
如该名单有侵权,我受到通知后,将立刻删除。热门指数主要参考ETF拯救世界和银行螺丝钉两位雪球大V的讨论文章
BigVlist=["000015","000922","CSPSADRP","500SNLV","000170","399975","000905","399989","000827","399006","000991","000300"]
mylist=["399417","399971","399814","000852"]
skiplist = ["CSPSADRP","500SNLV","399975","000170"]
hotlist=(BigVlist + mylist)
for i in skiplist: hotlist.remove(i)
"""
Hotlist 中是E大和钉大关注的指数,里面有些是重合的。
个人感觉E大比较注重资产配置,投资节奏;钉大比较注重现金流,即每个投资品种的股息率,回报率。
上证红利指数(000015)、
中证红利指数(000922)、
标普A股红利机会指数(CSPSADRP)、#缺数据,略
中证500行业中性低波指数(500SNLV),#缺数据,略
50AH优选 (000170) #缺数据,略
证券指数(399975) #缺数据,略
中证500(000905)
中证医疗(399989)
中证环保(000827)
创业板(399006)
全指医药(000991)
"""
mask1 = UQ_Stat.index.isin(hotlist)
mask2 = UQ_Stat["Group_Type"]=="Close"
mask = mask1 & mask2
tmp_count=UQ_Stat.loc[mask,"count"]/250
tmp =UQ_Stat.pivot(columns="Group_Type",values="Zscore").loc[hotlist]
tmp=pd.concat([tmp,tmp_count],axis=1)
tmp=tmp.join(sec_map[["secShortName"]])
columns_E2Cmap = {"secShortName":"名称",
"Close": "收盘价_Z值",
"PB1": "市净率_Z值",
"PE1": "市盈率Z指",
"TurnoverValue":"成交额_Z值",
"TurnoverVol":"成交量_Z指",
"count":"交易记录(年)",
#"Group_Type":"指标类型",
}
tmp=tmp[["secShortName","PE1","Close","PB1","TurnoverValue","TurnoverVol","count"]].rename(columns=columns_E2Cmap
)
tmp.index.name="代码"
print("2017年11月16日热门指数估值高低表")
print("交易记录年数约长越可靠")
tmp.sort_values(by=["交易记录(年)","市盈率Z指","收盘价_Z值"],ascending=False).round(2).style.bar(align="zero", color=[ '#5fba7d','#d65f5f',],width=100/2)
6 全市场概览 - (价格,市盈率,市净率)查看和比较目前所有指数的Z值平均数[-0.5,0.5] 常态
小于-0.5,市场低估
大于0.5, 市场高估活跃
#print(UQ_Stat.shape)
#shortname =sec_map.loc[ticker]["secShortName"]
columns =["PE1","TurnoverValue","Close",]
fig,axes=plt.subplots(1,3,figsize=(15,5), sharex=True, sharey=True)
fig.suptitle("{0}指数Z值频数图(2007-2017) ".format(Today))
for i in range(len(columns)):
mask=UQ_Stat["Group_Type"]==columns[i]
UQ_Result=UQ_Stat.loc[mask]
#print(UQ_Result.shape,fig.axes[i])
mean = UQ_Result["Zscore"].mean()
skew = UQ_Result["Zscore"].skew()
mean_limit=0.5
#print(columns[i],mean,skew)
if (mean>=(0-mean_limit) )and (mean<=mean_limit):
color_mean = "blue"
elif mean>mean_limit:
color_mean ="Y"
elif mean<(0-mean_limit):
color_mean ="g"
fig.axes[i].hist(UQ_Result["Zscore"],bins=50,color=color_mean)
fig.axes[i].set_title("{0}".format(columns[i]))
fig.axes[i].axvline(mean,color="k",linestyle='--')
fig.axes[i].set_xlabel("{0}".format(columns[i]))
#fig.axes[i].set_ylabel("指数频数")
#UQ_Result["Zscore"].hist(bins=50)
#fig.axes[i].legend()
#mask2=UQ_Result["Zscore"]<=0
print("综合指数之-{0}\t\t Z值{1:.3f}".format( columns[i],mean))
space =0.2
plt.subplots_adjust(wspace=0, hspace=space)
Z值频数图说明:横轴是从-3到+3的Z值范围,Y轴是指数的数量。 Z值=0时平均情况,不高不低。
PE1图(指数18日市盈率Z值):参考度:####当日约550只指数市盈率的Z值频数图。
正常波动:绝大多数指数市盈率在[-1,1]之间。
高估: 右侧,其中约有50只指数市盈率Z值>1,存在较大风险。约10只指数市盈率>2,异常高估(风险非常大)
低估: 左侧,其中约有10只指数市盈率Z值<-1。 长期定投买入,是不错的产品。
TurnoverValue(指数的18日市盈率成交量Z值): 参考度:###当日约550只指数市盈率的Z值频数图。 正常,高估,低估分析方法参考市盈率图。
Close图(指数的18日收盘价Z值图) 参考度:##当日约550只指数市盈率的Z值频数图。 正常,高估,低估分析方法参考市盈率图。
收盘价是绝对值,不像市盈率是相对值。因此中间线不是常规的0,而是大约1.3左右。
考虑到过去10年GDP每年增长8%,10年后经济增量,企业业绩增长,指数的绝对值也在增长。
7 3年时间以上的指数Z值
7.1 市盈率Z值最高5个指数。 某指数与自己过去历史的市盈率相比,现在所处的位置。
最低5个指数。 某指数与自己过去历史的市盈率相比,现在所处的位置。 我的观点Z值越大,越高估。因为大数定理认为:Z>1, Z>2,意味着继续变大的可能性小于16%, 5%。我的观点Z值越小,越低估。因为大数定理认为:Z<-1, Z<-2,意味着继续变小的可能性小于16%, 5% 综观550多只指数的历史数据。绝大部分指数的Z值都在-2,3之间。 注:少数的能源,金属类指数曾经出现过短暂疯狂的。Z值法就不太适用
7 3年时间以上的指数Z值
7.1 市盈率Z值最高5个指数。 某指数与自己过去历史的市盈率相比,现在所处的位置。
最低10个指数。 某指数与自己过去历史的市盈率相比,现在所处的位置。 我的观点Z值越大,越高估。因为大数定理认为:Z>1, Z>2,意味着继续变大的可能性小于16%, 5%。我的观点Z值越小,越低估。因为大数定理认为:Z<-1, Z<-2,意味着继续变小的可能性小于16%, 5% 综观550多只指数的历史数据。
注:在过去的1个月,10月到11月,许多指数出现了大幅下跌。太多的指数可以选,故本月发布最低的10个指数Z值
ndays = 750
Zscorelimit = -0.1
Type ="PE1"
mask1 = (UQ_Stat["Zscore"]
mask3 = (UQ_Stat["count"] >=ndays)
mask2 = UQ_Stat["Group_Type"] == Type
mask = mask3 & mask2
UQ_Z1M =UQ_Stat.loc[mask,["Zscore","last","Group_Type"]].drop_duplicates()
UQ_Z1M=UQ_Z1M.join(sec_map[["secShortName"]]).sort_values(by="Zscore")
UQ_Z1M=UQ_Z1M.rename(columns={"Zscore": "Z值",
"last": "最新数据",
"Group_Type":"指标类型",
"secShortName":"名称"
}
)
UQ_Z1M.index.name="代码"
#idx = pd.IndexSlice
#UQ_Z1M=UQ_Z1M.set_index("指标类型",append=True)
#mask = UQ_Z1M["名称"].str.contains("餐")
#UQ_Z1M[mask]
print(" 550指数市盈率Z值 最高5个和最低10个指数")
UQ_Z1M.iloc[np.arange(-5,10)].round(2).sort_values(by="Z值").style.bar(subset=["Z值"],align="zero", color=[ '#5fba7d','#d65f5f',],width=100/2)
7.2 指数市盈率Z值和指数收盘价Z值加权表
mask1 =(UQ_Stat["count"]>750)
#mask2 =(UQ_Stat["Zscore"]<0.5)
mask = mask1
Weight_Close = 0.2
Weight_PE1 = 0.8
tmp =UQ_Stat[mask].pivot(columns="Group_Type",values="Zscore")
tmp["OverallScore"] =(tmp["Close"]* Weight_Close +tmp["PE1"]* Weight_PE1)
tmp = tmp[~tmp.OverallScore.isnull()].sort_values(by="OverallScore",ascending=True)
tmp =tmp.join(sec_map.secShortName)
tmp = tmp[[u'secShortName',u'OverallScore',u'Close', u'PE1',u'TurnoverValue' ]]
tmp.iloc[np.arange(-5,10)].sort_values(by="OverallScore").style.bar(subset=["OverallScore"],align="zero", color=[ '#5fba7d','#d65f5f',],width=100/2)
7.3 最高和最低的指数市盈率,和收盘价例子指数: 中证1000,新能源车,中证传媒,和 食品饮料。 排除中证电信,和某些没有对应基金产品的指数。
红色的线表示,Z值=1
绿色的线表示,Z值=-1
注:左图:(以过去10年所有数据为基础计算Z值),最后一个点2017年11月16日
右图:(以2017年的所有数据为基础计算Z值),最后一个点2017年11月16日
KPIs=["PE1","Close"]
secCodes =["000852","399417" ,"399971","000807"]
for secCode in secCodes:
for KPI in KPIs:
show_KPI(history,secCode,KPI=KPI)
本文同时在雪球(仅结果)和知乎(包含程序和结果)发表,并发布到Python中文社区。
分享是对自己最好的投资!
祝大家周末快乐
2017年11月17日下午
python行业中性_用Python分析指数: 11月16日热门指数Z值表相关推荐
- python行业中性_用python进行金融市场文本数据的情感计算
之前我依据一篇论文中的中文金融情感词典CFSD(chinese financial sentiment dictionary),中文金融领域情感词典构建, 整理成csv文件的情感词典.现在我们找点财经 ...
- Python之pyecharts:利用pyecharts绘制2020年11月16日微博话题热度排行榜实时变化
Python之pyecharts:利用pyecharts绘制2020年11月16日微博话题热度排行榜实时变化 目录 利用pyecharts绘制2020年11月16日微博话题热度排行榜实时变化 Bar( ...
- 快速获取废料_【优废回收】11月16日有色金属废料回收参考行情!
优废再生资源2020年11月16日废料回收参考行情 类别 地区 品名 价格区间 单位 涨跌 废铜 广东 1#铜管 48100-48300 元/吨 1,400 广东 二号铜 44500-44800 元/ ...
- python行业中性_【量化课堂】因子研究系列之四 -- 市值与行业的中性化
导语:本文给出以BP(账面市值比)为例的因子缩尾处理和对市值与行业中性化的处理实现代码,展现单因子不同分位处在不同处理方法下的表现. 本文是一系列因子研究中的第四篇文章.本系列的文章有: 引言 因子系 ...
- python行业中性_单因子测试(上)——因子中性化
之前做了很多因子测试的工作,但一直没有总结,感觉很凌乱,决定花时间把这部分东西写一写,温故知新,也为后续学习打基础.首先写一下单因子测试部分,分三篇,数据预处理一篇, 回归法一篇,分层测试法一篇.本篇 ...
- python行业中性_【建投金工丁鲁明团队 经典回顾】:零基础python代码策略模型实战...
原标题:[建投金工丁鲁明团队 经典回顾]:零基础python代码策略模型实战 编者按 本文<零基础python代码策略模型实战>,属于大数据选股领域,报告发布时间为2018年3月8日. 内 ...
- python行业中性_市场风险中性假设的r0只是等效r的其中之一
市场风险中性假设的r0只是等效r的其中之一 于德浩 2020.6.23 在BS期权定价方程中,用到了一个市场风险中性假设,可后来人们发现,由此方程解出的期权价格C不仅适用于理想的市场风险中性条件,也符 ...
- python行业中性_Python抓取分析淘宝连衣裙数据,128元真的是低价人群分界线吗?...
1.我是一个低价人群用户 上周发表文章<一个匿名用户的淘宝"连衣裙"大观>后,交流群里面很热闹地讨论了起来,小伙伴们都在秀自己的淘宝连衣裙搜索价格,相较于小伙伴们搜索出 ...
- python教学反思_信息组龚莹瑜11月教学反思
走出python的语法沼泽,让计算思维主导课堂 1.前言 python语言虽然格式规范比较简单,但是看到课程内容的时候我也犯了难.八年级的学生从来没有接触过纯代码的编程语言,虽然之前有scratch的 ...
最新文章
- SQL Server 2008 允许远程链接 解决方法
- Spring Cloud Eureka 配置原理详解
- python统计各分数段人数并可根据选择绘制不同的图形_python习题整理
- WTA (winner-take-all) 与 自组织映射 SOM (self organizing map)的理解
- 记一次虚拟机共享文件夹的采坑之旅
- config配置文件
- Java API(JDBC)连接操作数据库MySQL
- 黑苹果 hackintosh 安装初体验
- 人工智能产生式系统动物识别实验python
- VC++设置默认音频设备(附源码)
- 浅谈Java中的常量池
- si24r1程序_SI24R1技术支持--程序 射频识别(radio frequency indentificationx) - 下载 - 搜珍网...
- 使用GCJ编译Java程序供Matlab调用Java对象方法实践
- 计算机设计大赛海报素材,海报创意设计比赛方案(word版)
- 什么是java socket
- Halcon:多张图片合并成一张图片
- table-responsive响应式表格,手机端表格自适应
- Final SwfPlayer下载后在安卓12上玩宇宙的刻度2
- python编写程序公式计算s_python pandas库和stats库计算偏度和峰度(附程序)
- Springboot 工具类@Value取不到值
热门文章
- 耿丹CS16-2班第六次作业汇总
- 记一个npm安装问题 Refusing to delete xxx\.bin\xxx.cmd: is outside xxx\webpack and not a link
- Linux PXE无盘工作站
- 用谷歌浏览器来当手机模拟器
- python3《机器学习实战系列》学习笔记----3.2 决策树实战
- 2022苹果CMS 全新绿豆二开影视源码app源码完整版带安装教程
- CSR BC417143BGQ蓝牙模块芯片替换方案
- 【机器学习入门到精通系列】OVR SVMs
- vscode使用方法
- 一个在线测试正则表达式的网站推荐