//+------------------------------------------------------------------+
//|                                           VisualTestingTools.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, komposter"
#property link      "mailto:komposterius@mail.ru"

extern string		VisualTestingTools	= "< - - - VisualTestingTools - - - >";
extern int			Rows						= 10;
extern bool			BigText					= false;
extern int			SignalPoints			= 10;

extern color		MainColor				= White;

extern color		BuyColor					= Green;
extern color		BuyOPColor				= Lime;
extern color		BuySLColor				= Lime;
extern color		BuyTPColor				= Lime;

extern color		SellColor				= Brown;
extern color		SellOPColor				= Red;
extern color		SellSLColor				= Red;
extern color		SellTPColor				= Red;

string MarketOrders[1][11], PendingOrders[1][11];
int win = -1, curMarketOrder = 0, curPendingOrder = 0;

int fontsize = 8;

void vTerminalInit()
{
	win = WindowFind( "vTerminal" );
	if ( IsTesting() ) { win = 1; }
	if ( win < 0 ) { return(-1); }

	ArrayResize( MarketOrders, Rows );
	ArrayResize( PendingOrders, Rows );

	int vshift = 13, shift1 = 3, shift2 = 60, shift3 = 160, shift4 = 220, shift5 = 260, shift6 = 325, shift7 = 385, shift8 = 445, shift9 = 500, shift10 = 555, shift11 = 610;
	if ( BigText )
	{
		fontsize = 9; vshift = 15; shift1 = 3; shift2 = 70; shift3 = 185; shift4 = 255; shift5 = 305; shift6 = 380; shift7 = 450; shift8 = 520; shift9 = 605; shift10 = 660; shift11 = 725;
	}

	vLabel( "Ticket_Head"		, shift1	, vshift ); SetText( "Ticket_Head"			, "Ticket"		, MainColor );
	vLabel( "OpenTime_Head"		, shift2	, vshift ); SetText( "OpenTime_Head"		, "OpenTime"	, MainColor );
	vLabel( "Type_Head"			, shift3	, vshift ); SetText( "Type_Head"				, "Type"			, MainColor );
	vLabel( "Lots_Head"			, shift4	, vshift ); SetText( "Lots_Head"				, "Lots"			, MainColor );
	vLabel( "OpenPrice_Head"	, shift5	, vshift ); SetText( "OpenPrice_Head"		, "OpenPrice"	, MainColor );
	vLabel( "StopLoss_Head"		, shift6	, vshift ); SetText( "StopLoss_Head"		, "StopLoss"	, MainColor );
	vLabel( "TakeProfit_Head"	, shift7	, vshift ); SetText( "TakeProfit_Head"		, "TakeProfit"	, MainColor );
	vLabel( "CurPrice_Head"		, shift8	, vshift ); SetText( "CurPrice_Head"		, "CurPrice"	, MainColor );
	vLabel( "Swap_Head"			, shift9	, vshift ); SetText( "Swap_Head"				, "Swap"			, MainColor );
	vLabel( "Profit_Head"		, shift10, vshift ); SetText( "Profit_Head"			, "Profit"		, MainColor );
	vLabel( "Comment_Head"		, shift11, vshift ); SetText( "Comment_Head"			, "Comment"		, MainColor );

	for ( int i = 0; i < Rows; i ++ )
	{
		vLabel ( "Ticket_" 		+ i, shift1, vshift*(i+2) );
		vLabel ( "OpenTime_" 	+ i, shift2, vshift*(i+2) );
		vLabel ( "Type_" 			+ i, shift3, vshift*(i+2) );
		vLabel ( "Lots_" 			+ i, shift4, vshift*(i+2) );
		vLabel ( "OpenPrice_" 	+ i, shift5, vshift*(i+2) );
		vLabel ( "StopLoss_" 	+ i, shift6, vshift*(i+2) );
		vLabel ( "TakeProfit_" 	+ i, shift7, vshift*(i+2) );
		vLabel ( "CurPrice_" 	+ i, shift8, vshift*(i+2) );
		vLabel ( "Swap_" 			+ i, shift9, vshift*(i+2) );
		vLabel ( "Profit_" 		+ i, shift10, vshift*(i+2) );
		vLabel ( "Comment_" 		+ i, shift11, vshift*(i+2) );
	}
}
void vTerminalRefresh()
{
	if ( win < 0 ) { return(-1); }

	int _GetLastError, _OrdersTotal = OrdersTotal(), digits;
	curMarketOrder = 0; curPendingOrder = 0;
	double SummProfit = 0.0;

	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;
		}

		digits = MarketInfo( OrderSymbol(), MODE_DIGITS );

		if ( OrderType() < 2 )
		{
			MarketOrders[curMarketOrder][0] = OrderTicket();
			MarketOrders[curMarketOrder][1] = TimeToStr( OrderOpenTime() );
			MarketOrders[curMarketOrder][2] = vOrderType( OrderType() );
			MarketOrders[curMarketOrder][3] = DoubleToStr( OrderLots(), 1 );
			MarketOrders[curMarketOrder][4] = DoubleToStr( OrderOpenPrice(), digits );
			MarketOrders[curMarketOrder][5] = DoubleToStr( OrderStopLoss(), digits );
			MarketOrders[curMarketOrder][6] = DoubleToStr( OrderTakeProfit(), digits );

			if ( OrderType() == OP_BUY )
			{ MarketOrders[curMarketOrder][7] = DoubleToStr( MarketInfo( OrderSymbol(), MODE_BID ), digits ); }
			else
			{ MarketOrders[curMarketOrder][7] = DoubleToStr( MarketInfo( OrderSymbol(), MODE_ASK ), digits ); }

			MarketOrders[curMarketOrder][8] = DoubleToStr( OrderSwap(), 2 );
			MarketOrders[curMarketOrder][9] = DoubleToStr( OrderProfit(), 2 );
			MarketOrders[curMarketOrder][10] = OrderComment();

			SummProfit += OrderProfit();
			curMarketOrder ++;
			if ( curMarketOrder >= Rows ) { break; }
		}
		else
		{
			PendingOrders[curPendingOrder][0] = OrderTicket();
			PendingOrders[curPendingOrder][1] = TimeToStr( OrderOpenTime() );
			PendingOrders[curPendingOrder][2] = vOrderType( OrderType() );
			PendingOrders[curPendingOrder][3] = DoubleToStr( OrderLots(), 1 );
			PendingOrders[curPendingOrder][4] = DoubleToStr( OrderOpenPrice(), digits );
			PendingOrders[curPendingOrder][5] = DoubleToStr( OrderStopLoss(), digits );
			PendingOrders[curPendingOrder][6] = DoubleToStr( OrderTakeProfit(), digits );

			if ( OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT )
			{ PendingOrders[curPendingOrder][7] = DoubleToStr( MarketInfo( OrderSymbol(), MODE_BID ), digits ); }
			else
			{ PendingOrders[curPendingOrder][7] = DoubleToStr( MarketInfo( OrderSymbol(), MODE_ASK ), digits ); }

			PendingOrders[curPendingOrder][8] = DoubleToStr( OrderSwap(), 2 );
			PendingOrders[curPendingOrder][9] = DoubleToStr( OrderProfit(), 2 );
			PendingOrders[curPendingOrder][10] = OrderComment();

			curPendingOrder ++;
			if ( curMarketOrder + curPendingOrder >= Rows ) { break; }
		}
	}

	//+------------------------------------------------------------------+
	//| Сортировка массивов ордеров
	//+------------------------------------------------------------------+
	string tmp[11];
	for ( int i = curMarketOrder - 1; i >= 0; i-- )
	{
		for ( int j = curMarketOrder - 1; j >= 0; j-- )
		{
			if ( StrToInteger( MarketOrders[i][0] ) > StrToInteger( MarketOrders[j][0] ) )
			{
				for ( int n = 0; n < 11; n ++ ) { tmp[n] = MarketOrders[i][n]; }
				for ( n = 0; n < 11; n ++ ) { MarketOrders[i][n] = MarketOrders[j][n]; }
				for ( n = 0; n < 11; n ++ ) { MarketOrders[j][n] = tmp[n]; }
			}
		}
	}
	for ( i = curPendingOrder - 1; i >= 0; i-- )
	{
		for ( j = curPendingOrder - 1; j >= 0; j-- )
		{
			if ( StrToInteger( PendingOrders[i][0] ) > StrToInteger( PendingOrders[j][0] ) )
			{
				for ( n = 0; n < 11; n ++ ) { tmp[n] = PendingOrders[i][n]; }
				for ( n = 0; n < 11; n ++ ) { PendingOrders[i][n] = PendingOrders[j][n]; }
				for ( n = 0; n < 11; n ++ ) { PendingOrders[j][n] = tmp[n]; }
			}
		}
	}

	bool SummLineOK = false;
	color tmp_MainColor, tmp_SLColor, tmp_TPColor, tmp_OPColor;
	for ( i = 0; i < Rows; i ++ )
	{
		if ( i < curMarketOrder )
		{
			if ( MarketOrders[i][2] == "Buy" )
			{
				tmp_MainColor = BuyColor;

				if ( StrToDouble( MarketOrders[i][5] ) > 0 &&  NormalizeDouble( SignalPoints*Point - ( StrToDouble( MarketOrders[i][7] ) - StrToDouble( MarketOrders[i][5] ) ), Digits ) >= 0.0 )
				{ tmp_SLColor = BuySLColor; }
				else
				{ tmp_SLColor = BuyColor; }

				if ( StrToDouble( MarketOrders[i][6] ) > 0 && NormalizeDouble( SignalPoints*Point - ( StrToDouble( MarketOrders[i][6] ) - StrToDouble( MarketOrders[i][7] ) ), Digits ) >= 0.0 )
				{ tmp_TPColor = BuyTPColor; }
				else
				{ tmp_TPColor = BuyColor; }
			}
			else
			{
				tmp_MainColor = SellColor;

				if ( StrToDouble( MarketOrders[i][5] ) > 0 &&  NormalizeDouble( SignalPoints*Point - ( StrToDouble( MarketOrders[i][5] ) - StrToDouble( MarketOrders[i][7] ) ), Digits ) >= 0.0 )
				{ tmp_SLColor = SellSLColor; }
				else
				{ tmp_SLColor = SellColor; }

				if ( StrToDouble( MarketOrders[i][6] ) > 0 && NormalizeDouble( SignalPoints*Point - ( StrToDouble( MarketOrders[i][7] ) - StrToDouble( MarketOrders[i][6] ) ), Digits ) >= 0.0 )
				{ tmp_TPColor = SellTPColor; }
				else
				{ tmp_TPColor = SellColor; }
			}

			SetText( "Ticket_" 		+ i, MarketOrders[i][0]		, tmp_MainColor );
			SetText( "OpenTime_" 	+ i, MarketOrders[i][1]		, tmp_MainColor );
			SetText( "Type_" 			+ i, MarketOrders[i][2]		, tmp_MainColor );
			SetText( "Lots_" 			+ i, MarketOrders[i][3]		, tmp_MainColor );
			SetText( "OpenPrice_" 	+ i, MarketOrders[i][4]		, tmp_MainColor );
			SetText( "StopLoss_" 	+ i, MarketOrders[i][5]		, tmp_SLColor );
			SetText( "TakeProfit_" 	+ i, MarketOrders[i][6]		, tmp_TPColor );
			SetText( "CurPrice_" 	+ i, MarketOrders[i][7]		, tmp_MainColor );
			SetText( "Swap_" 			+ i, MarketOrders[i][8]		, tmp_MainColor );
			SetText( "Profit_" 		+ i, MarketOrders[i][9]		, tmp_MainColor );
			SetText( "Comment_" 		+ i, MarketOrders[i][10]	, tmp_MainColor );
		}
		else
		{
			if ( !SummLineOK )
			{
				string tmp_margin = StringConcatenate( "Margin: ", DoubleToStr( AccountMargin(), 2 ) );
				string tmp_marginLevel = "";
				if ( AccountMargin() > 0 )
				{
					tmp_marginLevel = StringConcatenate( "  MarginLevel: ", DoubleToStr( AccountEquity()/AccountMargin()*100, 2 ), "%" );
				}
				SetText( "Ticket_" 		+ i, StringConcatenate( "Balance: ", DoubleToStr( AccountBalance(), 2 ), "  Equity: ", DoubleToStr( AccountEquity(), 2 ) ), MainColor );
				SetText( "OpenTime_" 	+ i );
				SetText( "Type_" 			+ i );
				SetText( "Lots_" 			+ i, StringConcatenate( tmp_margin, "  FreeMargin: ", DoubleToStr( AccountFreeMargin(), 2 ), tmp_marginLevel ), MainColor );
				SetText( "OpenPrice_" 	+ i );
				SetText( "StopLoss_" 	+ i );
				SetText( "TakeProfit_" 	+ i );
				SetText( "CurPrice_" 	+ i );
				SetText( "Swap_" 			+ i );
				SetText( "Profit_" 		+ i, DoubleToStr( SummProfit, 2 ), MainColor );
				SetText( "Comment_" 		+ i );
				i ++;
				SummLineOK = true;
			}

			if ( i <= curMarketOrder + curPendingOrder )
			{
				if ( PendingOrders[i-curMarketOrder-1][2] == "BuyLimit" || PendingOrders[i-curMarketOrder-1][2] == "BuyStop" )
				{
					tmp_MainColor = BuyColor;

					if ( NormalizeDouble( SignalPoints*Point - MathAbs( StrToDouble( PendingOrders[i-curMarketOrder-1][4] ) - StrToDouble( PendingOrders[i-curMarketOrder-1][7] ) ), Digits ) >= 0.0 )
					{ tmp_OPColor = BuyOPColor; }
					else
					{ tmp_OPColor = BuyColor; }
				}
				else
				{
					tmp_MainColor = SellColor;

					if ( NormalizeDouble( SignalPoints*Point - MathAbs( StrToDouble( PendingOrders[i-curMarketOrder-1][4] ) - StrToDouble( PendingOrders[i-curMarketOrder-1][7] ) ), Digits ) >= 0.0 )
					{ tmp_OPColor = SellOPColor; }
					else
					{ tmp_OPColor = SellColor; }
				}

				SetText( "Ticket_" 		+ i, PendingOrders[i-curMarketOrder-1][0], tmp_MainColor );
				SetText( "OpenTime_" 	+ i, PendingOrders[i-curMarketOrder-1][1], tmp_MainColor );
				SetText( "Type_" 			+ i, PendingOrders[i-curMarketOrder-1][2], tmp_MainColor );
				SetText( "Lots_" 			+ i, PendingOrders[i-curMarketOrder-1][3], tmp_MainColor );
				SetText( "OpenPrice_" 	+ i, PendingOrders[i-curMarketOrder-1][4], tmp_OPColor	);
				SetText( "StopLoss_" 	+ i, PendingOrders[i-curMarketOrder-1][5], tmp_MainColor );
				SetText( "TakeProfit_" 	+ i, PendingOrders[i-curMarketOrder-1][6], tmp_MainColor );
				SetText( "CurPrice_" 	+ i, PendingOrders[i-curMarketOrder-1][7], tmp_MainColor );
				SetText( "Swap_" 			+ i, PendingOrders[i-curMarketOrder-1][8], tmp_MainColor );
				SetText( "Profit_" 		+ i, PendingOrders[i-curMarketOrder-1][9], tmp_MainColor );
				SetText( "Comment_" 		+ i, PendingOrders[i-curMarketOrder-1][10],tmp_MainColor );
			}
			else
			{
				SetText( "Ticket_" 		+ i );
				SetText( "OpenTime_" 	+ i );
				SetText( "Type_" 			+ i );
				SetText( "Lots_" 			+ i );
				SetText( "OpenPrice_" 	+ i );
				SetText( "StopLoss_" 	+ i );
				SetText( "TakeProfit_" 	+ i );
				SetText( "CurPrice_" 	+ i );
				SetText( "Swap_" 			+ i );
				SetText( "Profit_" 		+ i );
				SetText( "Comment_" 		+ i );
			}
		}
	}
	ObjectsRedraw();
	return(0);
}

//+------------------------------------------------------------------+
// Создание объекта "Текстовая метка" с именем _LabelName.
// Координаты: х = _LabelXDistance, у = _LabelYDistance, угол - _LabelCorner.
//+------------------------------------------------------------------+
void vLabel ( string _LabelName, int _LabelXDistance, int _LabelYDistance, int _LabelCorner = 0 )
{
	int _GetLastError;

	if ( !ObjectCreate( _LabelName, OBJ_LABEL, win, 0, 0 ) )
	{
		_GetLastError = GetLastError();
		if ( _GetLastError != 4200 )
		{
			Print( "ObjectCreate( \"", _LabelName, "\", OBJ_LABEL,0,0,0 ) - Error #", _GetLastError );
			return(-1);
		}
	}
	if ( !ObjectSet( _LabelName, OBJPROP_CORNER, _LabelCorner ) )
	{
		_GetLastError = GetLastError();
		Print( "ObjectSet( \"", _LabelName, "\", OBJPROP_CORNER, ", _LabelCorner, " ) - Error #", _GetLastError );
	}
	if ( !ObjectSet( _LabelName, OBJPROP_XDISTANCE, _LabelXDistance ) )
	{
		_GetLastError = GetLastError();
		Print( "ObjectSet( \"", _LabelName, "\", OBJPROP_XDISTANCE, ", _LabelXDistance, " ) - Error #", _GetLastError );
	}
	if ( !ObjectSet( _LabelName, OBJPROP_YDISTANCE, _LabelYDistance ) )
	{
		_GetLastError = GetLastError();
		Print( "ObjectSet( \"", _LabelName, "\", OBJPROP_YDISTANCE, ", _LabelYDistance, " ) - Error #", _GetLastError );
	}
	if ( !ObjectSetText ( _LabelName, "", 8 ) )
	{
		_GetLastError = GetLastError();
		Print( "ObjectSetText( \"", _LabelName, "\", \"\", 8 ) - Error #", _GetLastError );
	}
}

//+------------------------------------------------------------------+
// Присвоение текста _LabelText объекту "Текстовая метка" с именем _LabelName.
//+------------------------------------------------------------------+
void SetText( string _LabelName, string _LabelText = "", color _LabelColor = Black )
{
	if ( !ObjectSetText( _LabelName, _LabelText, fontsize, "Arial", _LabelColor ) )
	{
		int _GetLastError = GetLastError();
		Print( "ObjectSetText( \"", _LabelName, "\", \"", _LabelText, "\", ", fontsize, "\"Arial\", ", _LabelColor, " ) - Error #", _GetLastError );
	}
}

//+------------------------------------------------------------------+
// возвращает OrderType в виде текста
//+------------------------------------------------------------------+
string vOrderType( int intOrderType )
{
	switch ( intOrderType )
	{
		case OP_BUY:			return("Buy"					);
		case OP_SELL:			return("Sell"					);
		case OP_BUYLIMIT:		return("BuyLimit"				);
		case OP_BUYSTOP:		return("BuyStop"				);
		case OP_SELLLIMIT:	return("SellLimit"			);
		case OP_SELLSTOP:		return("SellStop"				);
		default:					return("UnknownOrderType"	);
	}
}

