//+------------------------------------------------------------------+
//|                                                 TrailingLine.mq4 |
//|                                                            Roger |
//+------------------------------------------------------------------+
#property show_inputs

extern bool TrailingLine=false;
int _OrderTicket;
/*
Данный скрипт предназначен отслеживания уровней стопа и профита на парах, для которых ДЦ 
устанавливают непомерно большие минимально допустимые уровни стоп-лосса, в 
частности я писал это для золота, где этот уровень равен 200.
Работает так:
- захватываете мышкой скрипт и несете его на график на выбранный ордер.
Примечание: При большом количестве ордеров контролируйте захват нужного
ордера по журналу экспертов.
- в открывшемся окошке надо установить возможность трейлинга (по умолчанию
стоит false, что значит нет трейлинга).
- после закрытия окна на графике, появляются красная линия - стоп и зеленая линия - профит. 
Выделив любую из них, тяните на нужную позицию.
Примечание: и по Buy и по Sell все расчеты все равно ведутся по Биду!!!
- Если пожелаете тралить, поставьте значение TrailingLine=true.
Убрать скрипт можно удалив линии стопа и профита или закрыв сам отслеживаемый ордер.
*/
int start()
{
//+------------------------------------------------------------------+
// Максимальное расстояние в пунктах от места, на которое был "отпущен" скрипт, до
// цены открытия ордера. Для макимальной точности работы используйте "0",
// тогда ордер выделится только в случае точного попадания.
int Order_Find_Radius = 10;

// Расстояние между линией Stop_Loss/TakeProfit и линией Open_Price в пунктах по умолчанию.
// Будьте внимательны, скрипт работает по биду. При
// малых значениях возможно немедленное закрытие ордера.
int Stop_Loss = 150;
int Take_Profit = 150;

// Максимальное отклонение от запрошенной цены (для закрытия позиции)
int Slippage = 50;

//+------------------------------------------------------------------+
double Open_Price_Level, Stop_Loss_Level, PriceClose, Take_Profit_Level, Take_Profit_Level_new, Stop_Loss_Level_new;
int _break;
double lev;
double DropPrice = WindowPriceOnDropped();
bool mod;
// поиск ордера
for ( int x = 0; x <= Order_Find_Radius; x ++ )
{
	for ( int z = 0; z < OrdersTotal(); z ++ )
	{
		OrderSelect( z, SELECT_BY_POS, MODE_TRADES );
		if ( OrderSymbol() == Symbol() )
		{
			if ( MathAbs(( DropPrice - OrderOpenPrice() )/Point) <= x )
			{ _break = 1;
			    break;
		   }
		}
	}
	if ( _break == 1 ) break; 
}

if ( _break != 1 )
{
	MessageBox(  "Не удалось найти ордер!\n\n" +
					 "Переместите скрипт на график недалеко от цены открытия ордера, который хотите отслеживать	", 
          	 	 "Начало работы", 0x00000000 | 0x00000010 | 0x00040000 ); 
	return(0);
}
// Установка начальных значений:
string ord;
int _OrderType = OrderType();
if(_OrderType==0)ord="BUY"; else ord="SELL";
_OrderTicket = OrderTicket();
Open_Price_Level = Bid;
//Рисуем линии
if ( Stop_Loss > 0 )
   {
   if(_OrderType==0)Stop_Loss_Level = Open_Price_Level - Stop_Loss*Point; 
   if(_OrderType==1)Stop_Loss_Level = Open_Price_Level + Stop_Loss*Point;
   ObjectCreate( "Stop_Loss_Line"+_OrderTicket, OBJ_HLINE, 0, 0, Stop_Loss_Level, 0, 0, 0, 0 );
   ObjectSet( "Stop_Loss_Line"+_OrderTicket, OBJPROP_COLOR,Red );
   ObjectSetText( "Stop_Loss_Line"+_OrderTicket, "Stop_Loss_Line", 6, "Arial", Red );
   }
else Stop_Loss_Level =0;
if ( Take_Profit >0 )
   {
   if(_OrderType==0)Take_Profit_Level=Open_Price_Level + Take_Profit*Point; 
   if(_OrderType==1)Take_Profit_Level=Open_Price_Level - Take_Profit*Point; 
   ObjectCreate( "Take_Profit_Line"+_OrderTicket, OBJ_HLINE, 0, 0, Take_Profit_Level, 0, 0, 0, 0 );
   ObjectSet( "Take_Profit_Line"+_OrderTicket, OBJPROP_COLOR,Lime );
   ObjectSetText( "Take_Profit_Line"+_OrderTicket, "Take_Profit_Line", 6, "Arial", Lime );
   }   
else Take_Profit_Level=0;
lev=Open_Price_Level-Stop_Loss_Level;
Print("OrderType - ",ord," OrderTicket - ",_OrderTicket," OpenPrice - ",Open_Price_Level," StopLoss - ",Stop_Loss_Level," TakeProfit - ",Take_Profit_Level);
WindowRedraw();

int xx;
while( xx<1)
   {
// считываем значения с объектов и нормализуем:
   RefreshRates();
	if(ObjectFind("Stop_Loss_Line"+_OrderTicket)!=-1)Stop_Loss_Level_new = NormalizeDouble( ObjectGet( "Stop_Loss_Line"+_OrderTicket, OBJPROP_PRICE1 ), MarketInfo( Symbol(), MODE_DIGITS ) ); 
	else 
	  {
	  Stop_Loss_Level=0;
	  Stop_Loss_Level_new =0;
	  }
	if(ObjectFind("Take_Profit_Line"+_OrderTicket)!=-1)Take_Profit_Level = NormalizeDouble( ObjectGet( "Take_Profit_Line"+_OrderTicket, OBJPROP_PRICE1 ), MarketInfo( Symbol(), MODE_DIGITS ) );
	else Take_Profit_Level=0;
   if(Stop_Loss_Level==0&&Take_Profit_Level==0)break;//если линий нет, выходим из скрипта
   if(_OrderType==0)PriceClose=Bid; else PriceClose=Ask;
   if(Stop_Loss_Level!=Stop_Loss_Level_new)lev=Bid-Stop_Loss_Level_new;//если перемещали стоп, переопределяем расстояние от линии Бида
   Stop_Loss_Level=Stop_Loss_Level_new;
   if(TrailingLine)//если хотим тралить стоп
            {
            if(MathAbs(Bid-Stop_Loss_Level)>MathAbs(lev)&&Stop_Loss_Level!=0)//если цена уходит
                  {
                  Stop_Loss_Level=Bid-lev;//даем стопу новое значение
                  ObjectMove( "Stop_Loss_Line"+_OrderTicket, 0, 10,Stop_Loss_Level );//и перемещаем линию
                 WindowRedraw();            
                  }
            }   
      Comment("Order ",ord," - ",_OrderTicket, " StopLoss - ",Stop_Loss_Level," TakeProfit - ",Take_Profit_Level);
      if((lev<0&&iHigh(0,1,0)>=Stop_Loss_Level&&Stop_Loss_Level>0)||(lev>0&&iLow(0,1,0)<=Stop_Loss_Level)||
      (iHigh(0,1,1)<Take_Profit_Level&&iHigh(0,1,0)>=Take_Profit_Level)||(iLow(0,1,1)>Take_Profit_Level&&iLow(0,1,0)<=Take_Profit_Level))//условия пересечения стопа или профита
            {
            for(int i=0;i<OrdersTotal();i++)
                  {
                  OrderSelect( i, SELECT_BY_POS, MODE_TRADES );
	               if (_OrderTicket == OrderTicket())//находим ордер с нужным номером
                        {
                        if(OrderClose(OrderTicket(),OrderLots(),PriceClose,Slippage,CLR_NONE))//и удаляем
                              {
                              break;
                              }
                        }
                  }
            }
   OrderSelect(_OrderTicket,SELECT_BY_TICKET,MODE_TRADES);
   if(OrderCloseTime( ) !=0)break;//если ордер закрылся, сворачиваем скрипт
   Sleep(2000);//задержка
 }
return(-1);
}

int deinit()
{
// удаление объектов, созданного скриптом
ObjectDelete( "Stop_Loss_Line"+_OrderTicket );
ObjectDelete( "Take_Profit_Line"+_OrderTicket );
Comment("");
return(0);
}


