Обсуждение статьи "Что такое тренды и какова структура рынков — трендовая или флэтовая?" - страница 10

 

Я понял в чем была проблема у Вас. Изначально вы говорите  что процесс может быть максимум отклоненение на 40. и Рассчет делаете на 40. НО процесс имеет возможность ходить как в + так и в - в итоге получается 81 вариант ( с точной 0)

А график строите по 40 точкам сгрупированным с шагом 2 по оси Х

Вот по этому у Вас и получается такой график.

Я данные из Excel перенес в MQL.

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

Получается для вашего процесса с комбинаторикой подходит процесс с нормальным распределением МО 0 и сигма 6,45

//+------------------------------------------------------------------+
//|                                                 NormalSimple.mq5 |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Normal.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double mean_value=0;  // математическое ожиданиe (mean)
input double std_dev=6.45;     // среднеквадратическоe отклонениe (standard deviation)
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   double arrayTeoryX[41]= {-40,-38,-36,-34,-32,-30,-28,-26,-24,-22,-20,-18,-16,-14,-12,-10,-8,-6,-4,-2,0,
                            2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40
                           };
   double arrayTeoryY[41]= {0.00000009,3.63798E-06,7.09406E-05,0.000898581,0.008311872,0.059845479,0.349098627,
                            1.695621904,6.994440355,24.86912126,77.09427591,210.2571161,508.121364,1094.415245,
                            2110.657973,3658.473821,5716.365345,8070.162839,10311.87474,11940.06549,12537.06876,
                            11940.06549,10311.87474,8070.162839,5716.365345,3658.473821,2110.657973,1094.415245,
                            508.121364,210.2571161,77.09427591,24.86912126,6.994440355,1.695621904,0.349098627,
                            0.059845479,0.008311872,0.000898581,7.09406E-05,3.63798E-06,9.09495E-08
                           };
//--- отключим показ ценового графика
   ChartSetInteger(0,CHART_SHOW,false);
//--- инициализируем генератор случайных чисел
   MathSrand(GetTickCount());
//--- сгенерируем выборку случайной величины
   long chart=0;
   string name="GraphicNormal";
   int n=100000;       // количество значений в выборке
   int ncells=41;       // количество интервалов в гистограмме
   double x[];          // центры интервалов гистограммы
   double y[];          // количество значений из выборки, попавших в интервал
   double data[];       // выборка случайных значений
   double max,min;      // максимальное и минимальное значения в выборке
//--- получим выборку из нормального распределения
   MathRandomNormal(mean_value,std_dev,n,data);
//--- рассчитаем данные для построения гистограммы
   CalculateHistogramArray(data,x,y,max,min,ncells);
   /*
//--- получим границы последовательности и шаг для построения теоретической кривой
   double step;
   GetMaxMinStepValues(max,min,step);
   step=MathMin(step,(max-min)/ncells);
//--- получим теоретически рассчитанные данные на интервале [min,max]
   double x2[];
   double y2[];
   MathSequence(min,max,step,x2);
   MathProbabilityDensityNormal(x2,mean_value,std_dev,false,y2);
//--- масштабируем
   double theor_max=y2[ArrayMaximum(y2)];
   double sample_max=y[ArrayMaximum(y)];
   double k=sample_max/theor_max;
   */
   /*
   for(int i=0; i<ncells; i++)
      y[i]/=k;
      */
//--- выводим графики
   CGraphic graphic;
   if(ObjectFind(chart,name)<0)
      graphic.Create(chart,name,0,0,0,1000,680);
   else
      graphic.Attach(chart,name);
   graphic.BackgroundMain(StringFormat("Normal distribution mu=%G sigma=%G",mean_value,std_dev));
   graphic.BackgroundMainSize(16);
//--- plot all curves
   graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"MQL step 2").HistogramWidth(6);
   graphic.CurveAdd(arrayTeoryX,arrayTeoryY,CURVE_LINES,"Excel");
//--- а теперь построим теоретическую кривую плотности распределения
//graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
//--- plot all curves
   graphic.CurvePlotAll();
   graphic.Update();
   double summ=0;
   for(int i=0; i<ArraySize(y); i++)
     {
      summ+=y[i];
     }
   Print("Общая сумма по Y " + summ);
  }
//+------------------------------------------------------------------+
//|  Calculate frequencies for data set                              |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
                             double &maxv,double &minv,const int cells=10)
  {
   if(cells<=1)
      return (false);
   int size=ArraySize(data);
   if(size<cells*10)
      return (false);
   minv=data[ArrayMinimum(data)];
   maxv=data[ArrayMaximum(data)];
   double range=maxv-minv;
   double width=range/cells;
   width=2.0;
   minv=-41;
   if(width==0)
      return false;
   ArrayResize(intervals,cells);
   ArrayResize(frequency,cells);
//--- зададим центры интервалов
   for(int i=0; i<cells; i++)
     {
      intervals[i]=minv+(i+0.5)*width;
      frequency[i]=0;
     }
//--- заполним частоты попадания в интервал
   for(int i=0; i<size; i++)
     {
      int ind=int((data[i]-minv)/width);
      if(ind>=cells)
         ind=cells-1;
      frequency[ind]++;
     }
   return (true);
  }
  /*
//+------------------------------------------------------------------+
//|  Calculates values for sequence generation                       |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
  {
//--- вычислим абсолютный размах последовательности, чтобы получить точность нормализации
   double range=MathAbs(maxv-minv);
   int degree=(int)MathRound(MathLog10(range));
//--- нормализуем макс. и мин. значения с заданной точностью
   maxv=NormalizeDouble(maxv,degree);
   minv=NormalizeDouble(minv,degree);
//--- шаг генерации последовательности также зададим от заданной точности
   stepv=NormalizeDouble(MathPow(10,-degree),degree);
   if((maxv-minv)/stepv<10)
      stepv/=10.;
  }
//+------------------------------------------------------------------+
*/
 
Alexey Klenov:

Я понял в чем была проблема у Вас. Изначально вы говорите  что процесс может быть максимум отклоненение на 40. и Рассчет делаете на 40. НО процесс имеет возможность ходить как в + так и в - в итоге получается 81 вариант ( с точной 0)

А график строите по 40 точкам сгрупированным с шагом 2 по оси Х

Вот по этому у Вас и получается такой график.

Я данные из Excel перенес в MQL.

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

Получается для вашего процесса с комбинаторикой подходит процесс с нормальным распределением МО 0 и сигма 6,45

О, интересно получилось. Да, там диапазон от -40...0...40 с шагом 2, правильно все вы написали. Может я этот момент не разжевал в статье. Спасибо за код.
 

День добрый

Синяя гистограмма - повторение Вашего эксперимента  только на тиковых данных GBPUSD за 365 дней

ренко по 0,0002 пункта и нарезка по 40 ренко бар.

Практически полностью повторяет Вашу теоретическую кривую из экселя.

Так что не получается Ваш рисунок 7 к статье.

 

Вот код

Ищу ошибки и пока не нахожу.

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Normal.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
//input double mean_value=0;  // математическое ожиданиe (mean)
//input double std_dev=1;     // среднеквадратическоe отклонениe (standard deviation)
input double stepRenko=0.0002;   // Шаг ренко бара
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- отключим показ ценового графика
   ChartSetInteger(0,CHART_SHOW,false);
//--- инициализируем генератор случайных чисел
   MathSrand(GetTickCount());
//--- сгенерируем выборку случайной величины
   long chart=0;
   string name="GraphicNormal";
   int ncells=41;       // количество интервалов в гистограмме
   double x[];          // центры интервалов гистограммы
   double y[];          // количество значений из выборки, попавших в интервал
   double data[];       // выборка случайных значений
   double max,min;      // максимальное и минимальное значения в выборке

   MqlTick realTick[];
   ulong start=iTime(_Symbol,PERIOD_D1,365)*1000;         // в мс
   ulong finish=iTime(_Symbol,PERIOD_D1,1)*1000;         // в мс

   int countCopy=CopyTicksRange(_Symbol,realTick,COPY_TICKS_INFO,start,finish);
   Print("countCopy="+IntegerToString(countCopy));
   Print("0 tick time ="+TimeToString(realTick[0].time));
   Print("end tick time ="+TimeToString(realTick[countCopy-1].time));
   
   int index=0;
   double actualStep[];       // массив для ренко баров
   ArrayResize(actualStep,countCopy);
   ArrayInitialize(actualStep,0);
   double priceForCheck= realTick[0].bid;
   actualStep[0]=0;
   int cnt=0;

   for(int i=0; i<countCopy; i++)
     {
      if(realTick[i].bid>priceForCheck+stepRenko)
        {
         int add=(int)((realTick[i].bid-priceForCheck)/stepRenko);
         actualStep[index]+=add;
         priceForCheck+=stepRenko*(double)add;
         cnt+=add;
         if(cnt>39)
           {
            index++;
            cnt=0;
           }
         continue;
        }
      if(realTick[i].bid<priceForCheck-stepRenko)
        {
         int add=(int)((priceForCheck-realTick[i].bid)/stepRenko);
         actualStep[index]-=add;
         priceForCheck-=stepRenko*(double)add;
         cnt+=add;
         if(cnt>39)
           {
            index++;
            cnt=0;
           }
        }
     }
   ArrayResize(actualStep,index+1);
   Print("Count index="+IntegerToString(index));
   CalculateHistogramArrayItsMy(actualStep,x,y,max,min,ncells);

// Данные из Excel
   double arrayTeoryX[41]= {-40,-38,-36,-34,-32,-30,-28,-26,-24,-22,-20,-18,-16,-14,-12,-10,-8,-6,-4,-2,0,
                            2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40
                           };
   double arrayTeoryY[41]= {0.00000009,3.63798E-06,7.09406E-05,0.000898581,0.008311872,0.059845479,0.349098627,
                            1.695621904,6.994440355,24.86912126,77.09427591,210.2571161,508.121364,1094.415245,
                            2110.657973,3658.473821,5716.365345,8070.162839,10311.87474,11940.06549,12537.06876,
                            11940.06549,10311.87474,8070.162839,5716.365345,3658.473821,2110.657973,1094.415245,
                            508.121364,210.2571161,77.09427591,24.86912126,6.994440355,1.695621904,0.349098627,
                            0.059845479,0.008311872,0.000898581,7.09406E-05,3.63798E-06,9.09495E-08
                           };
   // Масштабирование теоретической кривой под реальную                        
   double div=100000/index;
   for(int i=0; i<ArraySize(arrayTeoryY); i++)
     {
      arrayTeoryY[i]/=div;
     }

   CGraphic graphic;
   if(ObjectFind(chart,name)<0)
      graphic.Create(chart,name,0,0,0,1080,580);
   else
      graphic.Attach(chart,name);
//graphic.BackgroundMain(StringFormat("Normal distribution mu=%G sigma=%G stepRenko=%G",mean_value,std_dev,stepRenko));
//graphic.BackgroundMain(StringFormat("Normal distribution mu=%G sigma=%G",mean_value,std_dev));
   graphic.BackgroundMainSize(16);
//--- plot all curves
   graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
   graphic.CurveAdd(arrayTeoryX,arrayTeoryY,CURVE_LINES,"Excel");


//--- plot all curves
   graphic.CurvePlotAll();
   graphic.Update();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CalculateHistogramArrayItsMy(const double &data[],double &intervals[],double &frequency[],
                                  double &maxv,double &minv,const int cells=10)
  {
   minv=data[ArrayMinimum(data)];
   maxv=data[ArrayMaximum(data)];
   int range=maxv-minv;
   ArrayResize(intervals,range+1);
   ArrayResize(frequency,range+1);
   for(int i=0; i<range+1; i++)
     {
      intervals[i]=minv+i;
     }
   for(int i=0; i<ArraySize(data); i++)
     {
      int ii=(MathAbs(minv)+data[i]);
      //frequency[ii]+=MathAbs(data[i]);
      frequency[ii]+=1.0;
     }
   return (true);
  }
//+------------------------------------------------------------------+
 
Alexey Klenov:

День добрый

Синяя гистограмма - повторение Вашего эксперимента  только на тиковых данных GBPUSD за 365 дней

ренко по 0,0002 пункта и нарезка по 40 ренко бар.

Практически полностью повторяет Вашу теоретическую кривую из экселя.

Так что не получается Ваш рисунок 7 к статье.

Я использовал минутные свечи для анализа, когда нарезаешь их слишком маленькими блоками, то возникает некоторая ошибка. 
У меня не ренко бары, алгоритм немного другой. У ренко для формировпния разворотного блока должно пройти 2х пунктов, а у меня всегда 1х. 
Скиньте пожалуйста тиковую историю, я попробую у себя на след неделе и покажу что у меня получилось. На тиках должно получиться слегка трендово по идее, но по факту, тики разные бывают, сильно зависит от источника. Например на некоторых демо счетах бывают излишнее колличество тиков, и это приводит к тому, что процесс становится разворотным.
 
Maxim Romanov:
Я использовал минутные свечи для анализа, когда нарезаешь их слишком маленькими блоками, то возникает некоторая ошибка. 
У меня не ренко бары, алгоритм немного другой. У ренко для формировпния разворотного блока должно пройти 2х пунктов, а у меня всегда 1х. 
Скиньте пожалуйста тиковую историю, я попробую у себя на след неделе и покажу что у меня получилось. На тиках должно получиться слегка трендово по идее, но по факту, тики разные бывают, сильно зависит от источника. Например на некоторых демо счетах бывают излишнее колличество тиков, и это приводит к тому, что процесс становится разворотным.

Тиковую историю терминал подгружает сам (MT5, сервер Alpari-MT5)

Вариант. в терминале Ctrl +U далее на закладке тики все можно сделать.

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

Из примеров приведенных в статье, действительно может так показаться. Но в реальности такого эффекта нет. Чем больше выборок, тем точнее результат, но распределение не приближается к нормальному (хотя тут тоже есть определенные условия, которые нужно выполнять при исследовании). Характер распределения больше зависит от торгового инструмента, у каждого он немного отличается.

 
Интересный подход к анализу тренда\флета. Но, считаю его на практике не очень приемлемым. Скорее можно отнести материал к ознакомлению с другого аспекта и не более.
 
Thank you very much for this market insight and explanation
Причина обращения: