Скачать MetaTrader 5

В МТ4 изменился механизм OnInit() и OnDeinit?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Alexey Volchanskiy
23012
Alexey Volchanskiy  

Что-то я в ступоре. При вызове OnDeinit() при переключении ТФ сбрасываются в нули глобальные переменные и массивы, заданные как динамические через ArrayResize(...) приобретают нулевую размерность.

Билд 971, но ведь раньше такого точно не было? Раньше при переключении ТФ глобальные переменные сохраняли свои значения и с массивы не ресайзились в ноль! Или у меня крыша потекла???

Вот пример с картинкой в отладчике после переключения таймфрейма. Видно, что переменная size равна нулю. 

OnInit 

Yuri Evseenkov
2327
Yuri Evseenkov  
Alexey Volchanskiy:

Что-то я в ступоре. При вызове OnDeinit() при переключении ТФ сбрасываются в нули глобальные переменные и массивы, заданные как динамические через ArrayResize(...) приобретают нулевую размерность.

Билд 971, но ведь раньше такого точно не было? Раньше при переключении ТФ глобальные переменные сохраняли свои значения и с массивы не ресайзились в ноль! Или у меня крыша потекла???

Вот пример с картинкой в отладчике после переключения таймфрейма. Видно, что переменная size равна нулю. 

 

Переменная size у Вас не глобальная, а локальная и объявлена внутри функции OnInit(). При смене ТФ сохраняются только глобальные переменные и внешние input  см. https://www.mql5.com/ru/forum/1111/page1511#comment_2232178
Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • www.mql5.com
Форум трейдеров MQL5.community
Alexey Volchanskiy
23012
Alexey Volchanskiy  
Yuri Evseenkov:
Переменная size у Вас не глобальная, а локальная и объявлена внутри функции OnInit(). При смене ТФ сохраняются только глобальные переменные и внешние input  см. https://www.mql5.com/ru/forum/1111/page1511#comment_2232178

Юрий, да что с вами )) Переменной size присваивается размер массива SpreadBuf, только для того, чтобы можно было посмотреть этот размер после смены ТФ. Зачем делать ее глобальной-то?

И размер массива после смены ТФ равен нулю.

И глобальная переменная SpreadBufIdx также обнуляется. Раньше точно такого не было.

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

ыыы 

 

//+------------------------------------------------------------------+
//|                                          ShowImportantParams.mq4 |
//|                               Copyright 2016, Alexey Volchanskiy |
//|                                          https://mql.gnomio.com/ |
//+------------------------------------------------------------------+

#property copyright "Copyright 2016 June 22, Alexey Volchanskiy"
#property link      "https://mql.gnomio.com/"
#property version   "1.00"
#property strict
#property description "Indicator shows important params for current symbol and account"
#property indicator_chart_window
#property indicator_buffers 0

input int       FontSize            = 10;
input color     FontColor           = clrYellow;
input string    FontName            = "Tahoma";
input int       XOffset             = 10;
input int       YOffset             = 15;
input int       SpreadSmoothTicks   = 60;

string lNames[]={"Margin4lot=","Leverage=1:","Spread=","SpreadPrice=","StopLevel=","StopOut=","MarginCall="};

double  SpreadBuf[];
int     SpreadBufIdx=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectsDeleteAll(0,"SIP");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {
   int size=ArraySize(SpreadBuf);
   ArrayResize(SpreadBuf,SpreadSmoothTicks);
   for(int n=0; n<SpreadSmoothTicks; n++)
      SpreadBuf[n]=0;
   SpreadBufIdx=0;
   ObjectsDeleteAll(0,"SIP");
   for(int n=ArraySize(lNames)-1; n>=0; n--)
     {
      if(!CreateLabel("SIP_"+lNames[ArraySize(lNames)-1-n],XOffset,YOffset*n+YOffset))
         Print("CreateLabel returns false, n = ",IntegerToString(n));
     }
   WindowRedraw();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
  {
   int size=ArraySize(SpreadBuf);
   SpreadBuf[SpreadBufIdx++]=Ask-Bid;
   if(SpreadBufIdx >= SpreadSmoothTicks)
      SpreadBufIdx = 0;
   double sprd=0;
   for(int n = 0; n < SpreadSmoothTicks; n++)
      sprd += SpreadBuf[n];
   sprd/=(double)SpreadSmoothTicks;
   ResetLastError();

   double price4lot;
   Quote2Price(sprd,price4lot,Symbol());

   ObjectSetString(0,"SIP_"+lNames[0],OBJPROP_TEXT,lNames[0]+DoubleToString(MarketInfo(Symbol(),MODE_MARGINREQUIRED),2));
   ObjectSetString(0,"SIP_"+lNames[1],OBJPROP_TEXT,lNames[1]+IntegerToString(AccountLeverage()));
   ObjectSetString(0,"SIP_"+lNames[2],OBJPROP_TEXT,lNames[2]+DoubleToString(sprd,_Digits));
   ObjectSetString(0,"SIP_"+lNames[3],OBJPROP_TEXT,lNames[3]+DoubleToString(price4lot,2));
   ObjectSetString(0,"SIP_"+lNames[4],OBJPROP_TEXT,lNames[4]+DoubleToString(MarketInfo(Symbol(),MODE_STOPLEVEL),0));

   ENUM_ACCOUNT_STOPOUT_MODE stop_out_mode=(ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
   string s=(stop_out_mode==ACCOUNT_STOPOUT_MODE_PERCENT)?" %":"";
   ObjectSetString(0,"SIP_"+lNames[5],OBJPROP_TEXT,lNames[5]+DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL),0)+s);
   ObjectSetString(0,"SIP_"+lNames[6],OBJPROP_TEXT,lNames[6]+DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_SO_SO),0)+s);
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool Quote2Price(double diff,double &price4lot,string symbol="EURUSD")
  {
   int dig=(int)MarketInfo(symbol,MODE_DIGITS);
   if(dig == 0)
      return(false); // symbol is none
   double tickSize = MarketInfo(symbol, MODE_TICKSIZE);   // пункт в валюте котировки (0,00001 для EURUSD на 5-знаке) 
   double tickValue = MarketInfo(symbol, MODE_TICKVALUE); // пункт в валюте депозита ($1 для EURUSD на 5-знаке)
   double price=diff/(tickSize/tickValue);
   price4lot=NormalizeDouble(price,2);
   return (true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CreateLabel(string name,int x,int y=10)
  {
   if(!ObjectCreate(0,name,OBJ_LABEL,0,0,0))
      return false;
   ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
   ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_LOWER);
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,FontSize);
   ObjectSetInteger(0,name,OBJPROP_COLOR,FontColor);
   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,true);
   ObjectSetString(0,name,OBJPROP_FONT,FontName);
   WindowRedraw();
   return true;
  }

 ***

Файлы:
Yuri Evseenkov
2327
Yuri Evseenkov  
Alexey Volchanskiy:

Юрий, да что с вами )) Переменной size присваивается размер массива SpreadBuf, только для того, чтобы можно было посмотреть этот размер после смены ТФ. Зачем делать ее глобальной-то?

И размер массива после смены ТФ равен нулю.

И глобальная переменная SpreadBufIdx также обнуляется. Раньше точно такого не было.

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

 

 

 ***

После смены ТФ или инструмента происходит вызов OnInit(). А переменную  SpreadBufIdx Вы в этой функции обнуляете. Насчет размера массива нужно сначало его установить а потом смотреть его значение в точке отладки. поменяйте   int size=ArraySize(SpreadBuf); и     ArrayResize(SpreadBuf,SpreadSmoothTicks); местами

P.S Актуальный индикатор 

Roman Busarov
5935
Roman Busarov  
кстате, сегодня заметил что при использовании скрипта закрытие всех ордеров, он их не закрывает.... ( сори за оффтоп )
Iurii Tokman
58550
Iurii Tokman  
Roman Busarov:
кстате, сегодня заметил что при использовании скрипта закрытие всех ордеров, он их не закрывает.... ( сори за оффтоп )
перед референдумом могут быть брокерские ограничения
почитайте письма от брокера, он должен был предупредить
Alexey Volchanskiy
23012
Alexey Volchanskiy  
Yuri Evseenkov:

После смены ТФ или инструмента происходит вызов OnInit(). А переменную  SpreadBufIdx Вы в этой функции обнуляете. Насчет размера массива нужно сначало его установить а потом смотреть его значение в точке отладки. поменяйте   int size=ArraySize(SpreadBuf); и     ArrayResize(SpreadBuf,SpreadSmoothTicks); местами

P.S Актуальный индикатор 

Вы шутите или реально не читаете, что я пишу? Массив принимает нулевой размер после смены таймфрейма! Вы в курсе, что при смене ТФ вызывается OnInit?

void OnInit()
  {
   int size=ArraySize(SpreadBuf);

   Print("Размер массива после смены ТФ=", size); //!!!!!!! так понятно? размер будет равен нулю! 

   ArrayResize(SpreadBuf,SpreadSmoothTicks); // поэтому я вынужден делать resize
   for(int n=0; n<SpreadSmoothTicks; n++)    // и обнулять на всякий случай 
      SpreadBuf[n]=0;
   SpreadBufIdx=0;
   ObjectsDeleteAll(0,"SIP");
   for(int n=ArraySize(lNames)-1; n>=0; n--)
     {
      if(!CreateLabel("SIP_"+lNames[ArraySize(lNames)-1-n],XOffset,YOffset*n+YOffset))
         Print("CreateLabel returns false, n = ",IntegerToString(n));
     }
   WindowRedraw();
  }
Yuriy Zaytsev
16462
Yuriy Zaytsev  
Alexey Volchanskiy:


ObjectSetString(0,"SIP_"+lNames[2],OBJPROP_TEXT,lNames[2]+DoubleToString(sprd,_Digits));

Алексей - это же не спред 

   ObjectSetString(0,"SIP_"+lNames[2],OBJPROP_TEXT,lNames[2]+DoubleToString(sprd,_Digits) + "   спред в реальном времени [ "+DoubleToString(Ask-Bid,_Digits)+"]" );
Alexey Kozitsyn
7770
Alexey Kozitsyn  
Alexey Volchanskiy:

Что-то я в ступоре. При вызове OnDeinit() при переключении ТФ сбрасываются в нули глобальные переменные и массивы, заданные как динамические через ArrayResize(...) приобретают нулевую размерность.

Билд 971, но ведь раньше такого точно не было? Раньше при переключении ТФ глобальные переменные сохраняли свои значения и с массивы не ресайзились в ноль! Или у меня крыша потекла???

Вот пример с картинкой в отладчике после переключения таймфрейма. Видно, что переменная size равна нулю. 

 

Задавал в MQ подобный вопрос недавно. Вот ответ: в индюках - сбрасывается, в советниках - не сбрасываются глобальные переменные. Это так "исторически сложилось". Менять поведение не будут.
Alexey Navoykov
4886
Alexey Navoykov  
Да в индикаторах так всегда было, насколько я помню. Приходилось костыльными способами решать эту проблему
Yuri Evseenkov
2327
Yuri Evseenkov  
Alexey Volchanskiy:

Вы шутите или реально не читаете, что я пишу? Массив принимает нулевой размер после смены таймфрейма! Вы в курсе, что при смене ТФ вызывается OnInit?

Да это Вы шутите. Я пишу  в первой же строчке поста   "После смены ТФ или инструмента происходит вызов OnInit()."  Вы в ответе на этот пост спрашиваете  "Вы в курсе, что при смене ТФ вызывается OnInit?"

Не получается диалога.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий