//+------------------------------------------------------------------+
//|
//| This MQL5 Expert Advisor is Built By EATree Version 1.0, 
//| The first drag and drop MQL5 Expert Advisor Builder
//| Copyright 2011, GGI
//| http://www.eatree.com
//| email: info@eatree.com
//|
//|     Disclaimer: For testing and evaluation purposes only.
//|     In no event will authors be liable for any damages whatsoever. 
//|
//| MQL5 and MetaTrader 5 platform are Copyrighted by 
//| MetaQuotes Software Corp.  http://www.mql5.com 
//|
//+------------------------------------------------------------------+
#property copyright   "Copyright 2011, GGI."
#property link        "http://www.eatree.com"

//---
#include <Trade/Trade.mqh>
#include <Trade/SymbolInfo.mqh>
#include <Trade/PositionInfo.mqh>
#include <Trade/AccountInfo.mqh>
#include <Indicators/Indicators.mqh>
//---
input bool		BuyOk = true;
input bool		SellOk = true;
input string		Symbols = "EURUSD";
input int		myTakeProfit = 100;
input int		myStopLoss = 35;
input int		myTrailingStop = 30;
input bool		MoneyManagement = true;
input double		myLots = 0.1;
input bool		useWeekDay = false;
input bool		useTimeZones = false;
input bool		useEveryHour = false;
input bool		Alerts = false;
input bool		EMails = false;
input int		MACDfast = 20;
input int		MACDslow = 22;
input int		MACDsignal = 7;
input ENUM_APPLIED_PRICE		MACDapplied = PRICE_CLOSE;
input int		MAperiod = 20;
input ENUM_MA_METHOD		MAmethod = MODE_EMA;
input ENUM_APPLIED_PRICE		MAapplied = PRICE_WEIGHTED;
//------------------------------------------------------------------------
//If useWeekDay is set to true, deactivate trading in certain week days
input    string   s31                  =  "===Trade Week Days ==="; 
input    bool     WeekDay_0            =  true;    //Sunday
input    bool     WeekDay_1            =  true;    //Monday
input    bool     WeekDay_2            =  true;    //Tuesday 
input    bool     WeekDay_3            =  true;    //Wednesday
input    bool     WeekDay_4            =  true;    //Thursday
input    bool     WeekDay_5            =  true;    //Friday
input    bool     WeekDay_6            =  true;    //Saturday
//------------------------------------------------------------------------
//If useTimeZones is set to true, Allows Using times from three time zones
// You can set only one time zone if you want to trade in a certain time of the day
input    string   s32                   =  "=== TimeZones ==="; 
input    int      StartHour_1          =  10;      //StartHour_1 
input    int      StartMinute_1        =  0;       //StartMinute_1 
input    int      EndHour_1            =  14;      //EndHour_1 
input    int      EndMinute_1          =  0;       //EndMinute_1 
input    int      StartHour_2          =  0;       //StartHour_2 
input    int      StartMinute_2        =  0;       //StartMinute_2  
input    int      EndHour_2            =  0;       //EndHour_2 
input    int      EndMinute_2          =  0;       //EndMinute_2  
input    int      StartHour_3          =  0;       //StartHour_3  
input    int      StartMinute_3        =  0;       //StartMinute_3 
input    int      EndHour_3            =  0;       //EndHour_3  
input    int      EndMinute_3          =  0;       //EndMinute_3 
//------------------------------------------------------------------------
// Do not trade on Friday after certain time: 
input    string   s33                  =  "=== Friday End Time ==="; 
input    int     FridayEndHour        =  23;
input    int     FridayEndMinute      =  0;

input int      MagicNumber = 12345;

//---
double Lots          =0.1; // Lots
int    TakeProfit    =50;  // Take Profit (in pips)
int    StopLoss      =50;  // Stop Loss (in pips)
int    TrailingStop  =30;  // Trailing Stop Level (in pips)

MqlTradeRequest myRequest;
MqlTradeResult myResult;
datetime limit_time[];
string sa[];
int	  ExtTimeOut	=10;  // time out in seconds between trade operations
double Close[],Open[],High[],Low[],VolumeTick[],VolumeReal[];
//---
//+------------------------------------------------------------------+
//| MACD Sample expert class                                         |
//+------------------------------------------------------------------+
class CMyExpert
  {
protected:
   double            m_adjusted_point;             // point value adjusted for 3 or 5 points
   CTrade            m_trade;                      // trading object
   CSymbolInfo       m_symbol;                     // symbol info object
   CPositionInfo     m_position;                   // trade position object
   CAccountInfo      m_account;                    // account info wrapper
   //--- indicators
   int               m_handle_MACD_4;                // MACD indicator handle
   int               m_handle_MA_6;                // MA indicator handle
   //--- indicator buffers
   double            m_buff_MACD_4_Main[];           // MACD indicator Main buffer
   double            m_buff_MACD_4_Signal[];           // MACD indicator Signal buffer
   double            m_buff_MA_6_Main[];           // MA indicator Main buffer
   //---
   double            m_take_profit;
   double            m_traling_stop;

public:
                     CMyExpert();
                    ~CMyExpert() { Deinit(); }
   bool              Init(string aSymbol);
   void              Deinit();
   bool              Processing();

protected:
   bool              InitCheckParameters(int digits_adjust);
   bool              InitIndicators();
   bool              LongClosed();
   bool              ShortClosed();
   bool              LongModified();
   bool              ShortModified();
   bool              LongOpened();
   bool              ShortOpened();
   bool              posModify(string aSymbol,double aStopLoss,double aTakeProfit,string aMessage="",bool aSound=false);
   void              GetBuySL(string aSymbol,double aPoint,int aStopLoss,double & aSL);
   void              GetSellSL(string aSymbol,double aPoint,int aStopLoss,double & aSL);
   double            GetLots();
   double            LotsOptimized();
   void              GetPositionInfo(string aSymbol,double & aThisVolume,double & aTotalVolume,int & aTotalCount);
   string            getTradeRetCode(int aRetCode);
  };
//---
CMyExpert ExtExpert;
CMyExpert *ExtExpert2[];
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CMyExpert::CMyExpert()
  {
//---
   m_adjusted_point=0;
   m_handle_MACD_4=INVALID_HANDLE;
   m_handle_MA_6=INVALID_HANDLE;

//---
   ArraySetAsSeries(m_buff_MACD_4_Main,true);
   ArraySetAsSeries(m_buff_MACD_4_Signal,true);
   ArraySetAsSeries(m_buff_MA_6_Main,true);

//---
   m_take_profit     =0;
   m_traling_stop    =0;
//---
  }
//+------------------------------------------------------------------+
//| Initialization and checking for input parameters                 |
//+------------------------------------------------------------------+
bool CMyExpert::Init(string aSymbol)
  {
//--- initialize common information
   m_symbol.Name(aSymbol);              // symbol
   m_trade.SetExpertMagicNumber(MagicNumber);  // magic
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10;

   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- set default deviation for trading in adjusted points
   m_trade.SetDeviationInPoints(3*digits_adjust);
//---
   if(!InitCheckParameters(digits_adjust)) return(false);
   if(!InitIndicators())                   return(false);
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Checking for input parameters                                    |
//+------------------------------------------------------------------+
bool CMyExpert::InitCheckParameters(int digits_adjust)
  {
//--- initial data checks
   if(TakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
   if(TrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- check for right lots amount
   if(Lots<m_symbol.LotsMin() || Lots>m_symbol.LotsMax())
     {
      printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(Lots/m_symbol.LotsStep()-MathRound(Lots/m_symbol.LotsStep()))>1.0E-10)
     {
      printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
      return(false);
     }
//--- warning
   if(TakeProfit<=TrailingStop)
      printf("Warning: Trailing Stop must be less than Take Profit");
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of the indicators                                 |
//+------------------------------------------------------------------+
bool CMyExpert::InitIndicators()
  {
   if(m_handle_MACD_4==INVALID_HANDLE)
      if((m_handle_MACD_4=iMACD( m_symbol.Name(), 0, MACDfast, MACDslow, MACDsignal, MACDapplied)
)==INVALID_HANDLE){
         printf("Error creating MACD indicator");
         return(false);
      }
   if(m_handle_MA_6==INVALID_HANDLE)
      if((m_handle_MA_6=iMA( m_symbol.Name(), 0, MAperiod, 0, MAmethod, MAapplied)
)==INVALID_HANDLE){
         printf("Error creating MA indicator");
         return(false);
      }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Function for deleting of dynamic objects                         |
//+------------------------------------------------------------------+
void CMyExpert::Deinit()
  {
   if(m_handle_MACD_4!=INVALID_HANDLE){
      IndicatorRelease(m_handle_MACD_4);
      m_handle_MACD_4=INVALID_HANDLE;
   }
   if(m_handle_MA_6!=INVALID_HANDLE){
      IndicatorRelease(m_handle_MA_6);
      m_handle_MA_6=INVALID_HANDLE;
   }
//---
  }
//+------------------------------------------------------------------+
//| Check for long position closing
//+------------------------------------------------------------------+
bool CMyExpert::LongClosed()
  {
   bool        longCloseFlag = false;
   bool		  res = false;
	bool		Crossover_3_T = false;
	bool		Crossover_3_F = false;
	bool		If_Else_5_T = false;
	bool		If_Else_5_F = false;
	bool		And_7_OUT = false;

   //--- should it be closed?
	// Box: 'Crossover_3'
   if((m_buff_MACD_4_Main[1] > m_buff_MACD_4_Signal[1])&&(m_buff_MACD_4_Main[2] < m_buff_MACD_4_Signal[2])) Crossover_3_T = true;
   else Crossover_3_F = true;

	// Box: 'If_Else_5'
   if(m_buff_MA_6_Main[1] > m_buff_MA_6_Main[2]) If_Else_5_T = true;
   else If_Else_5_F = true;

	// Box: 'And_7'
   And_7_OUT = Crossover_3_F && If_Else_5_F && true && true;

   if(And_7_OUT && !longCloseFlag)
      {
         //OK to close a long trade
         longCloseFlag = true;

      }

   if(longCloseFlag)
		{
			//--- close position
			if(m_trade.PositionClose(m_symbol.Name()))
				printf("Long position by %s to be closed",m_symbol.Name());
			else
				printf("Error closing position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
			//--- processed and cannot be modified
			res=true;
		}
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for short position closing                                 |
//+------------------------------------------------------------------+
bool CMyExpert::ShortClosed()
  {
   bool        shortCloseFlag = false;
   bool		  res = false;
	bool		Crossover_3_T = false;
	bool		Crossover_3_F = false;
	bool		If_Else_5_T = false;
	bool		If_Else_5_F = false;
	bool		And_2_OUT = false;

   //--- should it be closed?
	// Box: 'Crossover_3'
   if((m_buff_MACD_4_Main[1] > m_buff_MACD_4_Signal[1])&&(m_buff_MACD_4_Main[2] < m_buff_MACD_4_Signal[2])) Crossover_3_T = true;
   else Crossover_3_F = true;

	// Box: 'If_Else_5'
   if(m_buff_MA_6_Main[1] > m_buff_MA_6_Main[2]) If_Else_5_T = true;
   else If_Else_5_F = true;

	// Box: 'And_2'
   And_2_OUT = Crossover_3_T && If_Else_5_T && true && true;

   if(And_2_OUT && !shortCloseFlag)
      {
         //OK to close a short trade
         shortCloseFlag = true;

      }

   if(shortCloseFlag)
		{
			//--- close position
         if(m_trade.PositionClose(m_symbol.Name()))
				printf("Short position by %s to be closed",m_symbol.Name());
			else
				printf("Error closing position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
			//--- processed and cannot be modified
			res = true;
		}
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position modifying                                |
//+------------------------------------------------------------------+
bool CMyExpert::LongModified()
  {
   bool res=false;
//--- check for trailing stop
   if(TrailingStop>0)
     {
      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*TrailingStop)
        {
         if(m_position.StopLoss()<m_symbol.Bid()-m_adjusted_point*TrailingStop || m_position.StopLoss()==0.0)
           {
            double sl=m_symbol.Bid()-m_adjusted_point*TrailingStop;
            double tp=m_position.TakeProfit();
            //--- modify position
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Long position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            //--- modified and must exit from expert
            res=true;
           }
        }
     }
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for short position modifying
//+------------------------------------------------------------------+
bool CMyExpert::ShortModified()
  {
   bool   res=false;
//--- check for trailing stop
   if(TrailingStop>0)
     {
      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*TrailingStop))
        {
         if((m_position.StopLoss()>(m_symbol.Ask()+m_adjusted_point*TrailingStop)) || m_position.StopLoss()==0.0)
           {
            double sl=m_symbol.Ask()+m_adjusted_point*TrailingStop;
            double tp=m_position.TakeProfit();
           //--- modify position
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Short position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            //--- modified and must exit from expert
            res=true;
           }
        }
     }
//---
   return(res);
  }
//+------------------------------------------------------------------+
//|       Position Modify                                            |
//+------------------------------------------------------------------+
bool CMyExpert::posModify(string aSymbol,double aStopLoss,double aTakeProfit,string aMessage="",bool aSound=false)
   {
   myRequest.symbol=aSymbol; 
   myRequest.action=TRADE_ACTION_SLTP;
   myRequest.sl=aStopLoss;
   myRequest.tp=aTakeProfit;
   if(aMessage!="")Print(aMessage);
   if(aSound)PlaySound("stops");
   OrderSend(myRequest,myResult);
      if(myResult.retcode==TRADE_RETCODE_DONE){
         Print("...successfully ("+aSymbol+")");
         if(aSound)PlaySound("ok");
         return(1);
      }
      else{
         Print("...error "+IntegerToString(myResult.retcode)+" - "+getTradeRetCode(myResult.retcode)); 
         if(aSound)PlaySound("timeout");
         return(-1);
      }
   }

//+------------------------------------------------------------------+
//| Check for long position opening                                  |
//+------------------------------------------------------------------+
bool CMyExpert::LongOpened()
  {
   bool        longOpenFlag = false;
   bool        res=false;
	bool		Crossover_3_T = false;
	bool		Crossover_3_F = false;
	bool		If_Else_5_T = false;
	bool		If_Else_5_F = false;
	bool		And_2_OUT = false;

   if(!BuyOk) return(false);

	//--- check for long position (BUY) possibility
	// Box: 'Crossover_3'
   if((m_buff_MACD_4_Main[1] > m_buff_MACD_4_Signal[1])&&(m_buff_MACD_4_Main[2] < m_buff_MACD_4_Signal[2])) Crossover_3_T = true;
   else Crossover_3_F = true;

	// Box: 'If_Else_5'
   if(m_buff_MA_6_Main[1] > m_buff_MA_6_Main[2]) If_Else_5_T = true;
   else If_Else_5_F = true;

	// Box: 'And_2'
   And_2_OUT = Crossover_3_T && If_Else_5_T && true && true;

   if(And_2_OUT && !longOpenFlag)
      {
         //OK to open a long (buy) trade
         longOpenFlag = true;

         //Use box Trade_1 trading parameters
         TakeProfit = myTakeProfit;
         StopLoss = myStopLoss;
         Lots = myLots;
      }


	 //--- Is it OK to open a long trade?
   if(longOpenFlag)
      {
      double lts=GetLots();
		//--- If so, check for free money
      if(m_account.FreeMarginCheck(m_symbol.Name(),ORDER_TYPE_BUY,lts, m_symbol.Ask())<0.0){
         printf("We have no money. Free Margin = %f",m_account.FreeMargin());
      }
      else{
         double ThisVolume,TotalVolume; int TotalCount;
         GetPositionInfo(m_symbol.Name(),ThisVolume,TotalVolume,TotalCount);

         double price=m_symbol.Ask();
         double tp   =m_symbol.Bid()+TakeProfit*m_adjusted_point;
         //--- open position
         if(Alerts)Alert("Buy");
         if(EMails)SendMail(MQL5InfoString(MQL5_PROGRAM_NAME)+" Buy","Buy");
         double slts=0.0;
         GetBuySL(m_symbol.Name(),m_adjusted_point,StopLoss,slts);

         if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_BUY,lts,price,slts,tp)){
            printf("Position by %s to be opened",m_symbol.Name());
         }
         else{
            printf("Error opening BUY position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
            printf("Open parameters : price=%f,TP=%f",price,tp);
         }
      //--- in any case we must exit from expert
      res=true;
      }
//---
		}
      return(res);
  }
//+------------------------------------------------------------------+
//| Check for short position opening                                 |
//+------------------------------------------------------------------+
bool CMyExpert::ShortOpened()
  {
   bool        shortOpenFlag = false;
   bool		  res=false;
	bool		Crossover_3_T = false;
	bool		Crossover_3_F = false;
	bool		If_Else_5_T = false;
	bool		If_Else_5_F = false;
	bool		And_7_OUT = false;

   if(!SellOk) return(false);

	//--- check for short position (SELL) possibility
	// Box: 'Crossover_3'
   if((m_buff_MACD_4_Main[1] > m_buff_MACD_4_Signal[1])&&(m_buff_MACD_4_Main[2] < m_buff_MACD_4_Signal[2])) Crossover_3_T = true;
   else Crossover_3_F = true;

	// Box: 'If_Else_5'
   if(m_buff_MA_6_Main[1] > m_buff_MA_6_Main[2]) If_Else_5_T = true;
   else If_Else_5_F = true;

	// Box: 'And_7'
   And_7_OUT = Crossover_3_F && If_Else_5_F && true && true;

   if(And_7_OUT && !shortOpenFlag)
      {
         //OK to open a short (sell) trade
         shortOpenFlag = true;

         //Use box Trade_1 trading parameters
         TakeProfit = myTakeProfit;
         StopLoss = myStopLoss;
         Lots = myLots;
      }


	 //--- Is it OK to open a short trade?
   if(shortOpenFlag)
      {
      double lts=GetLots();
		//--- If so, check for free money
      if(m_account.FreeMarginCheck(m_symbol.Name(),ORDER_TYPE_SELL,lts, m_symbol.Bid())<0.0){
         printf("We have no money. Free Margin = %f",m_account.FreeMargin());
      }
      else{
         double ThisVolume,TotalVolume; int TotalCount;
         GetPositionInfo(m_symbol.Name(),ThisVolume,TotalVolume,TotalCount);

         double price=m_symbol.Bid();
         double tp   =m_symbol.Ask()-TakeProfit*m_adjusted_point;
         //--- open position
         if(Alerts)Alert("Sell");
         if(EMails)SendMail(MQL5InfoString(MQL5_PROGRAM_NAME)+" Sell","Sell");
         double slts=0.0;
         GetSellSL(m_symbol.Name(),m_adjusted_point,StopLoss,slts);

         if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_SELL,lts,price,slts,tp)){
            printf("Position by %s to be opened",m_symbol.Name());
         }
         else{
            printf("Error opening SELL position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
            printf("Open parameters : price= %f,TP= %f",price,tp);
         }
      //--- in any case we must exit from expert
      res=true;
      }
//---
		}
      return(res);
  }
//+------------------------------------------------------------------+
//|     GetBuySL                                                     |
//+------------------------------------------------------------------+
void CMyExpert::GetBuySL(string aSymbol,double aPoint,int aStopLoss,double & aSL)
   {
   aSL=0;
      if(aStopLoss<=0){
         return;
      }
   double msl;
   double pAsk=SymbolInfoDouble(aSymbol,SYMBOL_ASK);
   double pBid=SymbolInfoDouble(aSymbol,SYMBOL_BID); 
   double pPoint=SymbolInfoDouble(aSymbol,SYMBOL_POINT);
   int pStopLevel=(int)SymbolInfoInteger(aSymbol,SYMBOL_TRADE_STOPS_LEVEL);
   int pDigits=(int)SymbolInfoInteger(aSymbol,SYMBOL_DIGITS);
      if(aStopLoss>0){
         aSL=pAsk-aPoint*aStopLoss;
         aSL=NormalizeDouble(aSL,pDigits);
         msl=pBid-pPoint*(pStopLevel+1);
         msl=NormalizeDouble(msl,pDigits);
         aSL=MathMin(aSL,msl);
      }
   }

//+------------------------------------------------------------------+
//|     GetSellSL                                                    |
//+------------------------------------------------------------------+
void CMyExpert::GetSellSL(string aSymbol,double aPoint,int aStopLoss,double & aSL)
   {
   aSL=0;
      if(aStopLoss<=0){
         return;
      }
   double msl;
   double pAsk=SymbolInfoDouble(aSymbol,SYMBOL_ASK);
   double pBid=SymbolInfoDouble(aSymbol,SYMBOL_BID); 
   double pPoint=SymbolInfoDouble(aSymbol,SYMBOL_POINT);
   int pStopLevel=(int)SymbolInfoInteger(aSymbol,SYMBOL_TRADE_STOPS_LEVEL);
   int pDigits=(int)SymbolInfoInteger(aSymbol,SYMBOL_DIGITS);  
      if(aStopLoss>0){
         aSL=pBid+aPoint*aStopLoss;
         aSL=NormalizeDouble(aSL,pDigits);
         msl=pAsk+pPoint*(pStopLevel+1);
         msl=NormalizeDouble(msl,pDigits);
         aSL=MathMax(aSL,msl);
      }
   }

//+------------------------------------------------------------------+
//|     GetLots                                                      |
//+------------------------------------------------------------------+ 
double CMyExpert::GetLots()
   {
   double lot; 
      if(MoneyManagement){
         lot=LotsOptimized();
      }
      else{
         lot=myLots;
      }
   return(lot);
   } 
//+------------------------------------------------------------------+
//|     LotsOptimized                                                |
//+------------------------------------------------------------------+
double CMyExpert::LotsOptimized()
   {
   double lot=myLots;
   return(lot);
   }
//+------------------------------------------------------------------+
//| main function returns true if any position processed             |
//+------------------------------------------------------------------+
bool CMyExpert::Processing()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates()) return(false);
//---
   CopyBuffer(m_handle_MACD_4,0,0,20,m_buff_MACD_4_Main);
   CopyBuffer(m_handle_MACD_4,1,0,20,m_buff_MACD_4_Signal);
   CopyBuffer(m_handle_MA_6,0,0,20,m_buff_MA_6_Main);

//--- to simplify the coding and speed up access
//--- data are put into internal variables
//---
//--- it is important to enter the market correctly, 
//--- but it is more important to exit it correctly... 
//--- first check if position exists - try to select it
   if(m_position.Select(m_symbol.Name()))
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
        {
         //--- try to close or modify long position
         if(LongClosed())    return(true);
         if(LongModified())  return(true);
        }
      else
        {
         //--- try to close or modify short position
         if(ShortClosed())   return(true);
         if(ShortModified()) return(true);
        }
     }
//--- no opened position identified
   else
     {
      if(fTradeWeekDay()){
            if(EveryHourOk()){
               if(CheckTime()){
                  //--- check for long position (BUY) possibility
                  if(LongOpened())  return(true);
                  //--- check for short position (SELL) possibility
                  if(ShortOpened()) return(true);
               }
            }
      }
     }
//--- exit without position processing
   return(false);
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
      string _s = Symbols;
      StringTrimLeft(_s);
      StringTrimRight(_s);
         if(_s==""){
            _s=_Symbol;
         }
      StrSplit(_s,sa,"/");
      ArrayResize(ExtExpert2,ArraySize(sa));
      ArrayResize(limit_time,ArraySize(sa));
         for(int i=0;i<ArraySize(sa);i++){
            ExtExpert2[i]=new CMyExpert;
               if(!ExtExpert2[i].Init(sa[i])){
                  ExtExpert2[i].Deinit();
                  return(-1);
               }
         }
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
      for(int i=0;i<ArraySize(ExtExpert2);i++){
          if(ExtExpert2[i]!=NULL) delete ExtExpert2[i];
      }
  }
//+------------------------------------------------------------------+
//| Expert new tick handling function                                |
//+------------------------------------------------------------------+
void OnTick()
  {
      for(int i=0;i<ArraySize(sa);i++){
         //if(TimeCurrent()>=limit_time[i]){ 
               if(ExtExpert2[i].Processing()) limit_time[i]=TimeCurrent()+ExtTimeOut;
         //}
      }
   }

//+------------------------------------------------------------------+
//|     GetPositionInfo                                              |
//+------------------------------------------------------------------+
void CMyExpert::GetPositionInfo(string aSymbol,double & aThisVolume,double & aTotalVolume,int & aTotalCount)
   {
   aThisVolume=0;
   aTotalVolume=0;
   aTotalCount=0;
      for(int i=0;i<ArraySize(sa);i++){
         if(PositionSelect(sa[i])){
            aTotalVolume+=PositionGetDouble(POSITION_VOLUME);
            aTotalCount++;
         }
      }
   aTotalVolume=NormalizeDouble(aTotalVolume,2); 
      if(PositionSelect(aSymbol)){
         aThisVolume=PositionGetDouble(POSITION_VOLUME);
         aThisVolume=NormalizeDouble(aThisVolume,2); 
      }
   return;
   }

//+------------------------------------------------------------------+
//|     Get Trade Returned Code                                      |
//+------------------------------------------------------------------+
string CMyExpert::getTradeRetCode(int aRetCode)
   {
  string tErrText="Unknown error ("+IntegerToString(aRetCode)+")";
      switch(aRetCode){
         case TRADE_RETCODE_REQUOTE:            return("(REQUOTE)");
         case TRADE_RETCODE_REJECT:             return("(REJECT)");
         case TRADE_RETCODE_CANCEL:             return("(CANCEL)");
         case TRADE_RETCODE_PLACED:             return("(PLACED)");
         case TRADE_RETCODE_DONE:               return("(DONE)");
         case TRADE_RETCODE_DONE_PARTIAL:       return("(DONE_PARTIAL)");
         case TRADE_RETCODE_ERROR:              return("(ERROR)");
         case TRADE_RETCODE_TIMEOUT:            return("(TIMEOUT)");
         case TRADE_RETCODE_INVALID:            return("(INVALID)");
         case TRADE_RETCODE_INVALID_VOLUME:     return("(INVALID_VOLUME)");
         case TRADE_RETCODE_INVALID_PRICE:      return("(INVALID_PRICE)");
         case TRADE_RETCODE_INVALID_STOPS:      return("(INVALID_STOPS)");
         case TRADE_RETCODE_TRADE_DISABLED:     return("(TRADE_DISABLED)");
         case TRADE_RETCODE_MARKET_CLOSED:      return("(MARKET_CLOSED)");
         case TRADE_RETCODE_NO_MONEY:           return("(NO_MONEY)");
         case TRADE_RETCODE_PRICE_CHANGED:      return("(PRICE_CHANGED)");
         case TRADE_RETCODE_PRICE_OFF:          return("(PRICE_OFF)");
         case TRADE_RETCODE_INVALID_EXPIRATION: return("(INVALID_EXPIRATION)");
         case TRADE_RETCODE_ORDER_CHANGED:      return("(ORDER_CHANGED)");
         case TRADE_RETCODE_TOO_MANY_REQUESTS:  return("(TOO_MANY_REQUESTS)");
         case TRADE_RETCODE_NO_CHANGES:         return("(NO_CHANGES)");
         case TRADE_RETCODE_SERVER_DISABLES_AT: return("(SERVER_DISABLES_AT)");
         case TRADE_RETCODE_CLIENT_DISABLES_AT: return("(CLIENT_DISABLES_AT)");
         case TRADE_RETCODE_LOCKED:             return("(LOCKED)");
         case TRADE_RETCODE_FROZEN:             return("(FROZEN)");
         case TRADE_RETCODE_INVALID_FILL:       return("(INVALID_FILL)");
      }
   return("???");
   }

//+------------------------------------------------------------------+
//|     String Split Function                                        |
//+------------------------------------------------------------------+
void StrSplit(string aString,string & aArray[],string aDelimiter)
   {
   int tCounter=0;
   int tDelimiterLength=StringLen(aDelimiter);
   ArrayResize(aArray,tCounter);
   int tPos1=0;
   int tPos2=StringFind(aString,aDelimiter,0);
      while(tPos2!=-1){
            if(tPos2>=tPos1){
               tCounter++;
               ArrayResize(aArray,tCounter);
                  if(tPos2-tPos1==0){
                     aArray[tCounter-1]="";
                  }
                  else{
                     aArray[tCounter-1]=StringSubstr(aString,tPos1,tPos2-tPos1);
                  }
            }
         tPos1=tPos2+tDelimiterLength;
         tPos2=StringFind(aString,aDelimiter,tPos1);
      }
   tPos2=StringLen(aString); 
      if(tPos2>=tPos1){
         tCounter++; 
         ArrayResize(aArray,tCounter);
            if(tPos2-tPos1==0){
               aArray[tCounter-1]="";
            }
            else{
               aArray[tCounter-1]=StringSubstr(aString,tPos1,tPos2-tPos1); 
            }
      }
   }

//+------------------------------------------------------------------+
//|     CheckTime Function                                           |
//+------------------------------------------------------------------+
bool CheckTime(){
      if(useTimeZones){
            if(
               fTimeInZone(StartHour_1,StartMinute_1,EndHour_1,EndMinute_1,TimeCurrent()) ||
               fTimeInZone(StartHour_2,StartMinute_2,EndHour_2,EndMinute_2,TimeCurrent()) ||
               fTimeInZone(StartHour_3,StartMinute_3,EndHour_3,EndMinute_3,TimeCurrent())
            ){
               return(true);
            }
         return(false);
      }
   return(true);
}
//+------------------------------------------------------------------+
//|     fTimeInZone Function                                         |
//+------------------------------------------------------------------+
bool fTimeInZone(int aStartHour,int aStartMinute,int aEndHour,int aEndMinute,datetime aTimeNow){
   int tStartTime=3600*aStartHour+60*aStartMinute;
   int tEndTime=3600*aEndHour+60*aEndMinute;
   datetime tTimeNow=aTimeNow-86400*(aTimeNow/86400);
      if(tStartTime<=tEndTime){
         if(tTimeNow>=tStartTime && tTimeNow<tEndTime){
            return(true);
         }
      }
      else{
         if(tTimeNow>=tStartTime || tTimeNow<tEndTime){
            return(true);
         }
      }
   return(false);
}
//+------------------------------------------------------------------+
//|     EveryHourOk Function                                         |
//+------------------------------------------------------------------+
bool EveryHourOk(){
   if(useEveryHour){
      MqlDateTime dt_struct;
      TimeToStruct(TimeCurrent(),dt_struct);
      if(dt_struct.min==0 && dt_struct.sec<30){
         return(true);
      }
   }
   else{
      return(true);
   }

 return(false);
}
//+------------------------------------------------------------------+
//|     fTradeWeekDay Function                                       |
//+------------------------------------------------------------------+
bool fTradeWeekDay(){
   if(useWeekDay){
      switch(fTimeDayOfWeek(TimeCurrent()) ){
         case 0: return(WeekDay_0);
         case 1: return(WeekDay_1);
         case 2: return(WeekDay_2);
         case 3: return(WeekDay_3); 
         case 4: return(WeekDay_4);
         case 5: return(WeekDay_5);
         case 6: return(WeekDay_6); 
      }
   }
   return(true);
} 
//+------------------------------------------------------------------+
//|     fTimeDayOfWeek Function                                      |
//+------------------------------------------------------------------+
int fTimeDayOfWeek(datetime dt){
   MqlDateTime dt_struct;
   TimeToStruct(dt,dt_struct);
   return(dt_struct.day_of_week);
} 
