最近我遇到了一个新的有趣的问题。代码功能:打开新图表 --> 应用模板 --> 截图 --> 关闭图表。
但是在 30% 中会发生错误。错误 4024。 图表打开,但不返回图表 ID。我编写了一个小解决方法,我检查现在是否打开了割草图表,如果是,我只选择最新的。但后来我在应用图表模板时出现错误 4024。所以不是很好的解决方案...
4024 - ERR_INTERNAL_ERROR - 内部错误
但是是否有一个干净的版本来避免该错误或更好的解决方法?
用于处理图表的完整代码:因为它可能是消息队列的问题......
//*************************************************************************************************************************
//*** 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;
}