Непонятка с терминалом

 
В заголовочном файле файле есть функция внутри которой объявляеться массив double endOptimArr[][4]; дальше с ним идет работа через функции
ArrayResize(endOptimArr,ArrayRange(endOptimArr,0)+1);
Так вот, если при торговле открывать окно настроек эксперта несколько раз то размер endOptimArr увеличиваеться в 2 раза, т.е. получается что эксперт после deinitialized сохраняет данные массива. Это фишка или глюк?

Терминал обновил сегодня.
 
Приведите минимальный код с демонстрацией, пожалуйста. По всей видимости проблема в логике эксперта.
 
//+------------------------------------------------------------------+
//|                                             1_timeFiltroptim.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/"
 
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
// #define MacrosHello   "Hello, world!"
// #define MacrosYear    2005
 
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
// #import "user32.dll"
//   int      SendMessageA(int hWnd,int Msg,int wParam,int lParam);
 
// #import "my_expert.dll"
//   int      ExpertRecalculate(int wParam,int lParam);
// #import
 
//+------------------------------------------------------------------+
//| EX4 imports                                                      |
//+------------------------------------------------------------------+
// #import "stdlib.ex4"
//   string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+
 
 
extern double pribGood        =1.8;
 
int analisOptimization()
{
   //int count=(OptMaxArage-OptMinArage)/OptShagArage;
   double endOptimArr[0][4];
   double tmp;
   double prib,otn,prof1,prof2, prib1;
   int    total    =OrdersHistoryTotal(),q, count1,count2 ;
   int    OptMinArage     =0;
   int    OptMaxArage     =23;
   int    OptShagArage    =1;
   string OptstrIt     =""; 
  
  // ArrayResize(endOptimArr,0);
   Print(q," ",ArrayRange(endOptimArr,0)," ",tmp," ",prib," ",otn," ",prof1," ",prib1," ",OptstrIt);
   for(int i=OptMinArage; i<=OptMaxArage; i+=OptShagArage)
   {
      ArrayResize(endOptimArr,ArrayRange(endOptimArr,0)+1);  
 
     for(int pos=total-1;pos>=0;pos--)
     {
         if (OrderSelect(pos,SELECT_BY_POS,MODE_HISTORY ))
         {  
         
           if(TimeHour(OrderOpenTime())==OptMinArage+i)
            {
                tmp=OrderProfit()+OrderCommission()+OrderSwap();
                 if(tmp>0)
                 {
                    endOptimArr[ArrayRange(endOptimArr,0)-1][0]++;
                    endOptimArr[ArrayRange(endOptimArr,0)-1][1]+=tmp;
                 }
                 else
                 {
                    endOptimArr[ArrayRange(endOptimArr,0)-1][2]++;
                    endOptimArr[ArrayRange(endOptimArr,0)-1][3]+=tmp;
                 }
                 
            }
         }
     }
  } 
  
  tmp=0;
 
   for(q=0; q<ArrayRange(endOptimArr,0);q++)
   {
      prib=0;
      otn=0;
      if(endOptimArr[q][3]!=0)
      {
         prib=endOptimArr[q][1]/ MathAbs(endOptimArr[q][3]);
         otn=endOptimArr[q][0]/endOptimArr[q][2];
      }
      Print("от ",OptMinArage+(q*OptShagArage)," до ",OptMinArage+((q+1)*OptShagArage) ," || (", endOptimArr[q][0]," / ", endOptimArr[q][2],") отношение = " , otn ," всего прибыль ",(endOptimArr[q][1]+endOptimArr[q][3]), " прибыльность ",prib );
      tmp+=(endOptimArr[q][1]+endOptimArr[q][3]);
      
      if(prib>pribGood)
      {
       prof1+=endOptimArr[q][1];
       prof2+=endOptimArr[q][3];
       count1+=endOptimArr[q][0];
       count2+=endOptimArr[q][2];
       
         if(StringLen(OptstrIt)==0)
            OptstrIt=(q*OptShagArage);
         else
            OptstrIt=OptstrIt+","+(q*OptShagArage);
      }
   }
   
return;
}
Это заголовочный файл.
А это вызов функции:
int deinit()
{
//---- 
  PrintError();
  PrintEqBalans(1);  
  analisOptimization();
return(0);
}
никаких одноименных переменных нет, вызов
analisOptimization();
только в
int deinit()
 
Вот простейший советник который выявляет эту ошибку
//+------------------------------------------------------------------+
//|                                                    111111111.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/"
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern  int fgd=0;
 int str=0;
int init()
  {
//----
  Print(str);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   str=1;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+


переменная
int str=0;
перед выключением советника
str=1;

печатаем переменную str, она должна быть равна 0, а принт выводит 1
 Print(str);
 
Может быть, дело в этом:

int ArrayResize( & array[], int new_size)
Устанавливает новый размер в первом измерении массива. При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера, в противном случае возвращает -1, и массив не меняет размеры.
Замечание: массив, объявленный на локальном уровне в какой-либо функции, у которого был изменен размер, останется неизменным после завершения работы функции. При повторном вызове функции такой массив будет иметь размер, отличный от объявленного.
Параметры:
array[] - Массив для изменения размеров.
new_size - Новый размер для первого измерения.
Пример:
double array1[][4];
int element_count=ArrayResize(array1, 20);
// новый размер - 80 элементов
 
Так проблема не только с массивами, но и с переменными объявленными на глобальном уровне, после деинициализации они сохраняют свои параметры, смысл тогда делать ее если половина параметров не соотвествует действительности. Выше привел пример с глоабльной переменной int.
 
Данный ньюанс особенно актуален, когда на работающем советнике меняешь (клавиша F7) входные параметры. По логике советник должен выгрузиться со старыми входными параметрами и загрузиться с новыми. Но на деле выполняется только deinit(), а затем init() с новыми входными параметрами. Остальные переменные, объявленные вне функций (static не проверял) сохраняют свои значения. По этой причине все подобные переменные сбрасываю в начальное состояние в функции init().
 
Судя по 'Перенастройка эксперта' проблема это давняя и разработчики превратили ее в фишку :-))) так надо хотя бы сказать всем, что глобальные переменные не сбрасываются. А то сидишь, гадаешь, почему же эксперт не торгует на реале....
 

Пример:

extern int A = 0;

int B = -1;

int start()
{
Print("B == ", B);

if (B == -1)
B = 12345;


return(0);
}

Журнал:

Поэтому лучше так:

extern int A = 0;

int B;

int init()
{
B = -1;

return(0);
}
int start()
{
Print("B == ", B);

if (B == -1)
B = 12345;


return(0);
}

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


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

Вот Вы надеетесь, что после повторной инициализации (без перезагрузки эксперта) глобальные переменные переинициализируются. Тогда вопрос: Вы так же надеетесь на то, что локальная статическая переменная будет каждый раз инициализироваться одним и тем же значением при каждом вызове функции, в котором эта статическая переменная объявлена?

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