Ошибки, баги, вопросы - страница 590

 
Swan:

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

В дальнейшем пересчитывается пара значений - должно ж фсё лятать :)

 Не стоит забывать, что программисты - это ещё и человеки, которые любят в свободное от программирования время попрыгать по таймфреймам вручную. А каждый новый ТФ - это очередная деинициализация-инициализация всей анатомии индикатора, все расчёты будут происходить по новой. Поэтому и ArrayInitialize() будет срабатывать всякий раз при очередном перескакивании с ТФ на ТФ. Если индикатор сложный с несколькими буферами, нуждающимися в переинициализации, то задерки будут накапливаться нещадно, а уж про перерасход выделяемой автоматически памяти вообще молчу. 

 До чего ж я наивный товарищ!.. Ведь всё время нахожусь в уверенности, что достаточно провести инициализацию в OnInit() и отмучиться с ней на этом этапе, погрузившись с головой в OnCalculate() в более насущные задачи. Ан нет, дудки мне. Кстати, в целом более-менее успешное написание сложных индикаторов так и не дало мне чёткого понимания, почему ArrayInitialize() надо содержать именно в OnCalculate(), проверяя на каждом тике, а не отделаться первичной и единственной инициализацией в OnInit(). Опытным путём я лишь нашёл случаи, когда отказ от этого варианта тут же вскрывал проблемы, но об этом чуть позже. А пока замечу, что с точки зрения простой и очевидной человеческой логики (а не логики кода) весьма крамольно выглядит ArrayInitialize() в OnCalculate(), учитывая то обстоятельство, что мне ни разу не попадались случаи, где

if(prev_calculated<7) // или < чего-то там...
срабатывал бы более одного раза - при первичном запуске. То есть новые фракталы появляются, а условие молчит. Так какого Лешего оно делает в OnCalculate()?!

 

 Ещё более наивен я в своей уверенности, что 

handle=iFractals(_Symbol,_Period);

якобы обязан автоматически унаследовать те самые clean up'ы arrays, а также эффект работы экономного алгоритма из исходного Fractals.mq5, который там тоже есть, но немного в другом виде. Но - опять и снова дудки!! Пришлось самому думать дважды и раздувать собственный код копипастой из того индикатора, чей хэндл я задействую. Я помню, как впервые принялся изучать код индикаторов и выпал в осадок, когда при сравнении Fractals.mq5 и примера iFractals из справки с недоумением обнаружил, что второй код больше первого (даже после предельного сокращения). Не знаю. Закидайте меня шапками, но вообще-то программисты на то и рассчитывают, чтобы что-то подключать в свой код одной строой, ссылающейся на целую библиотеку, класс ли там ещё что-либо объёмное, а здесь...

 Теперь раскрою суть проблемы, о которой упомянул ранее. Прикрепляю упрощённый до верхних фракталов код индикатора iFractals. В исходном примере буфер заполняется на всю историю. Изменим ситуацию - скопируем лишь часть истории. Закомментируем присвоение на первом расчёте копируемых значений и зададим своё значение поменьше:

values_to_copy=100; // то же, что amount
Теперь попрыгаем по таймфреймам и ужаснёмся появившимся фрактальным артефактам. Я не придумал ничего лучше, кроме как скопипастить автоматически неунаследовавшийся блок кода clean up arrays из Fractals.mq5 с целью очистки от мусора той части истории, на которой фракталы не нужны:
   if(bars_calculated<7)
   {
      ArrayInitialize(FractalUpBuffer,EMPTY_VALUE);
      Print("the condition is true; ArraySize(FractalUpBuffer)=",ArraySize(FractalUpBuffer));
   }
Теперь всё (с большим избытком!!) прекрасно чистится, а заодно Print() показывает, когда и сколько раз сработает переинициализация плюс отображает размер буфера. Убеждаемся, что размерчик далеко не 100, а значительно больше. Если мне нужно протереть пыль со стола, я протираю пыль со стола, а не делаю уборку всей квартиры. Или фишка в том, чтобы меня любой ценой переубедить, что перерасход памяти и времени - это пустяк, можно найти способ решить задачу косвенно и не обращать внимания на вопиющее пожирание ресурсов, не зависящее от моих рук?


 

Swan:

Один фих, какой-то размер надо будет задать.. Зачем делать кривой цикл с другими границами, когда можно прямой с теми же)

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

 Честное слово, не хотел грузить, но заранее понимал, что сочувствующие пойдут по пути раскопки всего кода. Это как в анекдоте про Чапая и Петьку, когда Василий Иваныч вернулся, спросил лопату - она оказалась сломана - коня хоронили - на деревню напали белые, пока Чапая не было. Осознавая, что желающих углубляться в навороты чужого кода скорее всего не появится, могу лишь, без дальнейшего прогруза, сослаться на результат работы индикатора, который в итоге и получится (не считая тормозов и прчих недочётов): https://www.mql5.com/ru/forum/1111/page577#comment_119227. А теперь подумайте и скажите, стоит ли полагать, что там всё просто и предлагать кажущиеся очевидными решения?

 Я не зря упрощаю и ограничиваю код перед тем как что-то спросить по какой-либо конкретной части. Поэтому и прошу ограничиться именно этим, а не всего коня эксгумировать, если только не найдётся любитель...

 Вообще, четвёртый - особый - буфер в принципе выходит длинее первых трёх (равных между собой по длине), а за счёт SetIndexBuffer() он растягивается вообще на всю историю! Если границы цикла расширить под четвёртый буфер и заодно ресайзить до него же первые три массива, то как минимум увеличится прочёс в цикле количества элементов, что увеличит расчётное время на прочёс совершенно левого сегмента элементов буферов. Это лишь верхушка айсберга с проблемами, которая всплывёт при таком варианте алгоритма. Ну и плюсом ко всему увеличится время переиницализации других буферов, поскольку их размер стал больше. Четвёртый спецмассив нельзя явно заполнять EMPTY_VALUE в else, так как в индикаторе идёт жесточайшая перестановка фракталов от чужих таймфреймов по определённому алгоритму, где нет соответствия индексам между первой тройкой буферов и четвёртого буфера...

Swan:

//а значения EMPTY_VALUE присваивается 0 и 1 элементу массивов, мм.. и на последних трёх барах)

 Как так? Почему не всему? Вот этого не понял. Объясните? Вообще, речь не о присвоении лишь актуальных (эффективных) значений, а о неизбежном прочёсывании всего буфера. ArrayInitialize(), как и многие другие функции работы с массивами, основаны на цикле, неявном для конечных MQL-программистов.

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

 P.S.: похоже, я догадываюсь, почему ArrayInitialize() в OnInit() не является здесь эффективным. Буферы динамические, они меняют размер, а в OnInit() они инициализируются значениями лишь однажды и на текущую длину, будучи ещё не зная действительных размеров буферов в OnCalculate().

Файлы:
cleanup.mq5  2 kb
 
papaklass:

Не работает индикатор в визуализаторе:

 

В терминале в он-лайне работает нормально:

 

Вы бы привели какие-нибудь подробности? Каким образом индикатор попал на график визуализатора?
 
papaklass:

В код эксперта вставляю следующие строки

На чистый график вешаю эти три индикатора и сохраняю шаблон под именем эксперта. Картинка он-лайн в моем предыдущем посте.

Запускаю эксперт в визуализаторе. 

 

1. Покажите сохранённый шаблон 

2. Попробуйте прогнать визуализацию без шаблона (то есть предварительно удалите соответствующий tpl-файл). В последнем, 555 билде автоматически добавляемые кастомные индикаторы должны правильно отображаться.

 
papaklass:

Все работает. Спасибо.

Удалил шаблон. В эксперте в OnInit() прописал:

 

Свой шаблон покажите. Индикатор должен и с шаблоном нормально отображаться (то есть, проблема существует, и она должна быть решена)
 
papaklass:

Высылаю файл *.tpl

Сейчас опять попробовал с шаблоном - не работает. Удаляю шаблон - работает. 

Спасибо. Будем разбираться.
 

x100intraday:

А теперь подумайте и скажите, стоит ли полагать, что там всё просто и предлагать кажущиеся очевидными решения?

фсё гениальное - просто.

Остальное не осилил. Анекдот про вопрос на форуме, как удалить гланды напоминает :)

Пример imho православного индикатора фракталз лимитед. может таки поможет..

//+------------------------------------------------------------------+
//|                                                     Fractals.mq5 |
//+------------------------------------------------------------------+
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_ARROW
#property indicator_type2   DRAW_ARROW
#property indicator_color1  clrGray
#property indicator_color2  clrGray
#property indicator_label1  "Fractal Up"
#property indicator_label2  "Fractal Down"
//--- input parameters
input int BarsCount=100;
//---- indicator buffers
double ExtUpperBuffer[];
double ExtLowerBuffer[];
//--- 10 pixels upper from high price
int    ExtArrowShift=-10;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtUpperBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtLowerBuffer,INDICATOR_DATA);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_ARROW,217);
   PlotIndexSetInteger(1,PLOT_ARROW,218);
//---- arrow shifts when drawing
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,ExtArrowShift);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-ExtArrowShift);
//---- sets drawing line empty value--
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//---- initialization done
  }
//+------------------------------------------------------------------+
//|  Fractals                                                        |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,
                const datetime &Time[],
                const double &Open[],
                const double &High[],
                const double &Low[],
                const double &Close[],
                const long &TickVolume[],
                const long &Volume[],
                const int &Spread[])
  {
   int i,limit;
//---
   if(rates_total<5) return(0);
//---
   if(prev_calculated<7)
     {
      limit=2;
      if(rates_total-2>BarsCount) limit=rates_total-BarsCount;
      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,limit);//отрисовываются и расчитываются только значения на последних BarsCount барах
      PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,limit);

      for(i=rates_total-2;i<rates_total;i++)//Последним двум барам присваивается EMPTY_VALUE. Исправил циферку в соответствии с iFractal(там фрактал может быть на 2ом баре)
         {
         ExtUpperBuffer[i]=EMPTY_VALUE;
         ExtLowerBuffer[i]=EMPTY_VALUE;
         }
     }
   else
      {
      limit=prev_calculated-3;//Здесь от prev_calculated правильнее считать..
      
      //---Добавленным с появлением нового бара элементам массивов присваиваем значение EMPTY_VALUE//Возможно всё будет нормально и без этого.
      if(rates_total>prev_calculated)
         {
         for(i=prev_calculated;i<rates_total;i++)
            {
            ExtUpperBuffer[i]=EMPTY_VALUE;
            ExtLowerBuffer[i]=EMPTY_VALUE;
            }
         }
      //---
      }
//---
   for(i=limit;i<rates_total-2 && !IsStopped();i++)//Исправил циферку
     {
      //---- Upper Fractal
      if(High[i]>High[i+1] && High[i]>High[i+2] && High[i]>=High[i-1] && High[i]>=High[i-2])
         ExtUpperBuffer[i]=High[i];
      else ExtUpperBuffer[i]=EMPTY_VALUE;
      //---- Lower Fractal
      if(Low[i]<Low[i+1] && Low[i]<Low[i+2] && Low[i]<=Low[i-1] && Low[i]<=Low[i-2])
         ExtLowerBuffer[i]=Low[i];
      else ExtLowerBuffer[i]=EMPTY_VALUE;
     }
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+
Fractals
Fractals
  • голосов: 8
  • 2010.01.26
  • MetaQuotes Software Corp.
  • www.mql5.com
Фракталы (Fractals) — это один из пяти индикаторов торговой системы Билла Вильямса, позволяющий обнаруживать дно или вершину.
 
Swan:

фсё гениальное - просто.

Остальное не осилил. Анекдот про вопрос на форуме, как удалить гланды напоминает :)

Пример imho православного индикатора фракталз лимитед. может таки поможет..

 Вообще-то, я пишу индикатор через хэндл... но идея отказа от ArrayInitialize() в пользу явного ручного заполнения значениями EMPTY_VALUE мне понравилась. Спасибо, попробую на этом заварить новую кашу, которую потом, надеюсь, расхлёбывать не придётся. Хотя и здесь будут свои тонкости и неудобства, их заранее предвижу... но да ладно.
 

Следующий код:

struct Pos
{
   int x;
   int y;
};

class Test
{
public:
   Test(const Pos& other)
      : pos(other)
   {
      Print("other = {", other.x, ", ", other.y, "}");
      Print("pos = {", pos.x, ", ", pos.y, "}");
   }
   
public:
   Pos pos;
};

int OnInit()
{
   Pos pos = {123, 456};
   Test test(pos);
   
   return(0);
}

Выдает:

2011.12.05 22:01:28    RectLabel (EURUSD,H1)    pos = {12, 176314750}
2011.12.05 22:01:28    RectLabel (EURUSD,H1)    other = {123, 456}

То бишь список инициализации не отработал, в структуре мусор. Это бага или нельзя?

 

Отключил двух агентов от облака, а они все равно каждые 30 секунд коннектятся к облачным серверам.

MO    0    Network    00:00:17    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
LK    0    Network    00:00:47    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
RG    0    Network    00:01:17    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
NS    0    Network    00:01:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
RO    0    Network    00:02:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
OK    0    Network    00:02:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
MG    0    Network    00:03:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
DR    0    Network    00:03:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
DN    0    Network    00:04:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
EJ    0    Network    00:04:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
GF    0    Network    00:05:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
RR    0    Network    00:05:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
NN    0    Network    00:06:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
KJ    0    Network    00:06:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
QF    0    Network    00:07:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
HQ    0    Network    00:07:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
PM    0    Network    00:08:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
QI    0    Network    00:08:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
KE    0    Network    00:09:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
NQ    0    Network    00:09:51    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
OM    0    Network    00:10:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
RI    0    Network    00:10:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
LE    0    Network    00:11:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
EP    0    Network    00:11:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
IL    0    Network    00:12:18    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
HH    0    Network    00:12:48    connected to 2.agents.mql5.com (through a proxy server 192.168.0. )
FD    0    Network    00:13:18    connected to 2.agents.mql5.com (through a proxy server

 
Konstantin83:

Отключил двух агентов от облака, а они все равно каждые 30 секунд коннектятся к облачным серверам.

Давайте в сервисдеск. 

Уточните пожалуйста, каким именно образом отключили? Удалили (застопили) сервисы? Приложите логи проблемных агентов.

Несколько странные настройки прокси в логах. Вы настройки прокси в конфигах агентов прописывали? Приложите, пожалуйста, в заявке common.ini вашего менеджера агентов.

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