Новая статья: Типичные ошибки в программах на MQL4 и методы их устранения - страница 2

 
Contender:


В качестве эксперимента добавьте в Print() вывод OrdersTotal()


Привет. Что-то неладно в датском королевстве :) ... Не дается :) ...

Суть ...

При отключенной кнопке "Авто-торговля" загружаем терминал, устанавливается связь, включаем автоторговлю, счетчик в вышеприведенном коде, при наличии одного соответствующего ордера, устанавливается в 1.

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

Логика работы алгоритма зависит именно от нулевого значения счетчика и как "выкрутиться" - ума не приложу :), не то, что руки .... Хелпмиииии

 
dArd:


Привет. Что-то неладно в датском королевстве :) ... Не дается :) ...

Суть ...

При отключенной кнопке "Авто-торговля" загружаем терминал, устанавливается связь, включаем автоторговлю, счетчик в вышеприведенном коде, при наличии одного соответствующего ордера, устанавливается в 1.

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

Логика работы алгоритма зависит именно от нулевого значения счетчика и как "выкрутиться" - ума не приложу :), не то, что руки .... Хелпмиииии

Сначала попробуй обезжирить проверку ордеров на свой\чужой, убери из кода && OrderComment() == МеткаОрдера

А потом попробуй вызывать OrderStatus() из OnInit()

Хотя это уже лишнее. Я подозреваю что тут проблема в комментарии ордера.

Можно сразу после if(OrderSelect(...)) поставить принт с символом и комментарием ордера, тогда будет сразу понятна причина не увеличения переменных глобального уровня.

 
dArd:


Привет. Что-то неладно в датском королевстве :) ... Не дается :) ...

Суть ...

При отключенной кнопке "Авто-торговля" загружаем терминал, устанавливается связь, включаем автоторговлю, счетчик в вышеприведенном коде, при наличии одного соответствующего ордера, устанавливается в 1.

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

Логика работы алгоритма зависит именно от нулевого значения счетчика и как "выкрутиться" - ума не приложу :), не то, что руки .... Хелпмиииии


Выставить некий маячок: отложку очень далеко от цены. Если при сканировании ордеров "увидел" свой маяк - значит связь есть, и результат подсчета валидный, если нет - ждем-с.

 
AlexeyVik:

Сначала попробуй обезжирить проверку ордеров на свой\чужой, убери из кода && OrderComment() == МеткаОрдера

А потом попробуй вызывать OrderStatus() из OnInit()

Хотя это уже лишнее. Я подозреваю что тут проблема в комментарии ордера.

Можно сразу после if(OrderSelect(...)) поставить принт с символом и комментарием ордера, тогда будет сразу понятна причина не увеличения переменных глобального уровня.


Логика с Метками ордеров работает много лет ... и мне кажется, что это удобнее, чем магики ... поэтому тут ошибка маловероятна ... просто проверено уже все давно.


А вот с инициализацией, все ... чем дальше, тем веселее. :)

Код с Printами.

#property strict

// Входные данные

input string   Метка                   = "Метка Ордеров";   // Метка ордеров
input string   МеткаОрдера             = "11";
      
      int      Buy=0,Sell=0,
               BuyStop=0,SellStop=0;          // Кол-во соответствующих ордеров в рынке
               

//----                           // Г Л А В Н Ы Е    Ф У Н К Ц И И    Э К С П Е Р Т А

//----                                    // Ф У Н К Ц И Я      O N  I N I T ( )
void OnInit()
  {
//---- 
   OrderStatus();
  
  Print("OnInit ",OrderComment()," SellStop=",SellStop);
  
   return;
//----
   } //---- Конец функции OnInit
                                          // Ф У Н К Ц И Я      O N  T I C K ( )
void OnTick()
  {
//----
   //if(Bars<100 || IsTradeAllowed()==false)
      //return;
//----
// Блок управления ордерами
//----
   OrderStatus();
//----
   Comment(SellStop," ",Sell," ",BuyStop," ",Buy);
  
  Print("OnTick ",OrderComment()," SellStop=",SellStop);   

//   Print(SellStop," ",Sell," ",BuyStop," ",Buy);
//----
// Конец блока управления ордерами
//----
   return;
//----
  } // Конец функции OnTick
//----

//+------------------------------------------------------------------+
//| Модуль данных для управления                                     |
//+------------------------------------------------------------------+
void OrderStatus() 
{
//=====
   Buy=0; Sell=0; BuyStop=0; SellStop=0;
//=====
   int total=OrdersTotal();   // if(total<1) return;
//----
  for (int i=0; i<total; i++)
  {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      if (OrderSymbol()==Symbol())
      {
         if (OrderType()==OP_BUY && OrderComment()==МеткаОрдера)
         {
            Buy++;
         } // if         
         if (OrderType()==OP_BUYSTOP && OrderComment()==МеткаОрдера)
         {
            BuyStop++;
         } // if         
         if (OrderType()==OP_SELL && OrderComment()==МеткаОрдера)    
         {
            Sell++;
         } // if
         if (OrderType()==OP_SELLSTOP && OrderComment()==МеткаОрдера)
         {
            SellStop++;
         } // if         
    } // OrderSymbol
  }   // OrderSelect
  
  Print("OrderStatus ",OrderComment()," SellStop=",SellStop);
  
  }   // for
//-----
   return;
//----
} // OrderStatus
//-------

Вариант с работающим Терминалом ... компилируем ... устанавливаем Эксперт и т.п.

Вариант с запуском терминала ...

вывод: OnInit () в этом случае не вызывается? Т.е. инициализации данных не происходит ... ?

 

Как-же ты вытаскиваешь OrderComment() не выбрав ордер??? Я тебе предложил принт после выбора ордера. Это не значит что после закрывающей фигурной скобки, а сразу после выбора ордера...

    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      Print("OrderStatus ",OrderComment()," SellStop=",SellStop);
       if (OrderSymbol()==Symbol())
      {
// и дальше...

А лучше в двух местах

         if (OrderType()==OP_SELLSTOP && OrderComment()==МеткаОрдера)
         {
            SellStop++;
           Print("OrderStatus ",OrderComment()," SellStop=",SellStop);
         } // if    
 
AlexeyVik:

Как-же ты вытаскиваешь OrderComment() не выбрав ордер??? Я тебе предложил принт после выбора ордера. Это не значит что после закрывающей фигурной скобки, а сразу после выбора ордера...



Не зависит состояние счетчика от OrderComment() ... не в этом дело, уверен. Вся суть в том, что при загрузке терминала состояние счетчика, независимо от того, существует соответствующий ордер в рынке или нет, всегда равно 0.

Вводить новые переменные ... для инициализации ... разумно ... не спорю, но в данном случае, все равно необходимо пере присвоение ... поэтому ... результат так или иначе будет 0.

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

Вопрос конкретный :) ... как организовать обработку ордеров, чтобы состояние счетчика всегда выдавало правильный результат - и при работающем терминале и в случае его перезагрузки ...

Ведь в старом терминале - все работало :) ...

 
dArd:


Не зависит состояние счетчика от OrderComment() ... не в этом дело, уверен. Вся суть в том, что при загрузке терминала состояние счетчика, независимо от того, существует соответствующий ордер в рынке или нет, всегда равно 0.

Вводить новые переменные ... для инициализации ... разумно ... не спорю, но в данном случае, все равно необходимо пере присвоение ... поэтому ... результат так или иначе будет 0.

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

Вопрос конкретный :) ... как организовать обработку ордеров, чтобы состояние счетчика всегда выдавало правильный результат - и при работающем терминале и в случае его перезагрузки ...

Ведь в старом терминале - все работало :) ...

int      Buy=0, Sell=0, BuyStop=0, SellStop=0;
/*******************expert initialization function*******************/
int OnInit()
{
//---
   OrderStatus();
   Print("OnInit ",OrderComment()," SellStop=",SellStop);
//---
   return(INIT_SUCCEEDED);
}/*******************************************************************/

/*******************expert initialization function*******************/
void OnTick()
{
   OrderStatus();
   Print("OnTick ", OrderComment(), " SellStop=", SellStop);
   Comment("SellStop = ", SellStop);
}/*******************************************************************/
void OrderStatus() 
{
//=====
   Buy=0; Sell=0; BuyStop=0; SellStop=0;
//=====
   int total=OrdersTotal();   // if(total<1) return;
//----
  for (int i=0; i<total; i++)
  {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      if (OrderSymbol()==Symbol())
      {
         if (OrderType()==OP_BUY /*&& OrderComment()==МеткаОрдера*/)
         {
            Buy++;
         } // if         
         if (OrderType()==OP_BUYSTOP /*&& OrderComment()==МеткаОрдера*/)
         {
            BuyStop++;
         } // if         
         if (OrderType()==OP_SELL /*&& OrderComment()==МеткаОрдера*/)    
         {
            Sell++;
         } // if
         if (OrderType()==OP_SELLSTOP /*&& OrderComment()==МеткаОрдера*/)
         {
            SellStop++;
  Print("OrderStatus ",OrderComment()," SellStop=",SellStop);
         } // if         
    } // OrderSymbol
  }   // OrderSelect
  
  
  }   // for
//-----
   return;
//----
}/*******************************************************************/

Вот лог после первого перезапуска МТ.


19:36:17 Expert EA_Test EURAUD,H1: loaded successfully
Здесь я удалил инициализацию индикаторов
19:36:19 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:36:19 EA_Test EURAUD,H1: OnInit SellStop=1
19:36:19 EA_Test EURAUD,H1: initialized
19:36:20 EA_Test EURAUD,H1: OrderStatus SellStop=1

19:36:20 EA_Test EURAUD,H1: OnTick SellStop=1

А здесь я удалил деинициализацию индикаторов

19:36:22 EA_Test EURAUD,H1: uninit reason 4

Здесь я очень быстро закрыл МТ, так что принт проскочил только один раз... Второй тик не успел появиться...

И вот второй перезапуск МТ


19:44:39 Expert EA_Test EURAUD,H1: loaded successfully
Здесь я удалил инициализацию индикаторов
19:44:41 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:41 EA_Test EURAUD,H1: OnInit SellStop=1
19:44:41 EA_Test EURAUD,H1: initialized
19:44:43 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:43 EA_Test EURAUD,H1: OnTick SellStop=1
19:44:43 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:43 EA_Test EURAUD,H1: OnTick SellStop=1
19:44:45 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:45 EA_Test EURAUD,H1: OnTick SellStop=1
19:44:46 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:46 EA_Test EURAUD,H1: OnTick SellStop=1
А здесь я удалил деинициализацию индикаторов

19:44:46 EA_Test EURAUD,H1: uninit reason 4

А здесь подержал чуток подольше...

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

Вот лог после первого перезапуска МТ.


19:36:17 Expert EA_Test EURAUD,H1: loaded successfully
Здесь я удалил инициализацию индикаторов
19:36:19 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:36:19 EA_Test EURAUD,H1: OnInit SellStop=1
19:36:19 EA_Test EURAUD,H1: initialized
19:36:20 EA_Test EURAUD,H1: OrderStatus SellStop=1

19:36:20 EA_Test EURAUD,H1: OnTick SellStop=1

А здесь я удалил деинициализацию индикаторов

19:36:22 EA_Test EURAUD,H1: uninit reason 4

Здесь я очень быстро закрыл МТ, так что принт проскочил только один раз... Второй тик не успел появиться...

И вот второй перезапуск МТ


19:44:39 Expert EA_Test EURAUD,H1: loaded successfully
Здесь я удалил инициализацию индикаторов
19:44:41 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:41 EA_Test EURAUD,H1: OnInit SellStop=1
19:44:41 EA_Test EURAUD,H1: initialized
19:44:43 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:43 EA_Test EURAUD,H1: OnTick SellStop=1
19:44:43 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:43 EA_Test EURAUD,H1: OnTick SellStop=1
19:44:45 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:45 EA_Test EURAUD,H1: OnTick SellStop=1
19:44:46 EA_Test EURAUD,H1: OrderStatus SellStop=1
19:44:46 EA_Test EURAUD,H1: OnTick SellStop=1
А здесь я удалил деинициализацию индикаторов

19:44:46 EA_Test EURAUD,H1: uninit reason 4

А здесь подержал чуток подольше...

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


В билдах 625 и в 628 все тоже самое ... никакого эффекта ... как был счетчик с нулевым значением, так и остался.

А почему при "первой" загрузке терминала не вызывается OnInit() ?

В общем :), остается один вариант, скомпилировать в старом добром мт4 и работать с exeшным файлом. А про новый забыть как страшный сон :)

 
dArd:


В билдах 625 и в 628 все тоже самое ... никакого эффекта ... как был счетчик с нулевым значением, так и остался.

А почему при "первой" загрузке терминала не вызывается OnInit() ?

В общем :), остается один вариант, скомпилировать в старом добром мт4 и работать с exeшным файлом. А про новый забыть как страшный сон :)

Как не вызывается? Пока время не прошло, я выделил красным фоном принт из инита. Посмотри.

Повторяю... проверь без OrderComment() Мой тест в 625 м билде... Не в билдах причина это точно.

 
AlexeyVik:

Как не вызывается? Пока время не прошло, я выделил красным фоном принт из инита. Посмотри.

Повторяю... проверь без OrderComment() Мой тест в 625 м билде... Не в билдах причина это точно.



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

Мало ли, новый терминал, новые принципы обработки. В общем, проверил.

Я прошу прощения, мне необходимо было сразу явно указать (а не считать - из скриншота видно), что Эксперт устанавливается не на стандартный график МТ4, а на генерируемый жестко структурированный временной ряд,

представляемый визуально в виде стандартных объектов графиков МТ4 (свечи, ...).

Следовало бы сформулировать свой вопрос иначе:

Как организовать обработку ордеров на НЕСТАНДАРТНЫХ ТАЙМФРЕЙМАХ, чтобы производился вызов функции OnInit() при загрузке терминала?

Или, каковы принципы организации нестандартных таймфреймов в новом терминале МТ4, где почитать?

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