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

 
Vitaly Muzichenko:

Compara el siguiente compás, y si la secuencia se rompe, reinicia la bandera y registra cuántas fueron correctas, y sigue en el bucle.

Basta con saber que la barra es alcista y la siguiente es bajista, la siguiente, si es igual que la anterior, se anota el valor y se reinicia la bandera. Y así hasta el final.

Pero el primero puede no ser alcista.

   for(int i=limit-1; i>0; i--)

     {


      if(open[i]<close[i]&&open[i+1]>close[i+1]&&open[i+3]<close[i+3])

        {

         up++;

        }

      else up=0;

    
    
if(max_c<up)max_c=up;

Comment(max_c);
}

//--- return value of prev_calculated for next call

   return(rates_total);

  }

 
PolarSeaman:

pero el primero podría no ser un toro, pero no hay manera.

Aquí hay una variante, aunque no del todo correcta, siempre contando desde una vela bajista

Archivos adjuntos:
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

Aquí hay una variante, aunque no del todo correcta, siempre contando desde una vela bajista

Gracias. Si se eleva al cuadrado este número y se le suma uno, el resultado es correcto.

¿Se comprueba si(i%2==0)?
 
PolarSeaman:

pero el primero no puede ser un toro, de ninguna manera.


Aquí hay un ejemplo de encontrar las mismas velas y cambiar la dirección de la cadena:

//+------------------------------------------------------------------+
//|                                              CandlesSequence.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot Sequence
#property indicator_label1  "Sequence"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrGreen,clrRed,clrGray
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- enums
enum ENUM_CANDLE_TYPE
  {
   CANDLE_TYPE_BULL  =  0,       // Bullish candle
   CANDLE_TYPE_BEAR  =  1,       // Bearish candle
   CANDLE_TYPE_DOJI  = -1        // Doji candle
  };
//--- indicator buffers
double         BufferSeq[];
double         BufferSeqColors[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferSeq,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSeqColors,INDICATOR_COLOR_INDEX);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"Candles sequence");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferSeq,true);
   ArraySetAsSeries(BufferSeqColors,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- Проверка на минимальное колиество баров для расчёта
   if(rates_total<2) return 0;
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ENUM_CANDLE_TYPE type_refs=CANDLE_TYPE_DOJI;
   ENUM_CANDLE_TYPE type_curr=CANDLE_TYPE_DOJI;
//--- Проверка и расчёт количества просчитываемых баров   
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-2;
      ArrayInitialize(BufferSeq,EMPTY_VALUE);
      BufferSeq[rates_total-1]=open[rates_total-1];
     }
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      type_refs=GetTypeCandle(i+1,open,close);
      type_curr=GetTypeCandle(i,open,close);
   //--- смена направления цепочки свечей
      if(!CheckCandle(type_refs,type_curr))
        {
         BufferSeq[i]=(type_curr==CANDLE_TYPE_BULL ? low[i]: type_curr==CANDLE_TYPE_BEAR ? high[i]: open[i]);
        }
   //--- свечи одного типа
      else
        {
         BufferSeq[i]=BufferSeq[i+1];
        }
      BufferSeqColors[i]=(type_curr==CANDLE_TYPE_BULL ? 0 : type_curr==CANDLE_TYPE_BEAR ? 1 : 2);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает тип свечи                                             |
//+------------------------------------------------------------------+
ENUM_CANDLE_TYPE GetTypeCandle(const int shift,const double &open[],const double &close[])
  {
   return(close[shift]>open[shift] ? CANDLE_TYPE_BULL : close[shift]<open[shift] ? CANDLE_TYPE_BEAR : CANDLE_TYPE_DOJI);
  }
//+------------------------------------------------------------------+
//| Сравнивает два типа свечей                                       |
//+------------------------------------------------------------------+
bool CheckCandle(const ENUM_CANDLE_TYPE reference_candle_type,const ENUM_CANDLE_TYPE checked_candle_type)
  {
   return(reference_candle_type==checked_candle_type ? true : false);
  }
//+------------------------------------------------------------------+

Ahora, cuando la cadena continúe, puedes contar el número de velas en la cadena y guardarlas en una lista, y cuando la cadena cambie a una nueva, iniciar un nuevo recuento.

El número de velas de cada cadena puede almacenarse en una lista ordenada. Después, ordenando la lista, se pueden encontrar las secuencias máxima y mínima.

 
PolarSeaman:

Gracias. Si el número obtenido se eleva al cuadrado y se suma uno, el resultado es correcto.

¿Es eso lo que estamos comprobando si(i%2==0)?

Si i es un múltiplo de dos.

Es el resto de i dividido por 2

 
Juer:

Aquí el tamaño de las variables locales es demasiado grande (más de 512kb) durante la compilación.

¿Dónde buscar y qué hacer? Hay una matriz de cadenas CArrayString en la función, sospecho que puede ser un error.

Lo lleno usando el método Add(), luego hago Clear() y Shutdown() de nuevo. Y luego vuelvo a llenarla con nuevos datos usando el método Add(). En este caso, ¿se volverá a llenar el array con elementos cero?

Tenemos que eliminar esos miembros de las clases que ya ocupan memoria en la fase de compilación. Estos datos se asignarán en la memoria de la pila, que siempre es muy pequeña. La solución a este problema es asignar memoria a los miembros de la clase que ocupan mucha memoria de forma dinámica.

Por ejemplo, si hay un miembro de la clase

class A
{
   double m_arrfArray[9999999];
};

debería ser sustituido por:

class A
{
   double m_arrfMyArray[];
};

bool A::Init()
{
   if (ArrayResize(m_arrfMyArray, 9999999) != 9999999)
      return false;
   ....
}
 
Ihor Herasko:

Tenemos que eliminar de las clases aquellos miembros que ya ocupan memoria en la fase de compilación. Estos datos se colocarán en la memoria de la pila, que siempre es muy pequeña. La solución a este problema es asignar memoria a los miembros de la clase que ocupan mucha memoria de forma dinámica.

Por ejemplo, si hay un miembro de la clase

entonces debe ser sustituido por:

Gracias. De alguna manera me deshice de este problema eliminando la clase de los parámetros en cada función. En general, era posible inicializar este objeto una vez para todos los métodos.

Tengo otra pregunta sobre la clase CArray, más específicamente CArrayObj. ¿Existe el método Delete(), pero no mueve un elemento en el array? Es decir, borro Delete(18), elimina un elemento en esta posición y posteriormente si quiero consultar el elemento por este índice, obtengo un puntero no válido. ¿Existe un método que elimine y mueva elementos de manera que en este caso el elemento 18 sea el 19 después de la eliminación?

 
Juer:

Gracias. De alguna manera me libré de este problema eliminando la clase de los parámetros en cada una de las funciones. En general, era posible inicializar este objeto una vez para todos los métodos.

Tengo otra pregunta sobre la clase CArray, más específicamente CArrayObj. ¿Existe el método Delete(), pero no mueve un elemento en el array? Es decir, borro Delete(18), elimina un elemento en esta posición y posteriormente si quiero consultar el elemento por este índice, obtengo un puntero no válido. ¿Existe un método que borre y mueva los elementos para que el 18º elemento sea el 19º después de la eliminación?

No he trabajado con la biblioteca estándar, pero según la ayuda, el método Delete() debería eliminar físicamente el elemento, cambiando el tamaño del array. Excepción: si el mecanismo de gestión de la memoria está desactivado. Por defecto, este mecanismo está activado. El método FreeMode se utiliza para comprobar el estado de la bandera de gestión de la memoria.

Por mi parte, recomendaría usar mis propios arrays en MQL (aunque en C++ uso vectores y listas) y la gestión de la memoria por mí mismo, porque no veo ninguna conveniencia o ventaja particular en la clase CArray. Yo borro los elementos de las matrices propias con bastante rapidez utilizando este método:

template<typename Array>
bool DeleteArrayElement(Array &array[], int nIndex)
{
   int nArraySize = ArraySize(array);
   if (nIndex < 0 || nIndex >= nArraySize)
      return true;
   
   array[nIndex] = array[nArraySize - 1];
   return (ArrayResize(array, nArraySize - 1, ARRAY_RESERVE_SIZE) == nArraySize - 1);
}

Su única desventaja es que no mantiene la secuencia de los elementos del array. Es decir, se puede aplicar a todas las matrices, excepto a las ordenadas.

 

Hola, ¿podríais decirme dónde puedo encontrar un script que me permita colocar órdenes pendientes de compra y venta en MT4 de una sola vez por un número determinado de pips desde el precio actual, es decir, que no cuente manualmente y quizás ni siquiera entre en la ventana de órdenes? No quiero ir a la ventanilla de pedidos, gracias.

P.D.: tal vez estoy preguntando algo mal, nunca he usado scripts antes.

 

Por favor, explíqueme el punto -"Las órdenes de mercado no pueden cerrarse si sus valores StopLoss o TakeProfit violan el parámetro FreezeLevel".

¿Significa esto literalmente que una orden de mercado no puede cerrarse si su TakeProfit o StopLoss no alcanza el FreezeLevel? No entiendo muy bien cómo una orden de mercado abierto puede tener stops que violen las reglas de StopLevel o FreezeLevel. Al fin y al cabo, si se establecen paradas incorrectas, el servidor simplemente dará un error y no se establecerá ninguna parada.

También, por favor, indique qué más necesitamos saber al cerrar una orden de mercado, cuando un corredor utiliza FreezeLevel?

Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
  • book.mql4.com
В таблицах указаны расчётные значения, ограничивающие проведение торговых операций при открытии, закрытии, установке, удалении и модификации ордеров. Для получения значения минимальной дистанции StopLevel и дистанции заморозки FreezeLevel необходимо вызвать функцию MarketInfo(). Требования. Правильные цены, используемые при осуществлении...