簡體   English   中英

MQL4 錯誤 4024 ChartOpen() 不返回圖表 ID

[英]MQL4 Error 4024 ChartOpen() doesn't return Chart ID

最近我遇到了一個新的有趣的問題。 Function 的代碼: Open New Chart --> Apply Template --> Take Screenshot --> Close Chart

但是在 30% 中會發生錯誤。 錯誤 4024。圖表打開,但不返回圖表 ID 我編寫了一個小解決方法,我檢查現在是否打開了割草圖表,如果是,我只是 select 最新的一個。 但后來我在應用圖表模板時出現錯誤 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;
}

嘗試運行以下代碼來檢查 ChartOpen() 錯誤。

//+------------------------------------------------------------------+
//|                                                         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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM