vHandsTrade





//+------------------------------------------------------------------+
//|                                                  vHandsTrade.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, komposter"
#property link      "mailto:komposterius@mail.ru"

extern string		vHandsTrade			= "< - - - vHandsTrade - - - >";
extern int			CommentsCount		= 10;
extern color		SelectColor			= Magenta;
extern color		ModifyColor			= Yellow;
extern color		TrailingColor		= Yellow;

//+------------------------------------------------------------------+
//| vHandsTrade.mq4 - ýêñïåðò äëÿ "ðó÷íîé" òîðãîâëè íà òåñòåðå ÌÒ4
//| Ïîäðîáíîå îïèñàíèå - http://articles.mql4.com/ru/195
//| 
//| Ïåðåä èñïîëüçîâàíèåì ìîæíî íàñòðîèòü íåêîòîðûå ïàðàìåòðû:
//| RISK         - % äåïîçèòà, êîòîðûé áóäåò èñïîëüçîâàòüñÿ ïðè îòêðûòèè ïîçèöèè
//| LOT          - ðàçìåð ëîòà, êîòîðûé áóäåò èñïîëüçîâàòüñÿ ïðè îòêðûòèè ïîçèöèè, åñëè óêàçàí RISK = 0
//| STOPLOSS     - ðàçìåð ÑòîïËîññ äëÿ îòêðûâàåìûõ ïîçèöèé (åñëè ïðè îòêðûòèè íå äâèãàåòñÿ ëèíèÿ ÑòîïËîññ)
//| TAKEPROFIT   - ðàçìåð ÒåéêÏðîôèò äëÿ îòêðûâàåìûõ ïîçèöèé (åñëè ïðè îòêðûòèè íå äâèãàåòñÿ ëèíèÿ ÒåéêÏðîôèò)
//| TRAILINGSTOP - ðàçìåð ÒðåéëèíãÑòîïà, êîòîðûì áóäóò ñîïðîâîæäàòüñÿ âñå ïîçèöèè
//| EXPIRATION   - âðåìÿ èñòå÷åíèÿ îòëîæåííûõ îðäåðîâ (â ÷àñàõ)
//|
//| Êàæäîìó èç ýòèõ ïàðàìåòðîâ ñîîòâåòñòâóåò 2 ïåðåìåííûå:
//| Ìàññèâ (íàïðèìåð RISK[]) - 5 ÷èñåë, èç êîòîðûõ ìîæíî áóäåò âûáèðàòü çíà÷åíèå ïàðàìåòðà â ïðîöåññå ðàáîòû.
//| È ïåðåìåííàÿ SELECTED_*** (íàïðèìåð, SELECTED_RISK) - ¹ ÷èñëà èç ìàññèâà, êîòîðîå áóäåò âûáðàííî ïî óìîë÷àíèþ.
//|
//| Íàïðèìåð, åñëè âû èñïîëüçóåòå ÑòîïËîññû 20, 40, 60 è 80 ïóíêòîâ (è 0, ò.å. íå èñïîëüçóåòå), çàïîëíèòå ìàññèâ
//| STOPLOSS âîò òàê: "int STOPLOSS[] = { 0, 20, 40, 60, 80 };"
//| Äëÿ èñïîëüçîâàíèÿ ïî óìîë÷àíèþ ÑòîïËîññà 40 ïóíêòîâ, óêàæèòå "int SELECTED_STOPLOSS = 3;" (÷èñëî 40 - 3-å â ñïèñêå)

	 int RISK[] = { 0, 2, 5, 10, 25 };
	 int SELECTED_RISK = 1;

	 double LOT[] = { 0.1, 0.2, 0.5, 1.0, 5.0 };
	 int SELECTED_LOT = 1;

	 int STOPLOSS[] = { 0, 15, 25, 50, 100 };
	 int SELECTED_STOPLOSS = 4;

	 int TAKEPROFIT[] = { 0, 50, 100, 150, 250 };
	 int SELECTED_TAKEPROFIT = 1;

	 int TRAILINGSTOP[] = { 0, 15, 25, 50, 100 };
	 int SELECTED_TRAILINGSTOP = 4;

	 double EXPIRATION[] = { 0, 0.5, 1, 12, 24 };
	 int SELECTED_EXPIRATION = 1;


//| MIN_TRADE_PAUSE_MS - ìèíèìàëüíàÿ ïàóçà ìåæäó òîðãîâûìè îïåðàöèÿìè (ìñ).
//| Åñëè ïðè òîðãîâëå áåç ïàóçû ó âàñ óñòàíàâëèâàåòñÿ íåñêîëüêî îäèíàêîâûõ îðäåðîâ, ñäåëàéòå MIN_TRADE_PAUSE_MS áîëüøå.
#define MIN_TRADE_PAUSE_MS 750

//| Äàëüøå ñîâåòóþ íè÷åãî íå òðîãàòü ;)
//+------------------------------------------------------------------+

#include <VisualTestingTools.mq4>

int preTime = 0, BarsInWindow = 0, preBarsInWindow = 0, SecondsInBar = 0, Panel_Width = 0, Panel_T1 = 0, Panel_T2 = 0, left[3], right[3];
double WindowHighest = 0.0, WindowLowest = 0.0, preWindowHighest = 0.0, preWindowLowest = 0.0, Panel_P1 = 0.0, Panel_P2 = 0.0;
double Shag_X = 0.0, Zazor_X = 0.0, Dlina_X = 0.0, Shag_Y = 0.0, up[14];

double Lot = 0.1;
int Risk = 0, StopLoss = 50, TakeProfit = 150, TrailingStop = 50, Expiration = 0;

bool NeedRedrawObjects = true;
bool error = false;

string comment[];

int	vhtLotDigits = 0;
int	lastB = 0, lastS = 0, lastBS = 0, lastSS = 0, lastBL = 0, lastSL = 0;

int init()
{
	error = false;

	if ( !IsTesting() ) { Alert( "vHandsTrade: ñîâåòíèê ïðåäíàçíà÷åí òîëüêî äëÿ òåñòèðîâàíèÿ!" ); error = true; return(-1); }

	//---- ïðîâåðÿåì óêàçàííûå ïîëüçîâàòåëåì ïàðàìåòðû
	if ( SELECTED_RISK					< 1 || SELECTED_RISK					> 5 ) { Alert( "íåïðàâèëüíîå çíà÷åíèå SELECTED_RISK!" );								error = true; }
	if ( ArraySize( RISK )				< 1 || ArraySize( RISK )			> 5 ) { Alert( "íåïðàâèëüíîå êîëè÷åñòâî çíà÷åíèé â ìàññèâå RISK!" );				error = true; }

	if ( SELECTED_LOT						< 1 || SELECTED_LOT					> 5 ) { Alert( "íåïðàâèëüíîå çíà÷åíèå SELECTED_LOT!" );								error = true; }
	if ( ArraySize( LOT )				< 1 || ArraySize( LOT )				> 5 ) { Alert( "íåïðàâèëüíîå êîëè÷åñòâî çíà÷åíèé â ìàññèâå LOT!" );				error = true; }

	if ( SELECTED_STOPLOSS				< 1 || SELECTED_STOPLOSS			> 5 ) { Alert( "íåïðàâèëüíîå çíà÷åíèå SELECTED_STOPLOSS!" );						error = true; }
	if ( ArraySize( STOPLOSS )			< 1 || ArraySize( STOPLOSS )		> 5 ) { Alert( "íåïðàâèëüíîå êîëè÷åñòâî çíà÷åíèé â ìàññèâå STOPLOSS!" );		error = true; }

	if ( SELECTED_TAKEPROFIT			< 1 || SELECTED_TAKEPROFIT			> 5 ) { Alert( "íåïðàâèëüíîå çíà÷åíèå SELECTED_TAKEPROFIT!" );						error = true; }
	if ( ArraySize( TAKEPROFIT )		< 1 || ArraySize( TAKEPROFIT )	> 5 ) { Alert( "íåïðàâèëüíîå êîëè÷åñòâî çíà÷åíèé â ìàññèâå TAKEPROFIT!" );		error = true; }

	if ( SELECTED_TRAILINGSTOP			< 1 || SELECTED_TRAILINGSTOP		> 5 ) { Alert( "íåïðàâèëüíîå çíà÷åíèå SELECTED_TRAILINGSTOP!" );					error = true; }
	if ( ArraySize( TRAILINGSTOP )	< 1 || ArraySize( TRAILINGSTOP )	> 5 ) { Alert( "íåïðàâèëüíîå êîëè÷åñòâî çíà÷åíèé â ìàññèâå TRAILINGSTOP!" );	error = true; }

	if ( SELECTED_EXPIRATION			< 1 || SELECTED_EXPIRATION			> 5 ) { Alert( "íåïðàâèëüíîå çíà÷åíèå SELECTED_EXPIRATION!" );						error = true; }
	if ( ArraySize( EXPIRATION )		< 1 || ArraySize( EXPIRATION )	> 5 ) { Alert( "íåïðàâèëüíîå êîëè÷åñòâî çíà÷åíèé â ìàññèâå EXPIRATION!" );		error = true; }

	if ( error ) { return(-1); }

	//---- îïðåäåëÿåì çíà÷åíèÿ ïî óìîë÷àíèþ
	Risk				= RISK[SELECTED_RISK-1];
	Lot				= LOT[SELECTED_LOT-1];
	StopLoss			= STOPLOSS[SELECTED_STOPLOSS-1];
	TakeProfit		= TAKEPROFIT[SELECTED_TAKEPROFIT-1];
	TrailingStop	= TRAILINGSTOP[SELECTED_TRAILINGSTOP-1];
	Expiration		= EXPIRATION[SELECTED_EXPIRATION-1]*3600.0;

	vhtLotDigits = 0;
	double tmp = MarketInfo( Symbol(), MODE_LOTSTEP );

	while ( NormalizeDouble( 1.0 - tmp, 4 ) > 0.0 )
	{
		tmp *= 10;
		vhtLotDigits ++;
	}

	//---- ñòàâèì ïîìåòêó î ïåðåðèñîâêå îáúåêòîâ
	NeedRedrawObjects = true;

	//---- ïðîñ÷èòûâàåì êîîðäèíàòû îáúåêòîâ
	vHandsTrade_ReCount();

	//---- ïåðåðèñîâûâàåì îáúåêòû
	vHandsTrade_RefreshObjects();

	//---- èíèöèàëèçèðóåì çàêëàäêè "òåðìèíàë" è "èñòîðèÿ ñ÷åòà"
	vTerminalInit();
	vHistoryInit();

	ArrayResize( comment, CommentsCount );
	for ( int i = CommentsCount-1; i >= 0; i -- ) comment[i] = "";

	return(0);
}

int deinit()
{
	if ( error ) { return(-1); }

	//---- óäàëÿåì âñå ñëåäû ðàáîòû
	vHandsTrade_DeleteObjects();

	Comment( "" );

	return(0);
}
int start()
{
	if ( error ) { return(-1); }

	//---- ïðîâåðÿåì, íå âûáðàë ëè ïîëüçîâàòåëü äðóãîå çíà÷åíèå ÑË/ÒÏ/ÒÑ/Ëîòà è ò.ä.
	vHandsTrade_CheckSelection();

	//---- ïðîâåðÿåì, íå íàäî ëè îòêðûòü ïîçèöèþ
	vHandsTrade_Open();
	//---- ïðîâåðÿåì, íå íàäî ëè çàêðûòü ïîçèöèþ
	vHandsTrade_Close();
	//---- ïðîâåðÿåì, íå íàäî ëè ìîäèôèöèðîâàòü ïîçèöèþ
	vHandsTrade_Modify();
	//---- ïîãîëîâíûé òðåéëèíã
	vHandsTrade_TrailingStop();


	//---- ïåðåñ÷èòûâàåì êîîðäèíàòû îáúåêòîâ
	vHandsTrade_ReCount();

	//---- ïåðåðèñîâûâàåì îáúåêòû
	vHandsTrade_RefreshObjects();

	//---- îáíîâëÿåì çàêëàäêè "òåðìèíàë" è "èñòîðèÿ ñ÷åòà"
	vTerminalRefresh();
	vHistoryRefresh();

	return(0);
}

void vHandsTrade_CheckSelection()
{
	string name;
	for ( int i = 1; i < 6; i ++ )
	{
		name = "vHT_Risk" + i;
		if ( Panel_T1+(i+1)*Shag_X == ObjectGet( name, OBJPROP_TIME1 ) && up[8] == ObjectGet( name, OBJPROP_PRICE1 ) ) { continue; }

		NeedRedrawObjects = true;
		SELECTED_RISK = i;
		Risk = RISK[SELECTED_RISK-1];
		break;
	}

	for ( i = 1; i < 6; i ++ )
	{
		name = "vHT_Lot" + i;
		if ( Panel_T1+(i+1)*Shag_X == ObjectGet( name, OBJPROP_TIME1 ) && up[9] == ObjectGet( name, OBJPROP_PRICE1 ) ) { continue; }

		NeedRedrawObjects = true;
		SELECTED_LOT = i;
		Lot = LOT[SELECTED_LOT-1];
		break;
	}

	for ( i = 1; i < 6; i ++ )
	{
		name = "vHT_StopLoss" + i;
		if ( Panel_T1+(i+1)*Shag_X == ObjectGet( name, OBJPROP_TIME1 ) && up[10] == ObjectGet( name, OBJPROP_PRICE1 ) ) { continue; }

		NeedRedrawObjects = true;
		SELECTED_STOPLOSS = i;
		StopLoss = STOPLOSS[SELECTED_STOPLOSS-1];
		break;
	}

	for ( i = 1; i < 6; i ++ )
	{
		name = "vHT_TakeProfit" + i;
		if ( Panel_T1+(i+1)*Shag_X == ObjectGet( name, OBJPROP_TIME1 ) && up[11] == ObjectGet( name, OBJPROP_PRICE1 ) ) { continue; }

		NeedRedrawObjects = true;
		SELECTED_TAKEPROFIT = i;
		TakeProfit = TAKEPROFIT[SELECTED_TAKEPROFIT-1];
		break;
	}

	for ( i = 1; i < 6; i ++ )
	{
		name = "vHT_TrailingStop" + i;
		if ( Panel_T1+(i+1)*Shag_X == ObjectGet( name, OBJPROP_TIME1 ) && up[12] == ObjectGet( name, OBJPROP_PRICE1 ) ) { continue; }

		NeedRedrawObjects = true;
		SELECTED_TRAILINGSTOP = i;
		TrailingStop = TRAILINGSTOP[SELECTED_TRAILINGSTOP-1];
		break;
	}

	for ( i = 1; i < 6; i ++ )
	{
		name = "vHT_Expiration" + i;
		if ( Panel_T1+(i+1)*Shag_X == ObjectGet( name, OBJPROP_TIME1 ) && up[13] == ObjectGet( name, OBJPROP_PRICE1 ) ) { continue; }

		NeedRedrawObjects = true;
		SELECTED_EXPIRATION = i;
		Expiration = EXPIRATION[SELECTED_EXPIRATION-1]*3600.0;
		break;
	}
}
void vHandsTrade_Open()
{
	vHandsTrade_OpenBuy();
	vHandsTrade_OpenSell();
	vHandsTrade_OpenBuyStop();
	vHandsTrade_OpenSellStop();
	vHandsTrade_OpenBuyLimit();
	vHandsTrade_OpenSellLimit();
}
void vHandsTrade_Close()
{
	if ( TerminalRows <= 0 ) { return(0); }
	if ( vTerminal_win < 0 ) { return(-1); }

	int _GetLastError;

	//---- ïåðåáèðàåì âñå ïîçèöèè, îòîáðàæåííûå â òåðìèíàëå
	for ( int i = 0; i < TerminalRows; i ++ )
	{
		//---- åñëè èçìåíèëàñü îäíà èç êîîðäèíàò îáúåêòà "Òèêåò",
		if ( ObjectGet( "Ticket_" + i, OBJPROP_XDISTANCE ) != shift1 || ObjectGet( "Ticket_" + i, OBJPROP_YDISTANCE ) != vshift*(i+2) )
		{
			//---- åñëè îáúåêò íå óäàëåí,
			if ( GetLastError() != 4202 )
			{
				//---- çàïîìèíàåì è ïûòàåìñÿ âûáðàòü ñîîòâåòñòâóþùèé òèêåò
				int ticket = StrToInteger( ObjectDescription( "Ticket_" + i ) );
				if ( ticket > 0 )
				{
					if ( !OrderSelect( ticket, SELECT_BY_TICKET ) )
					{
						_GetLastError = GetLastError();
						Print( "OrderSelect( ", ticket, ", SELECT_BY_TICKET ) - Error #", _GetLastError );
					}
					else
					{
						//---- åñëè òàêîé îðäåð åñòü, è îí íå çàêðûò,
						if ( OrderCloseTime() <= 0 )
						{
							//---- åñëè ýòî ìàðêåò-ïîçèöèÿ (áàé èëè ñåëë)
							if ( OrderType() < 2 )
							{
								//---- çàêðûâàåì ïîçèöèþ
								if ( OrderType() == OP_BUY )
								{
									if ( !OrderClose( ticket, OrderLots(), Bid, 3, BuyOPColor ) )
									{
										_GetLastError = GetLastError();
										MultiComment( "Îøèáêà #" + _GetLastError + " ïðè çàêðûòèè îðäåðà ¹" + ticket + "!!!" );
									}
									else
									{
										MultiComment( "Îðäåð ¹" + ticket + " çàêðûò óñïåøíî!" );
									}
								}
								else
								{
									if ( !OrderClose( ticket, OrderLots(), Ask, 3, SellOPColor ) )
									{
										_GetLastError = GetLastError();
										MultiComment( "Îøèáêà #" + _GetLastError + " ïðè çàêðûòèè îðäåðà ¹" + ticket + "!!!" );
									}
									else
									{
										MultiComment( "Îðäåð ¹" + ticket + " çàêðûò óñïåøíî!" );
									}
								}
							}
							//---- åñëè ýòî îòëîæåííûé îðäåð, óäàëÿåì åãî
							else
							{
								if ( !OrderDelete( ticket ) )
								{
									_GetLastError = GetLastError();
									MultiComment( "Îøèáêà #" + _GetLastError + " ïðè óäàëåíèè îðäåðà ¹" + ticket + "!!!" );
								}
								else
								{
									MultiComment( "Îðäåð ¹" + ticket + " óäàëåí óñïåøíî!" );
								}
							}
						}
					}
				}
			}
			//---- ñîçäàåì ïåðåìåùåííûé/óäàëåííûé îáúåêò "òèêåò"
			vLabel( vTerminal_win, "Ticket_" + i, shift1 , vshift*(i+2) );
		}
	}
}
void vHandsTrade_Modify()
{
	if ( TerminalRows <= 0 ) { return(0); }
	if ( vTerminal_win < 0 ) { return(-1); }

	int _GetLastError, tmp, ticket;
	bool modifyOP = false, modifySL = false, modifyTP = false;
	bool deleteOP = false, deleteSL = false, deleteTP = false;

	//---- ïåðåáèðàåì âñå ïîçèöèè, îòîáðàæåííûå â òåðìèíàëå
	for ( int i = 0; i < TerminalRows; i ++ )
	{
		//---- îáíóëÿåì ôëàãè çàêðûòèÿ è ìîäèôèêàöèè
		modifyOP = false; modifySL = false; modifyTP = false;
		deleteOP = false; deleteSL = false; deleteTP = false;
		//---- åñëè èçìåíèëàñü êîîðäèíàòà îáúåêòà OpenPrice,
		if ( ObjectGet( "OpenPrice_" + i, OBJPROP_XDISTANCE ) != shift5 || ObjectGet( "OpenPrice_" + i, OBJPROP_YDISTANCE ) != vshift*(i+2) )
		{
			//---- äåëàåì ïîìåòêó, óäàëåí ýòîò îáúåêò èëè ïðîñòî ïåðåìåùåí
			if ( GetLastError() == 4202 )
			{ deleteOP = true; }
			else
			{ modifyOP = true; }
			//---- ñîçäà¸ì åãî çàíîâî
			vLabel( vTerminal_win, "OpenPrice_" + i, shift5 , vshift*(i+2) );
		}
		//---- òî æå ñàìîå äëÿ StopLoss
		if ( ObjectGet( "StopLoss_" + i, OBJPROP_XDISTANCE ) != shift6 || ObjectGet( "StopLoss_" + i, OBJPROP_YDISTANCE ) != vshift*(i+2) )
		{
			if ( GetLastError() == 4202 )
			{ deleteSL = true; }
			else
			{ modifySL = true; }
			vLabel( vTerminal_win, "StopLoss_" + i, shift6 , vshift*(i+2) );
		}
		//---- òî æå ñàìîå äëÿ TakeProfit
		if ( ObjectGet( "TakeProfit_" + i, OBJPROP_XDISTANCE ) != shift7 || ObjectGet( "TakeProfit_" + i, OBJPROP_YDISTANCE ) != vshift*(i+2) )
		{
			if ( GetLastError() == 4202 )
			{ deleteTP = true; }
			else
			{ modifyTP = true; }
			vLabel( vTerminal_win, "TakeProfit_" + i, shift7 , vshift*(i+2) );
		}

		//---- åñëè íå ïðîèçîøëî íè îäíîãî èçìåííåíèÿ, ïåðåõîäèì ê ñëåäóþùåìó îðäåðó
		if ( !modifyOP && !modifySL && !modifyTP && !deleteOP && !deleteSL && !deleteTP ) { continue; }

		//---- åñëè èçìåíåíèå áûëî, íà÷èíàåì åãî îáðàáàòûâàòü:
		//---- çàïîìèíàåì òèêåò
		ticket = StrToInteger( ObjectDescription( "Ticket_" + i ) );
		if ( ticket <= 0 ) { continue; }

		//---- âûáèðàåì åãî
		if ( !OrderSelect( ticket, SELECT_BY_TICKET ) )
		{
			_GetLastError = GetLastError();
			Print( "OrderSelect( ", ticket, ", SELECT_BY_TICKET ) - Error #", _GetLastError );
			continue;
		}

		//---- ïðîâåðÿåì, íå çàêðûëñÿ ëè îí
		if ( OrderCloseTime() > 0 ) { continue; }

		//---- åñëè áûë óäàëåí îáúåêò OpenPrice,
		if ( deleteOP )
		{
			//---- åñëè ýòî ìàðêåò-îðäåð, çàêðûâàåì åãî
			if ( OrderType() < 2 )
			{
				if ( OrderType() == OP_BUY )
				{
					if ( !OrderClose( ticket, OrderLots(), Bid, 3, BuyOPColor ) )
					{
						_GetLastError = GetLastError();
						MultiComment( "Îøèáêà #" + _GetLastError + " ïðè çàêðûòèè îðäåðà ¹" + ticket + "!!!" );
					}
					else
					{
						MultiComment( "Îðäåð ¹" + ticket + " çàêðûò óñïåøíî!" );
					}
				}
				else
				{
					if ( !OrderClose( ticket, OrderLots(), Ask, 3, SellOPColor ) )
					{
						_GetLastError = GetLastError();
						MultiComment( "Îøèáêà #" + _GetLastError + " ïðè çàêðûòèè îðäåðà ¹" + ticket + "!!!" );
					}
					else
					{
						MultiComment( "Îðäåð ¹" + ticket + " çàêðûò óñïåøíî!" );
					}
				}
			}
			//---- à åñëè îòëîæåííûé, óäàëÿåì
			else
			{
				if ( !OrderDelete( ticket ) )
				{
					_GetLastError = GetLastError();
					MultiComment( "Îøèáêà #" + _GetLastError + " ïðè óäàëåíèè îðäåðà ¹" + ticket + "!!!" );
				}
				else
				{
					MultiComment( "Îðäåð ¹" + ticket + " óäàëåí óñïåøíî!" );
				}
			}
		}

		//---- åñëè îáúåêò OpenPrice áûë ïåðåìåùåí, 
		if ( modifyOP )
		{
			//---- åñëè ýòî îòëîæåííûé îðäåð, ñîçäà¸ì ëèíèþ, ñ ïîìîùüþ êîòîðîé ìîæíî áóäåò èçìåíèòü îáúåêò
			if ( OrderType() > 1 )
			{
				CreateHLine( "vHT_Modify_OP_" + ticket, OrderOpenPrice(), STYLE_SOLID, 1, ModifyColor, ticket + ": modify OpenPrice" );
			}
		}


		//---- åñëè îáúåêò ÑòîïËîññ áûë óäàëåí, óäàëÿåì ÑòîïËîññ ó îðäåðà
		if ( deleteSL )
		{
			if ( OrderStopLoss() > 0 )
			{
				if ( !OrderModify( ticket, OrderOpenPrice(), 0.0, OrderTakeProfit(), OrderExpiration(), ModifyColor ) )
				{
					_GetLastError = GetLastError();
					MultiComment( "Îøèáêà #" + _GetLastError + " ïðè ìîäèôèêàöèè îðäåðà ¹" + ticket + "!!!" );
				}
				else
				{
					MultiComment( "Îðäåð ¹" + ticket + " ìîäèôèöèðîâàí óñïåøíî!" );
				}
			}
		}
		//---- åñëè îáúåêò ÑòîïËîññ áûë ïåðåìåùåí,
		if ( modifySL )
		{
			//---- íàõîäèì, êóäà ðèñîâàòü ëèíèþ ïåðåìåùåíèÿ ÑË, è ðèñóåì
			if ( OrderStopLoss() > 0 )
			{
				CreateHLine( "vHT_Modify_SL_" + ticket, OrderStopLoss(), STYLE_DASHDOT, 1, ModifyColor, ticket + ": modify StopLoss" );
			}
			else
			{
				tmp = StopLoss;
				if ( tmp <= 0 ) { tmp = 50; }

				if ( OrderType() == OP_BUY || OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT )
				{ CreateHLine( "vHT_Modify_SL_" + ticket, OrderOpenPrice() - tmp*Point, STYLE_DASHDOT, 1, ModifyColor, ticket + ": modify StopLoss" ); }
				else
				{ CreateHLine( "vHT_Modify_SL_" + ticket, OrderOpenPrice() + tmp*Point, STYLE_DASHDOT, 1, ModifyColor, ticket + ": modify StopLoss" ); }
			}
		}


		//---- òî æå ñàìîå äëÿ ÒÏ
		if ( deleteTP )
		{
			if ( OrderTakeProfit() > 0 )
			{
				if ( !OrderModify( ticket, OrderOpenPrice(), OrderStopLoss(), 0.0, OrderExpiration(), ModifyColor ) )
				{
					_GetLastError = GetLastError();
					MultiComment( "Îøèáêà #" + _GetLastError + " ïðè ìîäèôèêàöèè îðäåðà ¹" + ticket + "!!!" );
				}
				else
				{
					MultiComment( "Îðäåð ¹" + ticket + " ìîäèôèöèðîâàí óñïåøíî!" );
				}
			}
		}
		if ( modifyTP )
		{
			if ( OrderTakeProfit() > 0 )
			{
				CreateHLine( "vHT_Modify_TP_" + ticket, OrderTakeProfit(), STYLE_DASHDOT, 1, ModifyColor, ticket + ": modify TakeProfit" );
			}
			else
			{
				tmp = TakeProfit;
				if ( tmp <= 0 ) { tmp = 50; }

				if ( OrderType() == OP_BUY || OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT )
				{ CreateHLine( "vHT_Modify_TP_" + ticket, OrderOpenPrice() + tmp*Point, STYLE_DOT, 1, ModifyColor, ticket + ": modify TakeProfit" ); }
				else
				{ CreateHLine( "vHT_Modify_TP_" + ticket, OrderOpenPrice() - tmp*Point, STYLE_DOT, 1, ModifyColor, ticket + ": modify TakeProfit" ); }
			}
		}
	}
	ObjectsRedraw();

	//---- òåïåðü èññëåäóåì ëèíèè ìîäèôèêàöèè...
	int objectstotal = ObjectsTotal(); string name = "", modify; double newValue, oldValue, stoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point + Point;
	//---- ïåðåáèðàåì îáúåêòû,
	for ( i = objectstotal; i >= 0; i -- )
	{
		//---- åñëè â èìåíè îáúåêòà åñòü ñòðîêà "vHT_Modify_",
		name = ObjectName(i);
		if ( StringSubstr( name, 0, 11 ) == "vHT_Modify_" )
		{
			//---- çàïîìèíàåì òèêåò
			ticket = StrToInteger( StringSubstr( name, 14 ) );
			if ( ticket <= 0 ) { continue; }
			//---- íàõîäèì ïîìåòêó î òîì, ÷òî èìåííî íàäî ìåíÿòü
			modify = StringSubstr( name, 11, 2 );
			//---- çàïîìèíàåì óðîâåíü, íà êîòîðûé áóäåò ïåðåìåùåí óðîâåíü îòêðûòèÿ/ÑË/ÒÏ
			newValue = ObjectGet( name, OBJPROP_PRICE1 );
			if ( newValue <= 0 ) { continue; }

			if ( !OrderSelect( ticket, SELECT_BY_TICKET ) )
			{
				_GetLastError = GetLastError();
				Print( "OrderSelect( ", ticket, ", SELECT_BY_TICKET ) - Error #", _GetLastError );
				continue;
			}
			if ( OrderCloseTime() > 0 ) { ObjectDelete( name ); continue; }

			//---- åñëè ìîäèôèöèðîâàòü íàäî öåíó îòêðûòèÿ,
			if ( modify == "OP" )
			{
				//---- åñëè ýòî îòëîæåííûé îðäåð,
				if ( OrderType() > 1 )
				{
					//---- åñëè ëèíèþ ïåðåìåñòèëè,
					if ( NormalizeDouble( OrderOpenPrice() - newValue, Digits ) > 0 || NormalizeDouble( newValue - OrderOpenPrice(), Digits ) > 0 )
					{
						if ( OrderType() == OP_BUYSTOP )
						{
							if ( NormalizeDouble( ( newValue - Ask ) - stoplevel, Digits ) <= 0.0  )
							{
								MultiComment( "Íåïðàâèëüíàÿ öåíà îòêðûòèÿ äëÿ îðäåðà ¹" + ticket + "!!!" );
								continue;
							}
						}
						if ( OrderType() == OP_BUYLIMIT )
						{
							if ( NormalizeDouble( ( Ask - newValue ) - stoplevel, Digits ) <= 0.0  )
							{
								MultiComment( "Íåïðàâèëüíàÿ öåíà îòêðûòèÿ äëÿ îðäåðà ¹" + ticket + "!!!" );
								continue;
							}
						}
						if ( OrderType() == OP_SELLSTOP )
						{
							if ( NormalizeDouble( ( Bid - newValue ) - stoplevel, Digits ) <= 0.0  )
							{
								MultiComment( "Íåïðàâèëüíàÿ öåíà îòêðûòèÿ äëÿ îðäåðà ¹" + ticket + "!!!" );
								continue;
							}
						}
						if ( OrderType() == OP_SELLLIMIT )
						{
							if ( NormalizeDouble( ( newValue - Bid ) - stoplevel, Digits ) <= 0.0  )
							{
								MultiComment( "Íåïðàâèëüíàÿ öåíà îòêðûòèÿ äëÿ îðäåðà ¹" + ticket + "!!!" );
								continue;
							}
						}

						//---- ìîäèôèöèðóåì îðäåð
						if ( !OrderModify( ticket, newValue, OrderStopLoss(), OrderTakeProfit(), OrderExpiration(), ModifyColor ) )
						{
							_GetLastError = GetLastError();
							MultiComment( "Îøèáêà #" + _GetLastError + " ïðè ìîäèôèêàöèè îðäåðà ¹" + ticket + "!!!" );
						}
						else
						{
							MultiComment( "Îðäåð ¹" + ticket + " ìîäèôèöèðîâàí óñïåøíî!" );
							//---- è óäàëåì ëèíèþ
							ObjectDelete( name );
						}
					}
				}
			}
			//---- åñëè ìîäèôèöèðîâàòü íàäî ÑòîïËîññ,
			if ( modify == "SL" )
			{
				//---- íàõîäèì èñõîäíîå ïîëîæåíèå ëèíèè
				if ( OrderStopLoss() > 0 )
				{
					oldValue = OrderStopLoss();
				}
				else
				{
					tmp = StopLoss;
					if ( tmp <= 0 ) { tmp = 50; }

					if ( OrderType() == OP_BUY || OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT )
					{ oldValue = OrderOpenPrice() - tmp*Point; }
					else
					{ oldValue = OrderOpenPrice() + tmp*Point; }
				}

				//---- è, åñëè ëèíèÿ áûëà ïåðåìåùåíà, ìîäèôèöèðóåì îðäåð
				if ( NormalizeDouble( oldValue - newValue, Digits ) > 0 || NormalizeDouble( newValue - oldValue, Digits ) > 0 )
				{
					if ( OrderType() == OP_BUY || OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP )
					{
						if ( NormalizeDouble( MathAbs( Bid - newValue ) - stoplevel, Digits ) <= 0.0 )
						{
							MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ îðäåðà ¹" + ticket + "!!!" );
							continue;
						}
					}
					else
					{
						if ( NormalizeDouble( MathAbs( Ask - newValue ) - stoplevel, Digits ) <= 0.0 )
						{
							MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ îðäåðà ¹" + ticket + "!!!" );
							continue;
						}
					}

					if ( !OrderModify( ticket, OrderOpenPrice(), newValue, OrderTakeProfit(), OrderExpiration(), ModifyColor ) )
					{
						_GetLastError = GetLastError();
						MultiComment( "Îøèáêà #" + _GetLastError + " ïðè ìîäèôèêàöèè îðäåðà ¹" + ticket + "!!!" );
					}
					else
					{
						MultiComment( "Îðäåð ¹" + ticket + " ìîäèôèöèðîâàí óñïåøíî!" );
						ObjectDelete( name );
					}
				}
			}
			//---- òî æå ñàìîå äëÿ ÒÏ
			if ( modify == "TP" )
			{
				if ( OrderTakeProfit() > 0 )
				{
					oldValue = OrderTakeProfit();
				}
				else
				{
					tmp = TakeProfit;
					if ( tmp <= 0 ) { tmp = 50; }

					if ( OrderType() == OP_BUY || OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT )
					{ oldValue = OrderOpenPrice() + tmp*Point; }
					else
					{ oldValue = OrderOpenPrice() - tmp*Point; }
				}

				if ( NormalizeDouble( oldValue - newValue, Digits ) > 0 || NormalizeDouble( newValue - oldValue, Digits ) > 0 )
				{
					if ( OrderType() == OP_BUY || OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP )
					{
						if ( NormalizeDouble( MathAbs( Bid - newValue ) - stoplevel, Digits ) <= 0.0 )
						{
							MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ îðäåðà ¹" + ticket + "!!!" );
							continue;
						}
					}
					else
					{
						if ( NormalizeDouble( MathAbs( Ask - newValue ) - stoplevel, Digits ) <= 0.0 )
						{
							MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ îðäåðà ¹" + ticket + "!!!" );
							continue;
						}
					}

					if ( !OrderModify( ticket, OrderOpenPrice(), OrderStopLoss(), newValue, OrderExpiration(), ModifyColor ) )
					{
						_GetLastError = GetLastError();
						MultiComment( "Îøèáêà #" + _GetLastError + " ïðè ìîäèôèêàöèè îðäåðà ¹" + ticket + "!!!" );
					}
					else
					{
						MultiComment( "Îðäåð ¹" + ticket + " ìîäèôèöèðîâàí óñïåøíî!" );
						ObjectDelete( name );
					}
				}
			}
		}
	}
	GetLastError();
}
void vHandsTrade_TrailingStop()
{
	//---- åñëè òðåéëèíã áîëüøå 0 (âêëþ÷åí), ïåðåáèðàåì âñå îòêðûòûå ïîçèöèè è äâèãàåì èõ ñòÎÏÛ çà íèìè ;)
	if ( TrailingStop > 0 )
	{
		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 ( TrailingStop <= MarketInfo( OrderSymbol(), MODE_STOPLEVEL )+1 ) { continue; }

			if ( OrderType() == OP_BUY )
			{
				if ( NormalizeDouble( Bid - OrderOpenPrice() - TrailingStop*Point, Digits ) > 0.0 )
				{
					if ( NormalizeDouble( Bid - TrailingStop*Point - OrderStopLoss(), Digits ) > 0.0 )
					{
						if ( !OrderModify( OrderTicket(), OrderOpenPrice(), Bid - TrailingStop*Point, OrderTakeProfit(), 0, TrailingColor ) )
						{
							_GetLastError = GetLastError();
							MultiComment( "Îøèáêà #" + _GetLastError + " ïðè ìîäèôèêàöèè îðäåðà ¹" + OrderTicket() + "!!!" );
						}
					}
				}
				continue;
			}
			if ( OrderType() == OP_SELL )
			{
				if ( NormalizeDouble( OrderOpenPrice() - Ask - TrailingStop*Point, Digits ) > 0.0 )
				{
					if ( NormalizeDouble( OrderStopLoss() - ( Ask + TrailingStop*Point ), Digits ) > 0.0 || OrderStopLoss() <= 0 )
					{
						if ( !OrderModify( OrderTicket(), OrderOpenPrice(), Ask + TrailingStop*Point, OrderTakeProfit(), 0, TrailingColor ) )
						{
							_GetLastError = GetLastError();
							MultiComment( "Îøèáêà #" + _GetLastError + " ïðè ìîäèôèêàöèè îðäåðà ¹" + OrderTicket() + "!!!" );
						}
					}
				}
				continue;
			}
		}
	}
}

//---- îòêðûòèå áàé ïîçèöèè
void vHandsTrade_OpenBuy()
{
	//---- åñëè ëèíèÿ îòêðûòèÿ áàé áûëà ïåðåìåùåíà,
	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel; int _GetLastError;
	if ( left[1] != ObjectGet( "vHT_Buy_OP", OBJPROP_TIME1 )  || right[1]!= ObjectGet( "vHT_Buy_OP", OBJPROP_TIME2 ) ||
		  up[2]   != ObjectGet( "vHT_Buy_OP", OBJPROP_PRICE1 ) || up[2]   != ObjectGet( "vHT_Buy_OP", OBJPROP_PRICE2 ) )
	{
		//---- åñëè ëèíèþ óäàëèëè, âûõîäèì
		if ( GetLastError() == 4202 ) { NeedRedrawObjects = true; return(0); }
		if ( GetTickCount() - lastB < MIN_TRADE_PAUSE_MS ) { NeedRedrawObjects = true; return(0); }
		lastB = GetTickCount();

		double stoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point + Point;

		//---- à åñëè íåò, âûñ÷èòûâàåì óðîâåíü îòêðûòèÿ,
		_OpenPriceLevel = NormalizeDouble( Ask, Digits );

		//---- åñëè ëèíèÿ ÑË áàé ïîçèöèè áûëà ïåðåìåùåíà, 
		if ( left[1] != ObjectGet( "vHT_Buy_SL", OBJPROP_TIME1 )  || right[1]!= ObjectGet( "vHT_Buy_SL", OBJPROP_TIME2 ) ||
			  up[3]   != ObjectGet( "vHT_Buy_SL", OBJPROP_PRICE1 ) || up[3]   != ObjectGet( "vHT_Buy_SL", OBJPROP_PRICE2 ) )
		{
			//---- óðîâåíü ÑË óêàçàí - ýòî êîîðäèíàòà ëèíèè
			_StopLossLevel = NormalizeDouble( ObjectGet( "vHT_Buy_SL", OBJPROP_PRICE1 ), Digits );
		}
		//---- à åñëè ëèíèÿ ÑË íà ìåñòå, 
		else
		{
			//---- åñëè òåêóùèé âûáðàííûé ÑË áîëüøå 0 (âêëþ÷åí), ñ÷èòàåì óðîâåíü ÑË îò öåíû îòêðûòèÿ
			if ( StopLoss > 0 )
			{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel - StopLoss*Point, Digits ); }
			else
			{ _StopLossLevel = 0.0; }
		}
		if ( _StopLossLevel > 0.0 && NormalizeDouble( Bid - _StopLossLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ Buy-ïîçèöèè!!!" );
			return(0);
		}

		//---- ÒÏ - òî æå ñàìîå 
		if ( left[1] != ObjectGet( "vHT_Buy_TP", OBJPROP_TIME1 )  || right[1]!= ObjectGet( "vHT_Buy_TP", OBJPROP_TIME2 ) ||
			  up[1]   != ObjectGet( "vHT_Buy_TP", OBJPROP_PRICE1 ) || up[1]   != ObjectGet( "vHT_Buy_TP", OBJPROP_PRICE2 ) )
		{
			_TakeProfitLevel = NormalizeDouble( ObjectGet( "vHT_Buy_TP", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( TakeProfit > 0 )
			{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel + TakeProfit*Point, Digits ); }
			else
			{ _TakeProfitLevel = 0.0; }
		}
		if ( _TakeProfitLevel > 0.0 && NormalizeDouble( _TakeProfitLevel - Bid - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ Buy-ïîçèöèè!!!" );
			return(0);
		}

		//---- ðàñ÷èòûâàåì ëîò
		double UseLot = LotSize();
		if ( UseLot < 0 ) { return(0); }

		//---- è îòêðûâàåì ïîçèöèþ ;)
		if ( OrderSend( Symbol(), OP_BUY, UseLot, _OpenPriceLevel, 3, _StopLossLevel, _TakeProfitLevel, "vHandsTrade", 0, BuyOPColor ) < 0 )
		{
			_GetLastError = GetLastError();
			MultiComment( "Îøèáêà #" + _GetLastError + " ïðè îòêðûòèè Buy-ïîçèöèè!!!" );
		}
		else
		{
			//---- äåëàåì ïîìåòêó, ÷òî íàäî ïåðåðèñîâàòüñÿ...
			NeedRedrawObjects = true;
			MultiComment( "Buy-ïîçèöèÿ îòêðûòà óñïåøíî!" );
		}
	}
}
void vHandsTrade_OpenBuyStop()
{
	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel; int _Expiration, _GetLastError;
	if ( left[0] != ObjectGet( "vHT_BuyStop_OP", OBJPROP_TIME1 )  || right[0]!= ObjectGet( "vHT_BuyStop_OP", OBJPROP_TIME2 ) ||
		  up[2]   != ObjectGet( "vHT_BuyStop_OP", OBJPROP_PRICE1 ) || up[2]   != ObjectGet( "vHT_BuyStop_OP", OBJPROP_PRICE2 ) )
	{
		//---- åñëè ëèíèþ óäàëèëè, âûõîäèì
		if ( GetLastError() == 4202 ) { NeedRedrawObjects = true; return(0); }
		if ( GetTickCount() - lastBS < MIN_TRADE_PAUSE_MS ) { NeedRedrawObjects = true; return(0); }
		lastBS = GetTickCount();

		double stoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point + Point;
		double spread    = MarketInfo( Symbol(), MODE_SPREAD )*Point;

		_OpenPriceLevel = NormalizeDouble( ObjectGet( "vHT_BuyStop_OP", OBJPROP_PRICE1 ), Digits );
		if ( NormalizeDouble( _OpenPriceLevel - Ask - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé óðîâåíü îòêðûòèÿ BuyStop-îðäåðà!!!" );
			return(0);
		}

		if ( left[0] != ObjectGet( "vHT_BuyStop_SL", OBJPROP_TIME1 )  || right[0]!= ObjectGet( "vHT_BuyStop_SL", OBJPROP_TIME2 ) ||
		     up[3]   != ObjectGet( "vHT_BuyStop_SL", OBJPROP_PRICE1 ) || up[3]   != ObjectGet( "vHT_BuyStop_SL", OBJPROP_PRICE2 ) )
		{
			_StopLossLevel = NormalizeDouble( ObjectGet( "vHT_BuyStop_SL", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( StopLoss > 0 )
			{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel - StopLoss*Point, Digits ); }
			else
			{ _StopLossLevel = 0.0; }
		}
		if ( _StopLossLevel > 0.0 && NormalizeDouble( (_OpenPriceLevel - spread) - _StopLossLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ BuyStop-îðäåðà!!!" );
			return(0);
		}

		if ( left[0] != ObjectGet( "vHT_BuyStop_TP", OBJPROP_TIME1 )  || right[0]!= ObjectGet( "vHT_BuyStop_TP", OBJPROP_TIME2 ) ||
			  up[1]   != ObjectGet( "vHT_BuyStop_TP", OBJPROP_PRICE1 ) || up[1]   != ObjectGet( "vHT_BuyStop_TP", OBJPROP_PRICE2 ) )
		{
			_TakeProfitLevel = NormalizeDouble( ObjectGet( "vHT_BuyStop_TP", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( TakeProfit > 0 )
			{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel + TakeProfit*Point, Digits ); }
			else
			{ _TakeProfitLevel = 0.0; }
		}
		if ( _TakeProfitLevel > 0.0 && NormalizeDouble( _TakeProfitLevel - (_OpenPriceLevel - spread) - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ BuyStop-îðäåðà!!!" );
			return(0);
		}

		if ( Expiration > 0 )
		{ _Expiration = CurTime() + Expiration; }
		else
		{ _Expiration = 0; }

		double UseLot = LotSize();
		if ( UseLot < 0 ) { return(0); }

		if ( OrderSend( Symbol(), OP_BUYSTOP, UseLot, _OpenPriceLevel, 3, _StopLossLevel, _TakeProfitLevel, "vHandsTrade", 0, _Expiration, BuyOPColor ) < 0 )
		{
			_GetLastError = GetLastError();
			MultiComment( "Îøèáêà #" + _GetLastError + " ïðè óñòàíîâêå BuyStop-îðäåðà!!!" );
		}
		else
		{
			NeedRedrawObjects = true;
			MultiComment( "BuyStop-îðäåð óñòàíîâëåí óñïåøíî!" );
		}
	}
}
void vHandsTrade_OpenBuyLimit()
{
	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel; int _Expiration, _GetLastError;
	if ( left[0] != ObjectGet( "vHT_BuyLimit_OP", OBJPROP_TIME1 )  || right[0]!= ObjectGet( "vHT_BuyLimit_OP", OBJPROP_TIME2 ) ||
		up[6]   != ObjectGet( "vHT_BuyLimit_OP", OBJPROP_PRICE1 ) || up[6]   != ObjectGet( "vHT_BuyLimit_OP", OBJPROP_PRICE2 ) )
	{
		//---- åñëè ëèíèþ óäàëèëè, âûõîäèì
		if ( GetLastError() == 4202 ) { NeedRedrawObjects = true; return(0); }
		if ( GetTickCount() - lastBL < MIN_TRADE_PAUSE_MS ) { NeedRedrawObjects = true; return(0); }
		lastBL = GetTickCount();

		double stoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point + Point;
		double spread    = MarketInfo( Symbol(), MODE_SPREAD )*Point;

		_OpenPriceLevel = NormalizeDouble( ObjectGet( "vHT_BuyLimit_OP", OBJPROP_PRICE1 ), Digits );
		if ( NormalizeDouble( Ask - _OpenPriceLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé óðîâåíü îòêðûòèÿ BuyLimit-îðäåðà!!!" );
			return(0);
		}

		if ( left[0] != ObjectGet( "vHT_BuyLimit_SL", OBJPROP_TIME1 )  || right[0]!= ObjectGet( "vHT_BuyLimit_SL", OBJPROP_TIME2 ) ||
			  up[7]   != ObjectGet( "vHT_BuyLimit_SL", OBJPROP_PRICE1 ) || up[7]   != ObjectGet( "vHT_BuyLimit_SL", OBJPROP_PRICE2 ) )
		{
			_StopLossLevel = NormalizeDouble( ObjectGet( "vHT_BuyLimit_SL", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( StopLoss > 0 )
			{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel - StopLoss*Point, Digits ); }
			else
			{ _StopLossLevel = 0.0; }
		}
		if ( _StopLossLevel > 0.0 && NormalizeDouble( (_OpenPriceLevel - spread) - _StopLossLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ BuyLimit-îðäåðà!!!" );
			return(0);
		}

		if ( left[0] != ObjectGet( "vHT_BuyLimit_TP", OBJPROP_TIME1 )  || right[0]!= ObjectGet( "vHT_BuyLimit_TP", OBJPROP_TIME2 ) ||
			  up[5]   != ObjectGet( "vHT_BuyLimit_TP", OBJPROP_PRICE1 ) || up[5]   != ObjectGet( "vHT_BuyLimit_TP", OBJPROP_PRICE2 ) )
		{
			_TakeProfitLevel = NormalizeDouble( ObjectGet( "vHT_BuyLimit_TP", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( TakeProfit > 0 )
			{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel + TakeProfit*Point, Digits ); }
			else
			{ _TakeProfitLevel = 0.0; }
		}
		if ( _TakeProfitLevel > 0.0 && NormalizeDouble( _TakeProfitLevel - (_OpenPriceLevel - spread) - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ BuyLimit-îðäåðà!!!" );
			return(0);
		}

		if ( Expiration > 0 )
		{ _Expiration = CurTime() + Expiration; }
		else
		{ _Expiration = 0; }

		double UseLot = LotSize();
		if ( UseLot < 0 ) { return(0); }

		if ( OrderSend( Symbol(), OP_BUYLIMIT, UseLot, _OpenPriceLevel, 3, _StopLossLevel, _TakeProfitLevel, "vHandsTrade", 0, _Expiration, BuyOPColor ) < 0 )
		{
			_GetLastError = GetLastError();
			MultiComment( "Îøèáêà #" + _GetLastError + " ïðè óñòàíîâêå BuyLimit-îðäåðà!!!" );
		}
		else
		{
			NeedRedrawObjects = true;
			MultiComment( "BuyLimit-îðäåð óñòàíîâëåí óñïåøíî!" );
		}
	}
}
void vHandsTrade_OpenSell()
{
	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel; int _GetLastError;
	if ( left[1] != ObjectGet( "vHT_Sell_OP", OBJPROP_TIME1 )  || right[1]!= ObjectGet( "vHT_Sell_OP", OBJPROP_TIME2 ) ||
		  up[6]   != ObjectGet( "vHT_Sell_OP", OBJPROP_PRICE1 ) || up[6]   != ObjectGet( "vHT_Sell_OP", OBJPROP_PRICE2 ) )
	{
		//---- åñëè ëèíèþ óäàëèëè, âûõîäèì
		if ( GetLastError() == 4202 ) { NeedRedrawObjects = true; return(0); }
		if ( GetTickCount() - lastS < MIN_TRADE_PAUSE_MS ) { NeedRedrawObjects = true; return(0); }
		lastS = GetTickCount();

		double stoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point + Point;

		_OpenPriceLevel = NormalizeDouble( Bid, Digits );

		if ( left[1] != ObjectGet( "vHT_Sell_SL", OBJPROP_TIME1 )  || right[1]!= ObjectGet( "vHT_Sell_SL", OBJPROP_TIME2 ) ||
			  up[5]   != ObjectGet( "vHT_Sell_SL", OBJPROP_PRICE1 ) || up[5]   != ObjectGet( "vHT_Sell_SL", OBJPROP_PRICE2 ) )
		{
			_StopLossLevel = NormalizeDouble( ObjectGet( "vHT_Sell_SL", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( StopLoss > 0 )
			{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel + StopLoss*Point, Digits ); }
			else
			{ _StopLossLevel = 0.0; }
		}
		if ( _StopLossLevel > 0.0 && NormalizeDouble( _StopLossLevel - Ask - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ Sell-ïîçèöèè!!!" );
			return(0);
		}

		if ( left[1] != ObjectGet( "vHT_Sell_TP", OBJPROP_TIME1 )  || right[1]!= ObjectGet( "vHT_Sell_TP", OBJPROP_TIME2 ) ||
			  up[7]   != ObjectGet( "vHT_Sell_TP", OBJPROP_PRICE1 ) || up[7]   != ObjectGet( "vHT_Sell_TP", OBJPROP_PRICE2 ) )
		{
			_TakeProfitLevel = NormalizeDouble( ObjectGet( "vHT_Sell_TP", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( TakeProfit > 0 )
			{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel - TakeProfit*Point, Digits ); }
			else
			{ _TakeProfitLevel = 0.0; }
		}
		if ( _TakeProfitLevel > 0.0 && NormalizeDouble( Ask - _TakeProfitLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ Sell-ïîçèöèè!!!" );
			return(0);
		}

		double UseLot = LotSize();
		if ( UseLot < 0 ) { return(0); }

		if ( OrderSend( Symbol(), OP_SELL, UseLot, _OpenPriceLevel, 3, _StopLossLevel, _TakeProfitLevel, "vHandsTrade", 0, SellOPColor ) < 0 )
		{
			_GetLastError = GetLastError();
			MultiComment( "Îøèáêà #" + _GetLastError + " ïðè îòêðûòèè Sell-ïîçèöèè!!!" );
		}
		else
		{
			NeedRedrawObjects = true;
			MultiComment( "Sell-ïîçèöèÿ îòêðûòà óñïåøíî!" );
		}
	}
}
void vHandsTrade_OpenSellStop()
{
	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel; int _Expiration, _GetLastError;
	if ( left[2] != ObjectGet( "vHT_SellStop_OP", OBJPROP_TIME1 )  || right[2]!= ObjectGet( "vHT_SellStop_OP", OBJPROP_TIME2 ) ||
		  up[6]   != ObjectGet( "vHT_SellStop_OP", OBJPROP_PRICE1 ) || up[6]   != ObjectGet( "vHT_SellStop_OP", OBJPROP_PRICE2 ) )
	{
		//---- åñëè ëèíèþ óäàëèëè, âûõîäèì
		if ( GetLastError() == 4202 ) { NeedRedrawObjects = true; return(0); }
		if ( GetTickCount() - lastSS < MIN_TRADE_PAUSE_MS ) { NeedRedrawObjects = true; return(0); }
		lastSS = GetTickCount();

		double stoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point + Point;
		double spread    = MarketInfo( Symbol(), MODE_SPREAD )*Point;

		_OpenPriceLevel = NormalizeDouble( ObjectGet( "vHT_SellStop_OP", OBJPROP_PRICE1 ), Digits );
		if ( NormalizeDouble( Bid - _OpenPriceLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé óðîâåíü îòêðûòèÿ SellStop-îðäåðà!!!" );
			return(0);
		}

		if ( left[2] != ObjectGet( "vHT_SellStop_SL", OBJPROP_TIME1 )  || right[2]!= ObjectGet( "vHT_SellStop_SL", OBJPROP_TIME2 ) ||
			  up[5]   != ObjectGet( "vHT_SellStop_SL", OBJPROP_PRICE1 ) || up[5]   != ObjectGet( "vHT_SellStop_SL", OBJPROP_PRICE2 ) )
		{
			_StopLossLevel = NormalizeDouble( ObjectGet( "vHT_SellStop_SL", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( StopLoss > 0 )
			{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel + StopLoss*Point, Digits ); }
			else
			{ _StopLossLevel = 0.0; }
		}
		if ( _StopLossLevel > 0.0 && NormalizeDouble( _StopLossLevel - (_OpenPriceLevel + spread) - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ SellStop-îðäåðà!!!" );
			return(0);
		}

		if ( left[2] != ObjectGet( "vHT_SellStop_TP", OBJPROP_TIME1 )  || right[2]!= ObjectGet( "vHT_SellStop_TP", OBJPROP_TIME2 ) ||
			  up[7]   != ObjectGet( "vHT_SellStop_TP", OBJPROP_PRICE1 ) || up[7]   != ObjectGet( "vHT_SellStop_TP", OBJPROP_PRICE2 ) )
		{
			_TakeProfitLevel = NormalizeDouble( ObjectGet( "vHT_SellStop_TP", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( TakeProfit > 0 )
			{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel - TakeProfit*Point, Digits ); }
			else
			{ _TakeProfitLevel = 0.0; }
		}
		if ( _TakeProfitLevel > 0.0 && NormalizeDouble( (_OpenPriceLevel + spread) - _TakeProfitLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ SellStop-îðäåðà!!!" );
			return(0);
		}

		if ( Expiration > 0 )
		{ _Expiration = CurTime() + Expiration; }
		else
		{ _Expiration = 0; }

		double UseLot = LotSize();
		if ( UseLot < 0 ) { return(0); }

		if ( OrderSend( Symbol(), OP_SELLSTOP, UseLot, _OpenPriceLevel, 3, _StopLossLevel, _TakeProfitLevel, "vHandsTrade", 0, _Expiration, SellOPColor ) < 0 )
		{
			_GetLastError = GetLastError();
			MultiComment( "Îøèáêà #" + _GetLastError + " ïðè óñòàíîâêå SellStop-îðäåðà!!!" );
		}
		else
		{
			NeedRedrawObjects = true;
			MultiComment( "SellStop-îðäåð óñòàíîâëåí óñïåøíî!" );
		}
	}
}
void vHandsTrade_OpenSellLimit()
{
	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel; int _Expiration, _GetLastError;
	if ( left[2] != ObjectGet( "vHT_SellLimit_OP", OBJPROP_TIME1 )  || right[2]!= ObjectGet( "vHT_SellLimit_OP", OBJPROP_TIME2 ) ||
		  up[2]   != ObjectGet( "vHT_SellLimit_OP", OBJPROP_PRICE1 ) || up[2]   != ObjectGet( "vHT_SellLimit_OP", OBJPROP_PRICE2 ) )
	{
		//---- åñëè ëèíèþ óäàëèëè, âûõîäèì
		if ( GetLastError() == 4202 ) { NeedRedrawObjects = true; return(0); }
		if ( GetTickCount() - lastSL < MIN_TRADE_PAUSE_MS ) { NeedRedrawObjects = true; return(0); }
		lastSL = GetTickCount();

		double stoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point + Point;
		double spread    = MarketInfo( Symbol(), MODE_SPREAD )*Point;

		_OpenPriceLevel = NormalizeDouble( ObjectGet( "vHT_SellLimit_OP", OBJPROP_PRICE1 ), Digits );
		if ( NormalizeDouble( _OpenPriceLevel - Bid - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé óðîâåíü îòêðûòèÿ SellLimit-îðäåðà!!!" );
			return(0);
		}

		if ( left[2] != ObjectGet( "vHT_SellLimit_SL", OBJPROP_TIME1 )  || right[2]!= ObjectGet( "vHT_SellLimit_SL", OBJPROP_TIME2 ) ||
			  up[1]   != ObjectGet( "vHT_SellLimit_SL", OBJPROP_PRICE1 ) || up[1]   != ObjectGet( "vHT_SellLimit_SL", OBJPROP_PRICE2 ) )
		{
			_StopLossLevel = NormalizeDouble( ObjectGet( "vHT_SellLimit_SL", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( StopLoss > 0 )
			{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel + StopLoss*Point, Digits ); }
			else
			{ _StopLossLevel = 0.0; }
		}
		if ( _StopLossLevel > 0.0 && NormalizeDouble( _StopLossLevel - (_OpenPriceLevel + spread) - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÑòîïËîññ äëÿ SellLimit-îðäåðà!!!" );
			return(0);
		}

		if ( left[2] != ObjectGet( "vHT_SellLimit_TP", OBJPROP_TIME1 )  || right[2]!= ObjectGet( "vHT_SellLimit_TP", OBJPROP_TIME2 ) ||
			  up[3]   != ObjectGet( "vHT_SellLimit_TP", OBJPROP_PRICE1 ) || up[3]   != ObjectGet( "vHT_SellLimit_TP", OBJPROP_PRICE2 ) )
		{
			_TakeProfitLevel = NormalizeDouble( ObjectGet( "vHT_SellLimit_TP", OBJPROP_PRICE1 ), Digits );
		}
		else
		{
			if ( TakeProfit > 0 )
			{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel - TakeProfit*Point, Digits ); }
			else
			{ _TakeProfitLevel = 0.0; }
		}
		if ( _TakeProfitLevel > 0.0 && NormalizeDouble( (_OpenPriceLevel + spread) - _TakeProfitLevel - stoplevel, Digits ) <= 0.0 )
		{
			MultiComment( "Íåïðàâèëüíûé ÒåéêÏðîôèò äëÿ SellLimit-îðäåðà!!!" );
			return(0);
		}

		if ( Expiration > 0 )
		{ _Expiration = CurTime() + Expiration; }
		else
		{ _Expiration = 0; }

		double UseLot = LotSize();
		if ( UseLot < 0 ) { return(0); }

		if ( OrderSend( Symbol(), OP_SELLLIMIT, UseLot, _OpenPriceLevel, 3, _StopLossLevel, _TakeProfitLevel, "vHandsTrade", 0, _Expiration, SellOPColor ) < 0 )
		{
			_GetLastError = GetLastError();
			MultiComment( "Îøèáêà #" + _GetLastError + " ïðè óñòàíîâêå SellLimit-îðäåðà!!!" );
		}
		else
		{
			NeedRedrawObjects = true;
			MultiComment( "SellLimit-îðäåð óñòàíîâëåí óñïåøíî!" );
		}
	}
}

void vHandsTrade_ReCount()
{
	BarsInWindow	= BarsPerWindow();
	SecondsInBar	= Period() * 60;
	WindowHighest	= High[Highest(NULL,0,MODE_HIGH,BarsInWindow*4/5,0)];
	WindowLowest	= Low [Lowest (NULL,0,MODE_LOW, BarsInWindow*4/5,0)];

	//---- åñëè ïîÿâèëñÿ íîâûé áàð, âñå êîîðäèíàòû èçìåíèëèñü - íàäî ïåðåðèñîâûâàòü
	if ( preTime != Time[0] ) { NeedRedrawObjects = true; }
	preTime = Time[0];

	//---- åñëè èçìåíèëñÿ ðàçìåð îêíà, òà æå ñèòàöèÿ - íàäî ïåðåðèñîâûâàòü
	if ( BarsInWindow != preBarsInWindow || WindowHighest != preWindowHighest || WindowLowest != preWindowLowest ) { NeedRedrawObjects = true; }
	preBarsInWindow = BarsInWindow; preWindowHighest = WindowHighest; preWindowLowest = WindowLowest;

	//---- à åñëè íå íàäî ïåðåðèñîâûâàòü, òî è ïåðåñ÷èòûâàòü íå íàäî =)
	if ( NeedRedrawObjects == false ) { return(0); }

	Panel_Width	= MathMax( 7, (MathCeil(BarsInWindow/5.0/3.0)*3+1-3) )*SecondsInBar;
	Panel_T1		= Time[0] + (BarsInWindow/75+1)*SecondsInBar;
	Panel_T2		= Panel_T1+Panel_Width;
	Panel_P1		= WindowHighest-(WindowHighest-WindowLowest)/10;
	Panel_P2		= WindowLowest +(WindowHighest-WindowLowest)/10;

   Shag_X	= MathFloor( Panel_Width/7.0 );
	Zazor_X	= SecondsInBar*MathMax(1.0, MathCeil(Panel_Width/SecondsInBar/25));
	Dlina_X	= MathMax(1.0, MathCeil((Panel_Width-4*Zazor_X)/3) );
	Shag_Y	= (Panel_P1-Panel_P2)/17;

	left[0]  = Panel_T1 + Zazor_X;
	left[1]  = left[0] + Dlina_X + Zazor_X;
	left[2]  = left[1] + Dlina_X + Zazor_X;
	right[0] = left[0] + Dlina_X;
	right[1] = left[1] + Dlina_X;
	right[2] = left[2] + Dlina_X;
	up[0]		= Panel_P1 -  0.5*Shag_Y;
	up[1]		= Panel_P1 -  2.0*Shag_Y;
	up[2]		= Panel_P1 -  3.0*Shag_Y;
	up[3]		= Panel_P1 -  4.0*Shag_Y;
	up[4]		= Panel_P1 -  5.0*Shag_Y;
	up[5]		= Panel_P1 -  6.5*Shag_Y;
	up[6]		= Panel_P1 -  7.5*Shag_Y;
	up[7]		= Panel_P1 -  8.5*Shag_Y;
	up[8]		= Panel_P1 -  9.6*Shag_Y;
	up[9]		= Panel_P1 - 10.8*Shag_Y;
	up[10]	= Panel_P1 - 12.0*Shag_Y;
	up[11]	= Panel_P1 - 13.2*Shag_Y;
	up[12]	= Panel_P1 - 14.4*Shag_Y;
	up[13]	= Panel_P1 - 15.6*Shag_Y;
}
void vHandsTrade_RefreshObjects()
{
	//---- íå íàäî ðèñîâàòü - âûõîäèì
	if ( NeedRedrawObjects == false ) { return(0); }

	//---- ðèñóåì )
	ObjectDelete( "vHT_Panel" );
	if ( ObjectCreate( "vHT_Panel", OBJ_RECTANGLE, 0, Panel_T1, Panel_P1, Panel_T2, Panel_P2 ) )
	{
		ObjectSet   ( "vHT_Panel", OBJPROP_COLOR,		MainColor );
		ObjectSet   ( "vHT_Panel", OBJPROP_BACK,		false );
	}
	GetLastError();

	CreateText( "vHT_BuyStop", left[0]+Dlina_X/2, up[0], "BuyStop", 8, "Arial", MainColor );
	CreateLine( "vHT_BuyStop_TP", left[0], up[1], right[0], up[1], STYLE_DOT, 1, BuyColor );
	CreateLine( "vHT_BuyStop_OP", left[0], up[2], right[0], up[2], STYLE_DASH, 1, BuyColor );
	CreateLine( "vHT_BuyStop_SL", left[0], up[3], right[0], up[3], STYLE_DASHDOT, 1, BuyColor );

	CreateText( "vHT_Buy", left[1]+Dlina_X/2, up[0], "Buy", 8, "Arial", MainColor );
	CreateLine( "vHT_Buy_TP", left[1], up[1], right[1], up[1], STYLE_DOT, 1, BuyOPColor );
	CreateLine( "vHT_Buy_OP", left[1], up[2], right[1], up[2], STYLE_SOLID, 1, BuyOPColor );
	CreateLine( "vHT_Buy_SL", left[1], up[3], right[1], up[3], STYLE_DASHDOT, 1, BuyOPColor );

	CreateText( "vHT_SellLimit", left[2]+Dlina_X/2, up[0], "SellLimit", 8, "Arial", MainColor );
	CreateLine( "vHT_SellLimit_SL", left[2], up[1], right[2], up[1], STYLE_DASHDOT, 1, SellColor );
	CreateLine( "vHT_SellLimit_OP", left[2], up[2], right[2], up[2], STYLE_DASH, 1, SellColor );
	CreateLine( "vHT_SellLimit_TP", left[2], up[3], right[2], up[3], STYLE_DOT, 1, SellColor );

	CreateText( "vHT_BuyLimit", left[0]+Dlina_X/2, up[4], "BuyLimit", 8, "Arial", MainColor );
	CreateLine( "vHT_BuyLimit_TP", left[0], up[5], right[0], up[5], STYLE_DOT, 1, BuyColor );
	CreateLine( "vHT_BuyLimit_OP", left[0], up[6], right[0], up[6], STYLE_DASH, 1, BuyColor );
	CreateLine( "vHT_BuyLimit_SL", left[0], up[7], right[0], up[7], STYLE_DASHDOT, 1, BuyColor );

	CreateText( "vHT_Sell", left[1]+Dlina_X/2, up[4], "Sell", 8, "Arial", MainColor );
	CreateLine( "vHT_Sell_SL", left[1], up[5], right[1], up[5], STYLE_DASHDOT, 1, SellOPColor );
	CreateLine( "vHT_Sell_OP", left[1], up[6], right[1], up[6], STYLE_SOLID, 1, SellOPColor );
	CreateLine( "vHT_Sell_TP", left[1], up[7], right[1], up[7], STYLE_DOT, 1, SellOPColor );

	CreateText( "vHT_SellStop", left[2]+Dlina_X/2, up[4], "SellStop", 8, "Arial", MainColor );
	CreateLine( "vHT_SellStop_SL", left[2], up[5], right[2], up[5], STYLE_DASHDOT, 1, SellColor );
	CreateLine( "vHT_SellStop_OP", left[2], up[6], right[2], up[6], STYLE_DASH, 1, SellColor );
	CreateLine( "vHT_SellStop_TP", left[2], up[7], right[2], up[7], STYLE_DOT, 1, SellColor );


	CreateText( "vHT_Risk0", Panel_T1+1*Shag_X, up[8], "Risk", 8, "Arial", MainColor );
	for ( int i = 1; i < 6; i ++ )
	{
		CreateText( "vHT_Risk" + i, Panel_T1+(i+1)*Shag_X, up[8], RISK[i-1], 8, "Arial", MainColor );
	}
	ObjectSet ( "vHT_Risk" + SELECTED_RISK, OBJPROP_COLOR, SelectColor );

	CreateText( "vHT_Lot0", Panel_T1+1*Shag_X, up[9], "Lot", 8, "Arial", MainColor );
	for ( i = 1; i < 6; i ++ )
	{
		CreateText( "vHT_Lot" + i, Panel_T1+(i+1)*Shag_X, up[9], DoubleToStr( LOT[i-1], vhtLotDigits ), 8, "Arial", MainColor );
	}
	ObjectSet ( "vHT_Lot" + SELECTED_LOT, OBJPROP_COLOR, SelectColor );

	CreateText( "vHT_StopLoss0", Panel_T1+1*Shag_X, up[10], "SL", 8, "Arial", MainColor );
	for ( i = 1; i < 6; i ++ )
	{
		CreateText( "vHT_StopLoss" + i, Panel_T1+(i+1)*Shag_X, up[10], STOPLOSS[i-1], 8, "Arial", MainColor );
	}
	ObjectSet ( "vHT_StopLoss" + SELECTED_STOPLOSS, OBJPROP_COLOR, SelectColor );

	CreateText( "vHT_TakeProfit0", Panel_T1+1*Shag_X, up[11], "TP", 8, "Arial", MainColor );
	for ( i = 1; i < 6; i ++ )
	{
		CreateText( "vHT_TakeProfit" + i, Panel_T1+(i+1)*Shag_X, up[11], TAKEPROFIT[i-1], 8, "Arial", MainColor );
	}
	ObjectSet ( "vHT_TakeProfit" + SELECTED_TAKEPROFIT, OBJPROP_COLOR, SelectColor );

	CreateText( "vHT_TrailingStop0", Panel_T1+1*Shag_X, up[12], "TS", 8, "Arial", MainColor );
	for ( i = 1; i < 6; i ++ )
	{
		CreateText( "vHT_TrailingStop" + i, Panel_T1+(i+1)*Shag_X, up[12], TRAILINGSTOP[i-1], 8, "Arial", MainColor );
	}
	ObjectSet ( "vHT_TrailingStop" + SELECTED_TRAILINGSTOP, OBJPROP_COLOR, SelectColor );

	CreateText( "vHT_Expiration0", Panel_T1+1*Shag_X, up[13], "Exp", 8, "Arial", MainColor );
	for ( i = 1; i < 6; i ++ )
	{
		string exp = DoubleToStr( EXPIRATION[i-1], 0 );
		if ( EXPIRATION[i-1]-NormalizeDouble(EXPIRATION[i-1],0) != 0 ) { exp = DoubleToStr( EXPIRATION[i-1], 1 ); }
		CreateText( "vHT_Expiration" + i, Panel_T1+(i+1)*Shag_X, up[13], exp, 8, "Arial", MainColor );
	}
	ObjectSet ( "vHT_Expiration" + SELECTED_EXPIRATION, OBJPROP_COLOR, SelectColor );

	GetLastError();
	ObjectsRedraw();
	NeedRedrawObjects = false;
}
void CreateLine( string name, datetime t1, double p1, datetime t2, double p2, int style, int width, color col )
{
	ObjectDelete( name );
	if ( ObjectCreate( name, OBJ_TREND, 0, t1, p1, t2, p2 ) )
	{
		ObjectSet	( name, OBJPROP_COLOR	, col		);
		ObjectSet	( name, OBJPROP_RAY		, false	);
		ObjectSet	( name, OBJPROP_STYLE	, style	);
		ObjectSet	( name, OBJPROP_WIDTH	, width	);
	}
	GetLastError();
}
void CreateHLine( string name, double p1, int style, int width, color col, string description )
{
	ObjectDelete( name );
	if ( ObjectCreate( name, OBJ_HLINE, 0, CurTime(), p1 ) )
	{
		ObjectSet	( name, OBJPROP_COLOR	, col		);
		ObjectSet	( name, OBJPROP_STYLE	, style	);
		ObjectSet	( name, OBJPROP_WIDTH	, width	);
		ObjectSetText( name, description, 8 );
	}
	GetLastError();
}
void CreateText( string name, datetime t1, double p1, string text, int font_size, string font_name, color col )
{
	ObjectDelete( name );
	if ( ObjectCreate	( name, OBJ_TEXT, 0, t1, p1 ) )
	{
		ObjectSetText	( name, text, font_size, font_name, col );
	}
	GetLastError();
}
void vHandsTrade_DeleteObjects()
{
	int objectstotal = ObjectsTotal(); string name = "";
	for ( int i = objectstotal; i >= 0; i -- )
	{
		name = ObjectName(i);
		if ( StringSubstr( name, 0, 4 ) == "vHT_" ) { ObjectDelete( name ); }
	}
	GetLastError();
}
double LotSize()
{
	double 	lot_min		= MarketInfo( Symbol(), MODE_MINLOT  );
	double 	lot_max		= MarketInfo( Symbol(), MODE_MAXLOT  );
	double 	lot_step		= MarketInfo( Symbol(), MODE_LOTSTEP );
	double 	freemargin	= AccountFreeMargin();
	int		leverage		= AccountLeverage();
	int 		lotsize		= MarketInfo( Symbol(), MODE_LOTSIZE );

	if( lot_min < 0 || lot_max <= 0.0 || lot_step <= 0.0 || lotsize <= 0 ) 
	{
		MultiComment( "LotSize: invalid MarketInfo() results [" + lot_min + "," + lot_max + "," + lot_step + "," + lotsize + "]" );
		return(-1);
	}
	if( leverage <= 0 )
	{
		MultiComment( "LotSize: invalid AccountLeverage() [" + leverage + "]" );
		return(-1);
	}

	double lot = NormalizeDouble( Lot, 2 );
	if ( Risk > 0 ) { lot = NormalizeDouble( freemargin * Risk*0.01 * leverage / lotsize, 2 ); }

	lot = NormalizeDouble( lot / lot_step, 0 ) * lot_step;
	if ( lot < lot_min ) lot = lot_min;
	if ( lot > lot_max ) lot = lot_max;

	double margin_after_open = NormalizeDouble( AccountFreeMarginCheck( Symbol(), OP_BUY, lot ), 2 );

	if ( margin_after_open < 5 || GetLastError() == 134 )
	{
		MultiComment( "Íåäîñòàòî÷íî ñâîáîäíûõ ñðåäñòâ äëÿ îòêðûòèÿ ïîçèöèè " + DoubleToStr( lot, 2 ) + " ëîò ( FreeMargin = " + DoubleToStr( freemargin, 2 ) + ")!!!" );
		return(-1);
	}

	return(lot);
}
void MultiComment( string text )
{
	string multi = "";
	for ( int i = CommentsCount-1; i > 0; i -- )
	{
		comment[i] = comment[i-1];
	}
	comment[0] = TimeToStr( CurTime(), TIME_DATE | TIME_SECONDS ) + "  -  " + text + "\n";
	for ( i = 0; i < CommentsCount; i ++ )
	{
		multi = multi + comment[i];
	}
	Comment( multi );
}



Sample





Analysis



Market Information Used:

Series array that contains the highest prices of each bar
Series array that contains open time of each bar


Indicator Curves created:


Indicators Used:



Custom Indicators Used:

Order Management characteristics:

It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
Checks for the total of open orders
It automatically opens orders when conditions are reached

Other Features:

It issuies visual alerts to the screen