Обсуждение статьи "Знакомство с MQL5: написание простого советника и индикатора" - страница 2

 
Rosh:

Для индикаторных буферов говорится SetIndexBuffer:

Для советников должно быть аналогично, проверьте

Аналогии пока не получается. При проверке вот такого кода

//+------------------------------------------------------------------+
//|                                                      Test002.mq5 |
//+------------------------------------------------------------------+
double high[];
int bars;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   bars=Bars(Symbol(),PERIOD_CURRENT);
   ArraySetAsSeries(high,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int copied=CopyHigh(Symbol(),0,0,bars,high);
   return;
  }
//+------------------------------------------------------------------+

 поставил точку останова напротив оператора return. Отладчик выдаёт следующий результат: high "dynamic array[8563], S". Как я понимаю, S означает "Series".

 
Yedelkin:

 

Аналогии пока не получается. При проверке вот такого кода

 поставил точку останова напротив оператора return. Отладчик выдаёт следующий результат: high "dynamic array[8563], S". Как я понимаю, S означает "Series".

Почему же не получается. Если сомневаетесь, поставьте явную проверку на серийность функцией ArrayGetAsSeries:

//+------------------------------------------------------------------+
//|                                        Test_ArraySetAsSeries.mq5 |
//|              Copyright Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
double high[];
int bars;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   bars=Bars(Symbol(),PERIOD_CURRENT);
   ArraySetAsSeries(high,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int copied=CopyHigh(Symbol(),0,0,bars,high);
   bool IsSeries=ArrayGetAsSeries(high);
   return;
  }
//+------------------------------------------------------------------+

Результат


 
Rosh писал(а)  :

Почему же не получается. Если сомневаетесь, поставьте явную проверку на серийность функцией ArrayGetAsSeries:

Напомню, о чём речь. Я спрашивал, следует ли всегда индексировать массивы только после их копирования. Вы сослались на примечание к функции  SetIndexBuffer, и сказали, что для советников должно быть аналогично. Из этого примечания к функции  SetIndexBuffer следует, что "после связывания динамический массив buffer[]  будет иметь индексацию как в обычных массивах, даже если для связываемого массива будет предварительно установлена индексация как в таймсериях".

 Соответственно, аналогию для советников я усмотрел в том, что после использования функций CopyTime, CopyHigh и CopyLow прнимающие массивы также должны будут иметь индексацию, как в обычных массивах. Для проверки данной аналогии я разместил функцию ArraySetAsSeries перед функцией CopyHigh, в функции OnInit(). Но мой пример и предложенная Вами явная проверка на серийность функцией ArrayGetAsSeries показывают, что после использования функции CopyHigh предварительно установленная индексация (как в таймсериях) у принимающего массива high[] не изменилась. Это, в свою очередь, говорит о том, что упомянутая Вами аналогия с функцией  SetIndexBuffer пока не наблюдается, так как в противном случае явная проверка на серийность должна была показать, что IsSeries=false.

 

Yedelkin:

Для проверки данной аналогии я разместил функцию ArraySetAsSeries перед функцией CopyHigh, в функции OnInit(). Но мой пример и предложенная Вами явная проверка на серийность функцией ArrayGetAsSeries показывают, что после использования функции CopyHigh предварительно установленная индексация (как в таймсериях) у принимающего массива high[] не изменилась.

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

Полагаю, что мы пришли к согласию в этом вопросе и можно считать его исчерпанным.

 

Да, вопрос исчерпан. Благодарю за разъяснение!

 

Несколько вопросов.

1.

   if(CopyTime(Symbol(),0,0,i,t)<i || CopyHigh(Symbol(),0,0,i,h)<i || CopyLow(Symbol(),0,0,i,l)<i)
     {
      Print("Не удалось скопировать таймсерию!");
      return;
     }

Сказано что “В операторе if  …  при помощи оператора return происходит завершение выполнения функции OnTick.”

Разве OnTick ?, а не из if (….) {...}?

2. 

   for(i=0;i<PositionsTotal();i++) {…}

В MQL4 рекомендовали обратный перебор.

for(i= PositionsTotal();i>0;i--) {…}
как лучше ?

 

3. Скачал советник и индикатор (для модераторов Opera 10.54 проблемы со скачиванием прикрепленных файлов). Все откомпилировал. Запустил в тестере на M5 выбрав последний месяц.

Log

2010.05.15 13:16:02   Core 1 Disconnected

2010.05.15 13:16:01   Core 1 Log file "D:\MetaTrader 5\Tester\Agent-127.0.0.1-3000\logs\20100515.log" written

2010.05.15 13:16:01   Core 1 EURUSD,M5: 553908 ticks (2580 bars) generated within 1431016 ms (total bars in history 100352)

2010.05.15 13:16:01   Core 1 OnTester result 0

2010.05.15 12:52:13   Core 1 EURUSD,Daily: history begins from 2009.01.02 00:00

2010.05.15 12:52:13   Core 1 EURUSD,Daily: history cache reserved for estimated 355 bars

2010.05.15 12:52:13   Core 1 EURUSD: contains 484483 M1 records of beginning data from 2009.01.02 06:01 to 2010.05.03 00:00

2010.05.15 12:52:10   Core 1   Lots=0.100000

2010.05.15 12:52:10   Core 1   MAper=240

2010.05.15 12:52:10   Core 1   EndHour=19

2010.05.15 12:52:10   Core 1   StartHour=7

2010.05.15 12:52:10   Core 1 EURUSD,M5: testing of Experts\expert.ex5 from 2010.05.01 00:00 to 2010.05.14 00:00 started with inputs:

 

Уж очень он долго выполнялся и ни открыл, ни одной сделки. Авто торговля разрешена. В логе никаких сообщений ((( (правка наверное я еще не умею их находить). Индикатор и эксперт лежат вроде там где и положено. Windows XP, MT (build 274).

 

4. Попробовал режим отладки, он не идет. Наверное, из-за субботы. Нет котировок. Точку остановки делал также как и в статье. Если я прав жаль, получается, отлаживать можно только в рабочий день. Было бы неплохо для отладки иметь возможность подсовывать свой файл, с нужными данными и (или) с какими ни будь типовыми (пусть это будет кусок истории за какой то день), для отладки будет достаточно.

 

5. если кто то исследовал функции Copy… поделитесь информацией как она работает если есть пропущенные бары. Хотя наверное лучше будет заказать статью.

 
Prival:

Несколько вопросов.

1. Сказано что “В операторе if  …  при помощи оператора return происходит завершение выполнения функции OnTick.”

Разве OnTick ?, а не из if (….) {...}?

Из описания оператора возврата return:

Оператор return прекращает выполнение текущей функции и возвращает управление 
вызвавшей программе. Результат вычисления выражения возвращается вызываемой 
функции. Выражение может содержать оператор присваивания.

 Текущая функция для оператора return в данном примере - функция OnTick().

 

Prival:

4. Попробовал режим отладки, он не идет. Наверное, из-за субботы. Нет котировок. Точку остановки делал также как и в статье. Если я прав жаль, получается, отлаживать можно только в рабочий день. Было бы неплохо для отладки иметь возможность подсовывать свой файл, с нужными данными и (или) с какими ни будь типовыми (пусть это будет кусок истории за какой то день), для отладки будет достаточно.

На сайте уже обсуждались подобные вопросы насчёт отладки. Если интересно, воспользуйтесь поиском и поисковым словом "Отладка". 

 

После загрузки автоматического обновления (билд 275) компилятор начал выдавать предупреждения на строках, в которых проверяются условия типа

if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
Предупреждения однотипные:
implicit enum conversion Perito02-04temp3.mq5 1233 45
Вопросы: предполагает ли корректная работа компилятора появление данных предупреждений в указанной ситуации? О какой "конверсии" идёт речь?
 
Yedelkin :

После загрузки автоматического обновления (билд 275) компилятор начал выдавать предупреждения на строках, в которых проверяются условия типа

Предупреждения однотипные: Вопросы: предполагает ли корректная работа компилятора появление данных предупреждений в указанной ситуации? О какой "конверсии" идёт речь?

 

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

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

 
Prival:

Несколько вопросов.

1. Сказано что “В операторе if  …  при помощи оператора return происходит завершение выполнения функции OnTick.”

Разве OnTick ?, а не из if (….) {...}?

Если в операторе

if(CopyTime(Symbol(),0,0,i,t)<i || CopyHigh(Symbol(),0,0,i,h)<i || CopyLow(Symbol(),0,0,i,l)<i)

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

 

2.  В MQL4 рекомендовали обратный перебор.

как лучше ?

Варианты

for(i=0;i<PositionsTotal();i++)

и

for(i=PositionsTotal()-1;i>=0;i--)

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

 

3. Скачал советник и индикатор (для модераторов Opera 10.54 проблемы со скачиванием прикрепленных файлов). Все откомпилировал. Запустил в тестере на M5 выбрав последний месяц.

Уж очень он долго выполнялся и ни открыл, ни одной сделки. Авто торговля разрешена. В логе никаких сообщений ((( (правка наверное я еще не умею их находить). Индикатор и эксперт лежат вроде там где и положено. Windows XP, MT (build 274).

 

4. Попробовал режим отладки, он не идет. Наверное, из-за субботы. Нет котировок. Точку остановки делал также как и в статье. Если я прав жаль, получается, отлаживать можно только в рабочий день. Было бы неплохо для отладки иметь возможность подсовывать свой файл, с нужными данными и (или) с какими ни будь типовыми (пусть это будет кусок истории за какой то день), для отладки будет достаточно.

 

5. если кто то исследовал функции Copy… поделитесь информацией как она работает если есть пропущенные бары. Хотя наверное лучше будет заказать статью.

Честно говоря, и у меня тестер не очень хорошо работает: тестирование происходит значительно дольше, чем тестирование подобного советника на MQL4; сделки открываются только в первые один-два дня интервала тестирования (это наблюдается при тестировании разных севетников).

Функции OnTick и OnCalculate запускаются при поступлении новой котировки, поэтому для их отладки необходимо поступление котировок (в выходной день не будет работать). В остальном отладчик работает нормально (пробуйте, если что - спрашивайте).

 

По поводу массивов-таймсерий: - направление массивов можно менять в любое время в обе стороны, при этом расположение массивов в памяти не меняется, меняется только индексация (с 0,1,2,...,последний на  последний,...,2,1,0)

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