Универсальные функции для MetaTrader 4 и MetaTrader 5

 

В данной теме предлагаю вместе собрать универсальные функции для терминалов MetaTrader 4 и MetaTrader 5

Модераторов хочу попросить чистить тему от флуда и оставлять только полезные комментарии!

Основные требования к функциям:

  • Универсальность
  • Простота
  • Надежность
  • Скорость

Начну первым и по мере необходимости буду дополнять.


Универсальная функция определения нового бара/свечи на текущем периоде со сдвигом в секундах.

Сдвиг в секундах помогает торговой программе выполнять торговые приказы после основного пика нагрузки на сервера брокера.
Очень много советников которые ломятся на сервера брокеров при новом баре, (тем самым создавая большую нагрузку в короткий период времени) часто бывает что сервер не справляется по ряду причин и не принимает торгового приказа от советника.
Благодаря сдвигу на несколько секунд, можно обойти пиковую нагрузку.

//************************************************************************************************/
//                     Author of the new bar with shift function Voldemar227                     */
//                            https://www.forexfactory.com/voldemar227                           */
//************************************************************************************************/
bool NewBar(string aSymbol="", const ENUM_TIMEFRAMES aPeriod=PERIOD_CURRENT, const int aShiftSeconds=5)
  {
   if(aSymbol=="")
      aSymbol=Symbol();

   static datetime time    = 0;
   datetime        new_bar = (datetime)SeriesInfoInteger(aSymbol,aPeriod,SERIES_LASTBAR_DATE);

   if(time==0)
     {
      time=new_bar+PeriodSeconds(aPeriod);
      return false;
     }

   if((TimeCurrent()-time)>=aShiftSeconds)
     {
      time=new_bar+PeriodSeconds(aPeriod);
      return true;
     }

   return false;
  }
//************************************************************************************************/
//                                                                                               */
//************************************************************************************************/
 

функция нужна более универсальная. К примеру если я хочу отследить новый бар не на текущем ТФ.

И зачем использовать static для time ? 

 
Dmitiry Ananiev:

функция нужна более универсальная. К примеру если я хочу отследить новый бар не на текущем ТФ.

И зачем использовать static для time ? 

static для time - что бы time не теряло своего значения.

 
Dmitiry Ananiev:

функция нужна более универсальная. К примеру если я хочу отследить новый бар не на текущем ТФ.

Судя по всему, так и задумывалось, но доделать же нужно...

bool NewBar(string aSymbol="", const ENUM_TIMEFRAMES aPeriod=PERIOD_CURRENT, const int aShiftSeconds=5)
  {
   if(aSymbol=="")
      aSymbol=Symbol();

   static datetime time    = 0;
   datetime        new_bar = (datetime)SeriesInfoInteger(aSymbol,aPeriod,SERIES_LASTBAR_DATE);

   if(time==0)
     {
      time=new_bar+PeriodSeconds(aPeriod);
      return false;
     }

   if((TimeCurrent()-time)>=aShiftSeconds)
     {
      time=new_bar+PeriodSeconds(aPeriod);
      return true;
     }

   return false;
  }

Так работает, проверил. Но несколько ТФ отслеживать не получится.

Для работы с одним ТФ отличная функция. Чуть лишнего поубираю и оставлю себе :)

Вопрос: зачем const в параметрах?

 

Боюсь, из ветки ничего не выйдет, и ты, Владимир, уже, думаю, видишь почему - у каждого участника - свое видение "универсальности", "необходимости", да и запросы разные.

Кроме того, использование статической переменной с именем "time" - на мой взгляд, крайне опасно, в другой подобной функции ты объявишь такую же статическую переменную, и пойдут сложноуловимые ошибки.


Саму задачу - "не пропустить вход по открытию бара" лично я решаю через запоминание времени входа.  Запрашиваю текущее время, определяю момент начала бара, к которому это время относится, и проверяю - был ли вход по этому времени. Если был - ничего не делаю, жду следующего тика. Если не было - обрабатывают тик, и если успешно -  запоминаю момент открытия бара.

Таким образом,советник будет анализировать ситуацию на каждом тике, пока это не удастся, и потом - будет ждать нового бара.

На текущий таймфрейм я вобще не смотрю, каждая ТС у меня работает на своем, заранее определенном ТФ, таким образом, и анализ будет совершен именно на нужном ТФ, независимо от того, какой тикущий.
 
Oleksii Chepurnyi:

Судя по всему, так и задумывалось, но доделать же нужно...

Так работает, проверил. Но несколько ТФ отслеживать не получится.

Для работы с одним ТФ отличная функция. Чуть лишнего поубираю и оставлю себе :)

Вопрос: зачем const в параметрах?

Поправил благодарю.

 
Oleksii Chepurnyi:
 

Вопрос: зачем const в параметрах?

Затем, чтобы указать, какие параметры будут неизменны, а какие - могут поменяться в ходе работы. Это просто удобно, ограждает тебя от непредвиденных ошибок.

В данном случае - можно обойтись без const.

 
George Merts:

Затем, чтобы указать, какие параметры будут неизменны, а какие - могут поменяться в ходе работы. Это просто удобно, ограждает тебя от непредвиденных ошибок.

В данном случае - можно обойтись без const.

Спасибо!

Ну и я предложу функцию, больше к обсуждению :) Интересует мнение опытных.

int VolumeDigits(string symbol)
  {
   int count = 0;
   while(floor(SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP)*pow(10,count)) < 1) count++;
   return(count);
  }

Цель - вычислить количество знаков после запятой объема, для нормализации в основном. На основе шага объема.

По сути находит первое ненулевое значение после запятой. Отсюда и ограничение, если шаг будет, например, 0,015 функция вернет 2.

Я конечно мало с какими брокерами работал, но везде встречал шаг объема 0,1 или 0,01. Бывают ли какие-то экзотические значения шага? :) Или не заморачиваться? Может есть лучше вариант?

 
Oleksii Chepurnyi:

На счёт экзотических значений шага объёма - не скажу, не встречала. По этому вопросу может кто другой скажет, если такое есть по-факту. И если вам потребуется заморачиваться вычислить именно количество знаков после запятой, то посмотрите функцию под названием NumberOfDigitsGet в этом коде: id_digits_object. Она применима и к MT5, и к MT4.

P./S.: Попутно благодарю, что своим постом вы напомнили мне об этом коде. Мне там в обсуждении надо внести уточнения. По другому вопросу.

 
Dina Paches:

На счёт экзотических значений шага объёма - не скажу, не встречала. По этому вопросу может кто другой скажет, если такое есть по-факту. И если вам потребуется заморачиваться вычислить именно количество знаков после запятой, то посмотрите функцию под названием NumberOfDigitsGet в этом коде: id_digits_object. Она применима и к MT5, и к MT4.

P./S.: Попутно благодарю, что своим постом вы напомнили мне об этом коде. Мне там в обсуждении надо внести уточнения. По другому вопросу.

Спасибо! Идея с текстовой строкой почему-то не пришла в голову :)

Ну и я же буду не я, если не переделаю :) Если интересно:

//===================================================================
// Количество десятичных знаков
//+------------------------------------------------------------------
int DecimalPlacesAmt(double value,int digits=8)
  {
   if(digits<1 || digits>16) digits = 16;
   value = fabs(value);
   value = ND(value-floor(value),digits);
//--- 
   string text = DoubleToString(value,digits);
   for(int i=digits+1; i>1; i--)
     {
      if(StringFind(text,"0",i)==i) continue;
      return(i-1);
     }
//--- 
   return(0);
  }
//-------------------------------------------------------------------
Причина обращения: