//+------------------------------------------------------------------+
//|                                                  CustomDaily.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, zznbrm"
#property show_inputs

//+------------------------------------------------------------------+
//| Constants                                                        |
//+------------------------------------------------------------------+
#define cDATA_TIME      0
#define cDATA_OPEN      1
#define cDATA_LOW       2
#define cDATA_HIGH      3
#define cDATA_CLOSE     4
#define cDATA_VOL       5
#define cHISTORY_HEADER_SIZE 148 
#define cHISTORY_RECORD_SIZE 44 
#define WM_COMMAND 0x0111 

//+------------------------------------------------------------------+
//| Includes                                                         |
//+------------------------------------------------------------------+
#import "user32.dll"
   int PostMessageA(int hWnd,int Msg,int wParam,int lParam);
   int RegisterWindowMessageA(string lpString);
#import

//+------------------------------------------------------------------+
//| User Inputs                                                      |
//+------------------------------------------------------------------+
extern datetime edtFirstDayOpen = D'2011.01.01 08:00:00';
extern datetime edtFirstDayClose = D'2011.01.01 16:59:59';
extern int      eintOfflineTimeframe = 1430;

//*********************************************************************************************
//* STANDARD FUNCTIONS BELOW                                                                  *
//*********************************************************************************************
//+------------------------------------------------------------------+
//| start()                                                          |
//+------------------------------------------------------------------+
int start()
{  
   datetime dtCurrOpen = edtFirstDayOpen;
   datetime dtCurrClose = edtFirstDayClose;
   int intDay, intStart, intEnd, intHigh, intLow;
   double adblData[6];
   int intHandle = hsGetHistFileHandle( Symbol(), eintOfflineTimeframe, false ); 
   int inx; 
    
   hsWriteHdrRecord( Symbol(), intHandle, eintOfflineTimeframe, Digits );
          
   while( dtCurrOpen <= TimeCurrent() )
   {   
      intDay = TimeDayOfWeek( dtCurrOpen );
      
      if ( ( intDay >= 1 ) && ( intDay <= 5 ) )
      {      
         intStart = genCalcOpenShift( Symbol(), Period(), dtCurrOpen );
         intEnd = iBarShift( Symbol(), Period(), dtCurrClose, false );
         intHigh = iHighest( Symbol(), Period(), MODE_HIGH, intStart - intEnd + 1, intEnd );
         intLow = iLowest( Symbol(), Period(), MODE_LOW, intStart - intEnd + 1, intEnd );

         adblData[cDATA_TIME] = dtCurrOpen;
         adblData[cDATA_OPEN] = Open[intStart];
         adblData[cDATA_HIGH] = High[intHigh];
         adblData[cDATA_LOW] = Low[intLow];
         adblData[cDATA_CLOSE] = Close[intEnd];
         adblData[cDATA_VOL] = 0.0;
         
         for ( inx = intStart; inx >= intEnd; inx-- )
         {
            adblData[cDATA_VOL] += Volume[inx];
         }
         
         hsWriteHistRecord( adblData, intHandle, 0 );
      }
                   
      dtCurrOpen += ( 24 * 60 * 60 );
      dtCurrClose += ( 24 * 60 * 60 );
   }  
   
   if ( intHandle >= 0 )    
   {  
      Print( "File closed: " + intHandle );
      FileClose( intHandle );  
   }
   
   hsUpdateChartWindow( Symbol(), eintOfflineTimeframe ); 
                     
   return( 0 );
}

//*********************************************************************************************
//* MAIN PROCESSING FUNCTIONS BELOW                                                           *
//*********************************************************************************************
  
//*********************************************************************************************
//* UTILITY FUNCTIONS BELOW                                                                   *
//*********************************************************************************************
//+------------------------------------------------------------------+
//| genCalcOpenShift()                                               |
//+------------------------------------------------------------------+
int genCalcOpenShift( string strSymbol, int intTf, datetime dt )
{
   int intShift = iBarShift( strSymbol, intTf, dt, true );
   
   if ( intShift < 0 )    intShift = iBarShift( strSymbol, intTf, dt, false ) - 1;
   
   return( intShift );
}

//+------------------------------------------------------------------+
//| hsGetHistFileHandle                                                |
//+------------------------------------------------------------------+
int hsGetHistFileHandle( string strSymbol, int intTF, bool blnAppend )
{
   string strFileName = strSymbol + intTF + ".hst";
   int intHandle, intDelimiter;
   
   if ( blnAppend )   intDelimiter = FILE_BIN | FILE_READ | FILE_WRITE;
   else               intDelimiter = FILE_BIN | FILE_WRITE;
   
   intHandle = FileOpenHistory( strFileName, intDelimiter );
   
   if ( intHandle < 0 )   
      Print( "Error opening file: " + strFileName );
   
   return( intHandle );
}

//+------------------------------------------------------------------+
//| hsWriteHdrRecord()                                               |
//+------------------------------------------------------------------+
bool hsWriteHdrRecord( string strSymbol, int intHnd, int intTF, int intDigits = 5 )
{
   int    intBytes = 0;
   int    i_unused[13];
   string c_copyright="(C)opyright 2012, MetaQuotes Software Corp.";
   
   intBytes += FileWriteInteger( intHnd, 400, LONG_VALUE );
   intBytes += FileWriteString( intHnd, c_copyright, 64 );
   intBytes += FileWriteString( intHnd, strSymbol, 12 );
   intBytes += FileWriteInteger( intHnd, intTF, LONG_VALUE );
   intBytes += FileWriteInteger( intHnd, intDigits, LONG_VALUE );
   intBytes += FileWriteInteger( intHnd, 50, LONG_VALUE );      
   intBytes += FileWriteInteger( intHnd, 0, LONG_VALUE );       
   intBytes += FileWriteArray( intHnd, i_unused, 0, 13 );
   
   return( true ); 
}

//+------------------------------------------------------------------+
//| hsWriteHistRecord                                                  |
//+------------------------------------------------------------------+
bool hsWriteHistRecord( double& adblD[], int intHnd, int intBack )
{
   int intBytes = 0;
   int intPos = intBack * cHISTORY_RECORD_SIZE * (-1);
   
   if ( !FileSeek( intHnd, intPos, SEEK_END ) )
   {
      Print( "writeHistRecord() - File Seek Failed: " + GetLastError() );
      return( false );
   }
   
   if ( FileTell( intHnd ) < cHISTORY_HEADER_SIZE )
   {
      Print( "writeHistRecord() - File Pointer invalid: " + FileTell( intHnd ) );
      return( false );
   }
   
   intBytes += FileWriteInteger( intHnd, adblD[cDATA_TIME], LONG_VALUE );
   intBytes += FileWriteDouble( intHnd, adblD[cDATA_OPEN], DOUBLE_VALUE );
   intBytes += FileWriteDouble( intHnd, adblD[cDATA_LOW], DOUBLE_VALUE );
   intBytes += FileWriteDouble( intHnd, adblD[cDATA_HIGH], DOUBLE_VALUE );
   intBytes += FileWriteDouble( intHnd, adblD[cDATA_CLOSE], DOUBLE_VALUE );
   intBytes += FileWriteDouble( intHnd, adblD[cDATA_VOL], DOUBLE_VALUE );
   
   FileFlush( intHnd );
   
   if ( intBytes != cHISTORY_RECORD_SIZE )   
   {
      Print( "writeHistRecord() - Error writing to Hist File: " + GetLastError() );
      return( false );
   }
   
   return( true );
}

//+------------------------------------------------------------------+
//| hsUpdateChartWindow                                                |
//+------------------------------------------------------------------+
bool hsUpdateChartWindow( string strSymbol, int intTF ) 
{
   bool blnResult = false;   
   int intWindow = WindowHandle( strSymbol, intTF );
   static int intMT4MsgID = 0;
		
   if( intWindow > 0 ) 
   {
      // Send update (refresh) command to offline chart
      if ( PostMessageA( intWindow, WM_COMMAND, 33324, 0 ) == 0 )
         Print( strSymbol + "-" + intTF + " Chart window update failed!!!!" );
      else
         blnResult = true;
            
      // Send simulated tick to offline chart
      if ( intMT4MsgID == 0 )
         intMT4MsgID = RegisterWindowMessageA("MetaTrader4_Internal_Message");         
         
      if ( PostMessageA( intWindow, intMT4MsgID, 2, 1 ) == 0 )
      {
         Print( strSymbol + "-" + intTF + " Chart window sim tick failed!!!!" );
         intMT4MsgID = 0;
      }
   }
   
   return( blnResult );
}    
      














