Multiple PeriodConverter - Help needed ! I modified original script to use multiple periods, but missed something

 

Hello MQL community,

 

I am trying to adjust the script PeriodConverter that is included in MT4 samples, to use multiple timeframe periods in one conversion script.

The modified script works partially, but the modified part isn't updating on chart as original does.

With this script can be generated and used as regular charts, (even they are opened with File -> Open Offline), any custom periods of existing charts, M2, M3, H2, H5... even strange periods like M7 , M11 or H9. 

I attach code (see SRC below) , I think it can be usefull for other users if can be made to work with multiple periods output, maybe 4-5 periods in a shot (first, let's make it work with 2 periods).

I found very interesting that when opening offline chart generated by original script, can be seen updated prices, add indicators, additional scripts, even activate "Show Ask line".

There is only a delay of about one second in updating chart (initially it was 2 seconds but I changed value of delay to 1).

In the modified part , the calculation is made OK as it seems, but only to history part and doesn't update Ask & Bid lines.

If I open in Offline mode the generated charts, the first chart is updating and works great, but the second isn't. 

I'm new in programing MQL, can anyone help to correct this problem, and maybe to eliminate redundant / not necessary parameters that can be used only once in a run, to speed up script execution?

 

Thank you 

 

  Please, any ideas ?

 

For easier view, I attach source code in text. The second period variables that I added have 2 in the endpart of the name.  

Waiting for your help please, to tell what is the issue for the second chart doesn't update the same as the original does.

 Thank you

 

This is the begining part of the modified script, that seems to work OK: 

 

//+------------------------------------------------------------------+
//|                                              PeriodConverter.mq4 |
//|                   Copyright 2006-2014, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright   "2006-2014, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"
#property description "Period Converter to updated format of history base"
#property strict
#property show_inputs
#include <WinUser32.mqh>

input int InpPeriodMultiplier=2; // Period multiplier factor 1
input int InpPeriodMultiplier2=3; // Period multiplier factor 2    // ** Supplementary variable added
int       ExtHandle=-1;
int       ExtHandle2=-1;                                           // ** Supplementary variable handle added
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   datetime time0;
   ulong    last_fpos=0;
   ulong    last_fpos2=0;                                         // ** Supplementary fileposition added                    
   long     last_volume=0,last_volume2=0;
   int      i,start_pos,periodseconds,periodseconds2;
   int      hwnd=0,hwnd2=0,cnt=0,cnt2=0;
//---- History header
   int      file_version=401;
   string   c_copyright;
   string   c_symbol=Symbol();
   int      i_period=Period()*InpPeriodMultiplier;
   int      i_period2=Period()*InpPeriodMultiplier2;
   int      i_digits=Digits;
   int      i_unused[13];
   MqlRates rate, rate2;
//---  
   ExtHandle=FileOpenHistory(c_symbol+(string)i_period+".hst",FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI);
   ExtHandle2=FileOpenHistory(c_symbol+(string)i_period2+".hst",FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI);
   if(ExtHandle<0)
      return;
   if(ExtHandle2<0)
      return;
   c_copyright="(C)opyright 2003, MetaQuotes Software Corp.";
   ArrayInitialize(i_unused,0);
//--- write history file header
   FileWriteInteger(ExtHandle,file_version,LONG_VALUE);
   FileWriteString(ExtHandle,c_copyright,64);
   FileWriteString(ExtHandle,c_symbol,12);
   FileWriteInteger(ExtHandle,i_period,LONG_VALUE);
   FileWriteInteger(ExtHandle,i_digits,LONG_VALUE);
   FileWriteInteger(ExtHandle,0,LONG_VALUE);
   FileWriteInteger(ExtHandle,0,LONG_VALUE);
   FileWriteArray(ExtHandle,i_unused,0,13);
   
//--- write history file header2
   FileWriteInteger(ExtHandle2,file_version,LONG_VALUE);
   FileWriteString(ExtHandle2,c_copyright,64);
   FileWriteString(ExtHandle2,c_symbol,12);
   FileWriteInteger(ExtHandle2,i_period2,LONG_VALUE);
   FileWriteInteger(ExtHandle2,i_digits,LONG_VALUE);
   FileWriteInteger(ExtHandle2,0,LONG_VALUE);
   FileWriteInteger(ExtHandle2,0,LONG_VALUE);
   FileWriteArray(ExtHandle2,i_unused,0,13);
//--- write history file
   periodseconds=i_period*60;
   periodseconds2=i_period2*60;
   start_pos=Bars-1;
   
   rate.open=Open[start_pos];
   rate.low=Low[start_pos];
   rate.high=High[start_pos];
   rate.tick_volume=(long)Volume[start_pos];
   rate.spread=0;
   rate.real_volume=0;
   
   rate2.open=rate.open;
   rate2.low=rate.low;
   rate2.high=rate.high;
   rate2.tick_volume=rate.tick_volume;
   rate2.spread=0;
   rate2.real_volume=0;
   //--- normalize open time
   rate.time=Time[start_pos]/periodseconds;
   rate.time*=periodseconds;
   
   rate2.time=Time[start_pos]/periodseconds2;
   rate2.time*=periodseconds2;
   for(i=start_pos-1; i>=0; i--)
     {
      if(IsStopped())
         break;
      time0=Time[i];
      //--- history may be updated
      if(i==0)
        {
         //--- modify index if history was updated
         if(RefreshRates())
            i=iBarShift(NULL,0,time0);
        }
      //---
      if(time0>=rate.time+periodseconds || i==0)
        {
         if(i==0 && time0<rate.time+periodseconds)
           {
            rate.tick_volume+=(long)Volume[0];
            if(rate.low>Low[0])
               rate.low=Low[0];
            if(rate.high<High[0])
               rate.high=High[0];
            rate.close=Close[0];
           }
         last_fpos=FileTell(ExtHandle);
         last_volume=(long)Volume[i];
         FileWriteStruct(ExtHandle,rate);
         cnt++;
         if(time0>=rate.time+periodseconds)
           {
            rate.time=time0/periodseconds;
            rate.time*=periodseconds;
            rate.open=Open[i];
            rate.low=Low[i];
            rate.high=High[i];
            rate.close=Close[i];
            rate.tick_volume=last_volume;
           }
        }
       else
        {
         rate.tick_volume+=(long)Volume[i];
         if(rate.low>Low[i])
            rate.low=Low[i];
         if(rate.high<High[i])
            rate.high=High[i];
         rate.close=Close[i];
        }
      
   //---   // Start RATE2:
      if(time0>=rate2.time+periodseconds2 || i==0)
        {
         if(i==0 && time0<rate2.time+periodseconds2)
           {
            rate2.tick_volume+=(long)Volume[0];
            if(rate2.low>Low[0])
               rate2.low=Low[0];
            if(rate2.high<High[0])
               rate2.high=High[0];
            rate2.close=Close[0];
           }
         last_fpos2=FileTell(ExtHandle2);
         last_volume2=(long)Volume[i];
         FileWriteStruct(ExtHandle2,rate2);
         cnt2++;
         if(time0>=rate2.time+periodseconds2)
           {
            rate2.time=time0/periodseconds2;
            rate2.time*=periodseconds2;
            rate2.open=Open[i];
            rate2.low=Low[i];
            rate2.high=High[i];
            rate2.close=Close[i];
            rate2.tick_volume=last_volume2;
           }
        }
       else
        {
         rate2.tick_volume+=(long)Volume[i];
         if(rate2.low>Low[i])
            rate2.low=Low[i];
         if(rate2.high<High[i])
            rate2.high=High[i];
            rate2.close=Close[i];
        }  
         // FINAL RATE2  
     } 
   FileFlush(ExtHandle);
   FileFlush(ExtHandle2);     // This part works fine
 

Waiting for any ideas ...

I suppose the problem with refreshing second chart & file comes from the end part of the script, but I don't know exactly where :

  

   
   Print(cnt," record(s) written // ",cnt2," record2(s) written");
//--- collect incoming ticks
   datetime last_time=LocalTime()-5;
   while(!IsStopped())
     {
      datetime cur_time=LocalTime();
      //--- check for new rates
      if(RefreshRates())
        {
         time0=Time[0];
         FileSeek(ExtHandle,last_fpos,SEEK_SET);
         //--- is there current bar?
         if(time0<rate.time+periodseconds)
           {
            rate.tick_volume+=(long)Volume[0]-last_volume;
            last_volume=(long)Volume[0]; 
            if(rate.low>Low[0])
               rate.low=Low[0];
            if(rate.high<High[0])
               rate.high=High[0];
            rate.close=Close[0];
           }
         else
           {
            //--- no, there is new bar
            rate.tick_volume+=(long)Volume[1]-last_volume;
            if(rate.low>Low[1])
               rate.low=Low[1];
            if(rate.high<High[1])
               rate.high=High[1];
            //--- write previous bar remains
            FileWriteStruct(ExtHandle,rate);
            last_fpos=FileTell(ExtHandle);
            //----
            rate.time=time0/periodseconds;
            rate.time*=periodseconds;
            rate.open=Open[0];
            rate.low=Low[0];
            rate.high=High[0];
            rate.close=Close[0];
            rate.tick_volume=(long)Volume[0];
            last_volume=rate.tick_volume;
           }
           
         FileSeek(ExtHandle2,last_fpos2,SEEK_SET);
         if(time0<rate2.time+periodseconds2)
           {
            rate2.tick_volume+=(long)Volume[0]-last_volume2;
            last_volume2=(long)Volume[0]; 
            if(rate2.low>Low[0])
               rate2.low=Low[0];
            if(rate2.high<High[0])
               rate2.high=High[0];
            rate2.close=Close[0];
           }
         else
           {
            //--- no, there is new bar
            rate2.tick_volume+=(long)Volume[1]-last_volume2;
            if(rate2.low>Low[1])
               rate2.low=Low[1];
            if(rate2.high<High[1])
               rate2.high=High[1];
            //--- write previous bar remains
            FileWriteStruct(ExtHandle2,rate2);
            last_fpos2=FileTell(ExtHandle2);
            //----
            rate2.time=time0/periodseconds2;
            rate2.time*=periodseconds2;
            rate2.open=Open[0];
            rate2.low=Low[0];
            rate2.high=High[0];
            rate2.close=Close[0];
            rate2.tick_volume=(long)Volume[0];
            last_volume2=rate2.tick_volume;
           }
         //----
         FileWriteStruct(ExtHandle,rate);
         FileWriteStruct(ExtHandle2,rate2);
         FileFlush(ExtHandle2);
         FileFlush(ExtHandle);
         //---
         if(hwnd==0)
           {
            hwnd=WindowHandle(Symbol(),i_period);
            if(hwnd!=0)
               Print("Chart window detected period ", i_period);
           }
          if(hwnd2==0)
           {
            hwnd2=WindowHandle(Symbol(),i_period2);
            if(hwnd2!=0)
               Print("Chart window detected period ", i_period2);
           }
         //--- refresh window not frequently than 1 time in 1 second
         if(hwnd!=0 && hwnd2!=0 && cur_time-last_time>=1)
           {
            PostMessageA(hwnd,WM_COMMAND,33324,0);
            last_time=cur_time;
           }
        }
      Sleep(20); 
     }      
//---
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(ExtHandle>=0)
     {
      FileClose(ExtHandle);
      ExtHandle=-1;
     }
   if(ExtHandle2>=0)
     {
      FileClose(ExtHandle2);
      ExtHandle2=-1;
     }
//---
  }
//+------------------------------------------------------------------+
 
geru:

  Please, any ideas ?

 

For easier view, 

I can't see any comments in the code posted explaining what you changed and why  . . .  document your changes then it would be easier for someone else to help you,  they would easily and quickly see what you have done.
 
RaptorUK:
I can't see any comments in the code posted explaining what you changed and why  . . .  document your changes then it would be easier for someone else to help you,  they would easily and quickly see what you have done.

I added supplementary variables ending in 2 , for example  InpPeriodMultiplier2 , ExtHandle2  .

The changes were that I made again all the original calculation for another period, all new variables ending with 2.

This is just a prototype, when will be working I will use an array of MQLrates. As soon as will update on all charts the values.

Searching on internet, I found another function that could help (thanks to pips4life & original idea of rangebound) : 

 

void UpdateMultipleChartWindows()
{
  // This routine by pips4life is an offshoot of an incomplete (but useful)
  // suggestion by rangebound how to solve the problem that WindowHandle()
  // only returns the first window it finds.
  
  int hwnd,len;
  
  // GetWindowTextA overwrites gwstr but it should initially be at least as long as it will become.
  //     //12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789  //119 chars
  gwstr = "                                                                                                                       ";
  symboloutput = 
  hwnd = WindowHandle(symboloutput,NewPeriodDisplayed); //This is non-zero if at least one matching window exists
  if (hwnd != 0)
  {
    hwnd=GetParent(hwnd);
    hwnd = GetWindow(hwnd,GW_HWNDFIRST); 
    while (hwnd !=0)
    {
      len = GetWindowTextA(hwnd,gwstr,80);
      if ((len > 0) )      // MY MODIFIED !!!   initially was : if ((len >0) && gwstr == offlineChartName)
      {
         PostMessageA(hwnd,WM_COMMAND,CHART_CMD_UPDATE_DATA,0);
      }
      hwnd = GetWindow(hwnd,GW_HWNDNEXT);
    }
  }
} // end of UpdateMultipleChartWindows

 

I try to intregrate this in script but give error :   gwstr : Parameter conversion not allowed

 Original script from pips4life is attached.  Pips4life also had the problem with only one chart updating, but he solved the problem by this function.

 His script seems to be very good, complex but I want to keep the script very simple.

Files:
 

"I try to intregrate this in script but give error :   gwstr : Parameter conversion not allowed"

Put a 'W' on the end of the function call

Reason: