量化教育软件策略:统计分布在交易者工作中的作用
简介
本文是我的《用 MQL5 表示统计概率分布》一文的续篇,该文介绍了处理某些理论统计分布的类。我发现,必须首先以分布类的形式打下基础才能让用户更方便地在以后的实践中运用它们。
现在,赫兹量化已经有了理论基础,我建议我们应直接进入实际数据集,并尝试据此基础获得某些信息。同时,赫兹量化将阐明与数学统计有关的一些问题。

编辑
1. 指定分布下随机数的生成
但是在考虑实际数据集之前,能够获得与需要的理论分布紧密相关的几组值似乎非常重要。
换言之,用户应该只设置所需分布的参数和样本大小。一个程序(在我们的例子中为类的层次结构)应生成并输出此类值样本以供进一步处理。
另一个重要的细节是应将按指定规律生成的样本用于检查各种统计测试。数学统计的领域 - 在不同分布规律下随机变量的生成 - 是相当有趣且充满挑战的。
对我而言,我使用《Numerical Recipes:The Art of Scientific Computing(数值算法:科学计算的艺术)》一书 [2] 介绍的高质量生成器。其期段约等于 3.138*1057。以很简单的方式将 C 代码传递到 MQL5 中。
因此,我创建了 Random 类,如下所示:
//+------------------------------------------------------------------+ //| Random class definition | //+------------------------------------------------------------------+ class Random { private: ulong u, //unsigned 64-bit integers v, w; public: //+------------------------------------------------------------------+ //| The Random class constructor | //+------------------------------------------------------------------+ void Random() { randomSet(184467440737095516); } //+------------------------------------------------------------------+ //| The Random class set-method | //+------------------------------------------------------------------+ void randomSet(ulong j) { v=4101842887655102017; w=1; u=14757395258967641292; u=j^v; int64(); v = u; int64(); w = v; int64(); } //+------------------------------------------------------------------+ //| Return 64-bit random integer | //+------------------------------------------------------------------+ ulong int64() { uint k=4294957665; u=u*2862933555777941757+7046029254386353087; v^= v>> 17; v ^= v<< 31; v ^= v>> 8; w = k*(w & 0xffffffff) +(w>> 32); ulong x=u^(u<<21); x^=x>>35; x^=x<<4; return(x+v)^w; }; //+------------------------------------------------------------------+ //| Return random double-precision value in the range 0. to 1. | //+------------------------------------------------------------------+ double doub() { return 5.42101086242752217e-20*int64(); } //+------------------------------------------------------------------+ //| Return 32-bit random integer | //+------------------------------------------------------------------+ uint int32() { return(uint)int64(); } };
现在,赫兹量化可以为从一个分布取值的样本创建类。
作为一个例子,让我们看一看正态分布下的随机变量。CNormaldev 类如下所示:
//+------------------------------------------------------------------+ //| CNormaldev class definition | //+------------------------------------------------------------------+ class CNormaldev : public Random { public: CNormaldist N; //Normal Distribution instance //+------------------------------------------------------------------+ //| The CNormaldev class constructor | //+------------------------------------------------------------------+ void CNormaldev() { CNormaldist Nn; setNormaldev(Nn,18446744073709); } //+------------------------------------------------------------------+ //| The CNormaldev class set-method | //+------------------------------------------------------------------+ void setNormaldev(CNormaldist &Nn,ulong j) { N.mu=Nn.mu; N.sig=Nn.sig; randomSet(j); } //+------------------------------------------------------------------+ //| Return Normal deviate | //+------------------------------------------------------------------+ double dev() { double u,v,x,y,q; do { u = doub(); v = 1.7156*(doub()-0.5); x = u - 0.449871; y = fabs(v) + 0.386595; q = pow(x,2) + y*(0.19600*y-0.25472*x); } while(q>0.27597 && (q>0.27846 || pow(v,2)>-4.*log(u)*pow(u,2))); return N.mu+N.sig*v/u; } }; //+------------------------------------------------------------------+
如您所见,类有一个数据成员 N,其类型为 CNormaldist。原来的 C 代码缺少与分布的此类连接。对于此类(这里为 CNormaldev 类)生成的随机变量而言,我认为与其分布之间存在一个有逻辑的编程式连接是必不可少的。
在最初的版本中,Normaldev 类型的定义如下:
typedef double Doub; typedef unsigned __int64 Ullong; struct Normaldev : Ran { Doub mu,sig; Normaldev(Doub mmu, Doub ssig, Ullong i) ... }
此处使用 Leva 的均匀比例法从正态分布生成随机数。
帮助从各种分布计算随机变量的所有其他类,都在包含 Random_class.mqh 文件中列出。
现在,赫兹量化将结束随机数的生成,并在本文的实践部分讨论如何创建一个值数组以及测试一个样本。
2. 分布参数的估计、统计假设
显然我们将讨论离散变量。然而在实践中,如果离散变量的数量很多,则将此类离散变量的集合视为一组连续变量来考虑更加方便。这是数学统计中的一个标准方法。因此,要对它们进行分析,赫兹量化可以使用与连续变量有关的分析公式定义的分布。
那么,让我们开始经验分布的分析。
假定一个一般群体分布样本,其成员满足所研究的代表性条件。此外,还满足第 8.3 节指定的估值要求[9]。可通过点估值和区间方法找出数值分布参数。
2.1 使用 CExpStatistics 类处理样本
应该首先从样本中删除所谓的异常值;异常值指显著偏离样本主要部分的观察样本(包括向上和向下偏离)。删除异常值没有万能方法。
我建议使用在第 6.3 节中介绍的由 S.V. Bulashev 提出的方法 [5]。在 MQL4 论坛中已经创建了一个由统计函数组成的库,可以依据该库轻松地解决该问题。这就是说,赫兹量化将肯定应用 OOP 并对其稍微进行一些更新。
我将创建的统计特征的估值的类称为 CExpStatistics(预期统计类)。
它大体如下所述:
//+------------------------------------------------------------------+ //| Expected Statistics class definition | //+------------------------------------------------------------------+ class CExpStatistics { private: double arr[]; //initial array int N; //initial array size double Parr[]; //processed array int pN; //processed array size void stdz(double &outArr_st[],bool A); //standardization public: void setArrays(bool A,double &Arr[],int &n); //set array for processing bool isProcessed; //array processed? void CExpStatistics(){}; //constructor void setCExpStatistics(double &Arr[]); //set the initial array for the class void ZeroCheckArray(bool A); //check the input array for zero elements int get_arr_N(); //get the initial array length double median(bool A); //median double median50(bool A); //median of 50% interquantile range (midquartile range) double mean(bool A); //mean of the entire initial sample double mean50(bool A); //mean of 50% interquantile range double interqtlRange(bool A); //interquartile range double RangeCenter(bool A); //range center double meanCenter(bool A); //mean of the top five estimates double expVariance(bool A); //estimated variance double expSampleVariance(bool A); //shifted estimate of sample variance double expStddev(bool A); //estimated standard deviation double Moment(int index,bool A,int sw,double xm); //moment of distribution double expKurtosis(bool A,double &Skewness); ////estimated kurtosis and skewness double censorR(bool A); //censoring coefficient int outlierDelete(); //deletion of outliers from the sample int pArrOutput(double &outArr[],bool St); //processed array output void ~CExpStatistics(){};//destructor }; //+------------------------------------------------------------------+
在包含 ExpStatistics_class.mqh 文件中可详细讨论各个方法的实施,因此在这里我不做详细说明。
这个类做的重要事情是,它返回不含异常值的数组 (Parr[])(如果有的话)。此外,它有助于获取采样的某些描述性统计及其估值。
2.2 创建经过处理的样本直方图
现在,数组已经不含异常值,可以依据其数据绘制一个直方图(频率分布)。它帮助我们以可视方式估计随机变量分布规律。有一个创建直方图的分步过程。
应该首先计算需要的类的数量。在此上下文中,术语“类”指分组、区间。按 Sturges 的公式计算类的数量:

编辑
其中,k 是类的数量,n 是观察样本的数量。
在 MQL5 中,该公式可表示为:
int Sturges(int n) /* Function for determining the number of class intervals using Sturges' rule. Variables: y is the number of sampling observations. Returned value: number of class intervals. */ { double s; // Returned value s=1.+log2(y); if(s>15) // Empirical rule s=15; return(int) floor(s); }
在使用 Sturges 的公式得到需要的类(区间)的数量时,是将数组数据分成类的时候了。此数据被称为观察样本(英文为 observation)。我们将使用 Allocate 函数进行,如下所示:
void Allocate(double &data[],int n,double &f[],double &b[],int k) /* Function for allocating observations to classes. Variables: 1) data — initial sample (array) 2) n — sample size 3) f — calculated array of observations allocated to classes 4) b — array of class midpoints 5) k — number of classes */ { int i,j; // Loop counter double t,c; // Auxiliary variable t=data[ArrayMinimum(data)]; // Sample minimum t=t>0 ? t*0.99 : t*1.01; c=data[ArrayMaximum(data)]; // Sample maximum c=c>0 ? c*1.01 : c*0.99; c=(c-t)/k/2; // Half of the class interval b[0]=t+c; // Array of class interval midpoints f[0]= 0; for(i=1; i<k; i++) { b[i] = b[i - 1] + c + c; f[i] = 0; } // Grouping for(i=0; i<n; i++) for(j=0; j<k; j++) if(data[i]>b[j]-c && data[i]<=b[j]+c) { f[j]++; break; } }
如您所见,函数采用初始观察样本数组 (data)、其长度 (n)、类的数量 (k),并将观察样本分配到数组 f 的某个 f[i] 类,其中 b[i] 是 f[i] 类的中点。现在,直方图的数据准备就绪。
赫兹量化将使用在以前提过的一文中介绍的工具显示直方图。为此,我编写了 histogramSave 函数,该函数将在 HTML 中显示所研究的序列的直方图。函数采用 2 个参数:类数组 (f) 和类的中点数组 (b)。
作为一个例子,我使用 volatilityTest.mq5 脚本建立了EURUSD 货币对在四小时时间框架上 500 根柱的最大点和最小点之间的绝对差值直方图。

编辑切换为居中
图 1. 数据直方图(EURUSD H4 的绝对波动)
如直方图(图 1)所示,第一类有 146 个观察样本,第二类有 176 个观察样本,等等。直方图函数对所研究的样本的经验分布提供了一个看得见的概念。

编辑切换为居中
图 2. 数据直方图(EURUSD H4 标准化返回)
另一直方图(图 2)显示 EURUSD 货币对在 H4 时间框架上的 500 根柱的标准化对数返回。您会注意到,第四类和第五类给人的印象最深刻,因为它们分别有 244 个和 124 个观察样本。此直方图是使用 returnsTest.mq5 脚本建立的。
因此,直方图让我们能够选择将进一步估计其参数的分布规律。在不能明显看出供分布的情形中,您可以估算几种理论分布的参数。
我们考虑的两种分布在外观上都不像正态分布,尤其是第一种分布。然而,让我们不要相信图形,继续处理数字。