init() or deinit() ? В чем сила, start()?

 
Вторые грабли за 2 дня - многовато. Вот такой код работает:

//+------------------------------------------------------------------+
//|                                                     OutPrint.mq4 |
//|                                                       MetaQuotes |
//|                                        http://www.alpari-idc.ru/ |
//+------------------------------------------------------------------+
#property copyright "MetaQuotes"
#property link      "http://www.alpari-idc.ru/"
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   string FileName;
   int FileHandle;
   int ClOp; // разница между закрытием и открытием в пунктах
   int spread;// спред по инструменту
   int BarYear;// год
   int BarDay; // день недели, 0 - восресенье 
   
   spread=MarketInfo(Symbol(),MODE_SPREAD); // запомним спред
   
   // сформируем имя файла, например , EURUSD1440.csv
   FileName=Symbol()+Period()+".csv"; 
   //откроем файл с именем FileName (создадим указатель/handle на него)
   FileHandle=FileOpen(FileName,FILE_WRITE | FILE_CSV,";");
   if (FileHandle<1)
      {
      Print("Не удалось открыть файл, ошибка ",GetLastError());
      return;
      }   
      
   // запишем названия столбцов (создание шапки)
   FileWrite(FileHandle,"Дата","Open","High","Low","Close","Close-Open в пунктах",
      "Спред в пунктах","День недели","Год");   
   
   
   for (int index=Bars-1;index>=0;index--)
      {
      // пропустим бары до 2001 года
      if (TimeYear(Time[index])<2001) continue;
      
      // прервем (закончим) цикл, если 2005 год мы прошли весь
      if (TimeYear(Time[index])>2005) break;
      
      // Выведем High, Low, Open, Close  для бара с индексом index
      //Print(High[index],"  ",Low[index],"  ",Open[index],"  "
      //,Close[index],"  бар=",index);
      BarYear=TimeYear(Time[index]);
      BarDay=TimeDayOfWeek(Time[index]);
      ClOp=(Close[index]-Open[index])/Point;
      
      FileWrite(FileHandle,TimeToStr(Time[index]),Open[index],High[index],Low[index],
      Close[index],ClOp,spread,BarDay,BarYear);
      }
 
 
//----
 
 
   //закроем файл (освободим указатель/handle, чтобы файл можно было 
   //открыть для редактирования другими программами)
   if(FileHandle>0) FileClose(FileHandle);
 
 
   return(0);// работа скрипта завершена
  }
//+------------------------------------------------------------------+

А вот такой, более цивильный

//+------------------------------------------------------------------+
//|                                                     OutPrint.mq4 |
//|                                                       MetaQuotes |
//|                                        http://www.alpari-idc.ru/ |
//+------------------------------------------------------------------+
#property copyright "MetaQuotes"
#property link      "http://www.alpari-idc.ru/"
 
int FileHandle;
//+------------------------------------------------------------------+
//| script initialization function                                   |
//+------------------------------------------------------------------+
int init()
   {
   string FileName;
   int FileHandle;
   
   Print("Выполняем init()");
   
   // сформируем имя файла, например , 
   FileName=Symbol()+"CloseStat.csv"; 
   //откроем файл с именем FileName (создадим указатель/handle на него)
   FileHandle=FileOpen(FileName,FILE_WRITE | FILE_CSV,";");
   if (FileHandle<1)
      {
      Print("Не удалось открыть файл, ошибка ",GetLastError());
      return;
      }   
   return(0);
   }
//+------------------------------------------------------------------+
//| script deinitialization function                                   |
//+------------------------------------------------------------------+
int deinit()
   {
   Print("Выполняем deinit()");
 
   //закроем файл (освободим указатель/handle, чтобы файл можно было 
   //открыть для редактирования другими программами)
   if(FileHandle>0) FileClose(FileHandle);
   return(0);
   }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   int ClOp; // разница между закрытием и открытием в пунктах
   int spread;// спред по инструменту
   int BarYear;// год
   int BarDay; // день недели, 0 - восресенье 
   
   spread=MarketInfo(Symbol(),MODE_SPREAD); // запомним спред
   
   // запишем названия столбцов (создание шапки)
   FileWrite(FileHandle,"Дата","Open","High","Low","Close","Close-Open в пунктах",
      "Спред в пунктах","День недели","Год");   
   
   
   for (int index=Bars-1;index>=0;index--)
      {
      // пропустим бары до 2001 года
      if (TimeYear(Time[index])<2001) continue;
      
      // прервем (закончим) цикл, если 2005 год мы прошли весь
      if (TimeYear(Time[index])>2005) break;
      
      // Выведем High, Low, Open, Close  для бара с индексом index
      //Print(High[index],"  ",Low[index],"  ",Open[index],"  "
      //,Close[index],"  бар=",index);
      BarYear=TimeYear(Time[index]);
      BarDay=TimeDayOfWeek(Time[index]);
      ClOp=(Close[index]-Open[index])/Point;
      
      FileWrite(FileHandle,TimeToStr(Time[index]),Open[index],High[index],Low[index],
      Close[index],ClOp,spread,BarDay,BarYear);
      }
 
 
//----
 
 
 
 
   return(0);// работа скрипта завершена
  }
//+------------------------------------------------------------------+

уже не работает. Внимательно перечитал справку на всякий случай и выяснил, что :
а) не запрещены init() и deinit() в скриптах
б) не запрещены глобальные переменные в скриптах
в) init() и deinit() таки выполняются из скрипта
2006.05.12 23:08:52    WriteFile2 EURUSD,M15: removed
2006.05.12 23:08:52    WriteFile2 EURUSD,M15: deinitialized
2006.05.12 23:08:52    WriteFile2 EURUSD,M15: Выполняем deinit()
2006.05.12 23:08:52    WriteFile2: invalid handle 0 in FileWrite
2006.05.12 23:08:52    WriteFile2: invalid handle 0 in FileWrite
....
....
2006.05.12 23:08:52    WriteFile2: invalid handle 0 in FileWrite
2006.05.12 23:08:52    WriteFile2: invalid handle 0 in FileWrite
2006.05.12 23:08:52    WriteFile2: invalid handle 0 in FileWrite
2006.05.12 23:08:52    WriteFile2: invalid handle 0 in FileWrite
2006.05.12 23:08:41    Compiling 'WriteFile2'

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

В общем, такой вопрос возник.
 
Хмм... Вот этот старый скрипт с записью в файл и сейчас работает.
//+------------------------------------------------------------------+
//|                                             CrossMASignals-5.mq4 |
//|                                                       MetaQuotes |
//|                 http://forum.alpari-idc.ru/viewtopic.php?t=48186 |
//+------------------------------------------------------------------+
#property copyright "MetaQuotes"
#property link      "http://forum.alpari-idc.ru/viewtopic.php?t=48186"
#property show_inputs
 
extern int LongPeriod=21; // период медленной средней
extern int ShortPeriod=13; // период быстрой средней
 
int FileHandle;  // указательная на файл - глобальная переменная
 
//+------------------------------------------------------------------+
//| функия инициализации                                             |
//+------------------------------------------------------------------+
int init()
  {
   string FileName; // имя файла - локальная переменная
   int deletedArrows;
 
   // сформируем имя файла
   Print("Выполняется init()");
   FileName="CrossMA.csv"; 
   //откроем файл с именем FileName (создадим указатель/handle на него)
   FileHandle=FileOpen(FileName,FILE_WRITE | FILE_CSV,";");
   if (FileHandle<1)
      {
      Print("Не удалось открыть файл, ошибка ",GetLastError());
      return;
      }   
      
   // запишем названия столбцов (создание шапки)
   FileWrite(FileHandle,"Дата","Номер бара","Стрелка вверх","Стрелка вниз");   
   
   // удалим все стрелки, если они есть
   deletedArrows=ObjectsDeleteAll(0,OBJ_ARROW);
   Comment("Удалено ",deletedArrows," обектов OBJ_ARROW");
 
  } 
 
//+------------------------------------------------------------------+
//| функция деинициализации (заврещения)                             |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   Print("Выполняется deinit()");
   //закроем файл (освободим указатель/handle, чтобы файл можно было 
   //открыть для редактирования другими программами)
   if(FileHandle>0) FileClose(FileHandle);
 
//----
   return(0);
  }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
   double maLongCur, maLongPrev, maShortCur, maShortPrev;
   string arrowName; // здесь будут назначаться уникальное имя объекта-стрелки
   int arrowCounter=0;// счетчик стрелок
   // объявим служебные переменные, в которых будем хранить ценовые координаты стрелок
   double value1,value2;
 
   Print("Выполняется start()");
//----
   for(int i=Bars-1;i>=0;i--)
      {
      // обнулим службные переменные
      value1=0.0;
      value2=0.0;
      
      maLongCur=iMA(NULL,0,LongPeriod,0,MODE_SMA,PRICE_CLOSE,i+1);// медленная средняя на предыдущем баре
      maLongPrev=iMA(NULL,0,LongPeriod,0,MODE_SMA,PRICE_CLOSE,i+2);// медленная средняя на предпредыдущем баре
      maShortCur=iMA(NULL,0,ShortPeriod,0,MODE_SMA,PRICE_CLOSE,i+1);// быстрая средняя на предпредыдущем баре
      maShortPrev=iMA(NULL,0,ShortPeriod,0,MODE_SMA,PRICE_CLOSE,i+2);// быстрая средняя на предыдущем баре
 
 
      //Если есть сигнал к покупке на предыдущем баре - поставим синюю стрелку вверх 
      // по цене открытия бара  
      if((maShortCur>maLongCur)&&(maShortPrev<maLongPrev))
         {
         // Поставим стрелку
         // имя объекта - arrowName
         // тип объекта - OBJ_ARROW
         // координата по горизонтали - Time[i]  время открытия бара
         // координата по вертикали - Open[i] цена открытия бара
         arrowName="arrow"+arrowCounter;
         ObjectCreate(arrowName,OBJ_ARROW,0,Time[i],Open[i]);
         
         // зададим тип стрелки - 241 , стрелка вверх
         ObjectSet(arrowName,OBJPROP_ARROWCODE,241);
         
         // зададим цвет стрелке - голубой
         ObjectSet(arrowName,OBJPROP_COLOR,Blue);
         
         // увеличить счетчик стрелок
         arrowCounter++; 
         value1=Open[i];//запомним цену голубой стрелки
         }
      //Если есть сигнал к продаже на предыдущем баре - поставим красную стрелку вниз 
      // по цене открытия бара  
      if((maShortCur<maLongCur)&&(maShortPrev>maLongPrev))
         {
         // Поставим стрелку
         // имя объекта - arrowName
         // тип объекта - OBJ_ARROW
         // координата по горизонтали - Time[i]  время открытия бара
         // координата по вертикали - Open[i] цена открытия бара
         arrowName="arrow"+arrowCounter;
         ObjectCreate(arrowName,OBJ_ARROW,0,Time[i],Open[i]);
         
         // зададим тип стрелки - 242 , стрелка вниз
         ObjectSet(arrowName,OBJPROP_ARROWCODE,242);
 
         // зададим цвет стрелке - красный
         ObjectSet(arrowName,OBJPROP_COLOR,Red);
         // увеличить счетчик стрелок
         arrowCounter++; 
         value2=Open[i];//запомним цену красной стрелки
         }
 
      //запишем данные для текущего бара в файл
      FileWrite(FileHandle,TimeToStr(Time[i]),i,value1,value2);
          
      }
//----
 
 
   return(0);
  }
//+------------------------------------------------------------------+

Ничего не понимаю.
 
>> В общем, такой вопрос возник.

Все верно - второй вариант катастрофически ошибочен, так как хендл файла описан на локальном уровне.
Надо убрать из функции init:
int FileHandle;

Третий вариант правильный, так как в init не описан хендл.
 
Прикольно выглядит копирайт MetaQuotes и ссылка на Альпари, хотя пишет Rosh:
#property copyright "MetaQuotes"
#property link      "http://www.alpari-idc.ru/"
Может лучше указать свое авторство и соответствующие линки? :-)
 
Это не имеет значения. А вот авторизоваться на форуме с КПК - пытка. Чертов провайдер опять сдох икогда будет нормальный инет - неизвестно. Проглядел каким то образом локальный хендл в инит, хотя в качестве оправдания могу сказать, что был спровоцирован предыдущими граблями и пониил видимо требования к себе (хотя 3 раза искал повторное объявление чере Ctrl+F)
 
Наконец инет появился.Самое смешное - я выложил не тот скрипт, с которого все началось, а взял простейший и провел те же дейтствия, чтоыб повторить свою проблему. Оказалось, что я ее дейстивительно повторил, в обоих скриптах была одна и таже ошибка, связанная с тем, что я копировал лбъявление хэндла их start() и в init() и в интерфейсную часть. И проверка в обоих случаях не позволдила найти свою ошибку - глаз замылилися конкретно.
 
Rosh:
Это не имеет значения. А вот авторизоваться на форуме с КПК - пытка. Чертов провайдер опять сдох икогда будет нормальный инет - неизвестно. Проглядел каким то образом локальный хендл в инит, хотя в качестве оправдания могу сказать, что был спровоцирован предыдущими граблями и пониил видимо требования к себе (хотя 3 раза искал повторное объявление чере Ctrl+F)
Вот моя процедура попадания на форум (1 из трез раз). Сначала выдает такую картинку.
 
Затем я урезаю линк до https://www.mql5.com/en/forum - попадаю на англоязычный форум.
 
Потом я жму кнопку авторизации и вылезает следующее
 
Потом я отмечаю чек-бокс "Запомнить данные и..." и жму кнопку "Вход" - и вот я на форуме :)