Помогите разобраться с индикатором!

 

Все, сил нет. Работает через раз(но работает!).
Во, первых, ошибка 4401: не копирует данные таймсерии. Через раз, иногда все таки копирует. Пробовал в ините прописать обращение через iClose(), без толку. Все равно пишет ошибку.

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

Индюк работает, но после нескольких перезапусков, что небезупречно.

//+------------------------------------------------------------------+
//|                                                    statistik.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#include <CCheckNewCandle.mqh>
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

bool check_first=true;
int file_handle,count = 10000,alert_counter;
datetime time_current,time_dest;
ENUM_TIMEFRAMES tf[]={PERIOD_M1,PERIOD_M15,PERIOD_H1};
MqlRates rates[];
MqlRates rates_print[];
string sym_itogo,symb_vol[];
struct symb_vol_struct
  {
   string sym;
   int tf;
   int vol;
   
  };
symb_vol_struct to_file,from_file[];


CCheckNewCandle candle;

template <typename T>                                       
void ArrayReindex( T &Array[], const double &TmpSort[][2] )
{                         
  T TmpArray[];
  


  for (int x = ::ArrayResize(TmpArray, ::ArrayRange(TmpSort, 0)) - 1; x >= 0; x--)
    TmpArray[x] = Array[(int)(TmpSort[x][1] + 0.1)];
    
  ::ArraySwap(Array, TmpArray);
              
  return;     
}             


#define ArraySortStruct(ARRAY, FIELD)                                      \
{                                                                          \
  double TmpSort[][2];                                                     \
                                                                           \
  for (int x =::ArrayResize(TmpSort, ::ArraySize(ARRAY)) - 1; x >= 0; x--) \
  {                                                                        \
    TmpSort[x][0] = (double)ARRAY[x].FIELD;                                \
    TmpSort[x][1] = x;                                                     \
  }                                                                        \
                                                                           \
  ::ArraySort(TmpSort);                                                    \
  ::ArrayReindex(ARRAY, TmpSort);                                          \
}                                  

int OnInit()
  {
  IndicatorSetString(INDICATOR_SHORTNAME,"Statistik");
  for(int i=0;i<SymbolsTotal(true);i++)
     {
     string sym = SymbolName(i,true);
     iClose(sym,PERIOD_CURRENT,1);
     }
 +candle;
 
   return(INIT_SUCCEEDED);
  }

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[])
  {
   time_current = TimeCurrent();
   if (time_current+5400<(TimeLocal()) || check_first)  
   {
   check_first = false;

   file_handle = FileOpen("symb_volume",FILE_WRITE,FILE_READ,FILE_CSV);
   int sym_tot=SymbolsTotal(true);  
   for(int i=0;i<SymbolsTotal(true);i++)
     {
         string sym = SymbolName(i,true);
         for(int i_1=0;i_1<ArrayRange(tf,0);i_1++)
         {
            to_file.sym=sym;
            to_file.tf=tf[i_1];
            time_dest = time_current-2592000;
            int cost =Bars(sym,tf[i_1],time_dest,time_current);
            Print("bars ",cost,", ", _LastError,", Cимвол:",sym); ResetLastError();
            int y = CopyRates(sym,tf[i_1],time_dest,time_current,rates);
            Print("copy rates",y,", ", _LastError,", Cимвол:",sym);ResetLastError();
            if(y < 10)
            {  i_1=0;Print("i_1",i_1); continue;}
            
            if(iRealVolume(sym,tf[i_1],0)==0)           
            {
             ArraySortStruct(rates, tick_volume);
             int z=ArrayCopy(rates_print,rates,0,ArrayRange(rates,0)-10,10); 
             Print(z); 
             ArraySortStruct(rates_print, tick_volume);
            sym_itogo = "Символ:"+sym+"   ТФ:"+EnumToString(tf[i_1])+"   Макс.объем:"+rates_print[9].tick_volume;
            if(rates_print[9].tick_volume>5000000000)  i_1=-1;Print(sym_itogo); continue;
            to_file.vol = rates_print[0].tick_volume; //Print(to_file.vol);
                      
             }
            else if(iRealVolume(sym,tf[i_1],0)>0)
             {
               ArraySortStruct(rates, real_volume);
               ArrayCopy(rates_print,rates,0,ArrayRange(rates,0)-10,10);  
               ArraySortStruct(rates_print, real_volume);
               sym_itogo = "Символ:"+sym+"  ТФ:"+EnumToString(tf[i_1])+"   Макс.объем:"+rates_print[9].real_volume;
               to_file.vol = rates_print[0].real_volume;
             }
           
             string str_to_f;
             StringConcatenate(str_to_f,to_file.sym,";",to_file.tf,";",StringToInteger(to_file.vol));
             StringTrimLeft(str_to_f);
             StringTrimRight(str_to_f);
             FileWrite(file_handle,str_to_f);
              } 
            }
 FileClose(file_handle);
   }
   
if (!(FileIsExist("symb_volume"))) file_handle = FileOpen("symb_volume",FILE_WRITE); FileClose(file_handle);
file_handle = FileOpen("symb_volume",FILE_READ,FILE_WRITE,FILE_CSV);
int i_2 = 0; 
do
{
ArrayResize(from_file,(ArrayRange(from_file,0)+1),0);
string value=FileReadString(file_handle); 
string value_split[3]; 
StringSplit(value,StringGetCharacter(";",0),value_split);
from_file[i_2].sym=value_split[0];
from_file[i_2].tf=value_split[1];
from_file[i_2].vol=StringToInteger(value_split[2]);
 i_2++;
}
while(!FileIsEnding(file_handle));
FileClose(file_handle); 
+candle;
    for(int i_tf=0;i_tf<ArrayRange(tf,0);i_tf++)
         {
            if((candle[(ENUM_TIMEFRAMES)tf[i_tf]]))
               {  
                  for(int i=0;i<(ArrayRange(from_file,0));i++)
                     {
                                 int real_vol = iRealVolume(from_file[i].sym,(ENUM_TIMEFRAMES)from_file[i].tf,1);
                                 if (real_vol == 0) real_vol = iTickVolume(from_file[i].sym, (ENUM_TIMEFRAMES)from_file[i].tf,1);
                                 if (real_vol>from_file[i].vol && from_file[i].vol>0&&!(alert_counter=real_vol))  //from_file[i].sym!=NULL && 
                                       {
                                       Alert(from_file[i].sym, "   повышенный объем!!   ",real_vol,"  против расчетного  ",from_file[i].vol,"   на тф  ", EnumToString((ENUM_TIMEFRAMES)from_file[i].tf));
                                       Print(from_file[i].sym, "   повышенный объем!!   ",real_vol,"  против расчетного  ",from_file[i].vol,"   на тф  ", EnumToString((ENUM_TIMEFRAMES)from_file[i].tf));
                                       alert_counter=real_vol;
                                       Print(alert_counter);
                                       }
                  }
   }
         }
   ArrayFree(from_file);
   return(rates_total);
  }

void OnDeinit(const int reason)
{
ChartIndicatorDelete(0,0,"Statistik");
}
 
Виктор Астахов:

Все, сил нет. Работает через раз(но работает!).
Во, первых, ошибка 4401: не копирует данные таймсерии. Через раз, иногда все таки копирует. Пробовал в ините прописать обращение через iClose(), без толку. Все равно пишет ошибку.

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

Индюк работает, но после нескольких перезапусков, что небезупречно.

Не запускал, не знаю, но для начала, я бы рекомендовал изменить эти строки:

#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"

на Ваши данные.

Запустить индикатор не могу по независящим от меня причинам. Пока что, надеюсь )))

 
Сергей Таболин:

Не запускал, не знаю, но для начала, я бы рекомендовал изменить эти строки:

на Ваши данные.

Запустить индикатор не могу по независящим от меня причинам. Пока что, надеюсь )))

эээ, а зачем? что в этих-то не так?

 

Зато вот такая версия в итоге работает правильно. Убрал все проверки. Сначала оут оф рэндж, не скопировал значит бары. Это понятно. Повторный запуск, начинает копировать, но какие-то гигантские объемы. Удаляю индюк, снова запускаю еще пару раз, та же картина.
И раз на пятый, он копирует правильные объемы, и переходит на следующий этап.

Почему так?


//+------------------------------------------------------------------+
//|                                                    statistik.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#include <CCheckNewCandle.mqh>
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

bool check_first=true;
int file_handle,count = 10000,alert_counter;
datetime time_current,time_dest,first_date;
ENUM_TIMEFRAMES tf[]={PERIOD_M1,PERIOD_M15,PERIOD_H1};
MqlRates rates[], rates_print[];
double close_array[];
string sym_itogo,symb_vol[];
struct symb_vol_struct
  {
   string sym;
   int tf;
   int vol;
   
  };
symb_vol_struct to_file,from_file[];


CCheckNewCandle candle;
//////////////////
template <typename T>                                       
void ArrayReindex( T &Array[], const double &TmpSort[][2] )
{                         
  T TmpArray[];
  


  for (int x = ::ArrayResize(TmpArray, ::ArrayRange(TmpSort, 0)) - 1; x >= 0; x--)
    TmpArray[x] = Array[(int)(TmpSort[x][1] + 0.1)];
    
  ::ArraySwap(Array, TmpArray);
              
  return;     
}             

// Сортировка массива структур и указателей на объекты по (под-) полю/методу.
#define ArraySortStruct(ARRAY, FIELD)                                      \
{                                                                          \
  double TmpSort[][2];                                                     \
                                                                           \
  for (int x =::ArrayResize(TmpSort, ::ArraySize(ARRAY)) - 1; x >= 0; x--) \
  {                                                                        \
    TmpSort[x][0] = (double)ARRAY[x].FIELD;                                \
    TmpSort[x][1] = x;                                                     \
  }                                                                        \
                                                                           \
  ::ArraySort(TmpSort);                                                    \
  ::ArrayReindex(ARRAY, TmpSort);                                          \
}                                  
//////////////////

void Delay(int delay)
{
delay = TimeCurrent()+delay;
while(TimeCurrent()<delay) {  }

}

int OnInit()
  {
  IndicatorSetString(INDICATOR_SHORTNAME,"Statistik");
 /* for(int i=0;i<SymbolsTotal(true);i++)
     {
     string sym = SymbolName(i,true);
    
     CopyClose(sym,PERIOD_CURRENT,(TimeCurrent()-2592000),TimeCurrent()-60,close_array);
     long init_bars = SeriesInfoInteger(sym,PERIOD_M1,SERIES_BARS_COUNT); Print("init bars:",init_bars," sym:",sym);
     }
*/     
 +candle;

//Delay(60);
  //Print("Init");
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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("oninit");
   time_current = TimeCurrent()-60;
   //Print(time_current,check_first);
   if (time_current+5400<(TimeLocal()) || check_first)  
   {
   //Print(check_first);
   check_first = false;

   file_handle = FileOpen("symb_volume",FILE_WRITE,FILE_READ,FILE_CSV);
   //Print("file_handle ",file_handle); 
   int sym_tot=SymbolsTotal(true); 
   
   for(int i=0;i<SymbolsTotal(true);i++)
     {
         string sym = SymbolName(i,true);
       
      //Print(sym);
        
       
       for(int i_1=0;i_1<ArrayRange(tf,0);i_1++)
         {
          
            to_file.sym=sym;        Print(to_file.sym);   
            to_file.tf=tf[i_1]; Print(to_file.tf);
            time_dest = time_current-2592000;
            
   //         Print("serios first date:",first_date);
            int cost =Bars(sym,tf[i_1],time_dest,time_current);
            Print("bars ",cost,", ", _LastError,", Cимвол:",sym); ResetLastError();
            int y = CopyRates(sym,tf[i_1],time_dest,time_current,rates);
           Print("copy rates",y,", ", _LastError,", Cимвол:",sym);ResetLastError();
          //if(y<10) Print(i_1); Delay(60); i_1=0; continue;
            if(iRealVolume(sym,tf[i_1],5)==0)           
            {
             ArraySortStruct(rates, tick_volume);
             int z=ArrayCopy(rates_print,rates,0,ArrayRange(rates,0)-10,10); 
             Print("bars copied:",z); 
             ArraySortStruct(rates_print, tick_volume);
            sym_itogo = "Символ:"+sym+"   ТФ:"+EnumToString(tf[i_1])+"   Макс.объем:"+rates_print[9].tick_volume;
            Print(sym_itogo);
            if(rates_print[9].tick_volume>5000000000)  i_1=0;Print(sym_itogo); continue;
            //Print(time_dest);
            //Print(time_current);
            to_file.vol = rates_print[0].tick_volume; //Print(to_file.vol);
           //ArrayPrint(rates_print);
            
             }
            else if(iRealVolume(sym,tf[i_1],5)>0)
             {
               ArraySortStruct(rates, real_volume);
               ArrayCopy(rates_print,rates,0,ArrayRange(rates,0)-10,10);  
               ArraySortStruct(rates_print, real_volume);
               sym_itogo = "Символ:"+sym+"  ТФ:"+EnumToString(tf[i_1])+"   Макс.объем:"+rates_print[9].real_volume;
               Print(sym_itogo);
               //Print(ArraySize(rates_print));
               to_file.vol = rates_print[0].real_volume;
             }
             
             string str_to_f;
             StringConcatenate(str_to_f,to_file.sym,";",to_file.tf,";",StringToInteger(to_file.vol));
             StringTrimLeft(str_to_f);
             StringTrimRight(str_to_f);
             FileWrite(file_handle,str_to_f);
             Print(str_to_f);
             //ArrayPrint(rates_print);
            
          
         } 
       
    
     }
 FileClose(file_handle);
   }
   
   


//ЧТЕНИЕ ДАННЫХ ПО ОБЪЕМАМ ИЗ ФАЙЛА
 if (!(FileIsExist("symb_volume"))) file_handle = FileOpen("symb_volume",FILE_WRITE); FileClose(file_handle);
file_handle = FileOpen("symb_volume",FILE_READ,FILE_WRITE,FILE_CSV);

int i_2 = 0; 
do
{

ArrayResize(from_file,(ArrayRange(from_file,0)+1),0);
string value=FileReadString(file_handle); 
//Print(value);
string value_split[3]; 
StringSplit(value,StringGetCharacter(";",0),value_split);
//   if(value_split[0]==NULL||value_split[1]==NULL||value_split[2]==NULL) i_2++; continue;
from_file[i_2].sym=value_split[0];
from_file[i_2].tf=value_split[1];
//int proba=StringToInteger(value_split[2]);
from_file[i_2].vol=StringToInteger(value_split[2]);
 i_2++;
 
}
while(!FileIsEnding(file_handle));

//ArrayPrint(from_file);
FileClose(file_handle); 
/*

*/
 +candle;
    for(int i_tf=0;i_tf<ArrayRange(tf,0);i_tf++)
         {
            
            if((candle[(ENUM_TIMEFRAMES)tf[i_tf]]))
            
               {  
               
                  //Print("Candle");
                 // Print(i_tf);
                  //Print(sym);
                  for(int i=0;i<(ArrayRange(from_file,0));i++)
                     {
                        //for(int i_1=0;i_1<ArrayRange(tf,0);i_1++)
                           //{
                                  //Print(1);
                                  //Print(from_file[i].sym,"   ",iTickVolume(from_file[i].sym,PERIOD_M1,0));
                                 int real_vol = iRealVolume(from_file[i].sym,(ENUM_TIMEFRAMES)from_file[i].tf,1);
                                 
                                 if (real_vol == 0) real_vol = iTickVolume(from_file[i].sym, (ENUM_TIMEFRAMES)from_file[i].tf,1);
                                 
                                 if (real_vol>from_file[i].vol && from_file[i].vol>0&&!(alert_counter=real_vol))  //from_file[i].sym!=NULL && 
                                       {
                                       
                                        Alert(from_file[i].sym, "   повышенный объем!!   ",real_vol,"  против расчетного  ",from_file[i].vol,"   на тф  ", EnumToString((ENUM_TIMEFRAMES)from_file[i].tf));
                                       Print(from_file[i].sym, "   повышенный объем!!   ",real_vol,"  против расчетного  ",from_file[i].vol,"   на тф  ", EnumToString((ENUM_TIMEFRAMES)from_file[i].tf));
                                        //ArrayPrint(from_file);
                                        //PrintFormat(from_file[i].sym, "   повышенный объем!!   ",real_vol,"  против расчетного  ",from_file[i].vol,"   на тф  ", EnumToString(tf[i_tf]));
                                        alert_counter=real_vol;
                                        Print(alert_counter);
                                       }
                                 //string sym = SymbolName(i,true);
                           
                                 //Print(iTickVolume(SymbolName(i,true),)
                                
         
                  //}
                  }
   }
         }

    //  else Print(1);
   ArrayFree(from_file);
   return(rates_total);
  }
 
Виктор Астахов:

Зато вот такая версия в итоге работает правильно. Убрал все проверки. Сначала оут оф рэндж, не скопировал значит бары. Это понятно. Повторный запуск, начинает копировать, но какие-то гигантские объемы. Удаляю индюк, снова запускаю еще пару раз, та же картина.
И раз на пятый, он копирует правильные объемы, и переходит на следующий этап.

Почему так?


 file_handle = FileOpen("symb_volume",FILE_WRITE,FILE_READ,FILE_CSV);

WTF ?

 
Maxim Kuznetsov:

WTF ?

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

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