Скачать MetaTrader 5

Роль статистических распределений в работе трейдера

28 апреля 2011, 15:55
Dennis Kirichenko
10
3 615

В жизни помогают закономерности, но не менее важно извлекать пользу из случайности.

(Георгий Александров)

 

Введение

Данная статья является логическим продолжением моей статьи Статистические распределения вероятностей в 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:
   //+------------------------------------------------------------------+
   //| Конструктор класса Random                                        |
   //+------------------------------------------------------------------+
   void Random()
     {
      randomSet(184467440737095516);
     }
   //+------------------------------------------------------------------+
   //| Set-метод класса Random                                          |
   //+------------------------------------------------------------------+
   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
   //+------------------------------------------------------------------+
   //| Конструктор класса CNormaldev                                    |
   //+------------------------------------------------------------------+
   void CNormaldev()
     {
      CNormaldist Nn;
      setNormaldev(Nn,18446744073709);
     }
   //+------------------------------------------------------------------+
   //| Set-метод класса CNormaldev                                      |
   //+------------------------------------------------------------------+
   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. В оригинальном сишном коде такой связи с распределением не было. Я счел нужным, чтобы случайная величина, генерируемая классом (здесь классом CNormaldev), имела логическую и программную связь со своим распределением.

В исходном варианте тип Normaldev задавался так:

typedef double Doub;
typedef unsigned __int64 Ullong;

struct Normaldev : Ran 
{
 Doub mu,sig;
 Normaldev(Doub mmu, Doub ssig, Ullong i)
...
}

Генерация случайных чисел из нормального распределения здесь происходит по методу коэффициента единообразия Левы.

Все прочие классы, с помощью которых вычисляются случайные величины из различных распределений, находятся во включаемом файле Random_class.mqh.

Сейчас с генерацией закончим, а в практической части статьи рассмотрим, как можно создавать массив величин и тестировать выборку.

 

2. Оценка параметров распределений, статистические гипотезы

Понятно, что мы будем исследовать дискретные величины. Однако, на практике, при большом количестве дискретных величин, удобнее считать совокупность таких величин группой непрерывных величин. Это стандартный подход в математической статистике. Поэтому для их анализа мы можем использовать распределения, описываемые аналитическими формулами, связанными с непрерывными величинами.

Итак, давайте приступим к процедуре анализа эмпирического распределения.

Предполагается, что изучается выборка некоторой генеральной совокупности, члены которой соответствуют условию репрезентативности. Кроме того, удовлетворяются требования к оценкам, указанные в разделе 8.3 [9]. Числовые параметры распределения могут быть найдены с помощью точечных или интервальных методов.

 

2.1 Обработка выборки с помощью класса CExpStatistics

Сначала из выборки нужно удалить так называемые выбросы (outliers) - значения признака, резко отличающиеся от значений признака у основной части единиц совокупности (как в большую, так и в меньшую сторону). Какого-то одного универсального метода удаления выбросов не существует.

Предлагаю применить тот, который был описан С.В. Булашевым в разделе 6.3 [5]. На форуме MQL4 была создана библиотека статистических функций, на основе которых мы легко решим поставленную задачу. При этом, конечно, мы обратимся к возможностям ООП и немного ее модернизируем.

Созданный класс оценок статистических характеристик я назвал CExpStatistics (Class of Expected Statistics).

Выглядит он примерно так:

//+------------------------------------------------------------------+
//|             Expected Statistics class definition                 |
//+------------------------------------------------------------------+
class CExpStatistics
  {
private:
   double            arr[];      //исходный массив
   int               N;          //размер исходного массива
   double            Parr[];     //обработанный массив
   int               pN;         //размер обработанного массива
   void              stdz(double &outArr_st[],bool A); //стандартизация
public:
   void              setArrays(bool A,double &Arr[],int &n); //задать массив для обработки
   bool              isProcessed;  //массив обработан?
   void              CExpStatistics(){};  //конструктор   
   void              setCExpStatistics(double &Arr[]); //задать исходный массив для класса
   void              ZeroCheckArray(bool A); //проверка входного массива на наличие нулевых элементов
   int               get_arr_N();           //получить длину исходного массива
   double            median(bool A);         //медиана
   double            median50(bool A); //центр 50%-ного интерквантильного промежутка (центр сгибов)
   double            mean(bool A);     //среднее по всей исходной выборке
   double            mean50(bool A);   //среднее по 50%-ному интерквантильному промежутку
   double            interqtlRange(bool A); //межквартильный размах
   double            RangeCenter(bool A); //центр размаха
   double            meanCenter(bool A);  //среднее значение верхних пяти оценок
   double            expVariance(bool A); //оценка дисперсии
   double            expSampleVariance(bool A); //смещенная оценка выборочной дисперсии
   double            expStddev(bool A);   //оценка СКО
   double            Moment(int index,bool A,int sw,double xm); //момент распределения
   double            expKurtosis(bool A,double &Skewness); ////оценка куртосиса и асимметрии
   double            censorR(bool A); //коэффициент цензурирования
   int               outlierDelete(); //исключение промахов из выборки 
   int               pArrOutput(double &outArr[],bool St); //вывод обработанного массива
   void              ~CExpStatistics(){};//деструктор
  };
//+------------------------------------------------------------------+

Реализацию каждого метода можно будет детально изучить во включаемом файле ExpStatistics_class.mqh, тут я ее пропускаю.

Важное, что выполняет данный класс, - это возврат очищенного от выбросов массива (Parr[]), если конечно выбросы имели место. Кроме того, с его помощью можно получить некоторые описательные статистики выборки и их оценки.

 

2.2 Создание гистограммы для обработанной выборки

Теперь, когда массив очищен от выбросов, по его данным можно построить гистограмму (распределение частот). Она позволит нам зрительно оценить закон распределения случайной величины. Гистограмма строится поэтапно.

Сначала нужно рассчитать количество необходимых классов. В данном контексте понятие "класс" означает группировку, интервал. Число классов рассчитаем по формуле Стерджеса (Sturges):

Формула Стерджеса

Где, k - число классов, n - численность совокупности.

В MQL5 варианте формулу можно представить так:

int Sturges(int n)
/*
   Функция определения числа классовых интервало по правилу Стерджеса.
   Переменные: 
     y — численность выборки вариант.
   Возвращаемое значение:
     число классовых интервалов.
*/
{
   double s;        // Возвращаемое значение
   s=1.+log2(y);
   if(s>15)         // Эмпирическое правило
      s=15;
   return(int) floor(s);
}

Когда мы получили нужное количество классов (интервалов) по формуле Стерджеса, наступает время разнести данные массива по классам. Такие данные называются вариантами (в ед. числе - вариáнта). Сделаем мы это с помощью функции Allocate следующим образом:

void  Allocate(double &data[],int n,double &f[],double &b[],int k)
/*
  Функция разнесения вариант по классам.
  Переменные:
   1) data — исходная выборка (массив);
   2) n — численность выборки;
   3) f — вычисляемый массив вариант, разнесенных по классам;
   4) b — массив середин классов;
   5) k — число классов.        
*/
  {
   int i,j;                     // Счетчик цикла
   double t,c;                  // Вспомогательная переменная
   t=data[ArrayMinimum(data)]; // Минимум выборки
   t=t>0 ? t*0.99 : t*1.01;
   c=data[ArrayMaximum(data)]; // Максимум выборки
   c=c>0 ? c*1.01 : c*0.99;
   c=(c-t)/k/2;                // Половина классового интервала
   b[0]=t+c;                   // Массив середин классовых интервалов
   f[0]= 0;
   for(i=1; i<k; i++)
     {
      b[i] = b[i - 1] + c + c;
      f[i] = 0;
     }
// Группировка
   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[i] массива f, где b[i] - это середина класса f[i]. После этого данные для гистограммы готовы.

Гистограмму будем отображать с помощью инструментов, описанных в упомянутой ранее статье. Для этого я написал функцию histogramSave, которая и выведет нам гистограмму для исследуемого ряда в формате HTML. Функция принимает 2 аргумента: массив классов (f) и массив середин классов (b).

В качестве примера я создал гистограмму для абсолютных разниц максимумов и минимумов 500-та баров пары EURUSD четырехчасового тайм-фрейма в пунктах с помощью скрипта volatilityTest.mq5.

Рисунок 1. Гистограмма данных (абсолютная волатильность пары EURUSD H4)

Рисунок 1. Гистограмма данных (абсолютная волатильность пары EURUSD H4)

Как видно на графике (Рис. 1), в первый класс попало 146 вариант, во второй - 176 вариант и т.д. Функция гистограммы - дать визуальное представление об эмпирическом распределении изучаемой выборки.

Рисунок 2. Гистограмма данных (стандартизированные доходности пары EURUSD H4)

Рисунок 2. Гистограмма данных (стандартизированные доходности пары EURUSD H4)

На другом графике (Рис.2) представлены стандартизированные логарифмические доходности 500-та баров пары EURUSD четырехчасового таймфрейма. Как можно заметить, самыми представительными классами стали четвертый и пятый, в которые попало 244 и 124 варианты соответственно. Гистограмма построена с помощью скрипта returnsTest.mq5.

Итак, гистограмма позволяет нам выбрать тот закон распределения, параметры которого будут оцениваться в дальнейшем. Если визуально не так очевидно, какому распределению отдать предпочтение, то можно оценивать параметры нескольких теоретических распределений.

По виду оба рассмотренных распределения не похожи на нормальные, особенно первое. Но давайте не будем доверять визуализации, а перейдем к цифрам.

 

2.3 Гипотеза о нормальности

Традиционно, сначала решается и тестируется предположение (гипотеза) о том, является ли изучаемое распределение нормальным. Такая гипотеза называется основной. Одним из самых популярных методов, проверяющих нормальность выборки, является Тест Харки-Бера.

Алгоритм его не самый сложный, но достаточно объемный ввиду наличия аппроксимации. Есть несколько версий алгоритма на языке С++ и прочих. Одной из самой удачных и проверенных является версия, находящаяся в кросс-платформенной библиотеке численного анализа ALGLIB. Ее автор [Бочканов С.А.] проделал огромную работу, в частности по составлению таблицы квантилей теста. Я лишь только немного ее обработал под нужды MQL5.

Основная функция jarqueberatest выглядит так:

//+------------------------------------------------------------------+
//                   the Jarque-Bera Test                            | 
//+------------------------------------------------------------------+
void jarqueberatest(double &x[],double &p)
/*
  The Jarque-Bera test is used to check hypothesis about the fact that
   a given sample xS  is a sample of normal random variable with unknown 
   mean and variance.
   Variables:
     x - sample Xs;
     p - p-value;
*/
  {
   int n=ArraySize(x);
   double s;
   p=0.;
   if(n<5)//N is too small
     {
      p=1.0;
      return;
     }
//N is large enough
   jarquebera_jarqueberastatistic(x,n,s);
   p=jarquebera_jarqueberaapprox(n,s);
  }
//+------------------------------------------------------------------+

Она обрабатывает исходную выборку данных (x) и возвращает р-значение, т.е. величину, характеризующую вероятность отклонить нулевую гипотезу, если на самом деле нулевая гипотеза верна.

В теле функции есть еще 2 вспомогательные функции. Первая функция - jarquebera_jarqueberastatistic - рассчитывает статистику Харки-Бера, а вторая - jarquebera_jarqueberaapprox - непосредственно пи-значение. Нужно заметить, что последняя функция, в свою очередь, задействует вспомогательные функции, связанные с аппроксимацией, которых в алгоритме почти 30.

Итак, давайте попробуем протестировать наши выборки на нормальность. Воспользуемся скриптом returnsTest.mq5, который обработает выборку стандартизированных доходностей пары EURUSD H4.

Как и ожидалось, тест показал, что вероятность отвергнуть верную нулевую гипотезу равна 0.0000. Т.е. распределение этой выборки не относится к семейству нормальных. Чтобы обработать выборку абсолютной волатильности пары EURUSD, запустим скрипт volatilityTest.mq5. Результат будет аналогичный - распределение не есть нормальное.

 

3. Подгонка распределения

В математической статистике есть несколько методов, которые позволяют сравнивать эмпирическое распределение с нормальным. Самая большая проблема заключается в том, что параметры нормального распределения нам неизвестны и есть предположение, что исследуемые данные не показывают нормальности распределения.

Поэтому приходится пользоваться непараметрическими тестами, а неизвестные параметры заполнять оценками, полученными из эмпирического распределения.

3.1 Оценка и тестирование

Одним из самых популярных, а главное подходящих, тестов в данной ситуации является χ2-тест. Он основан на критерии согласия Пирсона.

Провести этот тест нам поможет функция chsone:

void chsone(double &f[],double &ebins[],double &df,
            double &chsq,double &prob,const int knstrn=1)
/*  
   1) f — массив вариант, разнесенных по классам;   
   2) ebins - массив ожидаемых частот;
   3) df - число степеней свободы; 
   3) chsq — статистика хи-квадрата;
   4) prob - вероятность принятия верной нулевой гипотезы;
   5) knstrn — ограничение.           
*/
  {
   CGamma gam;
   int j,nbins=ArraySize(bins),q,g;
   double temp;
   df=nbins-knstrn;
   chsq=0.0;
   q=nbins/2;
   g=nbins-1;
   for(j=0;j<nbins/2;j++) //проход по левой части распределения
     {
      if(ebins[j]<0.0 || (ebins[j]==0. && bins[j]>0.))
         Alert("Bad expected number in chsone!");
      if(ebins[j]<=5.0)
        {
         --df;
         ebins[j+1]+=ebins[j];
         bins[j+1]+=bins[j];
        }
      else
        {
         temp=bins[j]-ebins[j];
         chsq+=pow(temp,2)/ebins[j];
        }
     }
   for(j=nbins-1;j>nbins/2-1;j--) //проход по правой части распределения     
    {
      if(ebins[j]<0.0 || (ebins[j]==0. && bins[j]>0.))
         Alert("Bad expected number in chsone!");
      if(ebins[j]<=5.0)
        {
         --df;
         ebins[j-1]+=ebins[j];   //начинаем с последнего класса
         bins[j-1]+=bins[j];
        }
      else
        {
         temp=bins[j]-ebins[j];
         chsq+=pow(temp,2)/ebins[j];
        }
     }
   if(df<1)df=1; //compensate
   prob=gam.gammq(0.5*df,0.5*chsq); //Chi-square probability function
  }

Из листинга видно, что используется экземпляр класса CGamma, представляющий неполную гамма-функцию, включенный, как и все упомянутые распределения в файл Distribution_class.mqh. Еще нужно сказать, что массив ожидаемых частот (ebins) мы получим с помощью функций estimateDistribution и expFrequency.

Теперь нужно подобрать числовые параметры, которые входят в аналитическую формулу теоретического распределения. Число параметров зависит от конкретного распределения. Так, в нормальном распределении их два, в показательном - один и т.д.

Обычно при нахождении параметров распределения используют такие методы точечной оценки параметров как: метод моментов, квантилей и метод максимального правдоподобия. Первый является более простым, так как предполагает, что выборочные оценки (матожидание, дисперсия, асимметрия и т.д.) должны совпадать с генеральными.

Давайте на примере попробуем подобрать теоретическое распределение для нашей выборки. Возьмем ряд стандартизированных доходностей пары EURUSD H4, для которого мы уже отображали гистограмму.

По первому впечатлению, нормальное распределение для этого ряда не подходит, т.к. наблюдается избыточный коэффициент эксцесса. Давайте попробуем применить для сравнения другое распределение.

Итак, при запуске уже известного скрипта returnsTest.mq5 попробуем выбрать такое распределение, как Hypersec. Помимо всего прочего скрипт оценит и выведет параметры выбранного распределения с помощью функции estimateDistribution и сразу же проведет χ2-тест. Параметры для выбранного распределения оказались такими:

Hyperbolic Secant distribution: X~HS(-0.00, 1.00);

а результаты теста такими:

"Статистика Хи-квадрат: 1.89; вероятность отвергнуть верную нулевую гипотезу: 0.8648"

Нужно отметить, что распределение подобрано очень удачно, так как величина χ2-статистики весьма незначительна.

В дополнение, с помощью функции histogramSaveE будет построена двойная гистограмма для фактических и ожидаемых частостей (частость-частота, выраженная в долях или процентах) стандартизированных доходностей (Рис. 3). На ней заметно, что столбики практически дублируют друг друга. Что говорит об успешной подгонке.

Рисунок 3. Гистограмма фактических и ожидаемых частостей (стандартизированные доходности пары EURUSD H4)

Рисунок 3. Гистограмма фактических и ожидаемых частостей (стандартизированные доходности пары EURUSD H4)

Проведем аналогичную процедуру для данных волатильности с помощью уже знакомого скрипта volatilityTest.mq5.

Рисунок 4. Гистограмма фактических и ожидаемых частостей (абсолютная волатильность пары EURUSD H4)

Рисунок 4. Гистограмма фактических и ожидаемых частостей (абсолютная волатильность пары EURUSD H4)

Я выбрал логнормальное распределение для тестирования Lognormal. После этого получил следующую оценку параметров:

Lognormal distribution: X~Logn(6.09, 0.53);

а результаты теста такими:

"Статистика Хи-квадрат: 6.17; вероятность отвергнуть верную нулевую гипотезу: 0.4040"

Для этого эмпирического распределения тоже весьма удачно подобрано теоретическое. Таким образом, можно считать, что нулевую гипотезу отвергнуть нельзя (при стандартном уровне значимости p=0.05). На Рис. 4 можно увидеть, что столбики ожидаемых и фактических частостей также очень похожи друг на друга.

Давайте теперь вспомним, что у нас еще есть возможность генерировать выборку случайных величин из некоторого распределения с заданными параметрами. Для использования иерархии классов, связанными с такой операцией, я написал скрипт randomTest.mq5.

При его запуске нужно будет ввести следующие параметры, проиллюстрированные на Рис. 5.

Рисунок 5. Входные параметры скрипта randomTest.mq5

Рисунок 5. Входные параметры скрипта randomTest.mq5

Тут можно выбрать тип распределения (Distribution Type), число случайных величин выборки (Sample Size), возможность сохранить выборку (Write sample data), параметр Nu (для распределения Стьюдента), параметр Mu и Sigma.

Если задать для Write sample data значение true, то скрипт сохранит выборку случайных величин с пользовательскими параметрами в файл Randoms.csv. В противном случае он будет считывать данные выборки из этого файла и потом проводить статистические тесты.

Для некоторых распределений, у которых параметры Mu и Sigma отсутствуют, я привожу таблицу параметрического соответствия полям в окне запуска скрипта.

РаспределениеПервый параметр в распределенииВторой параметр в распределении
Logistic alph --> Mu bet --> Sigma
Exponential lambda --> Mu --
Gamma alph --> Mu bet --> Sigma
Beta alph --> Mu bet --> Sigma
Laplace alph --> Mu bet --> Sigma
Binomial n --> Mu pe --> Sigma
Poisson lambda --> Mu --

 

Так, если выбрать распределение Poisson, то параметр lambda введем через поле Mu и т.д.

Скрипт не оценивает параметры распределения Стьюдента ввиду того, что оно используется в абсолютном большинстве случаев лишь для некоторых статистических процедур: для точечного оценивания, построения доверительных интервалов и тестирования гипотез, касающихся неизвестного среднего статистической выборки из нормального распределения.

В качестве примера я запустил скрипт для нормального распределения с параметрами X~Nor(3.50, 2.77) при Write sample data=true. Сначала скрипт сгенерировал выборку. Повторный его запуск при Write sample data=false построил такую гистограмму, как отображено на Рис.6.

Рисунок 6. Выборка случайных величин X~Nor(3.50,2.77)

Рисунок 6. Выборка случайных величин X~Nor(3.50,2.77)

Прочая информация, которая была выведена в окно терминала:

Тест Харки-Бера: "Тест Харки-Бера: вероятность отвергнуть верную нулевую гипотезу равна 0.9381";
Оценка параметров: Normal distribution: X~Nor(3.58, 2.94);
Результаты Хи-квадрат теста: "Статистика Хи-квадрат: 0.38; вероятность отвергнуть верную нулевую гипотезу: 0.9843".

И в итоге была отображена еще одна двойная гистограмма фактических и ожидаемых частостей для выборки (Рис. 7).

Рисунок 7. Гистограмма фактических и ожидаемых частостей для X~Nor(3.50,2.77)

Рисунок 7. Гистограмма фактических и ожидаемых частостей для X~Nor(3.50,2.77)

В общем, генерация указанного распределения прошла хорошо.

Еще я написал скрипт fitAll.mq5, который работает аналогично скрипту randomTest.mq5. Разница лишь в том, что в первом есть функция fitDistributions. Я поставил для нее следующую задачу: подогнать под выборку случайных величин все имеющиеся распределения и провести статистический тест.

Не всегда какое-то распределение можно подогнать к выборке из-за параметрического несоответствия, поэтому в терминале могут появляться строки, что оценка невозможна, например "Beta distribution can not be estimated!".

Еще, я решил, что этот скрипт будет визуализировать статистические результаты в виде небольшого HTML-отчета, пример которого есть в статье Графики и диаграммы в формате HTML (Рис. 8).

Рисунок 8. Статистический отчет оценки выборки

Рисунок 8. Статистический отчет оценки выборки

В верхней левой четверти показана обычная гистограмма выборки, а в правой - описательные статистики и результат теста Харки-Бера, где переменная Processed означает, что при значении 1 были удалены выбросы, а при значении 0 - их не было.

В нижней левой четверти приведены пи-значения χ2-теста для каждого подобранного распределения. Тут, самое лучшее с точки зрения подгонки стало нормальное распределение (p=0.9926). Поэтому для него была построена гистограмма фактических и ожидаемых частостей в нижней правой четверти.

Пока в моей галерее немного распределений. Но при большом числе распределений такой скрипт сэкономит много времени.

Теперь, когда мы точно знаем параметры распределений исследуемых выборок, можно перейти к вероятностным рассуждениям.

 

3.2 Вероятности значений случайных величин

В статье про теоретические распределения я приводил скрипт continuousDistribution.mq5 в качестве примера. С его помощью попробуем отобразить любой для нас интересный закон распределения с известными параметрами.

Так, для данных волатильности введем ранее полученные параметры логнормального распределения (Mu=6.09, Sigma=0.53), выберем тип распределения Lognormal и вид cdf (Рис.9).

Рисунок 9. Параметры логнормального распределения X~Logn(6.09,0.53)

Рисунок 9. Параметры логнормального распределения X~Logn(6.09,0.53)

После этого скрипт отобразит нам функцию распределения для нашей выборки. Она будет иметь вид, показанный на Рис. 10.

Рисунок 10. Функция распределения для X~Logn(6.09,0.53)

Рисунок 10. Функция распределения для X~Logn(6.09,0.53)

На графике мы видим, что курсор наведен на точку, координаты которой примерно равны [665;0.78]. Это означает, что с вероятностью 78% волатильность пары EURUSD H4 не превысит 665 пп. Такая информация может оказаться очень ценной для разработчика эксперта. Естественно, что значения на кривой можно взять и другие, передвигая курсор.

Допустим, что нас интересует вероятность того, что величина волатильности окажется в промежутке между 500-ми пп и 750-тью пп. Для этого нужно провести такую операцию:

cdf(750) - cdf(500) = 0.84 - 0.59 = 0.25.

Таким образом, в четверти случаев волатильность пары колеблется между 500-ми пп и 750-тью пп.

Давайте еще раз запустим скрипт с теми же параметрами распределения, только в качестве вида закона распределения укажем sf. Функция надежности (выживания) покажет нам следующую картину (Рис.11).

Рисунок 11. Функция надежности для X~Logn(6.09,0.53)

Рисунок 11. Функция надежности для X~Logn(6.09,0.53)

Выделенную точку на графике кривой можно трактовать следующим образом: почти с вероятностью 75% мы можем ожидать, что волатильность пары составит 310 пп. И чем ниже будем опускаться по кривой, тем меньше будет вероятность роста волатильности. Так, волатильность более 1000 пп уже можно будет отнести к редким событиям, т.к. вероятность ее появления составит менее 5%.

Для выборки стандартизированных доходностей, как впрочем и для других выборок, можно построить аналогичные кривые распределения. Полагаю, что методика в общем и целом ясна.

 

Заключение

Нужно отметить, что предлагаемые аналитические выводы не являются абсолютно успешными, т.к. сами ряды имеют свойство изменяться. Правда это не касается, например, рядов  логарифмических доходностей. Но в этой статье я и не ставил задачей оценивать сами методы. Предлагаю заинтересованному читателю высказываться по этой проблематике.

Считаю важным отметить необходимость отношения к рынку, рыночным инструментам и торговым экспертам с позиции вероятности. Такой подход я и попытался продемонстрировать. Надеюсь, что тема заинтересует читателя, что выльется в конструктивную дискуссию.

Расположение файлов:

#ФайлПутьОписание
1 Distribution_class.mqh %MetaTrader%\MQL5\Include Галерея классов распределений
2 DistributionFigure_class.mqh %MetaTrader%\MQL5\Include Классы графического отображения распределений
3 Random_class.mqh %MetaTrader%\MQL5\Include Классы генерации выборки случайных чисел
4 ExpStatistics_class.mqh %MetaTrader%\MQL5\Include Класс и функции оценок статистических характеристик
5 volatilityTest.mq5 %MetaTrader%\MQL5\Scripts Скрипт оценки выборки волатильности EURUSD H4
6 returnsTest.mq5 %MetaTrader%\MQL5\Scripts Скрипт оценки выборки доходностей EURUSD H4
7 randomTest.mq5 %MetaTrader%\MQL5\Scripts Скрипт оценки выборки случайных величин
8 fitAll.mq5 %MetaTrader%\MQL5\Scripts Скрипт подгонки и оценки всех распределений
9 Volat.csv %MetaTrader%\MQL5\Files Файл данных выборки волатильности EURUSD H4
10 Returns_std.csv %MetaTrader%\MQL5\Files Файл данных выборки доходностей EURUSD H4
11 Randoms.csv %MetaTrader%\MQL5\Files Файл данных выборки случайных величин
12 Histogram.htm %MetaTrader%\MQL5\Files HTML-график гистограммы выборки
13 Histogram2.htm %MetaTrader%\MQL5\Files HTML-график двойной гистограммы выборок
14 chi_test.htm %MetaTrader%\MQL5\Files Статистический HTML-отчет оценки выборки
15 dataHist.txt %MetaTrader%\MQL5\Files Данные для отображения гистограммы выборок
16 dataHist2.txt %MetaTrader%\MQL5\Files Данные для отображения двойной гистограммы выборок
17 dataFitAll.txt %MetaTrader%\MQL5\Files Данные для отображения HTML-отчета
18 highcharts.js %MetaTrader%\MQL5\Files JavaScript-библиотека интерактивных графиков
19 jquery.min.js %MetaTrader%\MQL5\Files JavaScript-библиотека
20 ReturnsIndicator.mq5 %MetaTrader%\MQL5\Indicators Индикатор логарифмических доходностей

 

Используемая литература:

  1. Ch. Walck, Hand-book on Statistical Distributions for Experimentalists, University of Stockholm Internal Report SUF-PFY/96-01

  2. Numerical Recipes: The Art of Scientific Computing, Third Edition William H. Press, Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery, Cambridge University Press: 2007. - 1256 pp.

  3. STATISTICS Methods and Applications Book By Pawel Lewicki and Thomas Hill, StatSoft, Inc.; 1 edition (November 2005), 800 pages.

  4. Боровков А.А. Математическая статистика. - Учебник. - М.: Наука. Главная редакция физико-математической литературы, 1984. - 472 с.

  5. Булашев С.В. Статистика для трейдеров. - М.: Компания Спутник +, 2003. - 245 с.

  6. Вадзинский Р.Н. Справочник по вероятностным распределениям. - СПб.: Наука, 2001. - 295 с., ил. 116.

  7. Гайдышев И. Анализ и обработка данных: специальный справочник - СПб: Питер, 2001. - 752 с.: ил.

  8. Гнеденко Б.В. Курс теории вероятности: Учебник. Изд. 8-е, испр. и доп. - М.: Едиториал УРСС, 2005. - 448 с.

  9. Іглін С. П. Теорія ймовірностей та математична статистика на базі MATLAB: Навч. посіб. – Харків: НТУ "ХПІ", 2006. – 612 c. – Рос. мовою.

  10. Ивченко Г.И., Медведев Ю.И. Математическая статистика: Учеб. пособие для втузов. - М.: Высш. шк., 1984. - 248 с., ил.

  11. Кибзун А.И., Горяинова Е.Р. — Теория вероятностей и математическая статистика. Базовый курс с примерами и задачами

  12. Письменный Д.Т. Конспект лекций по теории вероятностей и математической статистике. - М.: Айрис-пресс, 2004. - 256 с.

  13. NIST/SEMATECH e-Handbook of Statistical Methods

  14. xycoon.com

Прикрепленные файлы |
random_class.mqh (51.46 KB)
volatilitytest.mq5 (4.66 KB)
returnstest.mq5 (8.9 KB)
randomtest.mq5 (9.36 KB)
fitall.mq5 (14.56 KB)
data.zip (64.83 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (10)
Dennis Kirichenko
Dennis Kirichenko | 1 май 2011 в 11:24

alsu, вы затронули тему, которая хотя и не была предметом моей статьи, но является крайне интересной. По мере сил буду дальше исследовать этот вопрос.

Спасибо за конструктивную критику!

sizon56
sizon56 | 7 июл 2011 в 18:39
Денис, добрый день.

Мне импонирует ваше мнение по поводу применимости научных знаний в трейдинге.
Подскажите, пожалуйста, какую из предложенных в списке книг Вы порекомендуете человеку, который поверхность знаком с теорией вероятностей и мат. статистикой.
Dennis Kirichenko
Dennis Kirichenko | 9 июл 2011 в 23:15
sizon56:
Денис, добрый день.

Мне импонирует ваше мнение по поводу применимости научных знаний в трейдинге.
Подскажите, пожалуйста, какую из предложенных в списке книг Вы порекомендуете человеку, который поверхность знаком с теорией вероятностей и мат. статистикой.

Спасибо за мнение!

Я думаю, что нужно искать что-то для новичков тогда, какую-то лит-ру. Главное, чтобы текст книги не отбивал желание читать её дальше :-))

Мне чем-то понравился Гайдышев, а чем-то Булашев... 

Тут интересная ветка.

Andrey Dik
Andrey Dik | 11 июл 2011 в 10:49
alsu:

Вторая неточность в том, что вы не воспользовались априорным знанием о том, что вершина (она же матожидание) распределения доходностей должна находиться точно в точке 0 (иначе мы все бы давно были миллиардерами).

Вовсе нет. Смещение вершины распределения относительно 0 (рост/падение инструмента) вовсе не означает, что так будет и в будущем. Именно поэтому большинство трейдеров не миллиардеры, а не потому что.

С уважением.

Dennis Kirichenko
Dennis Kirichenko | 11 июл 2011 в 12:42

joo:

...Смещение вершины распределения относительно 0 (рост/падение инструмента) вовсе не означает, что так будет и в будущем...

Согласен.

Вопрос к alsu. Вы имели в виду рыночную эффективность, рассуждая про нулевую точку?

Мастер MQL5: Новая версия Мастер MQL5: Новая версия

Статья описывает возможности, появившиеся в новой версии Мастера MQL5. Изменения в архитектуре сигналов позволяют теперь создавать торговые роботы на основе комбинации различных рыночных моделей. На конкретном примере рассматривается процедура интерактивного создания готового к торговле эксперта.

Прогнозирование временных рядов в MetaTrader 5 при помощи библиотеки машинного обучения ENCOG Прогнозирование временных рядов в MetaTrader 5 при помощи библиотеки машинного обучения ENCOG

Статья посвящена использованию функционала нейронных сетей библиотеки машинного обучения ENCOG в MetaTrader 5. В качестве примера приведена реализация простого нейросетевого индикатора на основе технических индикаторов и советника, торгующего по сигналам нейросетевого индикатора. Все исходные коды, скомпилированные библиотеки и примеры обученной сети прилагаются к статье.

Плеер торговли на основе истории сделок Плеер торговли на основе истории сделок

Плеер торговли. Всего два слова и пояснения не нужны. В голове всплывают мысли об удобном ящичке с кнопками. Нажал одну кнопку - играет, передвинул рычажок - изменилась скорость воспроизведения. В реальности всё почти так и есть. В данной статье я хочу представить разработку, которая проигрывает торговую историю почти как в реал-тайме. В статье так же будут затронуты вопросы, проясняющие некоторые нюансы ООП, работу с индикаторами, управления чартами.

3 метода ускорения индикаторов на примере линейной регрессии 3 метода ускорения индикаторов на примере линейной регрессии

Рассматриваются методы оптимизации вычислительных алгоритмов индикаторов. Каждый читатель найдет себе метод по душе: описан один простой метод, один требующий серьезных познаний в математике, и еще один, для которого нужна смекалка. Реализация большинства представленных методов задействует конструкционные особенности устройства индикаторов или терминала MetaTrader 5. При этом сами методы довольно универсальны - применимы не только для ускорения расчета линейной регрессии, но и для многих других индикаторов.