[ea]DollarCostAverage_Ron_MT4_v01b

Author: Ron Thompson
Price Data Components
Series array that contains open time of each bar
Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reachedIt Closes Orders by itself
Miscellaneous
Uses files from the file systemIt writes information to fileIt issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites

Profitability Reports

GBP/CAD Oct 2024 - Jan 2025
53.00 %
Total Trades 1410
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff -1.88
Gross Profit 2930.27
Gross Loss -5578.80
Total Net Profit -2648.53
-100%
-50%
0%
50%
100%
[ea]DollarCostAverage_Ron_MT4_v01b
//+--------+
//|DollarCostAverage
//+--------+
#property copyright "Ron Thompson"
#property link      "http://www.lightpatch.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

// EA SPECIFIC
extern int    LSMAPeriod          =      57;

// user input
extern double MinFreeMarginPct    =      25.0;
extern double Lots                =       0.1;
extern int    slope               =       6;
extern double ProfitMade          =      32;
extern double LossLimit           =       0;
extern bool   CloseOnReverse      =    true;
extern bool   KillLogging         =    true;


// Trade control
int    Slippage=2;                           // how many pips of slippage can you tolorate
bool   TradeAllowed=true;                    // used to manage trades
int    loopcount;                            // count of order attempts
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
int      bartick=0;                          // number of times bars have moved

int i; //objects 


//EA specific
int lsmaDirection=0;



// used for verbose error logging
#include <stdlib.mqh>




//+-------------+
//| Custom init |
//|-------------+
// Called ONCE when EA is added to chart or recompiled

int init()
  {

   if( IsTesting() ) LL2SL=50;

   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()
  {
   // 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;

   // stoploss and takeprofit and close control
   double SL=0;
   double TP=0;
   
   double CurrentProfit=0;
     
   // direction control
   bool BUYme=false;
   bool SELLme=false;

   //safety counter
   int   loopcount=0;

   // LSMA slope adjustment
   int slopeADJ;
      
   
   // 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;

   if(OrdersPerSymbol>0)
     {
      slopeADJ=slope;
     }
     else
     {
      slopeADJ=0;
     }
   

   // bar counting
   if(bartime!=Time[0]) 
     {
      bartime=Time[0];
      
      double lsma2=LSMA(LSMAPeriod, 2);
      double lsma1=LSMA(LSMAPeriod, 1);
   
      if( lsma1>(lsma2+(slopeADJ*Point)) )
        {
         // did we change directions (1=up 0=dn)
         if(CloseOnReverse && lsmaDirection==0) 
           {
            CloseEverything();
            lsmaDirection=1;
           }
         BUYme=true;
        }
      
      if( lsma1<(lsma2-(slopeADJ*Point)) )
        {
         // did we change directions (1=up 0=dn)
         if(CloseOnReverse && lsmaDirection==1) 
           {
            CloseEverything();
            lsmaDirection=0;
           }
         SELLme=true;
        }
      
      TradeAllowed=true;
     }


     
   //ENTRY LONG (buy, Ask) 
   if( TradeAllowed && BUYme)
     {
      OpenBuy();
     }
        

   //ENTRY SHORT (sell, Bid)
   if( TradeAllowed && SELLme)
     {
      OpenSell();
     }


   //
   // 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))
              {
               CloseBuy("PROFIT");
              }
              

            // Did we take a loss
            //====================
            if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point))
              {
               CloseBuy("LOSS");
              }
              
           } // if BUY


         if(OrderType()==OP_SELL)
           {
            CurrentProfit=(OrderOpenPrice()-Ask);

            // Did we make a profit
            //======================
            if( ProfitMade>0 && CurrentProfit>=(ProfitMade*Point) )
              {
               CloseSell("PROFIT");
              }
             

            // Did we take a loss
            //====================
            if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point) )
              {
               CloseSell("LOSS");
              }

           } //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);
     }
  } 


//ENTRY LONG (buy, Ask) 
void OpenBuy()
     {
      int      gle=0;
      int      ticket=0;
      
      double SL=0;
      double TP=0;

      int loopcount=0;
      while(true)
        {
         if( AccountFreeMargin()< (AccountBalance()*(MinFreeMarginPct/100)) )
           {
            logwrite(TradeComment,"Your BUY equity is too low to trade");
            break;
           }

         if(LossLimit ==0) SL=0; else SL=Ask-((LossLimit+LL2SL)*Point );
         if(ProfitMade==0) TP=0; else TP=Ask+((ProfitMade+LL2SL)*Point );
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,TradeComment,MagicNumber,White);
         gle=GetLastError();
         if(gle==0)
           {
            logwrite(TradeComment,"BUY Ticket="+ticket+" Ask="+Ask+" Lots="+Lots+" SL="+SL+" TP="+TP);
            TradeAllowed=false;
            break;
           }
            else 
           {
            logwrite(TradeComment,"-----ERROR-----  opening BUY order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); 
            
            RefreshRates();
            Sleep(500);

            loopcount++;
            if(loopcount>maxloop) break;
           }
        }//while   
     }//BUYme



   //ENTRY SHORT (sell, Bid)
void OpenSell()
     {
      int      gle=0;
      int      ticket=0;
      
      double SL=0;
      double TP=0;

      int loopcount=0;
      while(true)
        {
         if( AccountFreeMargin()< (AccountBalance()*(MinFreeMarginPct/100)) )
           {
            logwrite(TradeComment,"Your SELL equity is too low to trade");
            break;
           }

         if(LossLimit ==0) SL=0; else SL=Bid+((LossLimit+LL2SL)*Point );
         if(ProfitMade==0) TP=0; else TP=Bid-((ProfitMade+LL2SL)*Point );
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,TradeComment,MagicNumber,Red);
         gle=GetLastError();
         if(gle==0)
           {
            logwrite(TradeComment,"SELL Ticket="+ticket+" Bid="+Bid+" Lots="+Lots+" SL="+SL+" TP="+TP);
            TradeAllowed=false;
            break;
           }
            else 
           {
            logwrite(TradeComment,"-----ERROR-----  opening SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); 
                            
            RefreshRates();
            Sleep(500);

            loopcount++;
            if(loopcount>maxloop) break;
           }
        }//while
     }//SELLme



void CloseBuy (string myInfo)
  {
   int gle;
   int cnt;
   int OrdersPerSymbol;

   int loopcount=0;
   
   string bTK=" Ticket="+OrderTicket();
   string bSL=" SL="+OrderStopLoss();
   string bTP=" TP="+OrderTakeProfit();
   string bPM;
   string bLL;
   string bER;

   bPM=" PM="+ProfitMade;
   bLL=" LL="+LossLimit;

   while(true)
     {
      OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
      gle=GetLastError();
      bER=" error="+gle+" "+ErrorDescription(gle);

      if(gle==0)
        {
         logwrite(TradeComment,"CLOSE BUY "+myInfo+ bTK + bSL + bTP + bPM + bLL);
         break;
        }
       else 
        {
         logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+Bid+ bTK + bSL + bTP + bPM + bLL);
         RefreshRates();
         Sleep(500);
        }

      loopcount++;
      if(loopcount>maxloop) break;
                     
     }//while
  
  }


void CloseSell (string myInfo)
  {
   int gle;
   int cnt;
   int OrdersPerSymbol;

   int loopcount=0;

   string sTK=" Ticket="+OrderTicket();
   string sSL=" SL="+OrderStopLoss();
   string sTP=" TP="+OrderTakeProfit();
   string sPM;
   string sLL;
   string sER;
      
   sPM=" PM="+ProfitMade;
   sLL=" LL="+LossLimit;

   while(true)
     {
      OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red);
      gle=GetLastError();
      sER=" error="+gle+" "+ErrorDescription(gle);
      
      if(gle==0)
        {
         logwrite(TradeComment,"CLOSE SELL "+myInfo + sTK + sSL + sTP + sPM + sLL);
         break;
        }
      else 
        {
         logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+Ask+ sTK + sSL + sTP + sPM + sLL);
         RefreshRates();
         Sleep(500);
        }

      loopcount++;
      if(loopcount>maxloop) break;
                 
     }//while                 
  }      



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;
    
   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;

         //Close pending orders
         case OP_BUYLIMIT :
         case OP_BUYSTOP  :
         case OP_SELLLIMIT:
         case OP_SELLSTOP :result = OrderDelete( OrderTicket() );
       }
    
      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

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---