MQL4 - automated forex trading   /  

Articles

ODL Securities

Articles  Examples  "Free-of-Holes" Charts To post a new articles, please log in or register


This article is about
MetaTrader 4
Download MT4 - 3.5 Mb

Mobile trading!
Buy a license and be mobile in your trading!

"Free-of-Holes" Charts [ ru ]


1.   Motivation

In MT 4, only those bars are drawn, within which at least one price change took place. If no price change occurred within a minute, a one-bar gap will occur in the chart with one-minute period.


The developers have deliberately chosen this way of charts drawing since the most traders that use their product prefer charts, which contain only existing prices. Nevertheless, there are users who like continuous charts. They prefer the bar to be drawn if even its open price is equal to the close price of the preceding bar. Thus, there will be no gaps in the time scale of the chart, and 100 bars will always correspond with 100 minutes in the one-minute chart. These data can be different in the current realization. For example, 100 minutes can "fit" in 98 bars if there were 2 minutes among them when no quotes had income.


Fortunately, there are all necessary tools in MQL 4 that can help to draw such charts independently.

 

2.   Realization

First, let us split the task into two stages:

  • history data processing

  • latest bar updating

At the first stage, we create a new history file with prefix "ALL" before the symbol name ("ALL" means "all bars" here) and write the history with the added bars into it.


A similar problem is solved in the "period_converter" script that is delivered with МТ 4 Client Terminal. The script generates a chart with a non-standard period. We will use this example to learn how to work with the history file.


Before creation of a program, we have to decide what form will it have: Will it be a script, an indicator, or an expert? Indicators are used to display the contents of an array. We don't need it here. As to scripts and experts, the only difference between them is that scripts are deleted from the chart immediately after their operation has been completed. This suits us at this stage, so this will be script that we are going to produce now.


      This is what we get as a result (AllMinutes_Step1.mq4):


#property show_inputs
 
//---- Enable/disable drawing bars on holidays
//---- If == true, holidays will remain unfilled
//---- If == false, holidays will be filled out with bars O=H=L=C
extern bool  SkipWeekEnd = true;
 
int start()
 {
     int HistoryHandle = -1, pre_time, now_time, _PeriodSec;
   double  now_close, now_open, now_low, now_high, now_volume, pre_close;
 
   int    _GetLastError = 0, cnt_copy = 0, cnt_add = 0;
   int    temp[13];
 
   //---- remember the chart symbol and period
      string _Symbol = Symbol();
   int _Period = Period();
   _PeriodSec = _Period * 60;
 
   //---- open file, in which we will write the history
       string file_name = StringConcatenate( "ALL", _Symbol, _Period, ".hst" );
   HistoryHandle = FileOpenHistory( file_name, FILE_BIN | FILE_WRITE );
   if(HistoryHandle < 0 )
      {
          _GetLastError = GetLastError();
     Alert("FileOpenHistory( \"", file_name, "\", 
           FILE_BIN | FILE_WRITE )", " - Error #", _GetLastError );
     return(-1);
    }
 
      //---- Write the file heading
     FileWriteInteger    ( HistoryHandle, 400, LONG_VALUE );
  FileWriteString    ( HistoryHandle, "Copyright © 2006, komposter", 64 );
  FileWriteString    ( HistoryHandle, "ALL" + _Symbol, 12 );
  FileWriteInteger    ( HistoryHandle, _Period, LONG_VALUE );
  FileWriteInteger    ( HistoryHandle, Digits, LONG_VALUE );
  FileWriteInteger    ( HistoryHandle, 0, LONG_VALUE );       //timesign
    FileWriteInteger    ( HistoryHandle, 0, LONG_VALUE );       //last_sync
    FileWriteArray        ( HistoryHandle, temp, 0, 13 );
 
  //+-----------------------------------------------------------------+
    //| Process the history
     //+-----------------------------------------------------------------+
    int bars = Bars;
  pre_time = Time[bars-1];
  for( int i = bars - 1; i >= 0; i-- )
     {
          //---- Remember the bar parameters
         now_open        = Open    [i];
    now_high        = High    [i];
    now_low        = Low        [i];
    now_close    = Close    [i];
    now_volume    = Volume    [i];
    now_time     = Time    [i] / _PeriodSec;
    now_time        *=_PeriodSec;
 
    //---- if there are skipped bars,
         while ( now_time > pre_time + _PeriodSec )
          {
              pre_time += _PeriodSec;
       pre_time    /= _PeriodSec;
       pre_time    *= _PeriodSec;
 
       //---- if it is not the weekend,
              if( SkipWeekEnd )
               {
                   if( TimeDayOfWeek(pre_time) <= 0 || 
            TimeDayOfWeek(pre_time) > 5 ) 
          { 
            continue; 
          }
                 if ( TimeDayOfWeek(pre_time) == 5 )
                 {
                     if( TimeHour(pre_time) == 23 || 
            TimeHour(pre_time + _PeriodSec) == 23 )
                          {
                              continue; 
          }
                 }
             }
 
            //---- write the skipped bar into the file
            FileWriteInteger    ( HistoryHandle, pre_time, LONG_VALUE    );
     FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, 0, DOUBLE_VALUE);
     FileFlush            ( HistoryHandle );
     cnt_add ++;
    }
 
        //---- write the new bar into the file
        FileWriteInteger    ( HistoryHandle, now_time, LONG_VALUE    );
   FileWriteDouble    ( HistoryHandle, now_open, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_low, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_high, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_close, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_volume, DOUBLE_VALUE);
   FileFlush   ( HistoryHandle );
   cnt_copy ++;
 
   //---- remember the time value and the close price 
   //---- of the recorded bar
        pre_close = now_close;
   pre_time  = now_time / _PeriodSec;
   pre_time  *=_PeriodSec;
  }
 
    //---- close the file
    FileClose( HistoryHandle );
 
  //---- display statistics
    Print( "< - - - ", _Symbol, _Period, ": there were ", cnt_copy, 
        " bars, added ", cnt_add, " bars - - - >" );
 Print( "< - - - To view the results, open the chart \"ALL", 
        _Symbol, _Period, "\" - - - >" );
 return(0);
}


It is recommended to pay attention to the SkipWeekEnd variable. If its value is false, the weekends will be filled with bars O=H=L=C (en dashes).

Let us check how our script works by simple attaching it to the one-minute GBPUSD chart:


 
 

Now, let us open the ALLGBPUSD1 chart in offline mode and compare it to the initial chart:

 

As you can see, some skipped minutes were added into the chart. They are circled in red. This is what we wanted to achieve, isn't it?


As we have a chart with the holes filled now, we can update it. The new quotes will be displayed in it, but the new holes will remain unfilled again.


The "period_converter" script can be used as an example again. It can solve the problem of the charts updating, as well. We will make only one change: Add the block of filling the skipped bars.  Since the chart must be updated at every tick, let us transfer our code into the expert. It will be launched every time when a new quote incomes. Let us place the code from the first part into the init() function since this part must be executed only once, and the entire new part of the code will be placed in the start() function since it will be used every tick. Besides, the file closing will go to the deinit(), it is the right place for it.


      Thus, the expert code (AllMinutes_Step2.mq4) is as follows:


#include <WinUser32.mqh>
 
//---- Enable/disable drawing of bars on holidays
//---- If it is == true, the holidays will remain unfilled
//---- If it is == false, the holidays will be filled with the O=H=L=C bars
extern bool  SkipWeekEnd = true;
 
int  HistoryHandle = -1, hwnd = 0, last_fpos = 0, pre_time, now_time;
int  _Period, _PeriodSec;
double  now_close, now_open, now_low, now_high, now_volume;
double  pre_close, pre_open, pre_low, pre_high, pre_volume;
string  _Symbol;
 
int init()
 {
     int    _GetLastError = 0, cnt_copy = 0, cnt_add = 0;
   int    temp[13];
 
   //---- remember the chart symbol and period
       _Symbol = Symbol();
   _Period = Period();
   _PeriodSec = _Period * 60;
   hwnd = 0;
 
   //---- open the file to write the history in
     string file_name = StringConcatenate( "ALL", _Symbol, _Period, ".hst" );
   HistoryHandle = FileOpenHistory( file_name, FILE_BIN | FILE_WRITE );
   if ( HistoryHandle < 0 )
      {
             _GetLastError = GetLastError();
     Alert( "FileOpenHistory( \"", file_name, "\", 
           FILE_BIN | FILE_WRITE )"," - Error #", _GetLastError );
     return(-1);
    }
 
     //---- Write the file heading
     FileWriteInteger    ( HistoryHandle, 400, LONG_VALUE );
  FileWriteString    ( HistoryHandle, "Copyright © 2006, komposter", 64 );
  FileWriteString    ( HistoryHandle, StringConcatenate( "ALL", _Symbol ),
                      12 );
  FileWriteInteger    ( HistoryHandle, _Period, LONG_VALUE );
  FileWriteInteger    ( HistoryHandle, Digits, LONG_VALUE );
  FileWriteInteger    ( HistoryHandle, 0, LONG_VALUE );       //timesign
    FileWriteInteger    ( HistoryHandle, 0, LONG_VALUE );       //last_sync
    FileWriteArray        ( HistoryHandle, temp, 0, 13 );
 
    //+-----------------------------------------------------------------+
    //| Process the history
    //+-----------------------------------------------------------------+
    int bars = Bars;
  pre_time = Time[bars-1];
  for( int i = bars - 1; i >= 1; i-- )
      {
        //---- Remember the bar parameters
        now_open        = Open    [i];
   now_high        = High    [i];
   now_low        = Low        [i];
   now_close    = Close    [i];
   now_volume    = Volume    [i];
   now_time     = Time    [i] / _PeriodSec;
   now_time        *=_PeriodSec;
 
   //---- if there are skipped bars,
        while ( now_time > pre_time + _PeriodSec )
         {
              pre_time += _PeriodSec;
     pre_time    /= _PeriodSec;
     pre_time    *= _PeriodSec;
 
     //---- if it isn't a weekend,
            if( SkipWeekEnd )
             {
                 if( TimeDayOfWeek(pre_time) <= 0 || TimeDayOfWeek(pre_time) > 5 ) 
        { 
          continue; 
        }
                if( TimeDayOfWeek(pre_time) == 5 )
                 {
                     if ( TimeHour(pre_time) == 23 || 
            TimeHour(pre_time + _PeriodSec) == 23 )
                         { 
           continue; 
         }
                 }
             }
 
             //---- write the obtained bar into the file
            FileWriteInteger    ( HistoryHandle, pre_time, LONG_VALUE    );
     FileWriteDouble    ( HistoryHandle, pre_close,DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
     FileWriteDouble    ( HistoryHandle, 0, DOUBLE_VALUE);
     FileFlush            ( HistoryHandle );
     cnt_add ++;
    }
 
        //---- write the new bar into the file
        FileWriteInteger    ( HistoryHandle, now_time, LONG_VALUE    );
   FileWriteDouble    ( HistoryHandle, now_open, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_low, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_high, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_close, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, now_volume, DOUBLE_VALUE);
   FileFlush            ( HistoryHandle );
   cnt_copy ++;
 
   //---- remember the time value and the close price of the recorded 
   //---- bar
        pre_close = now_close;
   pre_time = now_time / _PeriodSec;
   pre_time *=_PeriodSec;
  }
 
    last_fpos = FileTell( HistoryHandle);
 
  //---- display statistics
    Print( "< - - - ", _Symbol, _Period, ": there were ", cnt_copy, " bars, 
        added ", cnt_add, " bars - - - >" );
  Print( "< - - - To view the results, open the chart \"ALL", 
        _Symbol, _Period, "\" - - - >" );
 
  //---- call the start function for the 0th bar to be drawn immediately
    start();
    
  return(0);
 }
//----
int start()
 {
     //+---------------------------------------------------------------+
     //| Process the incoming ticks
     //+---------------------------------------------------------------+
 
     //---- place the "cursor" before the latest bar
     //---- (this must be done at all launches except for the first one)
      FileSeek( HistoryHandle, last_fpos, SEEK_SET );
 
  //---- Remember the bar parameters
     now_open        = Open    [0];
  now_high        = High    [0];
  now_low        = Low        [0];
  now_close    = Close    [0];
  now_volume    = Volume    [0];
  now_time     = Time    [0] / _PeriodSec;
  now_time        *=_PeriodSec;
 
  //---- if the bar has been formed, 
    if( now_time >= pre_time + _PeriodSec )
     {
        //---- write the newly formed bar
        FileWriteInteger    ( HistoryHandle, pre_time, LONG_VALUE     );
   FileWriteDouble    ( HistoryHandle, pre_open, DOUBLE_VALUE );
   FileWriteDouble    ( HistoryHandle, pre_low, DOUBLE_VALUE );
   FileWriteDouble    ( HistoryHandle, pre_high, DOUBLE_VALUE );
   FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE );
   FileWriteDouble    ( HistoryHandle, pre_volume, DOUBLE_VALUE );
   FileFlush            ( HistoryHandle );
 
   //---- remember the position in the file, before writing of the 0th bar
        last_fpos = FileTell( HistoryHandle);
  }
 
    //---- if the skipped bars have appeared,
    while ( now_time > pre_time + _PeriodSec )
     {
         pre_time += _PeriodSec;
    pre_time /= _PeriodSec;
    pre_time *= _PeriodSec;
 
    //---- if this is not weekend,
         if ( SkipWeekEnd )
          {
              if ( TimeDayOfWeek(pre_time) <= 0 || 
          TimeDayOfWeek(pre_time) > 5 ) 
        { 
                         continue; 
        }
              if ( TimeDayOfWeek(pre_time) == 5 )
                   {
                   if ( TimeHour(pre_time) == 23 || 
             TimeHour(pre_time + _PeriodSec) == 23 )
                       {
                                 continue; 
           }
                   }
          }
 
         //---- write the skipped bar into the file
        FileWriteInteger    ( HistoryHandle, pre_time, LONG_VALUE    );
   FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, pre_close, DOUBLE_VALUE);
   FileWriteDouble    ( HistoryHandle, 0, DOUBLE_VALUE);
   FileFlush        (HistoryHandle);
 
   //---- remember the position in the file, before writing of the 0th bar
        last_fpos = FileTell( HistoryHandle);
  }
 
    //---- write the current bar
   FileWriteInteger    ( HistoryHandle, now_time, LONG_VALUE     );
 FileWriteDouble    ( HistoryHandle, now_open, DOUBLE_VALUE );
 FileWriteDouble    ( HistoryHandle, now_low, DOUBLE_VALUE );
 FileWriteDouble    ( HistoryHandle, now_high, DOUBLE_VALUE );
 FileWriteDouble    ( HistoryHandle, now_close, DOUBLE_VALUE );
 FileWriteDouble    ( HistoryHandle, now_volume, DOUBLE_VALUE );
 FileFlush            ( HistoryHandle );
 
 //---- remember the parameters of the recorded bar
   pre_open        = now_open;
 pre_high        = now_high;
 pre_low        = now_low;
 pre_close    = now_close;
 pre_volume    = now_volume;
 pre_time        = now_time / _PeriodSec;
 pre_time        *=_PeriodSec;
 
 //---- find the window the new quotes to be "sent" to
   if ( hwnd == 0 )
    {
        hwnd = WindowHandle( StringConcatenate( "ALL", _Symbol ), _Period );
   if( hwnd != 0 ) 
    { 
     Print( "< - - - Chart ", 
          "ALL" + _Symbol, _Period, " has been found! - - - >" ); 
    }
    }
   //---- and, if successfully found, update it
   if ( hwnd != 0 ) 
  { 
    PostMessageA( hwnd, WM_COMMAND, 33324, 0 ); 
  }
 }
//----
int deinit()
 {
     if ( HistoryHandle >= 0 )
      {
          //---- close the file
             FileClose( HistoryHandle );
     HistoryHandle = -1;
   }
   return(0);
}
   

    One reservation must be made first: The updating of the chart is rather processor-intensive, since the terminal loads all bars written in the file. If there are many bars in the file, the terminal can  become much slower. This mostly depends on the perfomance of PC where the МТ 4 Client Terminal is installed. In any case, resources are not inexhaustible. We will solve this problem in a simple way: Just reduce the amount of bars displayed in the chart to 10,000 ("Tools" – "Options" – "Charts", the "Max bars in chart" parameter). Now let us restart the terminal and attach the expert:


 
 

The expert has immediately "mended" the history and is waiting until the new ticks appear. After 2 minutes, the same charts appeared as follows:

 
  

As you can see, a one-minute bar was added in the upper chart while the skipped bar was added into the lower chart.

This means we have effected the desired result! 

3.   Scaling

One chart is ok, of course, but what should we do if there is a need to open 10 charts without skipped bars? Opening of an additional, "temporary" chart for every normal chart would not be the best solution. The extra resources will be spent and, respectively, the working will be less comfortable.

Let us create an expert that would process any amount of charts. This will be a suitable and saving solution.

Thus, we will have to modify our code to make it working with several charts simultaneously:

  • add an external variable that would help to change the list of charts,
  • replace all variables with arrays having the amount of elements equal to the amount of charts to be processed,
  • place the entire code into a loop where these charts will be searched, and
  • put the updating block into the infinite loop, having become independent on the quotes income in such a way. If different symbols are listed, their updating time can be different, as well.

This is what we should have drawn as a result (AllMinutes.mq4):

#include <WinUser32.mqh>
 
//---- The list of charts to be processed, separated by commas (",")
extern string    ChartList = "EURUSD1,GBPUSD1";
//---- Enable/disable to draw bars at weekends
//---- If it is == true, the weekends will remain unfilled
//---- If it is == false, the weekends will be filled with the bars of O=H=L=C
extern bool     SkipWeekEnd = true;
//---- Frequency of the charts updating, in milliseconds
//---- the higher the value is, the less resources the expert 
//---- will use.
extern int   RefreshLuft = 1000;
 
int init() 
 { 
      start(); 
  return(0); 
 }
int start()
 {
     int   _GetLastError = 0, cnt_copy = 0, cnt_add = 0, temp[13];
  int   Charts = 0, pos = 0, curchar = 0, len = StringLen( ChartList );
  string    cur_symbol = "", cur_period = "", file_name = "";
 
  string    _Symbol[100]; int _Period[100], _PeriodSec[], _Bars[];
  int HistoryHandle[], hwnd[], last_fpos[], pre_time[], now_time[];
  double   now_close[],now_open[],now_low[],now_high[],now_volume[];
  double   pre_close[],pre_open[],pre_low[],pre_high[],pre_volume[];
 
  //---- count the amount of charts to be processed
    while ( pos <= len )
     {
         curchar = StringGetChar( ChartList, pos );
    if ( curchar > 47 && curchar < 58 )
          { 
       cur_period = cur_period + CharToStr( curchar ); 
     }
          else
          {
              if ( curchar == ',' || pos == len )
               { 
                   MarketInfo( cur_symbol, MODE_BID );
         if ( GetLastError() == 4106 )
                    {
                              Alert( "Unknown symbol ", cur_symbol, "!!!" );
           return(-1);                
          }
                   if( iClose( cur_symbol, StrToInteger( cur_period ), 0 ) <= 0 )
                     {
                                 Alert("Unknown period ", cur_period, "!!!" );
            return(-1);                
           }
 
                   _Symbol[Charts] = cur_symbol; 
         _Period[Charts] = StrToInteger( cur_period );
         cur_symbol = ""; cur_period = "";
 
         Charts ++;
        }
                 else
               {
                        cur_symbol = cur_symbol + CharToStr( curchar ); 
       }
          }
           pos++;
   }
       Print( "< - - - Found ", Charts, " correct charts. - - - >" );
   ArrayResize( _Symbol, Charts ); 
   ArrayResize( _Period, Charts );
   ArrayResize( HistoryHandle, Charts ); 
   ArrayResize( hwnd, Charts );
   ArrayResize( last_fpos, Charts ); 
   ArrayResize( pre_time, Charts );
   ArrayResize( now_time, Charts ); 
   ArrayResize( now_close, Charts );
   ArrayResize( now_open, Charts ); 
   ArrayResize( now_low, Charts );
   ArrayResize( now_high, Charts ); 
   ArrayResize( now_volume, Charts );
   ArrayResize( pre_close, Charts ); 
   ArrayResize( pre_open, Charts );
   ArrayResize( pre_low, Charts ); 
   ArrayResize( pre_high, Charts );
   ArrayResize( pre_volume, Charts ); 
   ArrayResize( _PeriodSec, Charts );
   ArrayResize( _Bars, Charts );
 
   for ( int curChart = 0; curChart < Charts; curChart ++ )
      {
          _PeriodSec[curChart] = _Period[curChart] * 60;
 
     //---- open the file the history to be written in
          file_name = StringConcatenate( "ALL", _Symbol[curChart], 
                                   _Period[curChart], ".hst" );
     HistoryHandle[curChart] = FileOpenHistory( file_name, 
                                               FILE_BIN | FILE_WRITE );
     if ( HistoryHandle[curChart] < 0 )
           {
               _GetLastError = GetLastError();
       Alert( "FileOpenHistory( \"", file_name, "\", 
                  FILE_BIN | FILE_WRITE )", 
                  " - Error #", _GetLastError );
       continue;
      }
 
          //---- Write the file heading
          FileWriteInteger    ( HistoryHandle[curChart], 400, LONG_VALUE );
     FileWriteString    ( HistoryHandle[curChart], 
                       "Copyright © 2006, komposter", 64 );
     FileWriteString    ( HistoryHandle[curChart],
                       StringConcatenate( "ALL", 
                       _Symbol[curChart] ), 12 );
     FileWriteInteger    ( HistoryHandle[curChart], _Period[curChart], 
                        LONG_VALUE );
     FileWriteInteger    ( HistoryHandle[curChart], 
                        MarketInfo( _Symbol[curChart], 
                        MODE_DIGITS ), LONG_VALUE );
     FileWriteInteger    ( HistoryHandle[curChart], 0, 
                        LONG_VALUE );       //timesign
          FileWriteInteger    ( HistoryHandle[curChart], 0, 
                        LONG_VALUE );       //last_sync
             FileWriteArray        ( HistoryHandle[curChart], temp, 0, 13 );
 
     //+-----------------------------------------------------------+
          //| Process the history
            //+-----------------------------------------------------------+
            _Bars[curChart] = iBars( _Symbol[curChart], _Period[curChart] );
    pre_time[curChart] = iTime( _Symbol[curChart], 
    _Period[curChart], _Bars[curChart] - 1 );
    for( int i = _Bars[curChart] - 1; i >= 1; i-- )
          {
              //---- Remember the bar parameters
              now_open        [curChart] = iOpen    ( _Symbol[curChart], 
                                      _Period[curChart], i );
      now_high        [curChart] = iHigh    ( _Symbol[curChart], 
                                      _Period[curChart], i );
      now_low        [curChart] = iLow        ( _Symbol[curChart], 
                                     _Period[curChart], i );
      now_close    [curChart] = iClose    ( _Symbol[curChart], 
                                      _Period[curChart], i );
      now_volume    [curChart] = iVolume    ( _Symbol[curChart], 
                                        _Period[curChart], i );
      now_time        [curChart] = iTime    ( _Symbol[curChart], 
                                      _Period[curChart], i ) 
                                      / _PeriodSec[curChart];
      now_time        [curChart] *=_PeriodSec[curChart];
 
      //---- if there are skipped bars,
             while ( now_time[curChart] > pre_time[curChart] + 
            _PeriodSec[curChart] )
              {
                  pre_time[curChart] += _PeriodSec[curChart];
        pre_time[curChart] /= _PeriodSec[curChart];
        pre_time[curChart] *= _PeriodSec[curChart];
 
        //---- if this is not the weekend,
                  if ( SkipWeekEnd )
                   {
                       if ( TimeDayOfWeek(pre_time[curChart]) <= 0 || 
              TimeDayOfWeek(pre_time[curChart]) > 5 ) 
           { 
             continue; 
           }
                       if ( TimeDayOfWeek(pre_time[curChart]) == 5 )
                        {
                            if ( TimeHour(pre_time[curChart]) == 23 || 
              TimeHour(pre_time[curChart]+_PeriodSec[curChart])==23 ) 
              { 
                                         continue; 
              }
                        }
                   }
 
                  //---- write the skipped bar into the file
                    FileWriteInteger ( HistoryHandle[curChart], pre_time[curChart],
                         LONG_VALUE    );
       FileWriteDouble    ( HistoryHandle[curChart], 
                         pre_close[curChart], DOUBLE_VALUE);
       FileWriteDouble    ( HistoryHandle[curChart], 
                         pre_close[curChart],DOUBLE_VALUE);
       FileWriteDouble    ( HistoryHandle[curChart], 
                         pre_close[curChart], DOUBLE_VALUE)<