//+--------+
//|DollarCostAverage
//+--------+
#property copyright "Ron Thompson"
#property link      "http://www.ForexMT4.com/forex"
// This EA is NEVER to be SOLD individually 
// This EA is NEVER to be INCLUDED as part of a collection that is SOLD
// user input
extern int    LSMAPeriod          =      11;
extern double Lots                =       0.01;
extern int    ConsecOrders        =      10;
extern double slope               =       2.0;
extern double ProfitMade          =      10;
extern double LossLimit           =      40;
extern bool   KillLogging         =    true;
// Trade control
int    Slippage=2;                           // how many pips of slippage can you tolorate
int    maxloop=25;                           // maximum number of attempts to handle errors
int    LL2SL=10;                             // LossLimit to StopLoss server spread
int    maxOrders;                            // statistic for maximum numbers or orders open at one time
double maxLots;                              // Largest lot size ever opened
int    MagicNumber  = 142555;                // allows multiple experts to trade on same account
string TradeComment = "_DCA.txt";            // where to log information
// Bar handling
datetime bartime=0;                          // used to determine when a bar has moved
//objects 
int uniq=0;
int i; 
// used for verbose error logging
#include <stdlib.mqh>
// direction and change detector
double lsma0;
double lsma1;
double ldiff;      
int    currdir;
int    prevdir;
int    OrdersInRow;
//+-------------+
//| Custom init |
//|-------------+
// Called ONCE when EA is added to chart or recompiled
int init()
  {
   if( IsTesting() ) LL2SL=50;
   //remove the old objects 
   ObjectsDeleteAll();
   // current bar is current bar 
   // prevents trade when placing EA on chart 
   bartime=Time[0];
   
   // draw the indicator for comparison
   for(i=500; i>=0; i--) 
     {
      lsma0=LSMA(LSMAPeriod, i);
      lsma1=LSMA(LSMAPeriod, i+1);
      ldiff=((lsma0-lsma1)/Point);
      ObjectCreate("myx"+DoubleToStr(uniq,0), OBJ_TEXT, 0, Time[i], lsma0 );
      ObjectSetText("myx"+DoubleToStr(uniq,0),DoubleToStr(ldiff,0),15,"Arial",White);
      uniq++;
     }
   // set the directions at the end of the loop
   // based on Bar[0] and Bar[1]
   if(lsma0>lsma1) 
     {
      //Rising
      currdir=2;
      prevdir=2;
     }
    else
     {
      //falling
      currdir=1;
      prevdir=1;
     }
     
   
   logwrite(TradeComment,"Account balance="+AccountBalance()+" Lots="+Lots);
   logwrite(TradeComment,"Init Complete");
   Comment(" ");
  }
//+----------------+
//| Custom DE-init |
//+----------------+
// Called ONCE when EA is removed from chart
int deinit()
  {
   ObjectsDeleteAll();
   
   // always indicate deinit statistics
   logwrite(TradeComment,"MAX number of orders "+maxOrders);
   logwrite(TradeComment,"Max Lots is "+maxLots);
   
   logwrite(TradeComment,"DE-Init Complete");
   Comment(" ");
  }
//+-----------+
//| Main      |
//+-----------+
// Called EACH TICK and each Bar[]
int start()
  {
   int      cnt=0;
   int      gle=0;
   int      ticket=0;
   int      OrdersPerSymbol=0;
   string   cmt;
   string   sDir;
   string   sCA;
   string   sColor;
   // stoploss and takeprofit and close control
   double SL=0;
   double TP=0;
   
   double CurrentProfit=0;
   // order management
   string oTK;
   string oSL;
   string oTP;
   string oPM;
   string oLL;
   string oER;
   
   // keep some statistics
   OrdersPerSymbol=0;
   for(cnt=OrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         OrdersPerSymbol++;
        }
     }
   if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol;
   lsma1=LSMA(LSMAPeriod, 1);
   lsma0=LSMA(LSMAPeriod, 0);
   
   // bar counting
   if(bartime!=Time[0]) 
     {
      bartime=Time[0];
      
      Print ("-----Tick!");
      sColor="YELLOW";
      //draw number on chart 
      ldiff=((lsma0-lsma1)/Point);
      ObjectCreate("myx"+DoubleToStr(uniq,0), OBJ_TEXT, 0, Time[0], lsma0+(7*Point) );
      ObjectSetText("myx"+DoubleToStr(uniq,0),DoubleToStr(ldiff,0),15,"Arial",Aqua);
      uniq++;
      //default is sideways
      //and closeall =no change
      sDir=" Sideways";
      sCA=" as bafore";
      
      // Rising
      //if( lsma0>(lsma1+(slopeADJ*Point)) )
      if( lsma0>(lsma1+(slope*Point)) )
        {
         sDir="Rising";
         sColor="GREEN";
//ObjectCreate("myx"+DoubleToStr(uniq,0), OBJ_TEXT, 0, Time[0], High[0] );
//ObjectSetText("myx"+DoubleToStr(uniq,0),"G",15,"Arial",Aqua);
//uniq++;
         
         // has the direction changed, including slope 
         currdir=2;
         if(currdir!=prevdir)
           {
            sCA=" was Falling";
            CloseEverything();
            prevdir=currdir;
           }
         if(LossLimit ==0) SL=0; else SL=Ask-((LossLimit+LL2SL)*Point );
         if(ProfitMade==0) TP=0; else TP=Ask+((ProfitMade+LL2SL)*Point );
         if(OrdersInRow<=ConsecOrders)
           {
            ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,TradeComment,MagicNumber,White);
           }
         logwrite(TradeComment,"BUY Ticket="+ticket+" Ask="+Ask+" Lots="+Lots+" SL="+SL+" TP="+TP);
         OrdersInRow++;
        }
      
      // Falling
      //if( lsma0<(lsma1-(slopeADJ*Point)) )
      if( lsma0<(lsma1-(slope*Point)) )
        {
         sDir="Falling";
         sColor="RED";
//ObjectCreate("myx"+DoubleToStr(uniq,0), OBJ_TEXT, 0, Time[0], Low[0] );
//ObjectSetText("myx"+DoubleToStr(uniq,0),"R",15,"Arial",Aqua);
//uniq++;
         // has the direction changed, including slope 
         currdir=1;
         if(currdir!=prevdir)
           {
            sCA=" was Rising";
            CloseEverything();
            prevdir=currdir;
           }
         if(LossLimit ==0) SL=0; else SL=Bid+((LossLimit+LL2SL)*Point );
         if(ProfitMade==0) TP=0; else TP=Bid-((ProfitMade+LL2SL)*Point );
         if(OrdersInRow<=ConsecOrders)
           {
            ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,TradeComment,MagicNumber,Red);
           }
         logwrite(TradeComment,"SELL Ticket="+ticket+" Bid="+Bid+" Lots="+Lots+" SL="+SL+" TP="+TP);
         OrdersInRow++;
        }
      
      
      if(sColor=="YELLOW")
        {
         OrdersInRow=0;
//         ObjectCreate("myx"+DoubleToStr(uniq,0), OBJ_TEXT, 0, Time[0], Open[0] );
//         ObjectSetText("myx"+DoubleToStr(uniq,0),"Y",15,"Arial",Aqua);
//         uniq++;
        }
      cmt="LSMA[0]="+lsma0+" LSMA[1]="+lsma1+" DIFF="+ldiff+" DIRECTION="+sDir+sCA;
      Comment(cmt);
      
     }//bartime
     
   //
   // Order Management
   //
   for(cnt=OrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber )
        {
        
         if(OrderType()==OP_BUY)
           {
            CurrentProfit=(Bid-OrderOpenPrice()) ;
            // Did we make a profit
            //======================
            if(ProfitMade>0 && CurrentProfit>=(ProfitMade*Point))
              {
               oTK=" Ticket="+OrderTicket();
               oSL=" SL="+OrderStopLoss();
               oTP=" TP="+OrderTakeProfit();
               oPM=" PM="+ProfitMade;
               oLL=" LL="+LossLimit;
               OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
               logwrite(TradeComment,"CLOSE BUY PROFIT" + oTK + oSL + oTP + oPM + oLL);
              }
              
            // Did we take a loss
            //====================
            if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point))
              {
               oTK=" Ticket="+OrderTicket();
               oSL=" SL="+OrderStopLoss();
               oTP=" TP="+OrderTakeProfit();
               oPM=" PM="+ProfitMade;
               oLL=" LL="+LossLimit;
               OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
               logwrite(TradeComment,"CLOSE BUY LOSS" + oTK + oSL + oTP + oPM + oLL);
              }
              
           } // if BUY
         if(OrderType()==OP_SELL)
           {
            CurrentProfit=(OrderOpenPrice()-Ask);
            // Did we make a profit
            //======================
            if( ProfitMade>0 && CurrentProfit>=(ProfitMade*Point) )
              {
               oTK=" Ticket="+OrderTicket();
               oSL=" SL="+OrderStopLoss();
               oTP=" TP="+OrderTakeProfit();
               oPM=" PM="+ProfitMade;
               oLL=" LL="+LossLimit;
               OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red);
               logwrite(TradeComment,"CLOSE SELL PROFIT"+ oTK + oSL + oTP + oPM + oLL);
              }
             
            // Did we take a loss
            //====================
            if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point) )
              {
               oTK=" Ticket="+OrderTicket();
               oSL=" SL="+OrderStopLoss();
               oTP=" TP="+OrderTakeProfit();
               oPM=" PM="+ProfitMade;
               oLL=" LL="+LossLimit;
               OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red);
               logwrite(TradeComment,"CLOSE SELL LOSS"+ oTK + oSL + oTP + oPM + oLL);
              }
           } //if SELL
           
        } // if(OrderSymbol)
        
     } // for
  } // start()
// log data to a file name passed in
// print everything regardless of log setting
void logwrite (string filename, string mydata)
  {
   int myhandle;
   string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);
   Print(mydata+" "+gregorian);
   
   // don't log anything if testing or if user doesn't want it
   if(IsTesting()) return(0);
   if(KillLogging) return(0);
   myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
   if(myhandle>0)
     {
      FileSeek(myhandle,0,SEEK_END);
      FileWrite(myhandle, mydata+" "+gregorian);
      FileClose(myhandle);
     }
  } 
double LSMA(int myLPeriod, int myShift )
  {
   int myI;
   double myLengthvar;
   double myTmp;
   double mySum=0;
   for(myI = myLPeriod; myI >= 1  ; myI--)
     {
      myLengthvar = myLPeriod + 1;
      myLengthvar /= 3;
      myTmp = 0;
      myTmp = ( myI - myLengthvar)*Open[myLPeriod-myI+myShift];
      mySum+=myTmp;
     }
   return( mySum*6/(myLPeriod*(myLPeriod+1)) );
  }  
//+-----------------+
//| CloseEverything |
//+-----------------+
// Closes all OPEN and PENDING orders
int CloseEverything()
  {
   double myAsk;
   double myBid;
   int    myTkt;
   double myLot;
   int    myTyp;
   int i;
   bool result = false;
  //   int total=OrdersTotal();
  //   for(int pos=0;pos<total;pos++)
   
   for( i=OrdersTotal(); i>=0; i-- )
     {
      OrderSelect(i, SELECT_BY_POS);
      myAsk=MarketInfo(OrderSymbol(),MODE_ASK);            
      myBid=MarketInfo(OrderSymbol(),MODE_BID);            
      myTkt=OrderTicket();
      myLot=OrderLots();
      myTyp=OrderType();
            
      switch( myTyp )
        {
         //Close opened long positions
         case OP_BUY      :result = OrderClose(myTkt, myLot, myBid, Slippage, Red);
         break;
      
         //Close opened short positions
         case OP_SELL     :result = OrderClose(myTkt, myLot, myAsk, Slippage, Red);
         break;
       }
    
      if(result == false)
        {
         Alert("Order " , myTkt , " failed to close. Error:" , GetLastError() );
         Print("Order " , myTkt , " failed to close. Error:" , GetLastError() );
         Sleep(3000);
        }  
      Sleep(1000);
     } //for
  
  } // closeeverything
             
            
Comments