Особенности языка mql4, тонкости и приёмы работы - страница 8

 
  1. Первый вызов индикатора через советника с помощью iCustom вызывает запуск OnInit и OnCalculate индикатора
  2. До следующего вызова iCustom индикатор не вызывает своего OnCalculate.
  3. Выход из советника вызывает выполнение OnDeinit индикатора.
iCustom-индикаторы не полноценные. А получить с вручную запущенных индикаторов значения индикаторных буферов не получится средствами MQL4.
 
fxsaber:
iCustom-индикаторы не полноценные.

А в чем неполноценность? События не обрабатывают?

 
Andrey Khatimlianskii:

А в чем неполноценность? События не обрабатывают?

Да.

 
#property strict

#define HOUR 3600
#define DAY (24 * HOUR)
#define WEEK 7

datetime GetBarTime( const datetime time, const bool NextBar = false, string Symb = NULL, const ENUM_TIMEFRAMES TimeFrame = PERIOD_M1 )
{
  if (Symb == NULL)
    Symb = _Symbol;
    
  return(iTime(Symb, TimeFrame, iBarShift(Symb, TimeFrame, time) - (NextBar ? 1 : 0)));
}

datetime GetTimeDayOfWeek( const int Shift = 0, const ENUM_DAY_OF_WEEK Day = SUNDAY )
{
  const datetime Res = TimeCurrent() / DAY * DAY;
  
  return(Res - (((WEEK + (TimeDayOfWeek(Res) - Day)) % WEEK) + Shift * WEEK) * DAY);
}

// Аналог по серверному времени - https://www.mql5.com/ru/docs/dateandtime/timegmtoffset
// Работает для FOREX-символов, когда M1-история доступна за ближайшую неделю
int TimeServerGMTOffset( void )
{
  const datetime Sunday = GetTimeDayOfWeek();
  
  return(((int)MathRound((double)MathMin(Sunday - DAY - GetBarTime(Sunday), Sunday + DAY - GetBarTime(Sunday, true)) / HOUR) - 3) * HOUR);
}

// Аналог по серверному времени - https://www.mql5.com/ru/docs/dateandtime/timegmt
// Работает для FOREX-символов, когда M1-история доступна за ближайшую неделю
datetime TimeServerGMT( void )
{
  return(TimeCurrent() + TimeServerGMTOffset());
}


Применение

#define PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{  
  PRINT(TimeGMT());
  PRINT(TimeServerGMT());  
}


Подход хорош тем, что работает не только на выходных, в Тестере и реал-тайме, но и на сторонних данных. Т.е. определяется GMT котировок, взятых не из MT.

 
fxsaber:

А что если брать вместо TimeCurrent(), время последнего тика по инструменту, расчёт не нарушится?

 
Vitaly Muzichenko:

А что если брать вместо TimeCurrent(), время последнего тика по инструменту, расчёт не нарушится?

Не нарушится. На алгоритм TimeCurrent влияет очень косвенно. Можно взять время бара и т.д.

Надо просто любым способом вычислить дату последнего прошедшего (в истории баров) воскресенья - чтобы были бары до воскресенья и после. Т.е можете взять хоть TimeLocal для этого.

 
Сложно не любить язык, который позволяет писать такой код
double Lots[] = {0, 0, 0, 0, 0, 0};

for (int i = OrdersTotal() - 1; i >= 0; i--)
  if (OrderSelect(i, SELECT_BY_POS))
    Lots[OrderType()] += OrderLots();

Уверен, разработчики не закладывались на такие вещи при написании языка. Как получилось, что таких удобных вещей полно именно в MQL4 - загадка.

 
fxsaber:
Сложно не любить язык, который позволяет писать такой код

Уверен, разработчики не закладывались на такие вещи при написании языка. Как получилось, что таких удобных вещей полно именно в MQL4 - загадка.

Никаких загадок. Я этим пользуюсь уже много лет и в mql5 тоже, только надо явно привести к типу int тип позиции и ордера.

Только объявляю массив вот так

double Lots[6] = {0.0};
Так-же можно хранить в массиве тикеты.
 
Alexey Viktorov:

Никаких загадок. Я этим пользуюсь уже много лет и в mql5 тоже, только надо явно провести к типу int 

Так там смысл будет совсем иной.