Numpy 发现幂律分布

我们现在要假设自己在运作一只对冲基金。让我们沉浸到这个假设场景中,你现在是资本市场中的一名精英了。

幂律分布存在于众多领域之中,更多相关信息参见http://en.wikipedia.org/wiki/Power_law。帕累托法则(Pareto principle)就是幂律分布的一个实例,它描述了财富分布的不均匀性。该法则告诉我们,如果按照拥有财富的多少把人们划分成组,每组人数的差异是巨大的。简单地说就是,富人不会太多,亿万富豪更少。同样,社会精英也是少数人。

使用股票的收盘价计算收益率(log returns),假设其符合幂律分布。这当然是一个大的假设,但幂律分布似乎在众多领域中广泛存在。

考虑到每笔交易涉及的交易成本,我们并不想频繁进行交易。假设我们倾向于每个月进行一次买卖操作,交易时间选择在股价出现明显修正的时候,也就是说在股价大跌时。现在的问题就是,如果我们想每隔20天左右进行一笔交易,怎样确定一个适当的交易信号。

具体步骤

首先需要从雅虎财经频道获取过去一年的盘后数据,然后从中提取出收盘价数据。相关的步骤已在上一篇攻略中介绍了。

  1. 提取正的收益率数据。

现在要根据收盘价计算收益率,有关收益率的更多信息请参见http://en.wikipedia.org/wiki/Rate_of_return 。
首先需要计算收盘价的对数,然后使用NumPy的diff函数,对其结果进行一阶差分运算。之后从收益率数据中,选出其中的正值。为什么要把正值选出来?这个选择其实无关紧要,关键是我想研究这些正的收益率数据。

logreturns = numpy.diff(numpy.log(close))
pos = logreturns[logreturns > 0]

  1. 获得收益率的出现频率。

我们需要使用histogram函数,获得收益率的出现频率。该函数会进行分组计数,并返回一个包含各组计数值的数组。1为了能获得一个直观的线性关系,我们需要对这些频率值取对数。

counts, rets = numpy.histogram(pos)
rets = rets[:-1] + (rets[1] - rets[0])/2
freqs = 1.0/(counts + 0.01)
freqs =  numpy.log(freqs)

语句freqs = 1.0/(counts+0.01)中,加0.01目的是为了避免可能的除零错误,因为counts中可能会存在取值为0的计数值。

  1. 利用频率值和收益率数据拟合直线。

使用ployfit函数拟合直线。

p = numpy.polyfit(rets,freqs, 1)
  1. 图示结果。

最后,使用Matplotlib绘制出结果数据和拟合后的直线。

matplotlib.pyplot.plot(rets, freqs, 'o')
matplotlib.pyplot.plot(rets, p[0] * rets + p[1])
matplotlib.pyplot.show()

我们得到了一幅漂亮的由拟合直线、收益率和频率值构成的图形。
发现幂律分布

本攻略的完整代码如下。

from matplotlib.finance import quotes_historical_yahoo
from datetime import date
import numpy
import sys
import matplotlib.pyplot

#1. 获取收盘价数据
today = date.today()
start = (today.year - 1, today.month, today.day)

quotes = quotes_historical_yahoo(sys.argv[1], start, today)
close =  numpy.array([q[4] for q in quotes])

#2. 提取正的收益率数据
logreturns = numpy.diff(numpy.log(close))
pos = logreturns[logreturns > 0]

#3. 获得收益率的出现频率
counts, rets = numpy.histogram(pos)
rets = rets[:-1] + (rets[1] - rets[0])/2
freqs = 1.0/(counts + 0.01)
freqs =  numpy.log(freqs)

#4. 利用频率值和收益率数据拟合直线
p = numpy.polyfit(rets,freqs, 1)

#5. 图示结果
matplotlib.pyplot.plot(rets, freqs, 'o')
matplotlib.pyplot.plot(rets, p[0] * rets + p[1])
matplotlib.pyplot.show()

小结

histgram函数利用输入的数据集计算直方图,其返回值为直方图数据和各组的界限值。polyfit函数把输入数据拟合为指定阶数的多项式曲线,本例中我们选择的是线性拟合。我们“发现”了一个幂律分布——宣布此类结论需要慎重,但直线拟合的结果让人觉得很有希望。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程