//+------------------------------------------------------------------+
//|                                      CrossMACD_DeLuxe_Visual.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, komposter"
#property link      "mailto:komposterius@mail.ru"
//----
extern int	_MagicNumber		= 1122;
extern int	StopLoss						= 50;
extern int	TakeProfit				= 100;
extern int	TrailingStop		= 50;
extern int	FastEMAPeriod	= 12;
extern int	SlowEMAPeriod	= 26;
extern int	OpenLuft						= 10;
extern int	CloseLuft					= 0;
//----
int _Ticket = 0, _Type = 0; 
double _Lots = 0.0, _OpenPrice = 0.0, _StopLoss = 0.0;
double _TakeProfit = 0.0; 
datetime _OpenTime = -1; 
double _Profit = 0.0, _Swap = 0.0;
double _Commission = 0.0; 
string _Comment = ""; 
datetime _Expiration = -1;
//----
#include <VisualTestingTools.mq4>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
	  if(FastEMAPeriod >= SlowEMAPeriod) 
	       return(-1); 
	  vTerminalInit();
	  vHistoryInit();
	  return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
	  if(FastEMAPeriod >= SlowEMAPeriod) 
	      return(-1); 
	  vTerminalRefresh();
	  vHistoryRefresh();
	  int _GetLastError = 0;
//---- Запоминаем параметры открытой позиции, если она есть
	  OneOrderInit(_MagicNumber);
	  //---- Запоминаем значения индикатора для дальнейшего анализа
	  double MACD_1 = iMACD(Symbol(), 0, FastEMAPeriod, SlowEMAPeriod, 9, 
															          PRICE_CLOSE, MODE_MAIN, 1);
	  double MACD_2 = iMACD(Symbol(), 0, FastEMAPeriod, SlowEMAPeriod, 9, 
															          PRICE_CLOSE, MODE_MAIN, 2);
//---- А теперь, вместо перебора позиций, просто смотрим, есть ли открытая позиция:
	  if(_Ticket > 0)
	    {
		     //---- если открыта БАЙ-позиция,
		     if(_Type == OP_BUY)
		       {
			        //---- если МАКД пересёк 0-ю линию вниз,
			        if(NormalizeDouble(MACD_1 + CloseLuft*Point*0.1, Digits + 1 ) <= 0.0)
			          {
				           //---- закрываем позицию
				           if(!OrderClose( _Ticket, _Lots, Bid, 5, Green))
				             {
					              _GetLastError = GetLastError();
					              Alert("Ошибка OrderClose № ", _GetLastError);
					               return(-1);
				             }
			          }
			        //---- если сигнал не изменился, выходим - пока рано открывать новую позицию
			        else
			          {
				           if(TrailingStop > 0)
				             {
					              if(NormalizeDouble( Bid - _OpenPrice, Digits) > 0.0)
					                {
						                 if(NormalizeDouble(Bid - _StopLoss - TrailingStop*Point, Digits) > 0.0 ||
							                                   _StopLoss < Point )
						                   {
							                    if(!OrderModify(_Ticket, _OpenPrice, Bid - TrailingStop*Point, 
																	                          _TakeProfit, _Expiration, Magenta))
							                      {
								                       _GetLastError = GetLastError();
								                       Alert( "Ошибка OrderModify № ", _GetLastError );
								                       return(-1);
							                      }
						                   }
					                }
				             }
				           return(0);
			          }
		       }
       //---- если открыта СЕЛЛ-позиция,
       if(_Type == OP_SELL)
         {
	          //---- если МАКД пересёк 0-ю линию вверх,
	          if(NormalizeDouble(MACD_1 - CloseLuft*Point*0.1, Digits + 1 ) >= 0.0)
	            {
		             //---- закрываем позицию
		             if(!OrderClose(_Ticket, _Lots, Ask, 5, Red))
		               {
			                _GetLastError = GetLastError();
			                Alert("Ошибка OrderClose № ", _GetLastError);
			                return(-1);
		               }
	            }
			        //---- если сигнал не изменился, выходим - пока рано открывать новую позицию
			        else
			          {
				           if(TrailingStop > 0)
				             {
					              if(NormalizeDouble(_OpenPrice - Ask, Digits ) > 0.0)
					                {
						                 if(NormalizeDouble(_StopLoss - (Ask + TrailingStop*Point), 
						                    Digits) > 0.0 || _StopLoss < Point )
						                   {
							                    if(!OrderModify(_Ticket, _OpenPrice, Ask + TrailingStop*Point, 
																	             _TakeProfit, _Expiration, Magenta))
							                      {
								                       _GetLastError = GetLastError();
								                       Alert("Ошибка OrderModify № ", _GetLastError);
								                       return(-1);
							                      }
						                   }
					                }
				             }
				           return(0);
			          }
		       }
	    }
	  //---- если нет позиции, открытой экспертом ( _Ticket == 0 )
	  //---- если МАКД пересёк 0-ю линию вверх,
	  if(NormalizeDouble(MACD_1 - OpenLuft*Point*0.1, Digits + 1) > 0.0 && 
		    NormalizeDouble(MACD_2, Digits + 1 ) <= 0.0)
	    {
		     //---- открываем БАЙ позицию
		     OpenBuy();
		     return(0);
	    }
	  //---- если МАКД пересёк 0-ю линию вниз,
	  if(NormalizeDouble(MACD_1 + OpenLuft*Point*0.1, Digits + 1) < 0.0 && 
		    NormalizeDouble( MACD_2, Digits + 1) >= 0.0)
	    {
		     //---- открываем СЕЛЛ позицию
		     OpenSell();
		     return(0);
	    }
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OneOrderInit(int magic)
  {
	  int _GetLastError, _OrdersTotal = OrdersTotal();
	  _Ticket = 0; _Type = 0; _Lots = 0.0; _OpenPrice = 0.0; _StopLoss = 0.0;
	  _TakeProfit = 0.0; _OpenTime = -1; _Profit = 0.0; _Swap = 0.0;
	  _Commission = 0.0; _Comment = ""; _Expiration = -1;
//----
	  for(int z = _OrdersTotal - 1; z >= 0; z --)
	    {
		     if(!OrderSelect(z, SELECT_BY_POS))
		       {
			        _GetLastError = GetLastError();
			        Print("OrderSelect( ", z, ", SELECT_BY_POS ) - Error #", _GetLastError);
			        continue;
		       }
		     if(OrderMagicNumber() == magic && OrderSymbol() == Symbol())
		       {
			        _Ticket	= OrderTicket();
			        _Type	= OrderType();
			        _Lots	= NormalizeDouble(OrderLots(), 1);
			        _OpenPrice	= NormalizeDouble(OrderOpenPrice(), Digits);
			        _StopLoss	= NormalizeDouble(OrderStopLoss(), Digits);
			        _TakeProfit	= NormalizeDouble(OrderTakeProfit(), Digits);
			        _OpenTime	= OrderOpenTime();
			        _Profit		= NormalizeDouble(OrderProfit(), 2);
			        _Swap			= NormalizeDouble(OrderSwap(), 2);
			        _Commission	= NormalizeDouble(OrderCommission(), 2);
			        _Comment		= OrderComment();
			        _Expiration	= OrderExpiration();
			        return(0);
		       }
	    }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OpenBuy()
  {
   int _GetLastError = 0;
   double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel;
   _OpenPriceLevel = NormalizeDouble(Ask, Digits);
//----
   if(StopLoss > 0)
       _StopLossLevel = NormalizeDouble(_OpenPriceLevel - StopLoss*Point, Digits); 
   else
       _StopLossLevel = 0.0; 
//----
   if(TakeProfit > 0)
       _TakeProfitLevel = NormalizeDouble(_OpenPriceLevel + TakeProfit*Point, Digits); 
   else
       _TakeProfitLevel = 0.0; 
//----
   if(OrderSend(Symbol(), OP_BUY, 0.1, _OpenPriceLevel, 3, _StopLossLevel, 
	     _TakeProfitLevel, "CrossMACD", _MagicNumber, 0, Green) < 0)
     {
	      _GetLastError = GetLastError();
	      Alert("Ошибка OrderSend № ", _GetLastError);
	     return(-1);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OpenSell()
  {
   int _GetLastError = 0;
   double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel;
   _OpenPriceLevel = NormalizeDouble(Bid, Digits);
//----
   if(StopLoss > 0)
       _StopLossLevel = NormalizeDouble(_OpenPriceLevel + StopLoss*Point, Digits); 
   else
       _StopLossLevel = 0.0; 
//----
   if(TakeProfit > 0)
       _TakeProfitLevel = NormalizeDouble(_OpenPriceLevel - TakeProfit*Point, Digits); 
   else
       _TakeProfitLevel = 0.0; 
//----
   if(OrderSend(Symbol(), OP_SELL, 0.1, _OpenPriceLevel, 3, _StopLossLevel, 
			   _TakeProfitLevel, "CrossMACD", _MagicNumber, 0, Red) < 0)
     {
	      _GetLastError = GetLastError();
	      Alert("Ошибка OrderSend № ", _GetLastError);
	      return(-1);
     }
  }
//+------------------------------------------------------------------+