ExcelMultiTerminal

Author: Copyright � 2009, komposter
Price Data Components
Series array that contains open time of each bar
Orders Execution
Checks for the total of open ordersChecks for the total of closed ordersIt Closes Orders by itself
Miscellaneous
It issuies visual alerts to the screenUses files from the file systemIt reads information from a fileIt writes information to fileIt sends emailsIt plays sound alerts
0 Views
0 Downloads
0 Favorites
ExcelMultiTerminal
//+------------------------------------------------------------------+
//|                                           ExcelMultiTerminal.mq4 |
//|                                      Copyright © 2009, komposter |
//|                                       mailto:komposter@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, komposter"
#property link      "mailto:komposter@gmail.com"

//+------------------------------------------------------------------+
//| extern
//+------------------------------------------------------------------+
extern int		RefreshInterval_ms	= 1000;	// ×àñòîòà ïðîâåðêè ïîñòóïëåíèÿ çàïðîñà íà îáíîâëåíèå (ìñ)


extern bool		CentAccount				= false;
extern bool		AllowAlert				= false;
extern bool		AllowPrint				= true;
extern bool		AllowComment			= false;
extern bool		AllowMail				= false;
extern bool		AllowSound				= false;
extern string	SoundFileName			= "Alert.wav";
extern bool		AllowFile				= true;
extern string	FilePath					= "D:\\_Forex\\Skyper\\ForSend\\";


//+------------------------------------------------------------------+
//| import
//+------------------------------------------------------------------+
#define WM_COMMAND	0x0111

#import "user32.dll"
	// Âîçâðàùàåò èäåíòèôèêàòîð hierarchyid, ïðåäñòàâëÿþùèé n-ãî ïðåäêà äàííîãî ýëåìåíòà.
	int      GetAncestor (int hWnd,      // Èäåíòèôèêàòîp îêíà.
                       	int gaFlags);  // Óðîâåíü îêíà îò òåêóùåãî îêíà (1, 2, 3...).

	// Ñ÷èòûâàåò îïèñàòåëü îpãàíà óïpàâëåíèÿ, ñîäåpæàùèéñÿ â óêàçàííîì áëîêå äèàëîãà. Âîçâpàùàåìîå çíà÷åíèå: èäåíòèôèêàòîp îpãàíà óïpàâëåíèÿ; 0 - åñëè óêàçàííûé îpãàí óïpàâëåíèÿ íå ñóùåñòâóåò.
	int      GetDlgItem (int hDlg,        // Áëîê äèàëîãà, ñîäåpæàùèé îpãàí óïpàâëåíèÿ. 
                      	int nIDDlgItem); // Èäåíòèôèêàòîp îpãàíà óïpàâëåíèÿ.

	// int   SendMessageA (int hWnd, int Msg, int wParam, int lParam);
	// Ïîñûëàåò ñîîáùåíèå îêîííîé ôóíêöèè óêàçàííîãî îêíà. Âîçâpàò èç ôóíêöèè îñóùåñòâëÿåòñÿ òîëüêî ïîñëå îápàáîòêè ñîîáùåíèÿ.
	// SendMessageA (hwnd, WM_COMMAND, 37400, 0) - êîìàíäà ïåðñêàíèðîâàíèå ñåðâåðîâ.
	int      SendMessageA (int  hWnd,      // Îêíî, ïpèíèìàþùåå ñîîáùåíèå èëè $FFFF äëÿ ïîñûëêè âñåì âñïëûâàþùèì îêíàì â ñèñòåìå. 
                        	int  Msg,       // Òèï ñîîáùåíèÿ.
                        	int  wParam,    // Äîïîëíèòåëüíàÿ èíôîpìàöèÿ î ñîîáùåíèè.
                        	int& lParam[]); // Äîïîëíèòåëüíàÿ èíôîpìàöèÿ î ñîîáùåíèè.
#import "kernel32.dll"
   int _lopen  (string path, int of);
   int _lcreat (string path, int attrib);
   int _llseek (int handle, int offset, int origin);
   int _lread  (int handle, int& buffer[], int bytes);
   int _lwrite (int handle, string buffer, int bytes);
   int _lclose (int handle);
#import


//+------------------------------------------------------------------+
//| vars
//+------------------------------------------------------------------+
int		RequestCode					= 0;
int		preHistoryOrdersCount	= 0;
int		preHistoryOrders			[999999];

int		pre_OrdersCount			= -1;		// êîë-âî ïîçèöèé, ñîñòîÿíèåì íà ïðåäûäóùèé òèê
int		pre_OrdersArray			[][2];	// ìàññèâ îòêðûòûõ ïîçèöèé, ñîñòîÿíèåì íà ïðåäûäóùèé òèê [¹ òèêåòà, òèï ïîçèöèè]
int		pre_HistoryCount			= 0;
int		pre_HistoryArray			[];		// ìàññèâ çàêðûòûõ ïîçèöèé, ñîñòîÿíèåì íà ïðåäûäóùèé òèê


//+------------------------------------------------------------------+
//| init
//+------------------------------------------------------------------+
int init()
{
	pre_OrdersCount = -1;
	start();
	return(0);
}


//+------------------------------------------------------------------+
//| deinit
//+------------------------------------------------------------------+
int deinit()
{
	// óäàëÿåì ñåìàôîð, óêàçûâàþùèé, ÷òî ýêñïåðò çàïóùåí
	FileDelete( "ExcelMultiTerminal\\status.csv" );

	return(0);
}


//+------------------------------------------------------------------+
//| start
//+------------------------------------------------------------------+
int start()
{
	if ( !IsDllsAllowed() ) Alert( "Âûçîâ DLL çàïðåùåí, óïðàâëåíèå êíîïêîé \"Ñîâåòíèêè\" ðàáîòàòü íå áóäåò!" );

	// ñîçäàåì ñåìàôîð, óêàçûâàþùèé, ÷òî ýêñïåðò çàïóùåí
	int _GetLastError, file_handle = FileOpen( "ExcelMultiTerminal\\status.csv",FILE_WRITE );

	// Åñëè âîçíèêëà îøèáêà,
	if ( file_handle < 0 )
	{
		// Âûâîäèì ñîîáùåíèå è âûõîäèì
		_GetLastError = GetLastError();
		Print( "init() - FileOpen() Error #", _GetLastError, "!" );
		return(-1);
	}

	FileClose(file_handle);

	// Ðàáîòàåì â áåñêîíå÷íîì öèêëå ïîêà ïîëüçîâàòåëü íå óäàëèò ýêñïåðòà
	while ( !IsStopped() )
	{
		RefreshRates		();

		CheckEvents			();
		CheckCommands		();
		CheckRequest		();
		WriteSummaryData	();
		WriteTerminalData	();
		WriteHistoryData	();

		if ( RequestCode > 0 ) FileDelete("ExcelMultiTerminal\\request.csv"); 
		Sleep(RefreshInterval_ms);	// Äåëàåì ïàóçó ÷òîá íå ãðóçèòü ïðîöåññîð
	}

	return(0);
}

void CheckCommands()
{
	// åñëè åñòü ôàéë command.csv 
	int file_handle = FileOpen( "ExcelMultiTerminal\\command.csv", FILE_READ | FILE_CSV );
	if ( file_handle > 0 )
	{
		string Command_ExpertsEnabled	= FileReadString( file_handle );
		string Command_CloseAll			= FileReadString( file_handle );

		FileClose(file_handle);

		// óñòàíàâëèâàåì ïîëîæåíèå êíîïêè "Ñîâåòíèêè" ñîãëàñíî ïåðâîìó çíà÷åíèþ èç ôàéëà
		if ( IsDllsAllowed() )
		{
			if ( Command_ExpertsEnabled == "1" )
			{
				if ( !IsExpertEnabled() ) SetExpertEnabled( true );
			}
			else
			{
				if ( IsExpertEnabled() ) SetExpertEnabled( false );
			}
		}

		// åñëè âòîðîå çíà÷åíèå èç ôàéëà = 1, çàêðûâàåì âñå ïîçèöèè, óäàëÿåì îòëîæêè è óäàëÿåì ôàéë command.csv
		if ( Command_CloseAll == "1" )
		{
			Print( "ExcelMultiTerminal: closing all orders!" );
			if ( CloseAll() ) FileDelete("ExcelMultiTerminal\\command.csv");
		}
		else
		{
			FileDelete("ExcelMultiTerminal\\command.csv"); 
		}
	}
}

void CheckRequest()
{
	RequestCode = 0;

	int file_handle = FileOpen( "ExcelMultiTerminal\\request.csv", FILE_READ | FILE_CSV );
	if ( file_handle > 0 )
	{
		RequestCode = StrToInteger( FileReadString( file_handle ) );
		FileClose(file_handle);
	}
}

// Çàïèñü "summary.csv": íîìåð ñ÷åòà, áàëàíñ, ïðèáûëü ïî îòêðûòûì ïîçèöèÿì, èñïîëüçóåìàÿ ìàðæà, ñîñòîÿíèå êíîïêè "Ñîâåòíèêè".
void WriteSummaryData()
{
	if ( RequestCode <= 0 ) return;

	// Îòêðûâàåì ôàéë äëÿ çàïèñè	
	int _GetLastError, file_handle = FileOpen( "ExcelMultiTerminal\\summary.csv", FILE_WRITE | FILE_CSV );
	
	// Åñëè âîçíèêëà îøèáêà,
	if ( file_handle < 0 )
	{
		// Âûâîäèì ñîîáùåíèå è âûõîäèì
		_GetLastError = GetLastError();
		Print( "WriteSummaryData() - FileOpen() Error #", _GetLastError, "!" );
		return;
	}

	// Çàïèñûâàåì äàííûå â ôàéë
	if ( FileWrite( file_handle, AccountNumber(), AccountBalance(), AccountProfit(), AccountMargin(), IsExpertEnabled() ) <= 0 )
	{
		// Åñëè âîçíèêëà îøèáêà, âûâîäèì ñîîáùåíèå
		_GetLastError = GetLastError();
		Print( "WriteSummaryData() - FileWrite() Error #", _GetLastError, "!" );
	}

	// Çàêðûâàåì ôàéë
	FileClose( file_handle );
}

// "terminal.csv": 
void WriteTerminalData()
{
	if ( RequestCode <= 0 ) return;

	// Îòêðûâàåì ôàéë äëÿ çàïèñè
	int _GetLastError, file_handle = FileOpen( "ExcelMultiTerminal\\terminal.csv", FILE_WRITE | FILE_CSV );
	
	// Åñëè âîçíèêëà îøèáêà,
	if ( file_handle < 0 )
	{
		// Âûâîäèì ñîîáùåíèå è âûõîäèì
		_GetLastError = GetLastError();
		Print( "WriteTerminalData() - FileOpen() Error #", _GetLastError, "!" );
		return;
	}

	for ( int z = OrdersTotal() - 1; z >= 0; z -- )
	{
		if ( !OrderSelect(z, SELECT_BY_POS, MODE_TRADES) )
		{
			Print( "OrderSelect( ", z, ", SELECT_BY_POS, MODE_TRADES ) - Error #", GetLastError() );
			continue;			
		}

		string strType = "";
		switch ( OrderType() )
		{
			case 0: strType = "buy";			break;
			case 1: strType = "sell";			break;
			case 2: strType = "buy limit";	break;
			case 3: strType = "buy stop";		break;
			case 4: strType = "sell limit";	break;
			case 5: strType = "sell stop";	break;
			default:strType = "";				break;
		}

		// Çàïèñûâàåì äàííûå â ôàéë
		if ( FileWrite( file_handle, OrderTicket(), TimeToStr( OrderOpenTime(), TIME_DATE | TIME_SECONDS ), strType, OrderLots(), OrderSymbol(), OrderOpenPrice(), OrderStopLoss(), 
								OrderTakeProfit(),TimeToStr( TimeCurrent(), TIME_DATE | TIME_SECONDS ), OrderClosePrice(), OrderCommission(), OrderSwap(), OrderProfit(), OrderComment(), OrderMagicNumber() ) <= 0 )
		{
			// Åñëè âîçíèêëà îøèáêà, âûâîäèì ñîîáùåíèå
			_GetLastError = GetLastError();
			Print( "WriteTerminal() - FileWrite() Error #", _GetLastError, "!" );
		}
	}

	// Çàêðûâàåì ôàéë
	FileClose( file_handle );
}

// "history.csv"
void WriteHistoryData()
{
	if ( RequestCode <= 0 ) return;

	static int		preNumber		= 0;
	static int		HistoryOrders = -1;

	if ( preNumber == AccountNumber() && HistoryOrders == OrdersHistoryTotal() ) return;

	if ( HistoryOrders == -1 )
	{
		preHistoryOrdersCount = 0;
		FileDelete( "ExcelMultiTerminal\\history.csv" );
		FileDelete( "ExcelMultiTerminal\\history-add.csv" );
	}

	// Îòêðûâàåì ôàéë äëÿ çàïèñè
	int _GetLastError, file_handle = FileOpen( "ExcelMultiTerminal\\history.csv", FILE_READ | FILE_WRITE | FILE_CSV );

	// Åñëè âîçíèêëà îøèáêà,
	if ( file_handle < 0 )
	{
		// Âûâîäèì ñîîáùåíèå è âûõîäèì
		_GetLastError = GetLastError();
		Print( "WriteHistoryData() - FileOpen() Error #", _GetLastError, "!" );
		return;
	}

	if ( !FileSeek( file_handle, 0, SEEK_END ) )
	{
		// Âûâîäèì ñîîáùåíèå è âûõîäèì
		_GetLastError = GetLastError();
		Print( "WriteHistoryData() - FileOpen() Error #", _GetLastError, "!" );
		FileClose( file_handle );
		return;
	}

	// Îòêðûâàåì ôàéë äëÿ çàïèñè
	int file_handle_add = FileOpen( "ExcelMultiTerminal\\history-add.csv", FILE_WRITE | FILE_CSV );

	// Åñëè âîçíèêëà îøèáêà,
	if ( file_handle_add < 0 )
	{
		// Âûâîäèì ñîîáùåíèå è âûõîäèì
		_GetLastError = GetLastError();
		Print( "WriteHistoryData() - FileOpen() Error #", _GetLastError, "!" );
		FileClose( file_handle );
		return;
	}

	for ( int z = OrdersHistoryTotal() - 1; z >= 0; z -- )
	{
		if ( !OrderSelect(z, SELECT_BY_POS, MODE_HISTORY) )
		{
			Print( "OrderSelect( ", z, ", SELECT_BY_POS, MODE_HISTORY ) - Error #", GetLastError() );
			continue;			
		}

		if ( OldTicket( OrderTicket() ) ) continue;

		preHistoryOrdersCount ++;
		preHistoryOrders[preHistoryOrdersCount-1] = OrderTicket();

		string strType = "";
		switch ( OrderType() )
		{
			case 0: strType = "buy";			break;
			case 1: strType = "sell";			break;
			case 2: strType = "buy limit";	break;
			case 3: strType = "buy stop";		break;
			case 4: strType = "sell limit";	break;
			case 5: strType = "sell stop";	break;
			default:strType = "";				break;
		}

		// Çàïèñûâàåì äàííûå â ôàéë			
		if ( FileWrite( file_handle, OrderTicket(), TimeToStr( OrderOpenTime(), TIME_DATE | TIME_SECONDS ), strType, OrderLots(), OrderSymbol(), OrderOpenPrice(), OrderStopLoss(), 
								OrderTakeProfit(), TimeToStr( OrderCloseTime(), TIME_DATE | TIME_SECONDS ), OrderClosePrice(), OrderCommission(), OrderSwap(), OrderProfit(), OrderComment(), OrderMagicNumber() ) <= 0 )
		{
			// Åñëè âîçíèêëà îøèáêà, âûâîäèì ñîîáùåíèå
			_GetLastError = GetLastError();
			Print( "WriteHistory() - FileWrite() Error #", _GetLastError, "!" );
		}

		if ( HistoryOrders >= 0 )
		{
			// Çàïèñûâàåì äàííûå â ôàéë			
			if ( FileWrite( file_handle_add, OrderTicket(), TimeToStr( OrderOpenTime(), TIME_DATE | TIME_SECONDS ), strType, OrderLots(), OrderSymbol(), OrderOpenPrice(), OrderStopLoss(), 
									OrderTakeProfit(), TimeToStr( OrderCloseTime(), TIME_DATE | TIME_SECONDS ), OrderClosePrice(), OrderCommission(), OrderSwap(), OrderProfit(), OrderComment(), OrderMagicNumber() ) <= 0 )
			{
				// Åñëè âîçíèêëà îøèáêà, âûâîäèì ñîîáùåíèå
				_GetLastError = GetLastError();
				Print( "WriteHistory() - FileWrite() Error #", _GetLastError, "!" );
			}
		}
	}

	// Çàêðûâàåì ôàéë
	FileClose( file_handle );
	FileClose( file_handle_add );

	preNumber = AccountNumber(); HistoryOrders = OrdersHistoryTotal();
}

bool OldTicket( int ticket )
{
	for ( int o = 0; o < preHistoryOrdersCount; o ++ )
	{
		if ( preHistoryOrders[o] == ticket ) return(true);
	}
	return(false);
}

bool CloseAll()
{
	bool result = true;
	int _GetLastError, _OrdersTotal = OrdersTotal();

	for ( int z = _OrdersTotal - 1; z >= 0; z -- )
	{
		if ( !OrderSelect( z, SELECT_BY_POS, MODE_TRADES ) )
		{
			_GetLastError = GetLastError();
			Print( "OrderSelect( ", z, ", SELECT_BY_POS, MODE_TRADES ) - Error #", _GetLastError );
			continue;
		}

		if ( OrderType() > 1 )
		{
			if ( !OrderDelete( OrderTicket() ) )
			{
				result = false;
				Print( "OrderDelete error #", GetLastError(), "!" );
			}
		}
		else
		{
			if ( !OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), 5 ) )
			{
				result = false;
				Print( "OrderClose error #", GetLastError(), "!" );
			}
		}
	}

	return(result);
}

// Copyright © Èëüíóð
// Èñòî÷íèê - http://forum.mql4.com/ru/22509
// Ôóíêöèÿ âêëþ÷åíèÿ/îòêëþ÷åíèÿ ýêñïåðòà.
void SetExpertEnabled (bool Switch) // TRUE - âêëþ÷èòü ýêñïåðò, FALSE - îòêëþ÷èòü ýêñïåðò.
 {
  int HandlWindow = WindowHandle (Symbol(), Period()); // Ñèñòåìíûé äåñêðèïòîð îêíà.
  int HandlMT4;        // Ñèñòåìíûé äåñêðèïòîð îêíà ÌÒ4.
  int HandlToolbar;    // Ñèñòåìíûé äåñêðèïòîð îêíà èíñòðóìåíòîâ.
  // Ìàññâû.
  int ArIntTemp[1]; // Âðåìåííûé ìàññèâ.
  //
  if (Switch == true) // Åñëè òðåáóåòñÿ ðàçðåøèòü ðàáîòó ýêñïåðòà.
   {
    if (!IsExpertEnabled()) // Ðàçðåøàåì ðàáîòó ýêñïåðòîâ, åñëè îíà áûëà çàïðåùåíà.
     {
      HandlMT4 = GetAncestor (HandlWindow, 2);	
      HandlToolbar = GetDlgItem (HandlMT4, 0x63);
      ArIntTemp[0] = HandlToolbar;
      SendMessageA (HandlMT4, WM_COMMAND, 33020, ArIntTemp);
     }
   }
  else // Åñëè òðåáóåòñÿ çàïðåòèòü ðàáîòó ýêñïåðòà.
   {
    if (IsExpertEnabled()) // Ðàçðåøàåì ðàáîòó ýêñïåðòîâ, åñëè îíà áûëà çàïðåùåíà.
     {
      HandlMT4 = GetAncestor (HandlWindow, 2);	
      HandlToolbar = GetDlgItem (HandlMT4, 0x63);
      ArIntTemp[0] = HandlToolbar;
      SendMessageA (HandlMT4, WM_COMMAND, 33020, ArIntTemp);
     }
   }
 }


//+------------------------------------------------------------------+
//| Events
//+------------------------------------------------------------------+
void CheckEvents()
{
	string	strReason					= "";
	int		_GetLastError				= 0;

	int		now_HistoryCount			= OrdersHistoryTotal();

	if ( now_HistoryCount <= 0 ) return;
	
	int		now_OrdersTotal			= OrdersTotal();
	int		now_OrdersArray			[][2];	// ìàññèâ îòêðûòûõ ïîçèöèé, ñîñòîÿíèåì íà òåêóùèé òèê [¹ òèêåòà, òèï ïîçèöèè]

	// èçìåíÿåì ðàçìåð ìàññèâà îòêðûòûõ ïîçèöèé ïîä òåêóùåå êîë-âî
	ArrayResize( now_OrdersArray, MathMax( now_OrdersTotal, 1 ) ); ArrayInitialize( now_OrdersArray, 0.0 );

	//+------------------------------------------------------------------+
	//| Ïåðåáèðàåì âñå ïîçèöèè è çàïèñûâàåì â ìàññèâ òîëüêî òå, êîòîðûå ñîîòâåòñòâóþò êðèòåðèÿì
	//+------------------------------------------------------------------+
	for ( int z = now_OrdersTotal - 1; z >= 0; z -- )
	{
		if ( !OrderSelect( z, SELECT_BY_POS, MODE_TRADES ) )
		{
			_GetLastError = GetLastError();
			Print( "OrderSelect( ", z, ", SELECT_BY_POS, MODE_TRADES ) - Error #", _GetLastError );
			continue;
		}

		// Ñîõðàíÿåì òèêåò è òèï äëÿ äàëüíéøèõ ïðîâåðîê
		now_OrdersArray[z][0] = OrderTicket();
		now_OrdersArray[z][1] = OrderType();


		// Ïðîâåðÿåì, íå îòêðûëñÿ ëè îðäåð íà ýòîì òèêå
		bool OrderOpened = true;
		for ( int prev = 0; prev < pre_OrdersCount; prev ++ )
		{
			if ( now_OrdersArray[z][0] == pre_OrdersArray[prev][0] )
			{
				OrderOpened = false;
				break;
			}
		}

		if ( OrderOpened )
		{
			if ( now_OrdersArray[z][1] < 2 )
			{
				AllInfo( StringConcatenate( strOrderType( now_OrdersArray[z][1] ), " #", now_OrdersArray[z][0], " (", strLots( OrderLots() ), " ", OrderSymbol(), 
														") was opened at ", DoubleToStr( OrderOpenPrice(), MarketInfo( OrderSymbol(), MODE_DIGITS ) ), "!" ) );
			}
			else
			{
				AllInfo( StringConcatenate( strOrderType( now_OrdersArray[z][1] ), " #", now_OrdersArray[z][0], " (", strLots( OrderLots() ), " ", OrderSymbol(), 
														") was placed at ", DoubleToStr( OrderOpenPrice(), MarketInfo( OrderSymbol(), MODE_DIGITS ) ), "!" ) );
			}
		}
	}


	//+------------------------------------------------------------------+
	//| Ïåðåáèðàåì ñïèñîê ïîçèöèé ïðåäûäóùåãî òèêà, è ñ÷èòàåì ñêîëüêî çàêðûëîñü ïîçèöèé è ñðàáîòàëî îòëîæåííûõ îðäåðîâ
	//+------------------------------------------------------------------+
	for ( int p = 0; p < pre_OrdersCount; p ++ )
	{
		// çàïîìèíàåì òèêåò è òèï îðäåðà
		int ticket = pre_OrdersArray[p][0];
		int type   = pre_OrdersArray[p][1];

		// ïðåäïîëîãàåì, ÷òî åñëè ýòî ïîçèöèÿ, òî îíà çàêðûëàñü
		bool OrderClosed = true;

		// ïåðåáèðàåì âñå ïîçèöèè èç òåêóùåãî ñïèñêà îòêðûòûõ ïîçèöèé
		for ( int o = 0; o < now_OrdersTotal; o ++ )
		{
			// åñëè ïîçèöèÿ ñ òàêèì òèêåòîì åñòü â ñïèñêå,
			if ( ticket == now_OrdersArray[o][0] )
			{
				// çíà÷èò ïîçèöèÿ íå áûëà çàêðûòà (îðäåð íå áûë óäàë¸í)
				OrderClosed = false;

				// åñëè å¸ òèï ïîìåíÿëñÿ,
				if ( type != now_OrdersArray[o][1] )
				{
					// çíà÷èò ýòî áûë îòëîæåííûé îðäåð, è îí ñðàáîòàë
					if ( !OrderSelect( ticket, SELECT_BY_TICKET ) )
					{
						_GetLastError = GetLastError();
						Print( "OrderSelect( ", ticket, ", SELECT_BY_TICKET ) - Error #", _GetLastError );
						break;
					}

					AllInfo( StringConcatenate( strOrderType( type ), " #", ticket, " (", strLots( OrderLots() ), " ", OrderSymbol(), 
														") was executed at ", DoubleToStr( OrderOpenPrice(), MarketInfo( OrderSymbol(), MODE_DIGITS ) ), "!" ) );
				}
				break;
			}
		}

		// åñëè áûëà çàêðûòà ïîçèöèÿ (óäàë¸í îðäåð),
		if ( OrderClosed )
		{
			// âûáèðàåì å¸
			if ( !OrderSelect( ticket, SELECT_BY_TICKET ) )
			{
				_GetLastError = GetLastError();
				Print( "OrderSelect( ", ticket, ", SELECT_BY_TICKET ) - Error #", _GetLastError );
				continue;
			}

			// è îïðåäåëÿåì, ÊÀÊ çàêðûëàñü ïîçèöèÿ (óäàëèëñÿ îðäåð):
			if ( type < 2 )
			{
				// Áàé è Ñåëë: âðó÷íóþ, ÑË èëè ÒÏ
				strReason = "";

				if ( OrderStopLoss() > 0.000001 && ((type == OP_BUY && OrderStopLoss() - OrderClosePrice() > -0.000001) || (type == OP_SELL && OrderClosePrice() - OrderStopLoss() > -0.00001)) )
				{
					if ( MathAbs( OrderClosePrice() - OrderStopLoss() ) > 0.000001 )
						strReason = " (SL-GAP)";
					else
						strReason = " (SL)";
				}
				else if ( OrderTakeProfit() > 0.000001 && ((type == OP_BUY && OrderClosePrice() - OrderTakeProfit() > -0.000001) || (type == OP_SELL && OrderTakeProfit() - OrderClosePrice() > -0.00001)) )
				{
					if ( MathAbs( OrderClosePrice() - OrderTakeProfit() ) > 0.000001 )
						strReason = " (TP-GAP)";
					else
						strReason = " (TP)";
				}

				AllInfo( StringConcatenate( strOrderType( type ), " #", ticket, " (", strLots( OrderLots() ), " ", OrderSymbol(), 
														") was closed at ", DoubleToStr( OrderClosePrice(), MarketInfo( OrderSymbol(), MODE_DIGITS ) ), 
														" (", strPlus( OrderProfit()+OrderSwap()+OrderCommission(), 2 ), " ", AccountCurrency(), ")", strReason, "!" ) );
			}
			else
			{
				// Îòëîæåííûå îðäåðà: âðó÷íóþ èëè ïî âðåìåíè èñòå÷åíèÿ
				if ( StringFind( OrderComment(), "expiration" ) >= 0 )
					AllInfo( StringConcatenate( strOrderType( type ), " #", ticket, " (", strLots( OrderLots() ), " ", OrderSymbol(), ") was expired!" ) );
				else
					AllInfo( StringConcatenate( strOrderType( type ), " #", ticket, " (", strLots( OrderLots() ), " ", OrderSymbol(), ") was deleted!" ) );
			}

			continue;
		}
	}


	//+------------------------------------------------------------------+
	//| Ïåðåáèðàåì èñòîðèþ, è ñìîòðèì, íå ïîÿâèëèñü ëè òàì íîâûå ïîïîëíåíèÿ/ñíÿòèÿ
	//+------------------------------------------------------------------+
	for ( z = now_HistoryCount - 1; z >= 0; z -- )
	{
		if ( !OrderSelect( z, SELECT_BY_POS, MODE_HISTORY ) )
		{
			_GetLastError = GetLastError();
			Print( "OrderSelect( ", z, ", SELECT_BY_POS, MODE_HISTORY ) - Error #", _GetLastError );
			continue;
		}

		if ( OrderType() != 6 && OrderType() != 7 ) continue;

		// Ïðîâåðÿåì, íå îòêðûëñÿ ëè îðäåð íà ýòîì òèêå
		bool IsNew = true;
		for ( int pre = 0; pre < pre_HistoryCount; pre ++ )
		{
			if ( OrderTicket() == pre_HistoryArray[pre] )
			{
				IsNew = false;
				break;
			}
		}

		if ( IsNew )
		{
			if ( OrderProfit() > 0 )
			{
				AllInfo( StringConcatenate( "deposit ", strLots( OrderProfit() ), " ", AccountCurrency(), " (#", OrderTicket(), ", \"", OrderComment(), "\")!" ) );
			}
			else
			{
				AllInfo( StringConcatenate( "withdraw ", strLots( -OrderProfit() ), " ", AccountCurrency(), " (#", OrderTicket(), ", \"", OrderComment(), "\")!" ) );
			}

			pre_HistoryCount ++;
			ArrayResize( pre_HistoryArray, pre_HistoryCount );
			pre_HistoryArray[pre_HistoryCount-1] = OrderTicket();
		}
	}


	//---- ñîõðàíÿåì ìàññèâ òåêóùèõ ïîçèöèé â ìàññèâ ïðåäûäóùèõ ïîçèöèé
	ArrayResize( pre_OrdersArray, MathMax( now_OrdersTotal, 1 ) );
	for ( int now_CurOrder = 0; now_CurOrder < now_OrdersTotal; now_CurOrder ++ )
	{
		pre_OrdersArray[now_CurOrder][0] = now_OrdersArray[now_CurOrder][0];
		pre_OrdersArray[now_CurOrder][1] = now_OrdersArray[now_CurOrder][1];
	}
	pre_OrdersCount = now_OrdersTotal;
}

void AllInfo( string msg )
{
	if ( pre_OrdersCount < 0 ) return;

	string subj = StringConcatenate( "Account #", AccountNumber(), " (", TimeToStr( TimeLocal(), TIME_DATE | TIME_SECONDS ), ")" );
	string text = StringConcatenate( subj, ": ", msg );

	if ( AllowAlert		) Alert( text );
	if ( AllowPrint		) Print( text );
	if ( AllowComment		) Comment( text );
	if ( AllowMail			) SendMail( StringConcatenate( "Acc #", AccountNumber() ), StringConcatenate( TimeToStr( TimeLocal(), TIME_DATE | TIME_SECONDS ), ": ", msg ) );
	if ( AllowSound		) PlaySound( SoundFileName );
	if ( AllowFile			) WriteFile( StringConcatenate( FilePath, "SendMe(", msg, ").txt" ), text );
}

string strOrderType( int intOrderType )
{
	switch ( intOrderType )
	{
		case OP_BUY:			return("buy"					);
		case OP_SELL:			return("sell"					);
		case OP_BUYLIMIT:		return("buy limit"			);
		case OP_BUYSTOP:		return("buy stop"				);
		case OP_SELLLIMIT:	return("sell limit"			);
		case OP_SELLSTOP:		return("sell stop"			);
		default:					return("UnknownOrderType"	);
	}
}

string strPlus( double value, int digits )
{
	if ( CentAccount ) value *= 0.01;
	if ( value < 0 )
		return( "-" + DoubleToStr( -value, digits ) );
	else
		return( "+" + DoubleToStr( value, digits ) );
}

string strLots( double value )
{
	if ( CentAccount ) value *= 0.01;
	return( DoubleToStr( value, 2 ) );
}

bool WriteFile( string path, string buffer ) 
{
	int handle, result, count = StringLen( buffer ); bool res = true;

	handle =_lopen( path, 1 );
	if ( handle < 0 )
	{
		handle =_lcreat( path, 0 );
		if ( handle < 0 ) 
		{
//			Print( "Îøèáêà ñîçäàíèÿ ôàéëà ", path );
			return(false);
		}
		result =_lclose( handle );
	}

	handle = _lopen( path, 1 );              
	if ( handle < 0 )
	{
		Print( "Îøèáêà îòêðûòèÿ ôàéëà ", path );
		return(false);
	}

	result = _llseek( handle, 0, 0 );
	if ( result < 0 )
	{
		Print( "Îøèáêà óñòàíîâêè óêàçàòåëÿ" );
		return(false);
	}

	result = _lwrite( handle, buffer, count );
	if ( result < 0 )
	{
		Print( "Îøèáêà çàïèñè â ôàéë ", path, " ", count, " áàéò" );
		res = false;
	}

	result = _lclose( handle );
	if ( result < 0 )
	{
		Print( "Îøèáêà çàêðûòèÿ ôàéëà ", path );
		res = false;
	}
	return(res);
}

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---