Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 531

 
Vitaly Muzichenko:

Сравниваете следующий бар, и если последовательность нарушена, то сбрасывать флаг и записывать сколько было правильных, и идёте дальше в цикле.

Достаточно выяснить, что бар бычий, а следующий медвежий, следующий если такой-же как предыдущий - записываете значение и сбрасываете флаг. Ну и так до конца

но первый может быть и не бык, чёт ни как.

   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:

но первый может быть и не бык, чёт ни как.

Вот такой вариант, хотя не совсем верный, отсчёт всегда от медвежьей свечи

Файлы:
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

Вот такой вариант, хотя не совсем верный, отсчёт всегда от медвежьей свечи

Спасибо. Если полученное число возвести в квадрат и прибавить единицу, получается верный результат.

Это что проверяем if(i%2==0)?
 
PolarSeaman:

но первый может быть и не бык, чёт ни как.


Вот примерный поиск одинаковых свечей и смена направления цепочки:

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

Теперь там, где цепочка продолжается можно подсчитывать количество свечей в цепочке и сохранять в список, а там, где цепочка сменяется на новую - начинать новый подсчёт.

Количество свечей в каждой цепочке можно хранить в сортированном списке. Далее, отсортировав список, можно найти максимальную и минимальную последовательности.

 
PolarSeaman:

Спасибо. Если полученное число возвести в квадрат и прибавить единицу, получается верный результат.

Это что проверяем if(i%2==0)?

Если i кратно двум.

Это остаток от деления i на 2

 
Juer:

Здесь вылазит the size of local variables is too large (more than 512kb) при компиляции.

Куда смотреть и что делать? В функции есть массив строк CArrayString, подозреваю, что с ним может быть связана ошибка.

Я его заполняю методом Add(), затем делаю Clear() и еще Shutdown(). А потом заполняю снова новыми данными методом Add(). В этом случае массив снова с нулевого элемента будет заполняться?

Нужно убрать из классов такие члены, которые занимают память уже на этапе компиляции. Эти данные будут размещены в стековой памяти, которой всегда очень мало. Решение проблемы - выделять память для членов класса, занимающих много памяти, динамически.

Например, если имеется член класса:

class A
{
   double m_arrfArray[9999999];
};

то его нужно заменить на:

class A
{
   double m_arrfMyArray[];
};

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

Нужно убрать из классов такие члены, которые занимают память уже на этапе компиляции. Эти данные будут размещены в стековой памяти, которой всегда очень мало. Решение проблемы - выделять память для членов класса, занимающих много памяти, динамически.

Например, если имеется член класса:

то его нужно заменить на:

Спасибо. Как-то я избавился от этой проблемы, убрав класс из параметров в каждой из функций. В общем, можно было разово инициализировать этот объект на все методы.

У меня другой вопрос по классу CArray, а точнее CArrayObj. Вот есть метод Delete(), а он не сдвигает элемент в массиве? То есть, я удаляю Delete(18), удаляется элемент на этой позиции и далее если, например, запросить элемент по этому индексу, получишь invalid pointer. А есть такой метод, чтоб удалял и сдвигал элементы, чтоб на 18-м в данном случае оказался после удаления 19-й элемент?

 
Juer:

Спасибо. Как-то я избавился от этой проблемы, убрав класс из параметров в каждой из функций. В общем, можно было разово инициализировать этот объект на все методы.

У меня другой вопрос по классу CArray, а точнее CArrayObj. Вот есть метод Delete(), а он не сдвигает элемент в массиве? То есть, я удаляю Delete(18), удаляется элемент на этой позиции и далее если, например, запросить элемент по этому индексу, получишь invalid pointer. А есть такой метод, чтоб удалял и сдвигал элементы, чтоб на 18-м в данном случае оказался после удаления 19-й элемент?

Не работал со стандартной библиотекой, но, судя по справке, метод Delete() должен физически удалять элемент, изменяя размер массива. Исключение: если выключен механизм управления памятью. По умолчанию этот механизм включен. Для того, чтобы проверить состояние флага управления памятью, используется метод FreeMode.

Со своей стороны рекомендовал бы в MQL использовать собственные массивы (хотя в C++ использую векторы и списки) и самому управлять памятью, т. к. в классе CArray особых удобств или преимуществ не вижу. В собственных массивах удаляю элемент массива достаточно быстро при помощи такого способа:

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

Единственный его недостаток - не сохраняет последовательность элементов массива. То есть его можно применять ко всем массивам, кроме упорядоченных (сортированных).

 

Здравствуйте, подскажите пожалуйста, где можно найти\скачать скрипт, который позволяет в МТ4 выставлять отложенные ордера на покупку и продажу сразу на определенное количество пунктов от текущей цены, т.е. чтобы в ручную не считать, и может даже в окно ордера не заходить? Спасибо.

ПС: может что-то не так спрашиваю, еще не разу не использовал скрипты.

 

Поясните пожалуйста мне пункт - "Закрытие рыночных ордеров не осуществляется, если значения StopLoss или TakeProfit нарушают требования по параметру FreezeLevel."

Это в буквальном смысле означает, что рыночный ордер не сможет быть закрыт, если его TakeProfit или StopLoss не соответствует уровню заморозки? Просто не совсем понимаю, как может открытый рыночный ордер иметь стопы, которые нарушают правила StopLevel или FreezeLevel? Ведь при установке не правильных стопов, сервер просто выдаст ошибку и никаких стопов установлено не будет.

Также подскажите пожалуйста, что еще нужно знать при закрытии рыночного ордера, когда брокер использует FreezeLevel?

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