Discussão do artigo "O que é uma tendência e qual estrutura o mercado se baseia: Tendência ou Lateral?" - página 10

 

Estou vendo qual é o seu problema. Inicialmente, você diz que o processo pode ter um desvio máximo de 40. E você calcula com base em 40. Mas o processo tem a possibilidade de ir tanto para + quanto para -, resultando em 81 variantes (com um 0 exato).

E você traça 40 pontos agrupados em etapas de 2 no eixo X.

É por isso que você tem esse gráfico.

Transferi os dados do Excel para o MQL.

E, usando a funcionalidade da biblioteca padrão, selecionei parâmetros sigma para repetir seu gráfico do Excel, também agrupando forçosamente com a etapa 2.

Acontece que, para seu processo com combinatória, o processo com uma distribuição normal de MO 0 e sigma 6,45 é adequado.

//+------------------------------------------------------------------+
//|NormalSimple.mq5 |
//|https://www.mql5.com
//+------------------------------------------------------------------+
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Normal.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- parâmetros de entrada
input double mean_value=0;  // expectativa matemática (média)
input double std_dev=6.45;     // desvio padrão (desvio padrão)
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
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.63798 E-06,7.09406 E-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.09406 E-05,3.63798 E-06,9.09495 E-08
                           };
//--- desativar a exibição do gráfico de preços
   ChartSetInteger(0,CHART_SHOW,false);
//--- inicializar o gerador de números aleatórios
   MathSrand(GetTickCount());
//--- gerar uma amostra da variável aleatória
   long chart=0;
   string name="GraphicNormal";
   int n=100000;       // número de valores na amostra
   int ncells=41;       // número de intervalos no histograma
   double x[];          // centros de intervalo do histograma
   double y[];          // número de valores da amostra que se enquadram no intervalo
   double data[];       // amostragem de valores aleatórios
   double max,min;      // valores máximos e mínimos na amostra
//--- obter uma amostra da distribuição normal
   MathRandomNormal(mean_value,std_dev,n,data);
//--- calcular dados para a construção do histograma
   CalculateHistogramArray(data,x,y,max,min,ncells);
   /*
//--- obtenha os limites da sequência e a etapa para a construção da curva teórica
 double step;
 GetMaxMinStepValues(max,min,step);
 step=MathMin(step,(max-min)/ncells);
//--- obtenha dados calculados teoricamente no intervalo [min,max]
 double x2[];
 double y2[];
 MathSequence(min,max,step,x2);
 MathProbabilityDensityNormal(x2,mean_value,std_dev,false,y2);
//--- dimensionamento
 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;
 */
//--- exibir gráficos
   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);
//--- plotar todas as curvas
   graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"MQL step 2").HistogramWidth(6);
   graphic.CurveAdd(arrayTeoryX,arrayTeoryY,CURVE_LINES,"Excel");
//--- e agora vamos traçar a curva de densidade de distribuição teórica
//graphic.CurveAdd(x2,y2,CURVE_LINES, "Theory");
//--- plotar todas as curvas
   graphic.CurvePlotAll();
   graphic.Update();
   double summ=0;
   for(int i=0; i<ArraySize(y); i++)
     {
      summ+=y[i];
     }
   Print("Total amount by Y " + summ);
  }
//+------------------------------------------------------------------+
//| Calcular frequências para o conjunto de dados|
//+------------------------------------------------------------------+
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);
//--- definir os centros dos intervalos
   for(int i=0; i<cells; i++)
     {
      intervals[i]=minv+(i+0.5)*width;
      frequency[i]=0;
     }
//--- preencher as frequências de intervalo
   for(int i=0; i<size; i++)
     {
      int ind=int((data[i]-minv)/width);
      if(ind>=cells)
         ind=cells-1;
      frequency[ind]++;
     }
   return (true);
  }
  /*
//+------------------------------------------------------------------+
//| Calcula valores para a geração de sequências|
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
 {
//--- calcula o intervalo absoluto da sequência para obter a precisão da normalização
 double range=MathAbs(maxv-minv);
 int degree=(int)MathRound(MathLog10(range));
//--- normaliza max. e min. e min. com a precisão especificada
 maxv=NormaliseDouble(maxv,degree);
 minv=NormalizeDouble(minv,degree);
//--- também definimos a etapa de geração da sequência a partir da precisão fornecida
 stepv=NormalizeDouble(MathPow(10,-degree),degree);
 if((maxv-minv)/stepv<10)
 stepv/=10.;
 }
//+------------------------------------------------------------------+
*/
 
Alexey Klenov:

Estou vendo qual é o seu problema. Inicialmente, você diz que o processo pode ter um desvio máximo de 40. E você calcula com base em 40. Mas o processo tem a capacidade de ir tanto para + quanto para -, então você acaba com 81 variações (com um 0 exato).

E você traça 40 pontos agrupados em incrementos de 2 no eixo X.

É por isso que você tem esse gráfico.

Transferi os dados do Excel para o MQL.

E, usando a funcionalidade da biblioteca padrão, selecionei parâmetros sigma para repetir seu gráfico do Excel, também agrupando forçosamente com a etapa 2.

Acontece que, para seu processo com combinatória, o processo com uma distribuição normal de MO 0 e sigma 6,45 é adequado.

Isso é interessante. Sim, há um intervalo de -40...0...40 em etapas de 2. Você escreveu tudo corretamente. Talvez eu não tenha me aprofundado nesse ponto no artigo. Obrigado pelo código.
 

Boa tarde

O histograma azul é uma repetição do seu experimento, mas com 365 dias de dados de ticks do GBPUSD

Renko em 0,0002 pontos e corte em 40 barras de renko.

Repete quase completamente sua curva teórica do Excel.

Portanto, sua figura 7 do artigo não funciona.

 

Aqui está o código

Estou procurando por erros e ainda não encontrei nenhum.

//+------------------------------------------------------------------+
//|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
//--- parâmetros de entrada
//input double mean_value=0; // expectativa matemática (média)
//input double std_dev=1; //desvio padrão (desvio padrão)
input double stepRenko=0.0002;   // Inclinação da barra renko
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
void OnStart()
  {
//--- desativar a exibição do gráfico de preços
   ChartSetInteger(0,CHART_SHOW,false);
//--- inicializar o gerador de números aleatórios
   MathSrand(GetTickCount());
//--- gerar uma amostra da variável aleatória
   long chart=0;
   string name="GraphicNormal";
   int ncells=41;       // número de intervalos no histograma
   double x[];          // centros de intervalo do histograma
   double y[];          // número de valores da amostra que se enquadram no intervalo
   double data[];       // amostragem de valores aleatórios
   double max,min;      // valores máximos e mínimos na amostra

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

   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[];       // matriz para barras renko
   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);

// Dados do 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.63798 E-06,7.09406 E-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.09406 E-05,3.63798 E-06,9.09495 E-08
                           };
   // Dimensionamento da curva teórica para a curva real 
   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);
//--- plotar todas as curvas
   graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
   graphic.CurveAdd(arrayTeoryX,arrayTeoryY,CURVE_LINES,"Excel");


//--- plotar todas as curvas
   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]);
      //frequência[ii]+=MathAbs(data[i]);
      frequency[ii]+=1.0;
     }
   return (true);
  }
//+------------------------------------------------------------------+
 
Alexey Klenov:

Boa tarde

O histograma azul é uma repetição do seu experimento apenas com dados de ticks de 365 dias do GBPUSD

Renko a 0,0002 pips e corte de 40 barras de renko.

Repete quase completamente sua curva teórica do Excel.

Portanto, sua figura 7 do artigo não funciona.

Usei velas de minuto para analisar; quando você as divide em blocos muito pequenos, há algum erro.
Eu não tenho barras renko, o algoritmo é um pouco diferente. Nas barras renko, são necessários 2 pips para formar um bloco de reversão, mas comigo é sempre 1x.
Por favor, envie-me um histórico de ticks. Tentarei fazer isso na próxima semana e lhe mostrarei o que consegui. A ideia dos ticks deve ser um pouco moderna, mas, na verdade, os ticks são diferentes, depende da fonte. Por exemplo, em algumas contas de demonstração, há muitos ticks, e isso leva a um processo de reversão.
 
Maxim Romanov:
Usei candlesticks de minuto para analisar; quando você os divide em blocos muito pequenos, há algum erro.
Eu não tenho barras renko, o algoritmo é um pouco diferente. Com as barras renko, são necessários 2 pips para formar um bloco de reversão, mas comigo é sempre 1x.
Por favor, envie-me um histórico de ticks. Tentarei fazer isso na próxima semana e lhe mostrarei o que consegui. A ideia dos ticks deve ser um pouco moderna, mas, na verdade, os ticks são diferentes, depende da fonte. Por exemplo, em algumas contas de demonstração, há muitos ticks, e isso leva a um processo de reversão.

O terminal baixa o próprio histórico de ticks (MT5, servidor Alpari-MT5).

Variante. No terminal, Ctrl +U e, em seguida, na guia ticks, você pode fazer tudo.

 
A normalidade de sua distribuição de ações depende claramente do número de observações: quanto mais observações, mais normal ela é. Você deve comparar tamanhos de amostra iguais.
 
Kristian Kafarov:
A normalidade de sua distribuição de ações depende claramente do número de observações: quanto mais observações, mais normal ela é. Você deve comparar tamanhos de amostra semelhantes.

De acordo com os exemplos apresentados no artigo, isso pode de fato parecer assim. Mas, na realidade, esse efeito não existe. Quanto mais amostras, mais preciso é o resultado, mas a distribuição não se aproxima da normalidade (embora existam certas condições a serem cumpridas no estudo). A natureza da distribuição depende mais do instrumento de negociação, cada um deles é ligeiramente diferente.

 
Essa é uma abordagem interessante para analisar uma tendência plana. Mas considero que ela não é muito aceitável na prática. Em vez disso, o material pode ser atribuído à familiarização com outro aspecto e nada mais.
 
Muito obrigado por essa visão e explicação do mercado