глобальная инициализация не удалась!!!!!!! - страница 2

 

Без проблем, angevogeur

Изначально код был таким:

int init()
  {
      // Check for input errors
      if (Use_LT_TimeFrame_Confirmation)
      {
         if (Number_Of_TimeFrames < 1 || Number_Of_TimeFrames > 4)
         {
            Alert("Initialization Error: Number of time frames for timeframe trend confirmation must be between 2 and 4, inclusively.");
         }
         
         if (Number_Of_Periods_For_Trend_Agreement < 2)
         {
            Alert("Initialization Error: Number of time frames for timeframe trend aggreement must be greater than 1.");
         }
      }
      
      IndicatorShortName("White Wolf Custom Software Moving Averages Indicator");
      
//---- indicators
      SetIndexStyle(0,DRAW_LINE);
      SetIndexBuffer(0,EMABuffer1);
      SetIndexStyle(1,DRAW_LINE);
      SetIndexBuffer(1,EMABuffer2);
      SetIndexStyle(2,DRAW_LINE);
      SetIndexBuffer(2,EMABuffer3);
      SetIndexStyle(3,DRAW_LINE);
      SetIndexBuffer(3,SMABuffer);
   
      SetIndexEmptyValue(0,0.0);
      SetIndexEmptyValue(1,0.0);
      SetIndexEmptyValue(2,0.0);
      SetIndexEmptyValue(3,0.0);
//----

      // MA Period Buttons
      MA_Display_Time_Frame = Period(); // Set the trade entry time frame to the current chart period - this ensures that we have a TF for the MA calculations
   
   // Show the timeframe buttons so the user can refine their entry strategy if they wish
 
      ResetLastError();
      Alert("In init() - Calling CreateMAPeriodButtons()");
      CreateMAPeriodButtons();
      if (GetLastError() != 0)
         Alert("GetLasteError() returned " + IntegerToString(GetLastError()));
         
      ResetLastError();
      Alert("In init() - Calling CreateDismissSignalButtons()");
      CreateDismissSignalButtons();
      if (GetLastError() != 0)
         Alert("GetLasteError() returned " + IntegerToString(GetLastError()));
      
      ResetLastError();
      Alert("In init() - Calling SetPeriodButtonState()");
      SetPeriodButtonState();
      if (GetLastError() != 0)
         Alert("GetLasteError() returned " + IntegerToString(GetLastError()));
   
   // Set normalization factor for current currency pair
   if ((Digits == 4) || (Digits == 5))
         NormalizationFactor = 0.0001;
      else
         NormalizationFactor = 0.01;
   
   return(0);
  }

void deinit()
  {
      Alert("In de-init() - getting ready to delete objects ");
      
      ResetLastError();
      ObjectsDeleteAll(0, OBJ_LABEL);
      Alert("In de-init() - attempting to delete labels - GetLastError() returns  " + IntegerToString(GetLastError()));
      
      ResetLastError();
      ObjectsDeleteAll(0, OBJ_BUTTON);
      Alert("In de-init() - attempting to delete buttons - GetLastError() returns  " + IntegerToString(GetLastError()));

return(0);
 }

Я просто изменил его до этого:

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int OnInit()
  {
      // Check for input errors
      if (Use_LT_TimeFrame_Confirmation)
      {
         if (Number_Of_TimeFrames < 1 || Number_Of_TimeFrames > 4)
         {
            Alert("Initialization Error: Number of time frames for timeframe trend confirmation must be between 2 and 4, inclusively.");
         }
         
         if (Number_Of_Periods_For_Trend_Agreement < 2)
         {
            Alert("Initialization Error: Number of time frames for timeframe trend aggreement must be greater than 1.");
         }
      }
      
      IndicatorShortName("White Wolf Custom Software Moving Averages Indicator");
      
//---- indicators
      SetIndexStyle(0,DRAW_LINE);
      SetIndexBuffer(0,EMABuffer1);
      SetIndexStyle(1,DRAW_LINE);
      SetIndexBuffer(1,EMABuffer2);
      SetIndexStyle(2,DRAW_LINE);
      SetIndexBuffer(2,EMABuffer3);
      SetIndexStyle(3,DRAW_LINE);
      SetIndexBuffer(3,SMABuffer);
   
      SetIndexEmptyValue(0,0.0);
      SetIndexEmptyValue(1,0.0);
      SetIndexEmptyValue(2,0.0);
      SetIndexEmptyValue(3,0.0);
//----

      // MA Period Buttons
      MA_Display_Time_Frame = Period(); // Set the trade entry time frame to the current chart period - this ensures that we have a TF for the MA calculations
   
   // Show the timeframe buttons so the user can refine their entry strategy if they wish
 
      ResetLastError();
      Alert("In init() - Calling CreateMAPeriodButtons()");
      CreateMAPeriodButtons();
      if (GetLastError() != 0)
         Alert("GetLasteError() returned " + IntegerToString(GetLastError()));
         
      ResetLastError();
      Alert("In init() - Calling CreateDismissSignalButtons()");
      CreateDismissSignalButtons();
      if (GetLastError() != 0)
         Alert("GetLasteError() returned " + IntegerToString(GetLastError()));
      
      ResetLastError();
      Alert("In init() - Calling SetPeriodButtonState()");
      SetPeriodButtonState();
      if (GetLastError() != 0)
         Alert("GetLasteError() returned " + IntegerToString(GetLastError()));
   
   // Set normalization factor for current currency pair
   if ((Digits == 4) || (Digits == 5))
         NormalizationFactor = 0.0001;
      else
         NormalizationFactor = 0.01;
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
      Alert("In de-init() - getting ready to delete objects ");
      
      ResetLastError();
      ObjectsDeleteAll(0, OBJ_LABEL);
      Alert("In de-init() - attempting to delete labels - GetLastError() returns  " + IntegerToString(GetLastError()));
      
      ResetLastError();
      ObjectsDeleteAll(0, OBJ_BUTTON);
      Alert("In de-init() - attempting to delete buttons - GetLastError() returns  " + IntegerToString(GetLastError()));
  }

Как вы можете видеть, я не менял "мясо" функций. Я просто сделал изменения, необходимые для соответствия новой функциональности. Одна вещь, о которой я все еще немного туманен, это переход от start() к OnStart() или OnTick(), в зависимости от того, что это (я забыл на данный момент, но я все еще использую start() без проблем. Следует отметить, что это пользовательский индикатор. Еще одна вещь, которая меня раздражает, - это ограничения на то, что вы можете использовать в зависимости от того, кодируете ли вы советника, индикатор или скрипт. Есть некоторые вещи, которые имеют смысл (например, запрет на реализацию сделок, если вы не программируете советника), и другие, которые не имеют смысла (например, запрет на использование MessageBox в индикаторе). Еще одна вещь, которая меня очень раздражает, это отсутствие событий для таких вещей, как открытие и закрытие сделок. Это было бы очень полезно для того, что я сейчас создаю.

Пример того, к чему я клоню своим последним утверждением, следующий: Я хочу иметь возможность отображать сигнал на покупку, если выполняются определенные критерии, отображать сигнал на закрытие сделки на покупку, если выполняются определенные критерии, но я также хочу, чтобы мой пользователь мог отменить сигнал на покупку и ждать другого, если он хочет, и то же самое для сигнала на закрытие. Если пользователь решит закрыть сделку, я хочу, чтобы сигналы на покупку и закрытие сделки на покупку исчезли, а индикатор следил за критериями входа для другой сделки. Части отмены работают отлично, но я не могу обнаружить события Open и Close, потому что MQL4 не предоставляет для этого сообщений.

Если вы посмотрите мой профиль, то увидите, что я далеко не начинающий программист. Просто язык не предоставляет всей той функциональности, которую профессионал ожидает и требует от современной платформы разработки. И еще одно замечание: я не могу заставить отладку работать, что является моей основной проблемой. Я следовал документации, но когда я попытался привести отладчик в движение, я получил график, на котором появился диалог свойств для инициализации моего индикатора, но когда я нажал "Окей", чтобы завершить настройку индикатора, график исчез, и на этом все закончилось. Возможно, что-то теряется при переводе с русского на английский, и я что-то упускаю, или, возможно, "пирог" еще не испечен. Как профессионал, я знаю, насколько это грандиозная задача - создать такой язык и среду разработки. Мои замечания носят скорее характер FYI для сотрудников отдела разработки, а не жалоб.

Prof

 
ProfessorMetal:

Без проблем, angevogeur

Изначально код был таким:


Prof

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

Если у вас не объявлены переменные, которые я задаю, а также не объявлены и не проработаны методы, которые я вызываю, это не скомпилируется. Это невозможно. Я ожидал, что вы это знаете. Я опубликовал то, что, как я думал, вы просили - решение, которое устранило мою проблему. В любом случае, если вы работаете с MetaQuotes и пытаетесь понять, что происходит с MetaTrader и исправить это, я опубликовал больше информации ниже. Закомментируйте блок if в init(), объявите MA_Display_Time_Frame глобально как целое число и добавьте эти методы :

void CreateMAPeriodButtons()
  {
//  Alert("In CreateMAPeriodButtons()");
      int X_Distance = 10;
      int Y_Distance = 20;
      // Create MA Period Label
      ObjectCreate("MAPeriodLabel", OBJ_LABEL, 0, 0, 0);
      ObjectSet("MAPeriodLabel", OBJPROP_CORNER, CORNER_RIGHT_UPPER);
      ObjectSet("MAPeriodLabel", OBJPROP_XDISTANCE, X_Distance);
      ObjectSet("MAPeriodLabel", OBJPROP_YDISTANCE, Y_Distance);
      ObjectSetText("MAPeriodLabel", "MA Display Period", 12, "Arial", clrYellow);
      
      // Create Period Buttons
      CreateButton("M1", "M1", 1, 140, 50, 100, 20, "Arial", 12, clrYellow, clrGray);
}

void CreateDismissSignalButtons()
  {
      int X_Distance = 25;
      int Y_Distance = 100;
      
      // Create Dismiss Label
      ObjectCreate("DismissSignalsLabel", OBJ_LABEL, 0, 0, 0);
      ObjectSet("DismissSignalsLabel", OBJPROP_CORNER, CORNER_RIGHT_LOWER);
      ObjectSet("DismissSignalsLabel", OBJPROP_XDISTANCE, X_Distance);
      ObjectSet("DismissSignalsLabel", OBJPROP_YDISTANCE, Y_Distance);
      ObjectSetText("DismissSignalsLabel", "Dismiss Trade Signals", 12, "Arial", clrYellow);
      
      // Create Dismiss Buttons
      
      CreateButton("DismissBuySignal", "Dismiss Buy Signal", CORNER_RIGHT_LOWER, 200, 95, 190, 20, "Arial", 12, clrYellow, clrGray);
}

void CreateButton(string strButtonName, string strButtonText, const int nCorner, const int nXpos, const int nYpos, int nWidth, int nHeight, string strFont, 
                    int nFontSize, int nFontColor, int nBackColor, bool bSelected = false)
  {      
      ObjectCreate(0, strButtonName, OBJ_BUTTON, 0, 0, 0);

      //--- set button coordinates
      
      ObjectSetInteger(0, strButtonName, OBJPROP_CORNER, nCorner);

      ObjectSetInteger(0, strButtonName, OBJPROP_XDISTANCE, nXpos);

      ObjectSetInteger(0, strButtonName, OBJPROP_YDISTANCE, nYpos);
 
      //--- set button size
      ObjectSet(strButtonName, OBJPROP_XSIZE, nWidth);
     
      ObjectSet(strButtonName, OBJPROP_YSIZE, nHeight);

      //--- set the chart's corner, relative to which point coordinates are defined
      
      ObjectSet(strButtonName, OBJPROP_CORNER, nCorner);

      //--- set the text
      
      ObjectSetString(0, strButtonName, OBJPROP_TEXT, strButtonText);
      ObjectSetString(0, strButtonName, OBJPROP_FONT, strFont);
      ObjectSetInteger(0, strButtonName, OBJPROP_FONTSIZE, nFontSize);
      ObjectSetInteger(0, strButtonName, OBJPROP_COLOR, nFontColor);

      //--- set background color
      
      ObjectSetInteger(0, strButtonName, OBJPROP_BGCOLOR, nBackColor);
      
      return;
  }

Поскольку это коммерческий продукт, это далеко не весь код индикатора, но он должен скомпилироваться и потенциально вызвать проблему при использовании оригинальных методов init() и deinit(). Этого достаточно для создания пары меток и кнопок. Как отметил один из авторов, сбой был периодическим. Однако он был связан с любым действием, которое могло вызвать деинициализацию индикатора, например, изменение свойств индикатора, смена таймфреймов или остановка и перезапуск терминала. Если вы хотите проверить изменение свойств, добавьте эти экстерны в глобальные файлы:

extern int               Number_Of_TimeFrames = 2;
extern int               Number_Of_Periods_For_Trend_Agreement = 25;
extern bool             Allow_Modify_Entry_Timeframe = true;

Если вы добавите внешние компоненты, нет необходимости комментировать блок if, который ссылается на них. Этого должно быть достаточно, чтобы вы смогли скомпилировать программу и попытаться воспроизвести проблему. Проблема не возникала с тех пор, как я изменил старые функции инициализации и деинициализации и перешел на новые версии. Если вам понадобится что-то еще, дайте мне знать. Я буду следить за этой темой.

 

У меня была похожая ситуация, инди работал нормально при падении на график.

Он работал нормально после изменения параметров, он работал нормально после сдвига Tf.

После закрытия MT4 и перезапуска, инди не появился.

Он был в списке индикаторов на графике, но не работал.

После открытия окна параметров и нажатия кнопки OK, indi сразу же исчез из списка.

Я перепробовал все уловки, включая описанные в постах выше, ничего не помогло.

Оказалось, что это проблема деления на 0!

Простое условие if(x!=0) решило проблему.

 

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

Без "if" при каждом запуске платформы у инди возникает проблема деления на 0,

в новом MT4, похоже, не сохраняется информация, пока не будет поставлена галочка.

Другим решением было бы использовать OnCalculate() вместо start() или OnStart(), я полагаю?

Но об этом можно пожаловаться в MetaQuotes.

   double pipValue = MarketInfo(Symbol(),MODE_TICKVALUE); 

   if(pipValue!=0)
    {
   double lots   = AccountBalance()*(RiskPercent/100.0)/(StopLoss*pipValue);
    }
 

Вы должны использовать прием return (0).

Если есть интерес, кто-нибудь расскажет подробнее.

 
deysmacro:

Вы должны использовать трюк с возвратом (0).

Кто-нибудь расскажет об этом подробнее, если будет интерес.


Ну, старые индикаторы, которые вы можете найти везде в интернете, не получают свой код, измененный автоматически.

Если кто-то умеет настраивать коды и понимает проблему, он может сделать это самостоятельно.

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

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

Шаблоны - это другая история, в новом Built 625.

 

Ребята,

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

// Wait for the server "turmoil" to settle before doing anything
      string AcctCurrency = AccountCurrency();
       
      if (AcctCurrency == "")
          return(0);

Любая ошибка деления на ноль, которую вы получаете, связана с тем, что вы пытаетесь произвести вычисления до того, как сервер успокоился. Если вы делаете вычисления в функции инициализации - НЕ ДЕЛИТЕСЬ! Поместите приведенный выше код в start() или OnStart() и ТОГДА делайте то, что вам нужно. Дадас, попытка сделать все так просто, как ты делаешь, обернется для тебя большими неприятностями. Вам повезло с инди.

Когда indi исчезает, у вас сбой инициализации. Если вы посмотрите на свои журналы, вы увидите "сбой глобальной инициализации". Вам нужно выяснить, почему у вас это происходит, и устранить это. Если вы этого не сделаете, все, что вы сделали, это наложили пластырь на порез, на который нужно было наложить швы, и это вернется к вам.

 

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

Всего одна строка кода

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 &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
  Print(High[rates_total]);
  
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Он выдаст ошибку array out of range.

Смените таймфрейм и получите Global initialisation failed и индикатор будет удален с графика.

 
Может быть, GumRai, Похоже, что здесь есть разные проблемы. Одна из них - deinit() не вызывается в нужный момент и оставляет вещи висеть на месте. То, что вы видите с OnCalculate(), похоже на глюк в реализации этой функции в MQL, если я понимаю, как она должна работать. Другой вариант - попытка сделать что-то до того, как сервер успокоится и "инициализирует" информацию на стороне сервера. Я просто предполагаю, но последнее также может быть причиной того, что вы видите в OnCalculate(). Похоже, разработчикам MQL нужно немного поработать над отладкой. Честно говоря, то, что они пытаются сделать, не является тривиальным. Глюков можно только ожидать.