Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 12

 
Artyom Trishkin:

La lógica es esta:

  1. encontrar la última orden cerrada por su tipo y la hora de su cierre
  2. encontramos el bar en el que se cerró en el momento en que se cerró esta orden
  3. Si el valor obtenido de la barra es superior a cero, podemos abrir una nueva posición, de lo contrario, no.
Pido disculpas por la impertinencia) ¿Puedo ver un ejemplo de dicho código en alguna parte?
 
Viachaslau Baiko:
Perdone mi impertinencia) ¿Puedo ver un ejemplo de este código en alguna parte?

Es muy sencillo.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}


Lo siento, tal vez estoy hablando de la cosa equivocada.

 
Dmitry Fedoseev:

Medita sobre este indicador. Tiene muchas variables estáticas:

   static datetime LastTime=0;
   static int cDir=0;
   static int pDir=0;

Se hacen en lugar de topes.

Cuando IndicatorCounted()=0 LastTime debe ponerse a cero (los otros no son necesarios, pero sí deseables).

Luego, al principio del bucle, mueve los valores:

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }

Las variables que comienzan con "c" son el valor actual y con "p" el valor anterior.

Este enlace no se abre - error 404.

Intenté experimentar con el tiempo, pero no funcionó... Estaba pensando en la dirección de "cómo detener los cálculos en el último compás", creo que ese es mi error. Ahora pensaré en cómo no hacer un cambio en el último paso del cálculo antes de que cambie la barra actual.

 
Alekseu Fedotov:

Es muy sencillo.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}


Lo siento, tal vez estoy hablando de la cosa equivocada.

Gracias, lo intentaré.
 

¡Hola! ¡Por favor, ayúdenme con el algoritmo!
He escrito un sencillo script que calcula el coeficiente de correlación de Pearson. Las matrices se basan en los precios de cierre, a partir de la primera barra.

int start()
   {
   int n=25;
   int w=18;
   double sum_x=0;                                                // Сумма цен закрытия для пары 1
   double sum_y=0;                                                // Сумма цен закрытия для пары 2
   double Price_Close_x[];                                        // Массив Price_Close для пары 1
   double Price_Close_y[];                                        // Массив Price_Close для пары 2
   double dx[];                                                   // Отклонение от среднего значения для пары 1 dx
   double dy[];                                                   // Отклонение от среднего значения для пары 2 dy
   double dx2[];                                                  // Квадрат отклонения ср.значения dx2
   double dy2[];                                                  // Квадрат отклонения ср.значения dy2
   double dxdy[];                                                 // Произведение dx и dy



   ArrayResize(Price_Close_x, n);
   ArrayResize(Price_Close_y, n);
   ArrayResize(dx, n);
   ArrayResize(dy, n);  
   ArrayResize(dx2, n);
   ArrayResize(dy2, n);
   ArrayResize(dxdy, n);
   string sym_x="EURUSD";
   string sym_y="GBPUSD";
  
   for(int p=1; p<n; p++)
      {
      Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);
      Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);
      sum_x=sum_x+Price_Close_x[p];
      sum_y=sum_y+Price_Close_y[p];
      }
      
   Alert("Sum_x равно ", sum_x);
   Alert("Sum_y равно ", sum_y);
   double Mx=sum_x/(n-1);                                         // Среднее значение цен закрытия пары 1 Mx
   double My=sum_y/(n-1);                                         // Среднее значение цен закрытия пары 2 My
   Alert("Mx равно ", Mx);
   Alert("My равно ", My);  
  
   for(int i=1; i<n; i++)
      {
      dx[i]=Price_Close_x[i]-Mx;
      dy[i]=Price_Close_y[i]-My;
      dx2[i]=DoubleToString(dx[i]*dx[i], w);
      dy2[i]=DoubleToString(dy[i]*dy[i], w);
      dxdy[i]=DoubleToString(dx[i]*dy[i], w);
      Alert("Отклонение dx на баре ", i, " равно ", DoubleToString(dx[i], w));
      Alert("Отклонение dy на баре ", i, " равно ", DoubleToString(dy[i], w));
      Alert("Квадрат dx на баре ", i, " равен ", DoubleToString(dx2[i], w));
      Alert("Квадрат dy на баре ", i, " равен ", DoubleToString(dy2[i], w));
      Alert("dxdy на баре ", i, " равен ", DoubleToString(dxdy[i], w));    
      }
   double Edx2=0;                                                 // Сумма квадратов отклонений Edx2
   double Edy2=0;                                                 // Сумма квадратов отклонений Edy2
   double Edxdy=0;                                                // Сумма произведений отклонений Edxdy
   for(int q=0; q<n; q++)
      {
      Edx2=DoubleToString((Edx2+dx2[q]), w);
      Edy2=DoubleToString((Edy2+dy2[q]), w);
      Edxdy=DoubleToString((Edxdy+dxdy[q]), w);
      }  
   Alert("Сумма Edx2 равна ", DoubleToString(Edx2, w));
   Alert("Сумма Edy2 равна ", DoubleToString(Edy2, w));
   Alert("Сумма Edxdy равна ", DoubleToString(Edxdy, w));
  
   double Koef;                                                    // Коэффициент Пирсона
   Koef=Edxdy/(sqrt(DoubleToString((Edx2*Edy2), w)));
   Alert("Коэффициент корреляции Пирсона между ", sym_x, " и ", sym_y, " равен ", DoubleToString(Koef, w));    
   return;
 }

La matriz de precios se toma desde la primera barra hasta la 24ª barra.
Ahora quiero calcular la correlación para 24 barras también, pero tomar la matriz de precios de la SEGUNDA(!) barra.

Al no conocer el algoritmo, introduje cada matriz de precios manualmente:

for(int p=1; p<n; p++)

      {

      Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);

      Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);

      sum_x=sum_x+Price_Close_x[p];

      sum_y=sum_y+Price_Close_y[p];

         Price_Close_x1[p]=iClose(sym_x, PERIOD_H1, p+1);

         Price_Close_y1[p]=iClose(sym_y, PERIOD_H1, p+1);

         Price_Close_x2[p]=iClose(sym_x, PERIOD_H1, p+2);

         Price_Close_y2[p]=iClose(sym_y, PERIOD_H1, p+2);

         Price_Close_x3[p]=iClose(sym_x, PERIOD_H1, p+3);

         Price_Close_y3[p]=iClose(sym_y, PERIOD_H1, p+3);
         ...
   
         ...
         Price_Close_x24[p]=iClose(sym_x, PERIOD_H1, p+24);

         Price_Close_y24[p]=iClose(sym_y, PERIOD_H1, p+24);
}

24 barras es un rollo, y si quiero saber la correlación de 100 barras, es un coñazo entrar en cada matriz.
¿Qué hacer, gente?)

 
Timur1988:

Hola, ¿podríais ayudarme con el algoritmo?
He escrito un script que calcula el coeficiente de correlación de Pearson. Tomé matrices por precios de cierre, empezando por la primera barra

for(int p=1; p<n; p++)
{
Precio_Cierre_x[p]=iCierre(sym_x, PERIOD_H1, p);
Precio_Cierre_y[p]=iCierre(sym_y, PERIOD_H1, p);
suma_x=suma_x+Precio_Cierre_x[p];
suma_y=suma_y+Precio_Cierre_y[p];
}
_______________________________________

for(int p=1; p<n; p++)

{

Precio_Cierre_x[p]=iCierre(sym_x, PERIOD_H1, p);

Precio_Cierre_y[p]=iCierre(sym_y, PERIOD_H1, p);

suma_x=suma_x+Precio_Cierre_x[p];

suma_y=suma_y+Precio_Cierre_y[p];

Precio_Cierre_x1[p]=iCierre(sym_x, PERIOD_H1, p+1);

Precio_Cierre_y1[p]=iCierre(sym_y, PERIOD_H1, p+1);

Precio_Cierre_x2[p]=iCierre(sym_x, PERIOD_H1, p+2);

Precio_Cierre_y2[p]=iCierre(sym_y, PERIOD_H1, p+2);

Precio_Cierre_x3[p]=iCierre(sym_x, PERIOD_H1, p+3);

Precio_Cierre_y3[p]=iCierre(sym_y, PERIOD_H1, p+3);
...
Precio_Cierre_x24[p]=iCierre(sym_x, PERIOD_H1, p+24);

Precio_Cierre_y24[p]=iCierre(sym_y, PERIOD_H1, p+24);
}
____________________________________________________________________________


Matriz bidimensional

PriceClose[][2];

double PriceClose[][2];
int n=24;
ArrayResize(PriceClose,n);
for(int p=0; p<n; p++) {
   PriceClose[p][0]=iClose(sym_x, PERIOD_H1, p);
   PriceClose[p][1]=iClose(sym_y, PERIOD_H1, p);
   sum_x+=PriceClose[p][0];
   sum_y+=PriceClose[p][1];
   }
 

No sé en qué me estoy equivocando...

//+------------------------------------------------------------------+
//|                                                       SVA_03.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
#property strict

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Yellow

//---- input parameters
extern int RSIPeriod=14;
extern int Levl=50;
extern int TF=0;
//---- buffers
double MABuffer[];
static datetime TimeN=0;
static datetime TimeX=0;
int StopCalc=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
   IndicatorBuffers(1);
   SetIndexBuffer(0,MABuffer);

//---- indicator line
   SetIndexStyle(0,DRAW_LINE);
//----
//---- name for DataWindow and indicator subwindow label
//   short_name="RSI("+IntegerToString(RSIPeriod)+")";
   short_name="RSI("+RSIPeriod+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);

   return(0);
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int    i,counted_bars=IndicatorCounted();
   double rel,negative,positive,sma,x,y,Pos,Neg;
   double sumn=0.0,sump=0.0;
//----
   if(Bars<=RSIPeriod) return(0);
   if(TF!=0)
     {
      string name=WindowExpertName();
      for(i=0; i<Bars-counted_bars+1; i++)
        {
         int barIndex=iBarShift(NULL,TF,Time[i],false);
         MABuffer[i]=iCustom(Symbol(),TF,name,RSIPeriod,Levl,0,0,barIndex);
        }
      return(0);
     }

   i=Bars-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=Bars-counted_bars-1;
   datetime TimeC=iTime(NULL,TF,0);
   while(i>=0)
     {
      if(i!=0 && StopCalc==0)
        {
         sumn=0.0;sump=0.0;
         if(i==Bars-RSIPeriod-1)
           {
            int k=Bars-2;
            //---- initial accumulation
            while(k>=i)
              {
               rel=Close[k]-Close[k+1];
               if(rel>0) sump+=rel;
               else      sumn-=rel;
               k--;
              }
            positive=sump/RSIPeriod;
            negative=sumn/RSIPeriod;
           }
         else
           {
            //---- smoothed moving average
            rel=Close[i]-Close[i+1];
            if(rel>0) sump=rel;
            else      sumn=-rel;
            positive=(Pos*(RSIPeriod-1)+sump)/RSIPeriod;
            negative=(Neg*(RSIPeriod-1)+sumn)/RSIPeriod;
           }

         x=Pos;
         y=Neg;
         Pos=positive;
         Neg=negative;
         if(x>0)sma=Close[i+1]+x;
         else sma=Close[i+1]-y;
         MABuffer[i]=sma;
         Print("Этап 01 i=",i);      
        }

      if(i==0)
        {
          if(TimeC!=TimeX)
          {
        
            rel=Close[i+1]-Close[i+2];
            if(rel>0) sump=rel;
            else      sumn=-rel;
            positive=(Pos*(RSIPeriod-1)+sump)/RSIPeriod;
            negative=(Neg*(RSIPeriod-1)+sumn)/RSIPeriod;
            x=Pos;
            y=Neg;
            Pos=positive;
            Neg=negative;
            Print("positive=",positive);
            Print("negative=",negative);


            if(x>0)sma=Close[i+1]+x;
            else sma=Close[i+1]-y;
            MABuffer[i]=sma;
            Print("Этап 2 i=",i);          
            TimeX=iTime(NULL,TF,0);
            StopCalc=1;
          }          
        }
      i--;
     }

//----
   return(0);
  }
//+------------------------------------------------------------------+

los resultados son diferentes a los de la opción 4, ¿qué ocurre?

 
-Aleks-:

El enlace no se abre - error 404

Intenté experimentar con el tiempo, pero no funcionó... Estaba pensando en la dirección de "cómo detener el cálculo en el último compás", creo que ese es mi error. Ahora voy a pensar en cómo no hacer un cambio en el último paso del cálculo antes de cambiar la barra actual.

¿Por qué eres tan pesado y no pivotas? Ya se le ha dado una solución, todo lo que tiene que hacer es sentarse y pensar. Conclusión por supuesto, bueno no hay palabras - usted vio la palabra Tiempo, e inmediatamente concluyó que lo hizo...

No necesitas un enlace, o te perderás. Todo lo que necesitas está escrito en este post, déjame repetirlo en detalle:

1. Declarar una variable estática LastTime.

2. declarar un par de variables estáticas con los prefijos s y p.

3. Cuando IndicatorCounted()=0, anula todas las variables creadas en el paso 1 y 2.

4. Al principio del ciclo, restablece los valores:

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }
 
Dmitry Fedoseev:

¿Por qué eres tan pesado y no eres pivote? Ya te han dado una decisión, lo único que tienes que hacer es sentarte y pensar. La conclusión por supuesto, bueno no hay palabras - la palabra Tiempo vio, e inmediatamente concluyó que lo hiciste...

No necesitas un enlace, o te perderás. Todo lo que necesitas está escrito en este post, déjame repetirlo en detalle:

1. Declarar una variable estática LastTime.

2. declarar un par de variables estáticas con los prefijos s y p.

3. Cuando IndicatorCounted()=0, anula todas las variables creadas en el paso 1 y 2.

4. Al principio del bucle, restablece los valores:

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }

Gracias por querer ayudar.

No tengo mucha experiencia en la escritura de indicadores, por lo que hay algunas dificultades - la solución a la que estoy buscando - como mi último código de arriba demuestra.

La variante sugerida por usted causa dificultad ya que no puedo entender qué variables se me ofrecen a cero - aunque la idea es clara - para mantener los valores calculados originalmente.

Si puedes explicar por qué mi variante no funciona - también limito el cálculo a un tick por barra y las variables no deberían cambiar, y se espera que esta variante sea menos costosa ya que el bucle no estará inactivo en cada tick, a diferencia de la variante que has propuesto.

 
Artyom Trishkin:

La lógica es esta:

  1. encontrar la última orden cerrada por su tipo y hora de cierre
  2. encontramos el bar en el que se cerró en el momento en que esta orden se cerró
  3. Si el valor obtenido de la barra es superior a cero, podemos abrir una nueva posición, de lo contrario, no.

Aquí tengo el siguiente matiz: tomé este código (gracias a Alekseu Fedotov):

//+----------------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}

Y ahora pongo un cheque:

if(УСЛОВИЕ && NumberOfBarCloseLastPos()>0)

Y aquí está el problema, porque inicialmente NumberOfBarCloseLastPos se establecerá en "-1". Y en consecuencia, el primer pedido nunca se abrirá.

¿Qué podemos hacer en esta situación? ¿O tal vez he entendido algo mal?

Razón de la queja: