Discusión sobre el artículo "¿Qué son las tendencias y cómo es la estructura de los mercados: de tendencia o plana?" - página 10

 

Ya veo cuál era tu problema. Inicialmente dices que el proceso puede tener una desviación máxima de 40. Y calculas sobre 40. Pero el proceso tiene la posibilidad de ir tanto en + como en - resultando 81 variantes (con un 0 exacto).

Y trazas 40 puntos agrupados en pasos de 2 en el eje X.

Por eso tienes ese gráfico.

He transferido los datos de Excel a MQL.

Y utilizando la funcionalidad de la biblioteca estándar que he seleccionado los parámetros sigma para repetir su gráfico de Excel también agrupar forzosamente con el paso 2.

Resulta que para tu proceso con combinatoria es adecuado el proceso con una distribución normal de MO 0 y sigma 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
//--- parámetros de entrada
input double mean_value=0;  // expectativa matemática (media)
input double std_dev=6.45;     // desviación típica (desviación estándar)
//+------------------------------------------------------------------+
//| Función de inicio del 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
                           };
//--- desactivar la visualización del gráfico de precios
   ChartSetInteger(0,CHART_SHOW,false);
//--- inicializar el generador de números aleatorios
   MathSrand(GetTickCount());
//--- generar una muestra de la variable aleatoria
   long chart=0;
   string name="GraphicNormal";
   int n=100000;       // número de valores de la muestra
   int ncells=41;       // número de intervalos en el histograma
   double x[];          // centros de intervalo del histograma
   double y[];          // número de valores de la muestra que entran en el intervalo
   double data[];       // muestreo de valores aleatorios
   double max,min;      // valores máximo y mínimo de la muestra
//--- obtener una muestra de la distribución normal
   MathRandomNormal(mean_value,std_dev,n,data);
//--- calcular los datos para la construcción del histograma
   CalculateHistogramArray(data,x,y,max,min,ncells);
   /*
//--- get sequence boundaries and step for theoretical curve construction
 double step;
 GetMaxMinStepValues(max,min,step);
 step=MathMin(step,(max-min)/ncells);
//--- get theoretically calculated data on the interval [min,max]
 double x2[];
 double y2[];
 MathSequence(min,max,step,x2);
 MathProbabilityDensityNormal(x2,mean_value,std_dev,false,y2);
//--- escalado
 double teor_max=y2[ArrayMaximum(y2)];
 double muestra_max=y[ArrayMaximum(y)];
 double k=muestra_max/teor_max;
 */
   /*
 for(int i=0; i<ncells; i++)
 y[i]/=k;
 */
//--- visualizar 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);
//--- trazar todas las curvas
   graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"MQL step 2").HistogramWidth(6);
   graphic.CurveAdd(arrayTeoryX,arrayTeoryY,CURVE_LINES,"Excel");
//--- y ahora vamos a trazar la curva de densidad de distribución teórica
//graphic.CurveAdd(x2,y2,CURVE_LINES, "Teoría");
//--- trazar todas las curvas
   graphic.CurvePlotAll();
   graphic.Update();
   double summ=0;
   for(int i=0; i<ArraySize(y); i++)
     {
      summ+=y[i];
     }
   Print("Importe total por Y " + summ);
  }
//+------------------------------------------------------------------+
//| Calcular frecuencias para el conjunto de datos|
//+------------------------------------------------------------------+
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);
//--- fijar los centros de los intervalos
   for(int i=0; i<cells; i++)
     {
      intervals[i]=minv+(i+0.5)*width;
      frequency[i]=0;
     }
//--- rellenar las frecuencias 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 la generación de secuencias|
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
 {
//--- calcula el rango absoluto de la secuencia para obtener la precisión de la normalización
 double range=MathAbs(maxv-minv);
 int degree=(int)MathRound(MathLog10(range));
//--- normaliza max. y min. y min. con la precisión especificada
 maxv=NormaliseDouble(maxv,degree);
 minv=NormalizeDouble(minv,degree);
//--- también establecemos el paso de generación de la secuencia a partir de la precisión dada
 stepv=NormalizeDouble(MathPow(10,-degree),degree);
 if((maxv-minv)/stepv<10)
 stepv/=10.;
 }
//+------------------------------------------------------------------+
*/
 
Alexey Klenov:

Ya veo cuál era tu problema. Inicialmente dices que el proceso puede tener una desviación máxima de 40. Y calculas sobre 40. Pero el proceso tiene la capacidad de ir tanto + como -, por lo que terminas con 81 variaciones (con un 0 exacto).

Y trazas 40 puntos agrupados en incrementos de 2 en el eje X.

Por eso tienes ese gráfico.

He transferido los datos de Excel a MQL.

Y utilizando la funcionalidad de la biblioteca estándar he seleccionado parámetros sigma para repetir su gráfico de Excel, también agrupar forzosamente con el paso 2.

Resulta que para tu proceso con combinatoria es adecuado el proceso con distribución normal de MO 0 y sigma 6.45.

Qué interesante. Sí, hay un rango de -40...0...40 en pasos de 2, escribiste todo correctamente. Tal vez no mastiqué este punto en el artículo. Gracias por el código.
 

Buenas tardes

El histograma azul es una repetición de su experimento sólo en 365 días de datos de garrapatas GBPUSD

Renko a 0.0002 puntos y cortando por 40 barras renko.

Repite casi completamente tu curva teórica de excel.

Así que su figura 7 al artículo no funciona.

 

Aquí está el código

Estoy buscando errores y aún no he encontrado ninguno.

//+------------------------------------------------------------------+
//|ProjectName
//|Copyright 2020, CompanyName |
//|http://www.nombreempresa.net
//+------------------------------------------------------------------+
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Normal.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- parámetros de entrada
//entrada double valor_medio=0; // expectativa matemática (media)
//entrada double std_dev=1; // desviación estándar (desviación típica)
input double stepRenko=0.0002;   // El paso de la barra renko
//+------------------------------------------------------------------+
//| Función de inicio del programa de script|
//+------------------------------------------------------------------+
void OnStart()
  {
//--- desactivar la visualización del gráfico de precios
   ChartSetInteger(0,CHART_SHOW,false);
//--- inicializar el generador de números aleatorios
   MathSrand(GetTickCount());
//--- generar una muestra de la variable aleatoria
   long chart=0;
   string name="GraphicNormal";
   int ncells=41;       // número de intervalos en el histograma
   double x[];          // centros de intervalo del histograma
   double y[];          // número de valores de la muestra que entran en el intervalo
   double data[];       // muestreo de valores aleatorios
   double max,min;      // valores máximo y mínimo de la muestra

   MqlTick realTick[];
   ulong start=iTime(_Symbol,PERIOD_D1,365)*1000;         // en ms
   ulong finish=iTime(_Symbol,PERIOD_D1,1)*1000;         // en 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[];       // array 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);

// Datos de 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
                           };
   // Escala de la curva teórica a la 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("Distribución normal mu=%G sigma=%G stepRenko=%G",mean_value,std_dev,stepRenko));
//graphic.BackgroundMain(StringFormat("Distribución normal mu=%G sigma=%G",valor_medio,desv_est));
   graphic.BackgroundMainSize(16);
//--- trazar todas las curvas
   graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
   graphic.CurveAdd(arrayTeoryX,arrayTeoryY,CURVE_LINES,"Excel");


//--- trazar todas las 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]);
      //frecuencia[ii]+=MathAbs(datos[i]);
      frequency[ii]+=1.0;
     }
   return (true);
  }
//+------------------------------------------------------------------+
 
Alexey Klenov:

Buenas tardes

El histograma azul es una repetición de su experimento sólo en 365 días de datos de ticks GBPUSD

Renko a 0.0002 pips y cortando 40 barras renko.

Repite casi completamente su curva teórica de excel.

Así que su figura 7 al artículo no funciona.

Usé velas de minutos para analizar, cuando las cortas en bloques demasiado pequeños hay algún error.
No tengo barras renko, el algoritmo es un poco diferente. En renko bares se necesita 2 pips para formar un bloque de inversión, pero conmigo siempre es 1x.
Por favor, envíeme un historial de ticks, lo probaré la semana que viene y le mostraré lo que conseguí. En las garrapatas debe ser un poco de moda en la idea, pero de hecho, las garrapatas son diferentes, depende de la fuente. Por ejemplo, en algunas cuentas demo hay demasiadas garrapatas, y esto conduce a un proceso de inversión.
 
Maxim Romanov:
Utilicé velas de minutos para analizar, cuando las cortas en bloques demasiado pequeños hay algún error.
No tengo barras renko, el algoritmo es un poco diferente. Con barras renko toma 2 pips para formar un bloque de reversión, pero conmigo siempre es 1x.
Por favor, envíeme un historial de ticks, lo probaré la semana que viene y le mostraré lo que conseguí. En las garrapatas debe ser un poco de moda en la idea, pero de hecho, las garrapatas son diferentes, depende de la fuente. Por ejemplo, en algunas cuentas demo hay demasiadas garrapatas, y esto conduce a un proceso de inversión.

El propio terminal descarga el historial de ticks (MT5, servidor Alpari-MT5).

Variante. en el terminal Ctrl +U luego en la pestaña ticks puedes hacer todo.

 
La normalidad de la distribución de sus existencias depende claramente del número de observaciones: cuantas más observaciones, más normal será. Debe comparar tamaños de muestra iguales.
 
Kristian Kafarov:
La normalidad de la distribución de sus existencias depende claramente del número de observaciones: cuantas más observaciones, más normal será. Debería comparar tamaños de muestra similares.

Por los ejemplos que se dan en el artículo, puede parecer que sí. Pero en realidad, no existe tal efecto. Cuantas más muestras, más exacto es el resultado, pero la distribución no se aproxima a la normalidad (aunque hay ciertas condiciones que deben cumplirse en el estudio). La naturaleza de la distribución depende más del instrumento de negociación, cada uno es ligeramente diferente.

 
Se trata de un enfoque interesante para analizar una tendencia plana. Pero lo considero poco aceptable en la práctica. Más bien puede atribuirse a la familiarización con otro aspecto y nada más.
 
Muchas gracias por esta visión y explicación del mercado.