分享

清风拂山冈: 分位函数计算结果的研究 在指数估值时,需要计算当前指数估值在历史估值中的分位值,以判断...

 chrien 2018-01-01
在指数估值时,需要计算当前指数估值在历史估值中的分位值,以判断当前估值的位置。本人在计算分位值时,使用过的的函数有excel的PERCENTRANK、PERCENTRANK.INC、PERCENTRANK.EXC和python的stats.percentileofscore、以及利用bisect.bisect+线性插值,以上函数计算结果并不一致。当然,在实际使用时,模糊的正确即可。本文只是想搞清楚结果不一致的原因。

问题描述为求某个数值x在数列a={a[i]}(i=1,2,...)中的百分比排位。为了表述的方便,假设数列a为从小到大排序的有序数列。

结论:
当a包含x,且a中数值较多时,函数scipy.stats.percentileofscore(a, x, kind='strict&# 39;;)与函数PERCENTRANK(a,x,[significance])计算结果趋同。但若a中存在较多与x相等的值时,可能存在低估风险。

具体研究过程:
scipy.stats.percentileofscore(a, x, kind='rank&# 39;)
kind的取值包括rank、weak、strict和mean,缺省值为rank.

当kind='rank&# 39;时:
计算结果=x的排序位置/数列总数
若数列中含有多个相同的x,则计算结果为每个x计算结果的平均值。
如:stats.percentileofscore([1, 2, 3, 4], 3)    计算结果为 (3/4)*100 = 75
stats.percentileofscore([1, 2, 3, 3, 4], 3)   计算结果为((3/5)*100+(4/5)*100)/2=(60+80)/2=70

当kind='weak&# 39;时:
计算公式同rank,分子值取a中小于等于x的个数。
如:stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='weak&# 39;)  计算结果 (4/5)*100=80

当kind='strict&# 39;时:
计算公式同rank,分子值取a中小于x的个数。
如:stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='strict&# 39;) 计算结果 (2/5)*100=40

当kind='mean&# 39;时:
计算公式同rank,结果取kind为'strict&# 39;和'weak&# 39;时的平均值。
如:stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='mean&# 39;) 计算结果 ((4/5)*100 + (2/5)*100)/2 =60
当数列a不包含x时,计算结果=a中小于x的个数/数列总数。类似kind='strict&# 39;。
如:stats.percentileofscore([1, 2, 3, 4, 5], 1.5)  计算结果=(1/5)*100 = 20

bisect.bisect+线性插值(该方法来自@JoinQuant聚宽 用户 cjhren )
计算思路是:
利用函数quantile计算数列a的十分位数列B;利用函数bisect.bisect计算x在数列B中的位置i;利用差值计算公式计算x在数列a中的分位。函数代码为:
B = [a.quantile(i/10.0)  for i in range(11)]
i = bisect.bisect(B,x)
quantile = i-(B[i]-x)/(B[i]-B[i-1])
函数bisect.bisect(B,x)的计算结果等于序列B中小于等于x的个数。
如:bisect.bisect([1,2,3,4,5],3.5) =3 , bisect.bisect([1,2,3,4,5],5)=5
需要注意的是:
当数列B包含x时,如果x=max(B),i=len(B),则在利用线性插值公式时,公式B[i]的取值会溢出。故上述函数代码应添加一判断:if i==len(B):quantile = 1
当数列B不包含x时,如果x≥max(B),处理方法同上;如果x<min(B),i=0,B[i-1]=B[-1],quantile 的计算将失真。故代码还应添加一判断:if i==len(B):quantile = 1  elif i==0: quantile = 0
显然,quantile的计算精度取决于生成数列B,生成B时的分位点越密集,利用线性插值公式计算结果精度越高,极端情况B=a,则bisect.bisect(a,x)=len([i  for i in a if i<=x]), quantile="">

PERCENTRANK(a,x,[significance])
PERCENTRANK 函数语法具有下列参数:
a   必需。 定义相对位置的数值数组或数值数据区域。x   必需。 需要得到其排位的值。significance    可选。 用于标识返回的百分比值的有效位数的值。 如果省略,则 PERCENTRANK 使用 3 位小数 (0.xxx)。当a包含x时,计算结果=count(a



德艺双馨@ETF拯救世界 ,让我的投资认知上了好几个凳次,感激不尽啊!
@江州金猪 @冬日的阳光 @梧桐社 @qymu @forestgumpgg 大家都是我平时关注的基于指数估值的投资爱好者,欢迎交流指正。
最后感谢@JoinQuant聚宽 提供了优秀的量化研究平台。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约