经济学不是一门精确的科学:它仅仅由概率定律组成。因此,最谨慎的投资者是只追求“通常”正确的一般做法,而避免“通常”错误的行为和政策的人。——L.L.B.Angas

PART01 统计学基础概念

01 数据中心趋势(Central tendency)

平均法则是一个被严重误解和错误引用的原理。在交易中,当一长串异常的损失预计会被相等且相反的利润抵消时,最常被提及的是平均法则。同样,预期当前估值过高或超买的市场接下来会变成估值过低或超卖也是错误的。这不是平均法则的意思。在一个大的样本中,大部分事件将以这样一种方式分散到接近平均值,典型值压倒异常事件,使它们变得微不足道。长期的盈利、亏损或异常持续的价格波动只是一种罕见的异常事件,随着时间的推移,会被大量的正常事件所抵消。

算术平均(average)

平均数分为简单算术平均数、加权算术平均数。它主要适用于数值型数据,不适用于品质数据。根据表现形式的不同,算术平均数有不同的计算形式和计算公式。

算术平均数是加权平均数的一种特殊形式(特殊在各项的权重相等)。在实际问题中,当各项权重不相等时,计算平均数时就要采用加权平均数;当各项权相等时,计算平均数就要采用算术平均数。

其中Pi表示某时间价格。算术平均数是统计学中最基本、最常用的一种平均指标,每个数据之间不具有相互影响关系,是独立存在的。算术平均数易受极端数据的影响,这是因为平均数反应灵敏,每个数据的或大或小的变化都会影响到最终结果。

加权平均(Weighted average)

VWAP表示成交量加权平均价格,P为价格,V为成交量。加权算术平均数同时受到两个因素的影响,一个是各组数值的大小,另一个是各组分布频数的多少。在数值不变的情况下,一组的频数越多,该组的数值对平均数的作用就大,反之,越小。

几何平均(Geometric Mean)

几何平均数是指n个观察值连续乘积的n次方根。几何平均适用于任何一个连续时间平均变化率的问题,即对比率、指数等进行平均,比如投资收益率、某利润增长率等,除了年增长了外,还可以描述季度、月、周和每日的平均增长率。

等价于

其中:样本数据非负,主要用于对数正态分布

比如某项投资第一年收益率100%,第二年亏损50%,计算平均收益率。如果使用算术平均得,[100%+(-50%)]/2=25%。用几何平均数的方法计算:(1+r)(1+r)=(1+100%)(1-50%);r=0;几何平均数算出来的平均收益率是0%。也就是这两年没涨没跌,符合实际情况,投资100万,一年后变成200万,但第二年后还是100万。

调和平均值(Harmonic Mean)

调和平均数是各个变量值倒数的算数平均数的倒数,又称倒数平均数。因为调和平均数是算数平均数的倒数,小数值的倒数大于大数值的倒数,所以调和平均数也易受极端值的影响,而且受极小数值的影响比受极大数值的影响要大。调和平均值是另一种时间加权平均值,但不像几何平均值那样倾向于更高或更低的值。

即,

调和平均数可以用在相同距离但速度不同时,平均速度的计算。应用在股票上,可以计算组合投资多个股票的市盈率,计算基金/股票定投平均成本,比如每月定投N元,1月股价10元/股,2月9元/股,3月8元/股,假设平均股价为P,根据总股数等于三次购买之和可得:

方程两边同时含有N,可见计算平均成本时与每月定投的金额无关,约掉N,可得每股成本为:

,小于(10+9+8)/3=9元/股(算术平均)。

  • 调和平均数<几何平均数<算术平均数。只要有一个变量值为零,就不能计算调和平均数。
  • 当组距数列有开口组时,其组中值即使按相邻组距计算了,假定性也很大,这时,调和平均数的代表性就很不可靠。
  • 调和平均数应用的范围较小,调和平均数多用于已知分子资料,缺分母资料时。

价格分布

分布的测量非常重要,因为它告诉你通常会发生什么。我们无法知道明天上证综指的收盘价是多少,但如果目前收盘价是 3000,那么我们对今年指数落在 2500 至 3500 之间有很高的信心,但对落在 3100 至 3300 之间的信心较低,对它会落在3150 和 3250 之间的信心要小得多,而且几乎很难选择确切的范围。分布测量可以对事件发生的机会设置概率或置信水平。

中位数和众数

中位数和众数,经常被用来定义分布。中位数,或“中间项”,有助于建立数据的“中心”;当数据被排序时,它是中间的值。中位数的优点是不受极端值的影响,而这些极值则会扭曲算术平均值;缺点是必须对所有数据进行排序才能找到中间点。中位数优于均值,除非使用的项目数量非常少。众数是出现次数最多的数。pandas 可以使用 median,quantile,mode 函数分别计算中位数,分位数与众数。

02 数据变异性(Variability

概率分布的阶矩描述了各数据点位的形态,这些数据点均聚集于均值的周围。而所谓的阶矩有四,即均值、方差、偏度以及峰度,每一个阶矩所反映的是分布形态的不同情况,简单地说,均值就是中心值或平均值,方差是各个数据点与均值的距离,偏度是相对于均值左偏或右偏的倾斜度,而峰度则是相关数据集群的巅峰值。

方差(二阶矩)

标准差(Standard deviation)是方差(Variance)的平方根,反映数据序列中变异性的平均数量,即与均值的平均距离。

其中pi表示序列i的价格,P表示序列的平均值。

统计学中,标准差分为两种:

  • 总体标准差:标准差公式根号内除以n,是有偏的。
  • 样本标准差:标准差公式根号内除以n-1,是无偏的。
    pandas与numpy在计算标准差时的区别
    numpy:在numpy中计算标准差时,括号内要指定ddof的值,ddof表示自由度,当ddof=0时计算的是总体标准差;当ddof=1时计算的是样本标准差,当不为ddof设置值时,其默认为总体标准差。在使用pandas计算标准差时,其与numpy的默认情况是相反的,在默认情况下,pandas计算的标准差为样本标准差。

标准误差(Standard Error)

在整个交易系统的开发和测试过程中,我们想知道我们看到的结果是否如预期的那样。答案总是取决于数据样本的大小和这一时期典型数据的方差量。标准误差(SE)或标准误,是在抽样试验或重复测量中,计算样本平均值的标准差。标准误差给出了基于使用多个数据样本的数据分布的误差估计,是为了确定样本均值与所有数据的实际均值有何不同,解决了数据的一致性问题。

其中,Var表示样本均值的方差,n为样本均值的观测值。样本均值是指对数据进行多次采样,每次采样有n个数据点,用这些样本的均值来找出方差。

注意,标准差与标准误差是两个不同的概念!标准差是表示个体变异大小的指标,反映的是整个样本对样本均值的离散程度(variability),一般用表示,而标准误是反映样本均值对总体均值的变异程度,反映抽样误差的大小,一般用表示,主要用于统计推断,包括假设检验和参数估计,如样本均值的假设检验和参数的区间估计等。标准误等于标准差的

偏度(三阶矩)

偏度(Skwness)衡量随机变量概率分布的不对称性,是相对于平均值不对称程度的度量,通过对偏度系数的测量,我们能够判定数据分布的不对称程度以及方向。偏度的衡量是相对于正态分布来说,正态分布的偏度为0,即若数据分布是对称的,偏度为0。若偏度大于0,则分布右偏,即分布有一条长尾在右;若偏度小于0,则分布为左偏,即分布有一条长尾在左(如下图);同时偏度的绝对值越大,说明分布的偏移程度越严重。

关于价格与时间的关系,市场在价格低位运行的时间更长可以用偏度来衡量,偏度是对称分布的失真量,它使曲线看起来在左边短,在右边延伸(价格更高)。向两侧扩展的曲线涵盖的是尾部形态,向右延伸的尾部被称作正偏,向左延伸的尾部被称为负偏。数据分布的左偏或右偏,指的是数值拖尾的方向,而不是峰的位置。几乎所有的价格分布都存在正偏的趋向,即向右侧较高的价位所甩出的尾部较长

在一个完美的正态分布中,其均值、中位数以及众数都应该是完全一致的。而当价格呈现正偏的态势时,即相应的时间序列所相关的是较高的价格,那么,均值所相关的是最大的变化,众数所相关的是最小的变化,而中位数则介于二者之间。我们可以利用概率分布的标准差来调整均值与众数之间的离散差异,进而测算出比较可靠的偏度值

其中n是在相应分布中的价格数量;是相关价格的标准差。

正偏态分布有以下特性:众数 < 中位数 < 平均数;对于负偏态单峰分布则恰恰相反,众数 > 中位数 > 平均数。在对称分布中,三值相等。

(图片来源《Trading Systems and Methods》)

峰度(四阶矩)

峰度(Kurtosis),是研究数据分布陡峭或平滑的统计量,通过对峰度系数的测量,我们能够判定数据相对于正态分布而言是更陡峭还是平缓。比如正态分布的峰度为0,均匀分布的峰度为-1.2(平缓),指数分布的峰度为6(陡峭)。定义为四阶中心距除以方差的平方。

  • 若峰度≈0,分布的峰态服从正态分布;
  • 若峰度>0,分布的峰态陡峭(高尖);
  • 若峰度<0,分布的峰态平缓(矮胖);

在金融市场,峰度大于0表现为无趋势,峰度小于0表现为趋势市;偏度大于0可以解释为数据倾向于汇聚成正的趋势,偏度小于0可以解释为数据倾向于汇聚成负的趋势。对偏度的测量有利于我们得到一个公正的评估值,从而判断相关的行情是顺势运行还是横向调整。如果你看到价格稳步上涨,那么,其相应的分布区间所覆盖的范围会更广,并呈现均匀的态势,此为负峰度;如果价格在区间震荡,那么其分布频率将围绕于均值附近呈集群状态,此为正峰度。

最常使用的是溢出峰值,如此则可以更加容易地发现所谓的非正态分布。溢出峰值KE=K-3,因为正常的峰度值是3。

高峰值意味着规模相似的获利交易在数量上有压倒性的态势,但在现实交易中,这是不可能发生的。所以,我们对任何高峰值都应马上采取怀疑的态度。

(图片来源《Trading Systems and Methods》)

当分布的尖点高于正态分布的尖点时,我们视其为正峰态,其反映的是典型的盘整行情;当相应行情显示出明显的趋势性,且呈现扁平形的分布态势之时,我们则视其为负峰态。

03 相关性

皮尔逊相关系数(Correlation)

在统计学中,皮尔逊相关系数( Pearson correlation coefficient),又称皮尔逊积矩相关系数(Pearson product-moment correlation coefficient,简称 PPMCC或PCCs),是用于度量两个变量X和Y之间的相关(线性相关),其值介于-1与1之间

计算公式可表示为:

若大于0,表示正向相关,小于0,表示负向相关,等于0,表示不相关。注意,这里有一个普遍的误解,认为零相关意味着没有关联。实际上,相关性只是严格衡量了两个变量之间的线性关系。比如,对于U型或V型对称函数的两个变量相关系数为0,但两个变量是存在非线性的关系。

自相关(Autocorrelation)

序列相关或自相关意味着数据中存在持久性或趋势性,也就是说可以从过去的数据(在某种程度上)预测未来的数据。计算自相关的一种简单方法是计算时间序列与他滞后一期(或2,3,4等期)的相关系数(使用pandas的向量化运算很容易实现)。计算自相关的一种正式方法是使用 Durbin-Watson 检验,该检验给出 d 统计量。这种方法测量误差 (e) 的变化、N 个数据点与其平均值之间的差异。

d 的值始终介于 0 和 4 之间。如果 d=2,则没有自相关。如果 d 远小于 2,则存在正自相关;但是,如果它低于 1,则错误中的相似性比合理的要多。d 大于 2 越远,误差项中出现的负自相关越多。正自相关或序列相关意味着正误差因素很有可能跟随另一个正误差因素。

04 t统计量

t检验(也称为学生 t 检验)是W. S. Gossett为了观测酿酒质量提出来的,用t分布理论来推论差异发生的概率,从而比较两个平均数的差异是否显著,适用于样本容量较小(n<30),而总体标准差未知的正态分布。当分布中使用较少的价格或交易时,我们可以预期曲线的形状会更加多变。例如,它可能被分散开,这样分布的峰值会更低,而尾部会更高。t 检验根据其自由度 (df) 计算,即 n – 1,其中 n 是样本大小,即分布中使用的价格数量。

样本中的数据越多,结果就越可靠。随着样本量 n 的增加,t 的值接近尾部区域的标准正态值。

在测试交易系统时,自由度可以是策略产生的交易数量。当交易很少时,结果可能无法代表您使用更长的交易历史将获得的结果。在测试策略时,会发现交易数量与策略中使用的参数或变量数量之间存在类似的关系。使用的变量越多,需要进行的交易就越多,才能以可接受的置信水平创造预期。

t检验分为单样本检验、相关配对检验和独立双样本检验。

  • 单样本t检验主要检验单个样本的平均值是否等于目标值,如某只个股在某段时间周期内的平均收益率是否等于市场平均收益率(如上证综指)。
  • 相关配对t检验是检验相关或配对观测之差的平均值是否等于目标值,如为了检测业绩增长公告是否能带来超额收益,对发布业绩增长公告的公司公告前N日(如N=3)和公告后N日的收益率进行比较,检验是否存在显著差异。
  • 独立双样本检验是检验两个独立样本的平均值之差是否等于目标值,如检验某个交易策略在不同的交易期间内是否表现一致。
  • 其中,和分别是价格在期间1和期间2的平均值,和分别是价格在期间1和期间2的标准差,和分别是期间1和期间2的样本数量(观察值)。

PART 02 Python代码实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import tushare as ts
sns.set_style("darkgrid")
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
### 计算标准正态分布0-1之间的概率
def normal_pdf(x, mu=0, sigma=1):
    sqrt_two_pi = np.sqrt(2 * np.pi)
    pdf=(np.exp(-(x-mu) ** 2 / 2 / sigma ** 2) / (sqrt_two_pi * sigma))    return pdf
mu = 0    # 均值为0
sigma = 1 # 标准差为1

#用统计模拟绘制正态分布的直方图
plt.figure(figsize=(12,6))
sample = np.random.normal(mu, sigma, size=10000)
plt.hist(sample, bins=100, alpha=0.7, density=True)
print(pd.Series(sample).describe())
#根据正态分布的公式绘制PDF曲线
x = np.linspace(-4, 4, 300)
y = normal_pdf(x, mu, sigma)
plt.plot(x,y, color='orange', lw=3,label='$\mu=0,\sigma=1$')
plt.legend()
plt.show()
count    10000.000000
mean        -0.019925
std          0.995619
min         -3.453845
25%         -0.697581
50%         -0.009903
75%          0.660925
max          4.106088
dtype: float64

下面以全球指数交易数据为分析样本,使用Python进行描述性统计分析。使用efinance包获取全球指数数据,efinance相当于对东方财富网数据的爬虫。

#使用pip install efinance安装efinance包用于获取交易数据
import efinance as ef
from tqdm import tqdm
global_indexs=['道琼斯','标普500','NDX','上证指数','深证成指','沪深300',
               '创业板指','上证50','中证500','恒生指数','英国富时','法国CAC40','德国DAX',
              '日经225','韩国KOSPI','澳大利亚标普200','印度孟买SENSEX','俄罗斯RTS','加拿大S&P',
               '台湾加权','美元指数','路透CRB商品指数']
#NDX为纳斯达克指数
index_data=pd.DataFrame()
for index in tqdm(global_indexs):
    index_data[index]=ef.stock.get_quote_history(index).set_index('日期')['收盘']
index_data.rename(columns={'NDX':'纳斯达克'},inplace=True)
100%|██████████████████████████████████████████████████████████████████████████████████| 22/22 [00:10<00:00,  2.11it/s]
sns.pairplot(index_data[['上证指数','深证成指','沪深300','创业板指','上证50','中证500']]);

从配对相关和个体分布图来看,国内各大指数存在较强的相关性,分布呈现“左偏(负偏),长右尾的特征,即大部分时间处于较低点位数(收益低),短时间处于高点位数(异常高收益),这也反映了波动程度可能很大。

sns.pairplot(index_data[['上证指数','标普500','法国CAC40','德国DAX','日经225']]);

相关系数热力图

cols=['沪深300','恒生指数','标普500','英国富时','法国CAC40','德国DAX','日经225','韩国KOSPI','澳大利亚标普200','印度孟买SENSEX','台湾加权']
index_data[cols].corr()

全球指数之间存在一定的相关性,同一地域的相关性非常明显,甚至高达0.98,如标准普尔道琼斯指数。沪深300与全球其他市场指数的相关性均超过0.65,最高为0.77。
ax = plt.subplots(figsize=(12, 8))#画布大小
ax = sns.heatmap(index_data[cols].corr(),annot=True,cmap = "Reds");
#annot=True 表示显示系数
# 设置刻度字体大小
plt.xticks(fontsize=12);
plt.yticks(fontsize=12);

计算各指数之间的移动相关系数。

def cal_roll_cor(data=index_data,index1='沪深300',                  index2='标普500',period=120):
    data=data.dropna()
    cors=data[[index1,index2]].rolling(period).corr()
    cors=cors.dropna().iloc[1::2,0]
    cors=cors.reset_index()
    cors=cors.set_index('日期')
    cor=cors[index1]
    #可视化结果
    print(cor.describe())
    cor.plot(figsize=(14,6),label=f'移动{period}日相关系数')
    plt.title(f'{index1}与{index2}移动{period}日相关系数',size=15)
    plt.axhline(cor.mean(), c='r',label=f'相关系数均值={cor.mean():.2f}')
    plt.legend(loc=2)
    plt.show()
    return 
cal_roll_cor()
count    1756.000000
mean        0.395825
std         0.504222
min        -0.851314
25%         0.152758
50%         0.608515
75%         0.732023
max         0.950947
Name: 沪深300, dtype: float64


创业板指数与纳斯达克移动相关系数。

cal_roll_cor(data=index_data,index1='创业板指',index2='纳斯达克',period=120)
count 1756.000000
mean 0.429181
std 0.521487
min -0.896746
25% 0.290088
50% 0.649482
75% 0.778092
max 0.972854
Name: 创业板指, dtype: float64

各指数收益率描述性统计

def cal_ret_des(data=index_data,period='W'):
    data.index=pd.to_datetime(data.index)
    #删除缺失值
    data=data.dropna()
    rets=(data/data.shift(1)-1)
    ret_M=rets.to_period(period)
    ret_M=ret_M.groupby(ret_M.index).apply(lambda x:((1+x).cumprod()-1).iloc[-1])
    result=ret_M.describe().T
    result['skew']=ret_M.skew(axis=0)
    result['kurt']=ret_M.kurt(axis=0)
    #返回根据均值排序后数据
    return result.sort_values('mean',ascending=False)
#周收益率对比
cal_ret_des()

#月收益率
cal_ret_des(period='M')

#年收益率
cal_ret_des(period='Y')

指数价格统计分布。

#考虑到各指数点位差别较大,数据归一化或标准化处理
def normalization(data,flag=True):
    data=data.dropna()
    if flag:
        return (data-data.min())/(data.max()-data.min())
    else:
        return (data-data.mean())/data.std()
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
cols2=['沪深300','恒生指数','标普500','英国富时','法国CAC40','德国DAX','日经225','韩国KOSPI']

data=normalization(index_data,flag=False)
data[cols2].plot(kind='kde',figsize=(14,8));

参考资料:Kaufman P J . Trading Systems and Methods, + Website[M]. Wiley Publishing, 2013.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注