Reputation: 11
Recently I came across a new funny problem. Function of the code: Open New Chart --> Apply Template --> Take Screenshot --> Close Chart.
But in 30% an error occurs. ERROR 4024. The Chart Opens, but It doesn't return the Chart ID. I've programmed a little workaround where I check if there are now mow Charts open, if yes I just select the latest one. but then I have the error 4024 at applying the chart template. so not good solution...
4024 - ERR_INTERNAL_ERROR - Internal error
But Is there a clean version to avoid that bug or a better workaround?
Whole Code which is used for working with the Charts: As It may be a problem of the message queue...
//*************************************************************************************************************************
//*** Send Screenshot function ***************************************************************************************
//*************************************************************************************************************************
bool SendScreenShot( const long _chatID, //Unique identifier for the target chat
const string _symbol, //Symbol
const ENUM_TIMEFRAMES _period, //Timeframe
int _width_X = NULL, //Width in pixels
int _hight_Y = NULL, //Hight in pixels
const string _template = "", //Template
string _msg = "") //Caption
{
//--- Write all Open Chart IDs into Array so we can delete new Chart Arrays at the end of the function
long cntChartID [100]; //Max 100 Charts
cntChartID[0] = ChartFirst(); //First chart ID of the client terminal.
for(int iCharts = 1; iCharts <= 100; iCharts++) //Loop trough every Chart
{
cntChartID[iCharts] = ChartNext(cntChartID[iCharts-1]); //Get chart ID of the chart next to the specified one.
if(cntChartID[iCharts] == -1) //If this is the end of the chart list, Chart ID = -1.
{
ArrayResize(cntChartID, iCharts); //Resize Array
break;
}
}
//--- Open New Chart and apply template
long chartID = OpenNewChart(_symbol, _period, _template);
if(chartID == 0) { return false; }
//--- Get Pixels
if(_width_X == NULL) { _width_X = (int)ChartGetInteger(chartID, CHART_WIDTH_IN_PIXELS); }
if(_hight_Y == NULL) { _hight_Y = (int)ChartGetInteger(chartID, CHART_HEIGHT_IN_PIXELS); }
if(true) { _width_X = (int)round(_hight_Y/1.6); } //Special for myself about format
//--- Get Message
if(_msg == "") { _msg = _symbol+"_"+StringSubstr(EnumToString(_period),7); }
//--- Check file
string fileName = StringFormat("%s%d.gif", _symbol, _period);
if(FileIsExist(fileName)) { FileDelete(fileName); }
bool result = true;
//--- Take Screenshot
if(ChartScreenShot(chartID, fileName, _width_X, _hight_Y, ALIGN_RIGHT))
{
printf("Taking ScreenShot Succeded (%ix%i)", _width_X, _hight_Y);
Sleep(100);
bot.SendChatAction(_chatID, ACTION_UPLOAD_PHOTO); //Send Action to Telegram (Uploading photo...)
//--- waitng max 30 sec to save screenshot
int wait=300;
while(!FileIsExist(fileName))
{
Sleep(100);
wait --;
if(wait <= 0) { Print(LOG, " Waited for 30sec, but file was not safed"); result = false; break; }
}
if(FileIsExist(fileName))
{
string screenID;
int res = bot.SendPhoto(screenID, _chatID, fileName, _msg, "HTML");
if(res == 0) { Print("Taking Screenshot succeded!"); result = true; }
else { Print(LOG, " Sending screenshot to Telegram failed; ", ErrorMsg(res)); result = false;}
}
}
else { Print(LOG, " Error at taking screenshot; ", ErrorMsg()); result = false;}
//--- Close All newly opened Charts
int indexSearch;
chartID = ChartFirst();
ArraySort(cntChartID); //Binary search processes only sorted arrays. To sort numeric arrays use the ArraySort() function.
while(chartID > 0)
{
indexSearch = ArrayBsearch(cntChartID, chartID); //Search for selected Chart ID in Array
if(chartID != cntChartID[indexSearch]) //ChartID not found in Array --> New Chart which can be closed
{
if(!ChartClose(chartID)) { printf("%s Chart Close failed! %s %s ID: %.0f %s", LOG, ChartSymbol(chartID), TF2Str(ChartPeriod(chartID)), chartID, ErrorMsg()); }
Sleep(100);
}
chartID = ChartNext(chartID);
}
return result;
}
//*************************************************************************************************************************
//*** Open new Chart ***************************************************************************************************
//*************************************************************************************************************************
long OpenNewChart( const string _symbol,
const ENUM_TIMEFRAMES _period,
const string _template = "")
{
//--- Chount Open Charts
long cntChartID = ChartFirst();
int nCharts = 0;
while(cntChartID > 0)
{
cntChartID = ChartNext(cntChartID);
nCharts ++;
}
//--- Max Number of Charts reached (close 80 Charts)
if(nCharts >= CHARTS_MAX)
{
Print(LOG, " Max Number of Charts reached! Close till 20 charts");
//Close Charts (leave 20 Charts Open)
cntChartID = ChartFirst();
for(int i=1; i<20; i++) { cntChartID = ChartNext(cntChartID); } //Select Chart 20
for(int i=0; i<100; i++) //Close the other 80 charts
{
cntChartID = ChartNext(cntChartID); // Get the new chart ID by using the previous chart ID
if(cntChartID<0) { break; } // Have reached the end of the chart list
if(!ChartClose(cntChartID)) { printf("%s Chart Close failed! %s %s ID: %.0f %s", LOG, ChartSymbol(cntChartID), TF2Str(ChartPeriod(cntChartID)), cntChartID, ErrorMsg()); }
}
Sleep(100);
}
//--- Open Chart
Sleep(100);
long chartID = ChartOpen(_symbol, _period); //30% no chart id
if(chartID > 0) //Chart Open succeded
{
printf("Successfully Opend New Chart, %s %s", _symbol, EnumToString(_period));
}
else if(GetLastError() == 4024) //Chart open failed with error 4024 Internal error
{
Print(LOG, " Chart Open failed! ", ErrorMsg(4024));
//Count again all Charts, because it shou have opend the chart but just not retourned a Chart ID. (BUG ERROR 4024)
int nChartsOld = nCharts; nCharts = 0;
long cntChartIDprev = 0; cntChartID = ChartFirst();
while(cntChartID > 0)
{
cntChartIDprev = cntChartID;
cntChartID = ChartNext(cntChartIDprev);
nCharts ++;
printf("%i) %.0f %s %s", nCharts, cntChartIDprev, ChartSymbol(cntChartIDprev), EnumToString(ChartPeriod(cntChartIDprev)));
}
printf("Open Charts before: %i, Current Open Charts: %i", nChartsOld, nCharts);
//More open Charts than before error
if(nCharts > nChartsOld)
{
chartID = cntChartIDprev;
printf("%s Chart opend but trough Bug in MQL4 didn't return ID, Selected latest Chart: %s %s", LOG, ChartSymbol(chartID), EnumToString(ChartPeriod(chartID)));
}
}
else //Chart open failed because of other error, try to open again
{
int attempt = 1;
while(chartID == 0 && attempt < 4)
{
printf("%s %i. Attempt to open a new Chart failed! %s", LOG, attempt, ErrorMsg());
Sleep(1000); //Wait 1 Sec then try again
chartID = ChartOpen(_symbol, _period);
attempt ++;
}
}
if(chartID == 0) { Print(LOG, " Chart open failed completely!"); return -1; } //Still No Chart ID. Return
//--- updates chart
int wait=100;
while(--wait>0)
{
if(SeriesInfoInteger(_symbol, _period, 5)) { printf("%s Waited for %.1f Seconds to update chart [%s (%i)]", LOG, (100-wait)*0.1); break; }
Sleep(100);
}
//--- Apply Chart Template
bool res = false;
if(_template != "")
{
res = ChartApplyTemplate(chartID, _template);
if(res) { Print("Applied Chart Template ", _template, " successfully"); }
else if(!res && GetLastError() == 5020) { Print(LOG, " Apply Template to Chart failed, Template: ", _template, " ", ErrorMsg(5020)); }
else { Print(LOG, " Apply Template to Chart failed, Template: ", _template, " ", ErrorMsg()); }
}
if(_template == "" || res == false)
{
if(!ChartSetInteger(chartID,CHART_SHOW_GRID,false)) { Print(LOG, " Error at ChartSetInteger -> Show Grid (false); ", ErrorMsg()); }
if(!ChartSetInteger(chartID,CHART_SHOW_PERIOD_SEP,false)) { Print(LOG, " Error at ChartSetInteger -> Show Period Sep (false); ", ErrorMsg()); }
if(!ChartSetInteger(chartID,CHART_SCALE,3)) { Print(LOG, " Error at ChartSetInteger -> Chart Scale (3); ", ErrorMsg()); }
}
//Redraw
Sleep(100);
ChartRedraw(chartID);
Sleep(100);
return chartID;
}
Upvotes: 1
Views: 785
Reputation: 1403
Try running the following code to check for ChartOpen() errors.
//+------------------------------------------------------------------+
//| Test.mq4 |
//| ©Copyright 2021 PaulB |
//| https://bespokecoding.co.uk |
//+------------------------------------------------------------------+
#property copyright "©Copyright 2021 PaulB"
#property link "https://bespokecoding.co.uk"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int init()
{
EventSetMillisecondTimer(250);
return(0);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
EventKillTimer();
return(0);
}
//+------------------------------------------------------------------+
//| Expert start function |
//+------------------------------------------------------------------+
int start()
{
return(0);
}
//+------------------------------------------------------------------+
//| Expert start function |
//+------------------------------------------------------------------+
void OnTimer()
{
customFunction();
}
//+------------------------------------------------------------------+
//| Custom functions |
//+------------------------------------------------------------------+
bool customFunction()
{
long chartID = ChartOpen(Symbol(), PERIOD_M1);
if(chartID==0) Print("Error: ",GetLastError());
else ChartClose(chartID);
return(true);
}
Upvotes: 0