Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 531

 
Vitaly Muzichenko:

Compare the next bar, and if the sequence is broken, reset the flag and record how many were correct, and go on in the loop.

It is enough to find out that the bar is bullish and the next one is bearish, the next one, if it is the same as the previous one, you write down the value and reset the flag. And so on to the end.

But the first one may not be bullish.

   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:

but the first one might not be a bull, but there is no way.

Here's a variant, though not quite right, always counting from a bearish candle

Files:
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

Here's a variant, though not quite right, always counting from a bearish candle

Thank you. If you square this number and add one, the result is correct.

Is it checked if(i%2==0)?
 
PolarSeaman:

but the first one may not be a bull, no way.


Here's an example of finding the same candles and changing the direction of the chain:

//+------------------------------------------------------------------+
//|                                              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);
  }
//+------------------------------------------------------------------+

Now where the chain continues, you can count the number of candles in the chain and save to a list, and where the chain changes to a new one, start a new count.

The number of candles in each chain can be stored in a sorted list. Then, by sorting the list, the maximum and minimum sequences can be found.

 
PolarSeaman:

Thank you. If the number obtained is squared and one is added, the result is correct.

Is that what we're checking if(i%2==0)?

If i is a multiple of two.

It is the remainder of i divided by 2

 
Juer:

Here the size of local variables is too large (more than 512kb) during compilation.

Where to look and what to do? There is a string array CArrayString in the function, I suspect it may be an error.

I fill it using Add() method, then do Clear() and Shutdown() again. And then I fill it again with new data using Add() method. In this case, will the array be filled with zero items again?

We have to remove such members from the classes that already occupy memory at the compilation stage. This data will be allocated in the stack memory, which is always very small. The solution to this problem is to allocate memory for class members occupying a lot of memory dynamically.

For example, if there is a class member:

class A
{
   double m_arrfArray[9999999];
};

it should be replaced with:

class A
{
   double m_arrfMyArray[];
};

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

We need to remove from the classes those members that already occupy memory at the compilation stage. This data will be placed in stack memory, which is always very small. The solution to this problem is to allocate memory for class members occupying a lot of memory dynamically.

For example, if there is a class member:

then it should be replaced with:

Thanks. Somehow I got rid of this problem by removing the class from the parameters in each function. In general, it was possible to initialise this object once for all methods.

I have another question about the CArray class, more specifically CArrayObj. Is there a Delete() method, but it doesn't move an element in the array? That is, I delete Delete(18), it removes an item at this position and later if I want to query the item by this index, I get an invalid pointer. Is there such a method that would delete and move elements so that in this case the 18th element would be the 19th one after deletion?

 
Juer:

Thank you. Somehow I got rid of this problem by removing the class from the parameters in each of the functions. In general, it was possible to initialize this object once for all methods.

I have another question about the CArray class, more specifically CArrayObj. Is there a Delete() method, but it doesn't move an element in the array? That is, I delete Delete(18), it removes an item at this position and later if I want to query the item by this index, I get an invalid pointer. Is there such a method that would delete and move items so that the 18th item would be the 19th one after deletion?

I haven't worked with the standard library, but according to the help, the Delete() method should physically remove the element, changing the size of the array. Exception: if the memory management mechanism is disabled. By default, this mechanism is enabled. The FreeMode method is used to check the state of the memory management flag.

For my part, I would recommend using my own arrays in MQL (although in C++ I use vectors and lists) and memory management myself, because I do not see any particular convenience or advantage in the CArray class. I delete array items in my own arrays rather quickly using this method:

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);
}

Its only disadvantage is that it does not keep the sequence of array items. That is, it can be applied to all arrays, except for ordered (sorted) ones.

 

Hello, could you please tell me where I can find a script that allows me to place pending buy and sell orders in MT4 at once for a certain number of pips from the current price, i.e. not to count manually and maybe not even to enter the order window? I do not want to go to the order window. Thank you.

PS: maybe i am asking something wrong, i have never used scripts before.

 

Please explain me the point -"Market orders cannot be closed if their StopLoss or TakeProfit values violate the FreezeLevel parameter."

Does this literally mean that a market order cannot be closed if its TakeProfit or StopLoss does not meet the FreezeLevel? I just don't quite understand how an open market order can have stops that violate the StopLevel or FreezeLevel rules? After all, if the wrong stops are set, the server will just give an error and no stops will be set.

Also please advise what else we need to know when closing a market order, when a broker uses FreezeLevel?

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