//+------------------------------------------------------------------+
//|                                             Sample_MA_Trader.mq4 |
//|                               Copyright © 2009, Investatech Inc. |
//|                                       http://www.investatech.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Investatech Inc."
#property link      "http://www.investatech.com"

//---- input parameters
extern int        MA_Fast=5;
extern int        MA_Slow=25;
extern double     stop_loss = 200;
extern double     take_profit = 200;
extern double     LotsPerTrade=0.1;   //order lot size
extern int Limit_order_distance=10;

//---global variables
int magic_number = 123454321;
string _time_opened_1=""; //we use this string as the name of our GV to keep track of the time the last trade opened
//string _time_opened_2=""; //we use this string as the name of our GV to keep track of the time the trade prior to the last trade opened
double _my_point=0.0001; //we use this variable to consider the Pip value in decimal points


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   //I define and initiate a GV that tracks the time we have opened a trade.
   //I like GVs because even if you close MetaTrader for up to 4 weeks their value
   //remain intact. 
   //the first step is to choose a unique name for the GV. I use a combination of 
   //a fixed string, the chart symbol and the magic number
   _time_opened_1=StringConcatenate("DMA_1_",Symbol(),magic_number);
   //_time_opened_2=StringConcatenate("DMA_2_",Symbol(),magic_number);

   //if the variable exists then we won't change it but if it does not exist then we assign
   //0 to it.
   if (!GlobalVariableCheck(_time_opened_1)) GlobalVariableSet(_time_opened_1,0);
   //the following line helps in back-testing the system
   if (GlobalVariableGet(_time_opened_1)>TimeCurrent()) GlobalVariableSet(_time_opened_1,0);
   //if (!GlobalVariableCheck(_time_opened_2)) GlobalVariableSet(_time_opened_2,0);
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   
   int all_trades=OrdersTotal();
   int my_direction=TradeDirection();

   
   //if there is at least one trade open see if you can manage it
   if (all_trades>0) ManageTrades(all_trades,my_direction);
   
   if (my_direction!=0) PlaceTrades(my_direction);
   
   return(0);
  }
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| ManageTrades function                                             |
//+------------------------------------------------------------------+
void ManageTrades(int _trades, int _t_dir)
  {
   //this function currently closes the trades if the direction of the market changes
   //otherwise it does nothing
   if (_t_dir==0) return;
   
   //the loop goes through the list of trades to see if it needs to close a trade
   for (int i=0;i<_trades;i++)
      {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) Print("I failed selecting a trade");
         int order_magic=OrderMagicNumber();
         string order_symbol=OrderSymbol();


         //consider trades opened by this EA for being managed
         if ((order_magic==magic_number)&&(order_symbol==Symbol()))
            {
               int order_ticket=OrderTicket();
               double order_size=OrderLots();
               int order_type=OrderType();
               datetime open_time=OrderOpenTime();
               
               //if user changes the value of GV by mistake the following lines make necessary corrections
               datetime registered_time=GlobalVariableGet(_time_opened_1);
               if (open_time>registered_time)GlobalVariableSet(_time_opened_1,open_time);

               //close long trades if the current signal says go short
               if ((_t_dir==-1)&&(order_type==OP_BUY))
                  OrderClose(order_ticket,order_size,Bid,5,CLR_NONE);

               //close short trades if the current signal says go long
               if ((_t_dir==1)&&(order_type==OP_SELL))
                  OrderClose(order_ticket,order_size,Ask,5,CLR_NONE);  
                  
            }//end of if statement   
      }//end of loop
   
   
   return;
  }
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| TradeDirection function                                            |
//+------------------------------------------------------------------+
// valid return values
// 0 no trades
// 1 long trades
// -1 short trades
int TradeDirection()
  {
   // see if we have already opened trades in the current bar
   datetime time1=GlobalVariableGet(_time_opened_1);
   //datetime time2=GlobalVariableGet(_time_opened_2);
   
   //the opening time of the current bar 
   datetime _bar_open_time=iTime(Symbol(),0,0);
   
   //if the open time of the last trade is greater than the open time of the current bar then
   //the system has already opened a trade in this bar and there is no need to open another trade
   if ((time1-_bar_open_time)>=0) return(0);
   
   //Moving Average Calculations
   double fast_1=iMA(Symbol(),0,MA_Fast,0,MODE_EMA,PRICE_CLOSE,1);
   double fast_2=iMA(Symbol(),0,MA_Fast,0,MODE_EMA,PRICE_CLOSE,2);
   double slow_1=iMA(Symbol(),0,MA_Slow,0,MODE_EMA,PRICE_CLOSE,1);
   double slow_2=iMA(Symbol(),0,MA_Slow,0,MODE_EMA,PRICE_CLOSE,2);
   
   //corss up means trade long
   if ((fast_2<=slow_2)&&(fast_1>slow_1)) return(1);
   
   //corss down means trade shor
   if ((fast_2>=slow_2)&&(fast_1<slow_1)) return(-1);
   

   //if none of the conditions are met no trades
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| PlaceTrades function                                             |
//+------------------------------------------------------------------+
void PlaceTrades(int trade_dir)
  {
   //the following lines make the code compatible with fractioanl pips
   //we need to replace Point with _my_point in the rest of the code
   _my_point=Point;
   if (_my_point==0.00001) _my_point=0.0001;
   if (_my_point==0.001) _my_point=0.01;
   
   
   RefreshRates();
   //long trades
   if (trade_dir==1)
      {
         double order_price=Ask-Limit_order_distance*Point;
         double SL=order_price-(stop_loss*_my_point);
         double TP=order_price+(take_profit*_my_point);
         int ticket=OrderSend(Symbol(),OP_BUYLIMIT,LotsPerTrade,order_price,5,SL,TP,NULL,magic_number,0,Green);
         
         //registering the time the new order is opened
         if (ticket>=0) 
            {
               OrderSelect(ticket,SELECT_BY_TICKET);
               datetime open_time=OrderOpenTime();
               GlobalVariableSet(_time_opened_1,open_time);
            }
      }//end of long trades
   
   //short trades
   if (trade_dir==-1)
      {
         order_price=Bid+Limit_order_distance*Point;
         SL=order_price+(stop_loss*_my_point);
         TP=order_price-(take_profit*_my_point);         
         ticket=OrderSend(Symbol(),OP_SELLLIMIT,LotsPerTrade,order_price,5,SL,TP,NULL,magic_number,0,Red);
         
         //registering the time the new order is opened
         if (ticket>=0) 
            {
               OrderSelect(ticket,SELECT_BY_TICKET);
               open_time=OrderOpenTime();
               GlobalVariableSet(_time_opened_1,open_time);
            }
      }//end of short trades
   
   return;
  }
//+------------------------------------------------------------------+


