[ea]DivergenceTrader_Ron_MT4_v04

Author: Ron Thompson
Profit factor:
0.81

This script is designed to automatically trade in the Forex market based on divergence. Here's how it works, broken down into plain language:

1. Initial Setup:

  • User Choices: Before the script starts trading, you (the user) get to set various preferences like:

    • Lots: How much of a currency to trade at once. Think of it like the size of your bet.
    • Slippage: A small amount of price change you're willing to accept when placing an order. The market can move quickly!
    • Fast/Slow Periods: Numbers that determine how two moving averages (used for spotting divergence) are calculated.
    • Divergence Buy/Sell: Values used as thresholds. When the divergence calculation goes above this value, the script will try to buy. When it goes below the negative of this value, the script will try to sell.
    • Profit/Loss Limits: How much money you want to make or are willing to lose on each trade.
    • Trailing Stop: A feature that automatically adjusts the stop-loss order (an order to automatically close a trade if it loses too much) as the price moves in your favor.
    • Break-Even: Automatically moves your stop-loss to your entry price after a specific profit is reached.
    • Trading Hours: The specific hours of the day (in your local time) that the script is allowed to trade.
    • Basket Profit/Loss: Allows you to set a combined profit or loss target across all open trades. When the total profit or loss hits these levels, all trades will be closed.
    • File Data: A setting to save divergence data to a file for later analysis.
  • Behind-the-Scenes Stuff: The script also sets up some internal codes (like a "Magic Number") to keep track of its own trades and avoid interfering with other trading programs you might be running.

2. Watching the Market (Every Tick):

  • Tick-by-Tick Analysis: The script constantly watches the price movements (every "tick") of the currency pair you've selected.
  • Bar Recognition: The script detects the beginning of new price bars.
  • Order Counting: The script counts how many open trades it currently has for the specific currency pair.

3. Spotting Divergence:

  • Divergence Calculation: This is the core of the strategy. The script uses two "moving averages" (mathematical ways of smoothing out price data over time) with different settings ("Fast Period" and "Slow Period"). It then calculates a "divergence" value based on these averages.
  • Trade Signals:
    • If the divergence value goes above a certain threshold ("DVBuySell"), the script considers it a potential "buy" signal.
    • If the divergence value goes below a negative threshold (negative "DVBuySell"), the script considers it a potential "sell" signal.

4. Taking Action (Trading):

  • Buy Order: If the script sees a "buy" signal and it's allowed to trade (within your specified hours), it places a "buy" order. This means it's betting the price will go up. It also sets:
    • Stop-Loss: An automatic order to close the trade if the price goes too far down, limiting your potential losses.
    • Take-Profit: An automatic order to close the trade if the price goes up to your desired profit level.
  • Sell Order: If the script sees a "sell" signal and it's allowed to trade, it places a "sell" order. This means it's betting the price will go down. It also sets a stop-loss and take-profit.
  • Order Restrictions: The script is designed to only allow one buy/sell order per bar.

5. Managing Open Trades:

  • Watching for Profit/Loss: While a trade is open, the script constantly monitors how much profit or loss it's making.
  • Break-Even Adjustment: If the trade reaches a certain profit level ("PLBreakEven"), the script automatically adjusts the stop-loss to the entry price, guaranteeing you won't lose money on that trade.
  • Trailing Stop Adjustment: If the trade continues to move in your favor, the script automatically adjusts the stop-loss to "trail" the price, locking in profits as the price increases.
  • Closing Trades: The script will automatically close a trade if:
    • It hits your pre-set profit target ("ProfitMade").
    • It hits your pre-set loss limit ("LossLimit").
    • The overall "basket" of trades reaches a certain profit or loss ("BasketProfit" or "BasketLoss").

6. Overall Management:

  • Tracking Performance: The script keeps track of things like the maximum number of open orders, the highest and lowest equity (your account balance plus/minus open trade profits/losses), and the number of times it had to close all trades due to the "BasketProfit" or "BasketLoss" limits.
  • Closing All Trades: There is a function, "CloseEverything", that can be triggered automatically (by reaching BasketProfit/Loss) or manually (if you modify the code) which closes all open trades, and cancels any pending orders.

In essence, this script is designed to automatically trade based on divergence signals, with built-in mechanisms to manage risk (stop-loss), protect profits (trailing stop), and limit overall losses (basket limits). Remember, using this script involves risk, and past performance is not a guarantee of future results.

Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reachedIt can change open orders parameters, due to possible stepping strategyIt Closes Orders by itself
Indicators Used
Moving average indicator
Miscellaneous
Uses files from the file systemIt writes information to fileIt issuies visual alerts to the screen
6 Views
0 Downloads
0 Favorites
[ea]DivergenceTrader_Ron_MT4_v04
/*-----------------------------+
|			       |
| Shared by www.Aptrafx.com    |
|			       |
+------------------------------*/

/*
+--------+
|Divergence Trader
+--------+
*/


// variables declared here are GLOBAL in scope

#property copyright "Ron Thompson"
#property link      "http://www.lightpatch.com/forex"

// user input
extern double Lots=0.1;               // how many lots to trade at a time 
extern int    Slippage=2;             // how many pips of slippage can you tolorate
extern int    Fast_Period=7;
extern int    Fast_Price = PRICE_OPEN;
extern int    Slow_Period=88;
extern int    Slow_Price = PRICE_OPEN;
extern double DVBuySell=0.0011;
extern double DVStayOut=0.0079;
extern double ProfitMade=0;           // how much money do you expect to make
extern double LossLimit=0;            // how much loss can you tolorate
extern double TrailStop=9999;         // trailing stop (999=no trailing stop)
extern int    PLBreakEven=9999;       // set break even when this many pips are made (999=off)
extern int    StartHour=0;            // your local time to start making trades
extern int    StopHour=24;            // your local time to stop making trades
extern int    BasketProfit=75;        // if equity reaches this level, close trades
extern int    BasketLoss=9999;        // if equity reaches this negative level, close trades
extern bool   FileData=false;

// naming and numbering
int      MagicNumber  = 200601182020; // allows multiple experts to trade on same account
string   TradeComment = "Divergence_00_";

// Bar handling
datetime bartime=0;                   // used to determine when a bar has moved
int      bartick=0;                   // number of times bars have moved
int      objtick=0;                   // used to draw objects on the chart
int      tickcount=0;

// Trade control
bool TradeAllowed=true;               // used to manage trades

// Min/Max tracking
double maxOrders;
double maxEquity;
double minEquity;
double CECount;
double CEProc;
double CEBuy;
double CESell;



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

int init()
  {
   int    i;
   string o;
   
   //remove the old objects 
   for(i=0; i<Bars; i++) 
     {
      o=DoubleToStr(i,0);
      ObjectDelete("myx"+o);
      ObjectDelete("myz"+o);
     }
   objtick=0;

   ObjectDelete("Cmmt");
   ObjectCreate("Cmmt", OBJ_TEXT, 0, Time[20], High[20]+(5*Point));
   ObjectSetText("Cmmt","Divergence=0.0020",10,"Arial",White);

   Print("Init happened ",CurTime());
   Comment(" ");
  }

//+----------------+
//| Custom DE-init |
//+----------------+
// Called ONCE when EA is removed from chart

int deinit()
  {
   int    i;
   string o;
   //remove the old objects 
   
   for(i=0; i<Bars; i++) 
     {
      o=DoubleToStr(i,0);
      ObjectDelete("myx"+o);
      ObjectDelete("myz"+o);
     }
   objtick=0;
   
   Print("MAX number of orders ",maxOrders);
   Print("MAX equity           ",maxEquity);
   Print("MIN equity           ",minEquity);
   Print("Close Everything     ",CECount);
   Print("Close Proc           ",CEProc);
   Print("Proc Buy             ",CEBuy);
   Print("Proc Sell            ",CESell);
      
   Print("DE-Init happened ",CurTime());
   Comment(" ");
  }


//+-----------+
//| Main      |
//+-----------+
// Called EACH TICK and each Bar[]

int start()
  {

   double p=Point;
   double spread=Ask-Bid;
   
   int      cnt=0;
   int      gle=0;
   int      OrdersPerSymbol=0;
   int      OrdersBUY=0;
   int      OrdersSELL=0;
   
   int      iFileHandle;
  
   // stoploss and takeprofit and close control
   double SL=0;
   double TP=0;
   double CurrentProfit=0;
   double CurrentBasket=0;
   
   // direction control
   bool BUYme=false;
   bool SELLme=false;
   
   // Trade stuff
   double diverge;
      

   // bar counting
   if(bartime!=Time[0]) 
     {
      bartime=Time[0];
      bartick++; 
      objtick++;
      TradeAllowed=true;
     }

   OrdersPerSymbol=0;
   for(cnt=OrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         OrdersPerSymbol++;
         if(OrderType()==OP_BUY) {OrdersBUY++;}
         if(OrderType()==OP_SELL){OrdersSELL++;}
        }
     }
   if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol;


   //+-----------------------------+
   //| Insert your indicator here  |
   //| And set either BUYme or     |
   //| SELLme true to place orders |
   //+-----------------------------+
   
   diverge=divergence(Fast_Period,Slow_Period,Fast_Price,Slow_Price,0);
   ObjectDelete("Cmmt");
   ObjectCreate("Cmmt", OBJ_TEXT, 0, Time[0], High[0]+(10*p));
   ObjectSetText("Cmmt","Divergence="+DoubleToStr(diverge,4),10,"Arial",White);
   if( diverge>=DVBuySell        && diverge<=DVStayOut )         BUYme=true;
   if( diverge<=(DVBuySell*(-1)) && diverge>=(DVStayOut*(-1)) ) SELLme=true;
   //if( diverge>=DVBuySell        ) BUYme=true;
   //if( diverge<=(DVBuySell*(-1)) ) SELLme=true;
   
   if(FileData)
     {
      tickcount++;
      iFileHandle = FileOpen("iDivergence", FILE_CSV|FILE_READ|FILE_WRITE, ",");
      FileSeek(iFileHandle, 0, SEEK_END);
      FileWrite(iFileHandle, bartick, " ", tickcount, " ", diverge);
      FileFlush(iFileHandle);
      FileClose(iFileHandle);
     }

   //+------------+
   //| End Insert |
   //+------------+

   //ENTRY LONG (buy, Ask) 
   if(TradeAllowed && BUYme)
      {
       //Ask(buy, long)
      if(LossLimit ==0) SL=0; else SL=Ask-((LossLimit+7)*Point );
      if(ProfitMade==0) TP=0; else TP=Ask+((ProfitMade+7)*Point );
      OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,TradeComment,MagicNumber,White);
      gle=GetLastError();
      if(gle==0)
        {
         Print("BUY  Ask=",Ask," bartick=",bartick);
         ObjectCreate("myx"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], High[0]+(5*p));
         ObjectSetText("myx"+DoubleToStr(objtick,0),"B",15,"Arial",Red);
         bartick=0;
         TradeAllowed=false;
        }
         else 
        {
         Print("-----ERROR----- BUY  Ask=",Ask," error=",gle," bartick=",bartick);
        }
     }
        
   //ENTRY SHORT (sell, Bid)
   if(TradeAllowed && SELLme )
     {
      //Bid (sell, short)
      if(LossLimit ==0) SL=0; else SL=Bid+((LossLimit+7)*Point );
      if(ProfitMade==0) TP=0; else TP=Bid-((ProfitMade+7)*Point );
      OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,TradeComment,MagicNumber,Red);
      gle=GetLastError();
      if(gle==0)
        {
         Print("SELL Bid=",Bid," bartick=",bartick); 
         ObjectCreate("myx"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], High[0]+(5*p));
         ObjectSetText("myx"+DoubleToStr(objtick,0),"S",15,"Arial",Red);
         bartick=0;
         TradeAllowed=false;
        }
         else 
        {
         Print("-----ERROR----- SELL Bid=",Bid," error=",gle," bartick=",bartick);
        }
     }

     

   //Basket profit or loss
   CurrentBasket=AccountEquity()-AccountBalance();
   
   if(CurrentBasket>maxEquity) maxEquity=CurrentBasket;
   if(CurrentBasket<minEquity) minEquity=CurrentBasket;
   
   // actual basket closure
   if( CurrentBasket>=BasketProfit || CurrentBasket<=(BasketLoss*(-1)) )
     {
      CloseEverything();
      CECount++;
     }

   // CLOSE order if profit target made
   for(cnt=0;cnt<OrdersTotal();cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber )
        {
        
         if(OrderType()==OP_BUY)
           {
            CurrentProfit=Bid-OrderOpenPrice() ;

            // modify for break even
            if (CurrentProfit >= PLBreakEven*p && OrderOpenPrice()>OrderStopLoss())
              {
               SL=OrderOpenPrice()+(spread*2);
               TP=OrderTakeProfit();
               OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, White);
               gle=GetLastError();
               if(gle==0)
                 {
                  Print("MODIFY BREAKEVEN BUY  Bid=",Bid," bartick=",bartick); 
                  ObjectCreate("myz"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], Low[0]-(7*p));
                  ObjectSetText("myz"+DoubleToStr(objtick,0),"BE",15,"Arial",White);
                 }
                  else 
                 {
                  Print("-----ERROR----- MODIFY BREAKEVEN BUY  Bid=",Bid," error=",gle," bartick=",bartick);
                 }
              }

            // modify for trailing stop
            if(CurrentProfit >= TrailStop*p )
              {
               SL=Bid-(TrailStop*p);
               TP=OrderTakeProfit();
               OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, White);
               gle=GetLastError();
               if(gle==0)
                 {
                  Print ("MODIFY TRAILSTOP BUY  StopLoss=",SL,"  bartick=",bartick,"OrderTicket=",OrderTicket()," CurrProfit=",CurrentProfit); 
                  ObjectCreate("myz"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], Low[0]-(7*p));
                  ObjectSetText("myz"+DoubleToStr(objtick,0),"TS",15,"Arial",White);
                 }
                  else 
                 {
                  Print("-----ERROR----- MODIFY TRAILSTOP BUY  Bid=",Bid," error=",gle," bartick=",bartick);
                 }
              }

            // did we make our desired BUY profit
            // or did we hit the BUY LossLimit
            if((ProfitMade>0 && CurrentProfit>=(ProfitMade*p)) || (LossLimit>0 && CurrentProfit<=((LossLimit*(-1))*p))  )
              {
               OrderClose(OrderTicket(),Lots,Bid,Slippage,White);
               gle=GetLastError();
               if(gle==0)
                 {
                  Print("CLOSE BUY  Bid=",Bid," bartick=",bartick); 
                  ObjectCreate("myz"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], Low[0]-(7*p));
                  ObjectSetText("myz"+DoubleToStr(objtick,0),"C",15,"Arial",White);
                 }
                  else 
                 {
                  Print("-----ERROR----- CLOSE BUY  Bid=",Bid," error=",gle," bartick=",bartick);
                 }
              }
              
           } // if BUY


         if(OrderType()==OP_SELL)
           {

            CurrentProfit=OrderOpenPrice()-Ask;
            
            // modify for break even
            if (CurrentProfit >= PLBreakEven*p && OrderOpenPrice()<OrderStopLoss())
              {
               SL=OrderOpenPrice()-(spread*2);
               TP=OrderTakeProfit();
               OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, Red);
               gle=GetLastError();
               if(gle==0)
                 {
                  Print("MODIFY BREAKEVEN SELL Ask=",Ask," bartick=",bartick);
                  ObjectCreate("myz"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], Low[0]-(7*p));
                  ObjectSetText("myz"+DoubleToStr(objtick,0),"BE",15,"Arial",Red);
                 }
                  else 
                 {
                  Print("-----ERROR----- MODIFY BREAKEVEN SELL Ask=",Ask," error=",gle," bartick=",bartick);
                 }
              }

            // modify for trailing stop
            if(CurrentProfit >= TrailStop*p)
              {
               SL=Ask+(TrailStop*p);
               TP=OrderTakeProfit();
               OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, Red);
               gle=GetLastError();
               if(gle==0)
                 {
                  Print ("MODIFY TRAILSTOP SELL StopLoss=",SL,"  bartick=",bartick,"OrderTicket=",OrderTicket()," CurrProfit=",CurrentProfit); 
                  ObjectCreate("myz"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], Low[0]-(7*p));
                  ObjectSetText("myz"+DoubleToStr(objtick,0),"TS",15,"Arial",Red);
                 }
                  else 
                 {
                  Print("-----ERROR----- MODIFY TRAILSTOP SELL Ask=",Ask," error=",gle," bartick=",bartick);
                 }
              }

            // did we make our desired SELL profit?
            if( (ProfitMade>0 && CurrentProfit>=(ProfitMade*p)) || (LossLimit>0 && CurrentProfit<=((LossLimit*(-1))*p))  )
              {
               OrderClose(OrderTicket(),Lots,Ask,Slippage,Red);
               gle=GetLastError();
               if(gle==0)
                 {
                  Print("CLOSE SELL Ask=",Ask," bartick=",bartick);
                  ObjectCreate("myz"+DoubleToStr(objtick,0), OBJ_TEXT, 0, Time[0], Low[0]-(7*p));
                  ObjectSetText("myz"+DoubleToStr(objtick,0),"C",15,"Arial",Red);
                 }
                  else 
                 {
                  Print("-----ERROR----- CLOSE SELL Ask=",Ask," error=",gle," bartick=",bartick);
                 }
                 
              }

           } //if SELL
           
        } // if(OrderSymbol)
        
     } // for

  } // start()



//+-----------------+
//| 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);
      if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         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);
            CEBuy++;
            break;
         
            //Close opened short positions
            case OP_SELL     :result = OrderClose(myTkt, myLot, myAsk, Slippage, Red);
            CESell++;
            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);
         CEProc++;
        
        } //if
           
     } //for
  
  } // closeeverything




double divergence(int F_Period, int S_Period, int F_Price, int S_Price, int mypos)
  {

   int i;
   
   double maF1, maF2, maS1, maS2;
   double dv1, dv2;
   
   maF1=iMA(Symbol(),0,F_Period,0,MODE_SMA,F_Price,mypos);
   maS1=iMA(Symbol(),0,S_Period,0,MODE_SMA,S_Price,mypos);
   dv1=(maF1-maS1);

   maF2=iMA(Symbol(),0,F_Period,0,MODE_SMA,F_Price,mypos+1);
   maS2=iMA(Symbol(),0,S_Period,0,MODE_SMA,S_Price,mypos+1);
   dv2=((maF1-maS1)-(maF2-maS2));
     
   return(dv1-dv2);
   
  }




Profitability Reports

GBP/CAD Jul 2025 - Sep 2025
0.48
Total Trades 264
Won Trades 86
Lost trades 178
Win Rate 32.58 %
Expected payoff -19.84
Gross Profit 4918.18
Gross Loss -10156.77
Total Net Profit -5238.59
-100%
-50%
0%
50%
100%
GBP/AUD Jul 2025 - Sep 2025
1.27
Total Trades 884
Won Trades 663
Lost trades 221
Win Rate 75.00 %
Expected payoff 4.56
Gross Profit 18926.44
Gross Loss -14899.08
Total Net Profit 4027.36
-100%
-50%
0%
50%
100%
EUR/USD Jul 2025 - Sep 2025
0.00
Total Trades 119
Won Trades 74
Lost trades 45
Win Rate 62.18 %
Expected payoff -11522.61
Gross Profit 1651.50
Gross Loss -1372842.60
Total Net Profit -1371191.10
-100%
-50%
0%
50%
100%
USD/JPY Jan 2025 - Jul 2025
1.06
Total Trades 25
Won Trades 15
Lost trades 10
Win Rate 60.00 %
Expected payoff 1.87
Gross Profit 818.34
Gross Loss -771.59
Total Net Profit 46.75
-100%
-50%
0%
50%
100%
USD/CHF Jan 2025 - Jul 2025
0.68
Total Trades 590
Won Trades 339
Lost trades 251
Win Rate 57.46 %
Expected payoff -8.22
Gross Profit 10141.61
Gross Loss -14992.19
Total Net Profit -4850.58
-100%
-50%
0%
50%
100%
USD/CAD Jan 2025 - Jul 2025
0.11
Total Trades 220
Won Trades 61
Lost trades 159
Win Rate 27.73 %
Expected payoff -20.91
Gross Profit 560.81
Gross Loss -5161.19
Total Net Profit -4600.38
-100%
-50%
0%
50%
100%
NZD/USD Jan 2025 - Jul 2025
0.42
Total Trades 347
Won Trades 149
Lost trades 198
Win Rate 42.94 %
Expected payoff -18.43
Gross Profit 4590.60
Gross Loss -10986.40
Total Net Profit -6395.80
-100%
-50%
0%
50%
100%
GBP/USD Jan 2025 - Jul 2025
0.43
Total Trades 69
Won Trades 30
Lost trades 39
Win Rate 43.48 %
Expected payoff -123.75
Gross Profit 6488.90
Gross Loss -15027.90
Total Net Profit -8539.00
-100%
-50%
0%
50%
100%
GBP/CAD Jan 2025 - Jul 2025
0.97
Total Trades 1865
Won Trades 1354
Lost trades 511
Win Rate 72.60 %
Expected payoff -0.49
Gross Profit 34841.96
Gross Loss -35753.63
Total Net Profit -911.67
-100%
-50%
0%
50%
100%
GBP/AUD Jan 2025 - Jul 2025
0.60
Total Trades 330
Won Trades 181
Lost trades 149
Win Rate 54.85 %
Expected payoff -19.40
Gross Profit 9437.73
Gross Loss -15838.47
Total Net Profit -6400.74
-100%
-50%
0%
50%
100%

Comments