//+------------------------------------------------------------------+
//|                                             		AllMinutes.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, komposter"
#property link      "mailto:komposterius@mail.ru"

#include <WinUser32.mqh>

//---- Разрешить/запретить рисовать бары в выходные
//---- Если == true, выходные останутся незаполнеными
//---- Если == false, выходные будут заполнены барами O=H=L=C
extern bool		SkipWeekEnd		= true;

int HistoryHandle = -1, hwnd = 0, last_fpos = 0, pre_time, now_time, _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];

	//---- запоминаем символ и период графика
	_Symbol = Symbol();
	_Period = Period();
   _PeriodSec = _Period * 60;
   hwnd = 0;

	//---- открываем файл, в который будем записывать историю
	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);
	}

	//---- Записываем заголовок файла
	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 );

	//+------------------------------------------------------------------+
	//| Обрабатываем историю
	//+------------------------------------------------------------------+
	int bars = Bars;
	pre_time = Time[bars-1];
	for( int i = bars - 1; i >= 1; i-- )
	{
		//---- Запоминаем параметры бара
		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;

		//---- если есть пропущенные бары,
		while ( now_time > pre_time + _PeriodSec )
		{
			pre_time += _PeriodSec;
			pre_time	/= _PeriodSec;
			pre_time	*= _PeriodSec;

			//---- если это не выходные,
			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; }
				}
			}

			//---- записываем пропущенный бар в файл
			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 ++;
		}

		//---- записываем новый бар в файл
		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 ++;

		//---- запоминаем значение времени и цену закрытия записанного бара
		pre_close	= now_close;
		pre_time		= now_time / _PeriodSec;
		pre_time		*=_PeriodSec;
 	}

	last_fpos = FileTell( HistoryHandle);

	//---- выводим статистику
	Print( "< - - - ", _Symbol, _Period, ": было ", cnt_copy, " баров, добавлено ", cnt_add, " баров - - - >" );
	Print( "< - - - Для просмотра результатов, откройте график \"ALL", _Symbol, _Period, "\" - - - >" );

	//---- вызываем функцию старт, чтоб сразу наисовался 0-й бар
	start();
	
	return(0);
}
int start()
{
	//+------------------------------------------------------------------+
	//| Обрабатываем поступающие тики
	//+------------------------------------------------------------------+

	//---- ставим "курсор" перед последним баром
	//---- (это необходимо на всех запусках, кроме первого)
	FileSeek( HistoryHandle, last_fpos, SEEK_SET );

	//---- Запоминаем параметры бара
	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 ( now_time >= pre_time + _PeriodSec )
	{
		//---- записываем сформировавшийся бар
		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 );

		//---- запоминаем место в файле, перед записью 0-го бара
		last_fpos = FileTell( HistoryHandle);
	}

	//---- если появились пропущенные бары,
	while ( now_time > pre_time + _PeriodSec )
	{
		pre_time += _PeriodSec;
		pre_time /= _PeriodSec;
		pre_time *= _PeriodSec;

		//---- если это не выходные,
		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; }
			}
		}

		//---- записываем пропущенный бар в файл
		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);

		//---- запоминаем место в файле, перед записью 0-го бара
		last_fpos = FileTell( HistoryHandle);
	}

	//---- записываем текущий бар
	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 );

	//---- запоминаем параметры записанного бара
	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;

	//---- находим окно, в которое будем "отправлять" свежие котировки
	if ( hwnd == 0 )
	{
		hwnd = WindowHandle( StringConcatenate( "ALL", _Symbol ), _Period );
		if ( hwnd != 0 ) { Print( "< - - - График ", "ALL" + _Symbol, _Period, " найден! - - - >" ); }
	}
	//---- и, если нашли, обновляем его
	if ( hwnd != 0 ) { PostMessageA( hwnd, WM_COMMAND, 33324, 0 ); }
}
int deinit()
{
	if ( HistoryHandle >= 0 )
	{
		//---- закрываем файл
		FileClose( HistoryHandle );
		HistoryHandle = -1;
	}
	return(0);
}

