ChartOpen not returning long ChartID?

 

Hello

‌In th‌e init section of an EA Im successfully opening a chart of a different timeframe. (The chart opens). However, ChartOpen is not returning the chart id, which according to this it should. Instead it returns 0, and printing GetLastError says "internal error"‌

After opening the chart I want to apply a template with an indicator ‌using ChartApplyTemplate, but this functions needs the chartid

Any ideas? Thank you.

    tpChartID = ChartOpen(Symbol(), TMPRD);

    if (tpChartID==0) {
        Print(ErrorDescription(GetLastError()));
        Print("ChartID = ",tpChartID);
        return(INIT_FAILED);
    }

    if (!ChartApplyTemplate(tpChartID, "\\indicators\\FlowTP.tpl")) {
        Print("Could not apply template");
        return(INIT_FAILED);
    }

Documentation on MQL5: Chart Operations / ChartOpen
Documentation on MQL5: Chart Operations / ChartOpen
  • www.mql5.com
Chart Operations / ChartOpen - Reference on algorithmic/automated trading language for MetaTrader 5
 

is tpChartID declared as long type?

Im having similar issue opening multiple charts, gives me 4024 error....still cant fix it. 

 
dottybee:

is tpChartID declared as long type?

Im having similar issue opening multiple charts, gives me 4024 error....still cant fix it. 

Post the code.

 

Ok, i never post in forums, so hopefully i do it right...

This is a script I have that loads all charts and their respective EA (through a template file). I run it once, it opens all the charts after it removes all the old ones.

The code worked fine first couple times, now it refuses to work at all even with 8 files/charts (10 less than before). Error code returned is 4024.
I have tried closing all other applications and have only this terminal open with zero charts and I have tried restarting the terminal.

This code is in OnStart() and no user inputs.

   bool _ClearCharts = true;
   // First, close all other charts
   if( _ClearCharts ){
      long currChart,prevChart=ChartFirst();
      int i=0,limit=100;
           
      ChartClose(prevChart);
      while(i<limit)// We have certainly not more than 100 open charts
      {
         currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID
         if(currChart<0) break;          // Have reached the end of the chart list
         ChartClose(currChart);
         prevChart=currChart;// let's save the current chart ID for the ChartNext()
         i++;// Do not forget to increase the counter
      }
   }   
   
   
   long id;
   string Portfolio = "HIGHRISK";
   string file_name, chart;
   long search_handle=FileFindFirst("ASSETI/Templates/"+Portfolio+"/*",file_name);
   if(search_handle!=INVALID_HANDLE)
   {
      do
      {
         chart = StringSubstr(file_name,0,6); 
         if( StringSubstr(file_name,StringLen(file_name)-4,4) != ".tpl" ) continue;
            
         id = ChartOpen(chart,PERIOD_M15);
         
         Print("file_name = ", file_name, ". Chart= ", chart, ", Chart#",id);
         
         if( id > 0 ){
            if(ChartApplyTemplate(id,"//Files/ASSETI/Templates/"+Portfolio+"/"+file_name))
              { 
               Print("The template 'XX' applied successfully"); 
              } 
            else 
               Alert("Failed to apply '"+file_name+"', error code ",GetLastError());          
         } else {
            
            Alert("Failed to open Chart '"+chart+"' with file '"+file_name+"'. "+id,". Error:", GetLastError());
         }
      } while( FileFindNext(search_handle,file_name) );
      FileFindClose(search_handle);
   }
   else
      Alert("Strategy Files not found!");
   
   return;   

Any other ideas to try would be greatly appreciated.

I hope this is ok posting my problem in someone elses thread, as it is similar? If not, happy to start a new one.

Thanks

 
      long currChart,prevChart=ChartFirst();
      int i=0,limit=100;
           
      ChartClose(prevChart);
      while(i<limit)// We have certainly not more than 100 open charts
      {
         currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID
         if(currChart<0) break;          // Have reached the end of the chart list
         ChartClose(currChart);
         prevChart=currChart;// let's save the current chart ID for the ChartNext()
         i++;// Do not forget to increase the counter
      }

Only in this part there are 2 bugs, one from the original (you got this code from the documentation) and one you introduced. Can you find them ?

Beside that, there is no need to use i and limit.

 
Alain Verleyen:

Only in this part there are 2 bugs, one from the original (you got this code from the documentation) and one you introduced. Can you find them ?

Beside that, there is no need to use i and limit.

Interesting... worked fine as is, but I took a closer look at it. Not really sure where the bugs were but I took your advice and cleaned it up a little.... ?

   bool _ClearCharts = true;
   // First, close all other charts
   if( _ClearCharts ){
      long currChart,prevChart=ChartFirst();

      do
      {
         currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID
         ChartClose(prevChart);
         prevChart=currChart;// let's save the current chart ID for the ChartNext()
      } while( currChart > 0 );
   }   
 
dottybee:

Interesting... worked fine as is, but I took a closer look at it. Not really sure where the bugs were but I took your advice and cleaned it up a little.... ?

It is not. It will close the chart where you run the code (try it standalone to check)

The first version :

  long currChart,prevChart=ChartFirst();   
      int i=0,limit=100;
      // Both ChartClose() don't check if they are closing current chart.
      ChartClose(prevChart);       
      while(i<limit)// We have certainly not more than 100 open charts
      {
         currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID
         if(currChart<0) break;          // Have reached the end of the chart list
         ChartClose(currChart);
         prevChart=currChart;// let's save the current chart ID for the ChartNext()
         i++;// Do not forget to increase the counter
      }

Your second version introduce a new bug :

   bool _ClearCharts = true;
   // First, close all other charts
   if( _ClearCharts ){
      long currChart,prevChart=ChartFirst();

      do  // You are applying ChartFirst() and immediately after ChartNext(), you potentially "missed" one chart (or by chance you didn't close the current chart any more)
      {
         currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID
         ChartClose(prevChart);
         prevChart=currChart;// let's save the current chart ID for the ChartNext()
      } while( currChart > 0 );
   }   

Bug free and simpler code :

  bool _ClearCharts = true;
  //--- First, close all OTHER charts
  if( _ClearCharts )
    {
    long current=ChartID(),chartID=ChartFirst();

    while(chartID!=WRONG_VALUE)         // Wrong value = -1
      {
      if(chartID!=current)
        ChartClose(chartID);            // Ideally we could add a check of the return value to be sure it was closed
      chartID=ChartNext(chartID);       // Get the new chart ID by using the previous chart ID
      }
    }
Update your code and check for your initial issue.
 

Aha! Youre a genius! Thanks for making me aware of the bugs, it makes sense! Many thanks Alain, very much appreciated. I couldnt figure that one out for 2 days and couldnt find anything online to resolve it.

I want to close the current chart as well, so the script basically loads the environment. I added the ChartClose(current) and tested it multiple times, it all works perfectly. Thank you!

Code below for reference...

   bool _ClearCharts = true;
   // First, close all other charts
   if( _ClearCharts ){
    long current=ChartID(),chartID=ChartFirst();

    while(chartID!=WRONG_VALUE)         // Wrong value = -1
      {
      if(chartID!=current)
        ChartClose(chartID);            // Ideally we could add a check of the return value to be sure it was closed
      chartID=ChartNext(chartID);       // Get the new chart ID by using the previous chart ID
      }
      ChartClose(current);              // finally, close current chart 
   }  

// We use .tpl files to determine chart and load all charts programmatically from a file location

   long id;
   string Portfolio = "HIGHRISK";
   string file_name, chart;
   long search_handle=FileFindFirst("ASSETI/Templates/"+Portfolio+"/*",file_name);
   if(search_handle!=INVALID_HANDLE)
   {
      do
      {
         chart = StringSubstr(file_name,0,6); 
         if( StringSubstr(file_name,StringLen(file_name)-4,4) != ".tpl" ) continue;
            
         id = ChartOpen(chart,PERIOD_M15);
         
         Print("file_name = ", file_name, ". Chart= ", chart, ", Chart#",id);
         
         if( id > 0 ){
            if(ChartApplyTemplate(id,"//Files/ASSETI/Templates/"+Portfolio+"/"+file_name))
              { 
               Print("The template 'XX' applied successfully"); 
              } 
            else 
               Alert("Failed to apply '"+file_name+"', error code ",GetLastError());          
         } else {
            
            Alert("Failed to open Chart '"+chart+"' with file '"+file_name+"'. "+id,". Error:", GetLastError());
         }
      } while( FileFindNext(search_handle,file_name) );
      FileFindClose(search_handle);
   }
   else
      Alert("Strategy Files not found!");
   
   return;   
 
dottybee:

Aha! Youre a genius! Thanks for making me aware of the bugs, it makes sense! Many thanks Alain, very much appreciated. I couldnt figure that one out for 2 days and couldnt find anything online to resolve it.

I want to close the current chart as well, so the script basically loads the environment. I added the ChartClose(current) and tested it multiple times, it all works perfectly. Thank you!

Code below for reference...

You should not close the current chart at this place in the code, but at the end of your script. This will avoid you possible future issue.
Reason: