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

 
Dennis Kirichenko:
А позвольте полюбопытствовать, почему static?

Потому что вырвано из контекста - см. оригинальный пост.
 

не документированная особенность функции OnInit(), данную функцию можно запустить в любой части программы. Тестовый код.

//+------------------------------------------------------------------+
//|                                                       test10.mq5 |
//|                                                   Sergey Gritsay |
//|                         https://www.mql5.com/ru/users/sergey1294 |
//+------------------------------------------------------------------+
#property copyright "Sergey Gritsay"
#property link      "https://www.mql5.com/ru/users/sergey1294"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CNevBar
  {
private:
   datetime          curbar;
   datetime          lastbar;
public:
                     CNevBar();
                    ~CNevBar();
   bool              bar(string symbol,ENUM_TIMEFRAMES period);
  };
//+------------------------------------------------------------------+
void CNevBar::CNevBar()
  {

  }
//+------------------------------------------------------------------+
void CNevBar::~CNevBar(void)
  {

  }
//+------------------------------------------------------------------+
bool CNevBar:: bar(string symbol,ENUM_TIMEFRAMES period)
  {
   curbar=(datetime) SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);
   if(lastbar==0)lastbar=(datetime)SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);
   if(lastbar!=curbar)
     {
      lastbar=curbar;
      return(true);
     }
   return(false);
  }

int test=0;
CNevBar newbar;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

   test=5;
   Print(__FUNCTION__,": test = ",test);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(newbar.bar(_Symbol,PERIOD_CURRENT))
     {
      test=10;
      Print(__FUNCTION__,": test = ",test);
      OnInit();
     }
  }
//+------------------------------------------------------------------+

‌Результат

2017.03.10 19:26:02.977 test10 (EURUSD,M1)      OnInit: test = 5
2017.03.10 19:27:03.041 test10 (EURUSD,M1)      OnTick: test = 10
2017.03.10 19:27:03.042 test10 (EURUSD,M1)      OnInit: test = 5
2017.03.10 19:28:03.245 test10 (EURUSD,M1)      OnTick: test = 10
2017.03.10 19:28:03.245 test10 (EURUSD,M1)      OnInit: test = 5
2017.03.10 19:29:02.995 test10 (EURUSD,M1)      OnTick: test = 10
2017.03.10 19:29:02.995 test10 (EURUSD,M1)      OnInit: test = 5


‌...

 
Sergey Gritsay:

не документированная особенность функции OnInit(), данную функцию можно запустить в любой части программы. Тестовый код.


Все On-фукнции являются обычными функциями, и их, соответственно, можно вызывать, когда угодно. Хоть OnCalculate, хоть OnTradeTransaction.
 
fxsaber:

Все On-фукнции являются обычными функциями, и их, соответственно, можно вызывать, когда угодно. Хоть OnCalculate, хоть OnTradeTransaction.


но в документации то этого не написано

OnInit

Функция OnInit() является обработчиком событияInit. Может иметь типvoidилиint, параметров не имеет:

void OnInit();

Событие Init генерируется сразу после загрузки эксперта или индикатора, для скриптов это событие не генерируется. Функция OnInit() используется для инициализации. Если OnInit() имеет возвращаемое значение типа int, то ненулевой код возврата означает неудачную инициализацию и генерирует событиеDeinitс кодом причины деинициализацииREASON_INITFAILED.

Для оптимизации входных параметров эксперта рекомендуется в качестве кода возврата использовать значения из перечисленияENUM_INIT_RETCODE. Эти значения предназначены для организации управления ходом оптимизации, в том числе для выбора наиболее подходящихагентов тестирования. Прямо при инициализации эксперта еще до запуска самого тестирования можно запросить информацию о конфигурации и ресурсах агента (количество ядер, объем свободной памяти и т.д.) с помощью функцииTerminalInfoInteger(). И на основе полученной информации либо разрешить использовать данный агент тестирования, либо отказаться от него при оптимизации данного эксперта.

ENUM_INIT_RETCODE

Идентификатор

Описание

INIT_SUCCEEDED

Инициализация прошла успешно, тестирование эксперта можно продолжать.

Этот код означает то же самое, что и нулевое значение – инициализация эксперта в тестере прошла успешно.

INIT_FAILED

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

Возврат этого значения означает то же самое, что и возврат значения, отличного от нуля – инициализация эксперта в тестере прошла неудачно.

INIT_PARAMETERS_INCORRECT

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

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

При получении этого значения тестер стратегий гарантированно не будет передавать данное задание другим агентам для повторного выполнения.

INIT_AGENT_NOT_SUITABLE

Ошибок в работе программы при инициализации не возникло, но по каким-то причинам данный агент не подходит для проведения тестирования. Например, недостаточно оперативной памяти, нетподдержки OpenCLи так далее.

После возврата этого кода агент больше не будет получать заданий до самого концаданной оптимизации.

Функция OnInit() типа void всегда означает удачную инициализацию.

Документация по MQL5: Программы MQL5 / События клиентского терминала
Документация по MQL5: Программы MQL5 / События клиентского терминала
  • www.mql5.com
Программы MQL5 / События клиентского терминала - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
когда на выходных пишу код в OnInit вставляю OnTick. И все отлично получаю, даже если нет поступления новых тиков 
 
Sergey Gritsay:


но в документации то этого не написано

OnInit

Функция OnInit() является обработчиком событияInit. Может иметь типvoidилиint, параметров не имеет:

void OnInit();

Событие Init генерируется сразу после загрузки эксперта или индикатора

Написано же, что это функция.

До OnInit и после OnDeinit еще идут вызовы конструкторов/деструкторов глобальных объектов (неточность в Справке). Поэтому, например, в индикаторах можно объявлять индикаторные буферы без OnInit. Рудименты такие.

 
Поиск FullOnCalculate ведет сразу не множество совсем не документированных особенностей работы с индикаторными буферами в MT4/MT5 - местами отличаются серьезно.
 
Вот моё окончательное видение решение проблемы:
iCustom(... inputs, PRICE_CLOSE,
         color &colors[], int &widths[], int &styles[] );

iAlligator(... params, PRICE_CLOSE,
         color &colors[], int &widths[], int &styles[] );
Допустим, индикатор имеет такие параметры:
#property indicator_plots 5
#property indicator_color1 clrAquamarine, clrBeige, clrBurlyWood
#property indicator_color2 clrRed, clrGreen

#property indicator_color5 clrGold, clrCrimson, clrCadetBlue
то массив цветов для него будет таким:
color colors[] = {
   clrAquamarine, clrBeige, clrBurlyWood,  // 1 plot
   clrRed, clrGreen,                       // 2 plot
   clrBlack,                               // 3 plot
   clrWhite,                               // 4 plot
   clrGold, clrCrimson, clrCadetBlue,      // 5 plot
   clrBurlyWood, clrBlue                   // ignore
};

Если массив меньше, то передается только часть цветов. Если массив больше, то он обрезается.

Для массивов ширины и стилей принцип тот же.‌

 
fxsaber:

В OrderSendSync вызывается перегруженная (см. выше) HistoryDealSelect.

Каким образом можно определить время открытия последней позиции, время закрытия последней позиции?

Да и вообще, хотелось бы знать общие принципы и алгоритмы получения информации по открытым/закрытым позициям на mql5‌.

Что необходимо учитывать, какие особенности существуют на данный момент?

 
Artyom Trishkin:

Каким образом можно определить время открытия последней позиции, время закрытия последней позиции?

Да и вообще, хотелось бы знать общие принципы и алгоритмы получения информации по открытым/закрытым позициям на mql5‌.

Что необходимо учитывать, какие особенности существуют на данный момент?


Всё это определяется  выбором истории ордеров и сделок и последующим чтением свойств ордеров.

bool  HistorySelectByPosition( 
   long   position_id     // идентификатор позиции - POSITION_IDENTIFIER 
   );

POSITION_IDENTIFIER

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

 

Идентификатор позиции указывается в каждом ордере (ORDER_POSITION_ID) и сделке (DEAL_POSITION_ID), которая ее открыла, изменила или закрыла. Используйте это свойство для поиска ордеров и сделок, связанных с позицией.

 

При развороте позиции в режиме неттинга (единой сделкой in/out) идентификатор позиции POSITION_IDENTIFIER не изменяется. Однако при этом POSITION_TICKET изменяется на тикет ордера, в результате которого произошел разворот. В режиме хеджинга разворот позиции не предусмотрен.

long


‌И используя свойства из перечисления ENUM_DEAL_ENTRY

DEAL_ENTRY_IN

Вход в рынок

DEAL_ENTRY_OUT

Выход из рынка

DEAL_ENTRY_INOUT

Разворот

DEAL_ENTRY_OUT_BY

Закрытие встречной позицией

Причина обращения: