[ea]ShashiR2_MT4_v01d_MultiPair

Download script
Author: Ron Thompson
Profit factor:
1.35

This script is an automated trading system designed to manage multiple currency pairs simultaneously using a logic based on the Relative Strength Index (RSI). It is structured to handle high-frequency data and execute trades across various markets with specific risk management protocols.

Multi-Pair Management

One of the core features of this system is its ability to scan and trade a wide variety of currency pairs at once. Instead of focusing on just one chart, the script organizes a list of supported pairs (such as EURUSD, GBPJPY, etc.) and rotates through them systematically. It ensures that it does not open duplicate positions on the same pair by checking for existing active orders before initiating new ones.

Entry Logic: RSI Analysis

The system makes trading decisions based on the Relative Strength Index (RSI), specifically looking at daily price movements over a short period. The logic is divided into two distinct modes, which can be toggled by the user:

  • Standard Mode: This looks for specific momentum patterns. It triggers a "Buy" signal if the RSI values are decreasing steadily below a certain midpoint, or a "Sell" signal if they are increasing steadily above that midpoint.
  • Trend-Following Mode: This reverses the logic to align with prevailing market trends. In this mode, the system looks for specific momentum shifts to identify entries that favor the current direction of the market.

Trade Execution and Safety

To ensure reliability, the script includes a "retry" mechanism. If an order fails to open due to a temporary network glitch or broker delay, the system will automatically attempt to place the order again several times before moving on. This ensures that the strategy remains consistent even in volatile conditions.

Automated Risk Management

Once a trade is opened, the script takes over active management using three primary tools:

  1. Profit and Loss Limits: The user can define specific "Hard" targets. If a trade reaches a predetermined profit level or hits a maximum loss limit, the script will automatically close the position to lock in results.
  2. Break-Even Protection: This feature monitors the price as it moves in your favor. Once the trade reaches a specific profit milestone, the script moves the "Stop Loss" to the entry price. This effectively eliminates the risk of a winning trade turning into a loss.
  3. Trailing Stop: For further protection during large price swings, the system can follow the price upward (for buys) or downward (for sells). As the price moves favorably, the stop loss "trails" behind it at a set distance, allowing you to capture as much profit as possible while protecting the gains already made.

Logging and Monitoring

The script maintains a detailed internal log. It records every action—including successful trades, modifications to stop losses, and any errors encountered—into a dedicated file. This allows for comprehensive auditing of how the system performed over time without cluttering the visual interface of the trading platform.

Price Data Components
Series array that contains close prices for each barSeries array that contains open time of each bar
Orders Execution
Checks for the total of open ordersIt can change open orders parameters, due to possible stepping strategyIt automatically opens orders when conditions are reachedIt Closes Orders by itself
Indicators Used
Relative strength index
Miscellaneous
Uses files from the file systemIt writes information to file
10 Views
0 Downloads
0 Favorites
[ea]ShashiR2_MT4_v01d_MultiPair
//+-----------------------------+
//|Shashi RSI-R2 from Shell_20b |
//+-----------------------------+
#property copyright "Ron Thompson"
#property link      "http://www.ForexMT4.com/"

// 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 bool   WithTrend           =   false   ;
extern string Pairs               =       "AUDJPY,AUDNZD,AUDUSD,CHFJPY,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURUSD,GBPCHF,GBPJPY,GBPUSD,NZDJPY,NZDUSD,USDCAD,USDCHF,USDJPY" ;
extern double Lots                =       0.2 ;
extern double ProfitMade          =     130   ; 
extern double LossLimit           =     100   ;
extern double BreakEven           =       0   ;
extern double TrailStop           =       0   ;
extern bool   KillLogging         =    true   ;


// MULTI Pair handling
// hard coded to use current symbol() for testing
       string               Pairz[100];
static bool          TradeAllowed[100];
static datetime           bartime[100];
       int    ptrPMAX;
       int    ptrPairz=0;
       string mySymbol;
       double bid;
       double ask;
   

// Trade control
double        myPoint;                              // support for 3/5 decimal places
int           Slippage=2;                           // how many pips of slippage can you tolorate

int           loopcount;                            // count of order attempts
int           maxloop=20;                           // maximum number of attempts to handle errors
int           LL2SL=50;                             // LossLimit to StopLoss server spread
int           MagicNumber  = 142538004;             // allows multiple experts to trade on same account
string        TradeComment = "_ShashiM1d.txt";      // where to log information

// Statistics
int           maxOrders;                            // statistic for maximum numbers or orders open at one time

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


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

int init()
  {
   int OPS=0;
   int i;
   int cnt;

   // trades turned on only if there is NO open order
   // MULTIPLE order systems may need to change this 
   for (i=0; i<100; i++)
     {
      mySymbol=Pairz[i];
      OPS=0;
      for(cnt=OrdersTotal();cnt>=0;cnt--)
        {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) OPS++;
        }
      if(OPS==0) TradeAllowed[i]=true; else TradeAllowed[i]=false;

     }//for

   
   // Split the user string into an array 
   int ipair=0;
   int pcomma=0;
   int comma=0;

   //clear the array 
   for (i=0; i<100; i++)
     {
      Pairz[i]="";
     }

   
   while (true)
     {
      // if backtesting then set array to current symbol only
      if(IsTesting())
        {
         Pairz[0]=Symbol();
         ptrPMAX=1;
         break;
        }
     
      // if nothing in the extern that we can use
      // then set array to current symbol only
      if(StringLen(Pairs)<6)
        {
         Pairz[0]=Symbol();
         ptrPMAX=1;
         break;
        }
     
      //save the old comma
      pcomma=comma;
      // find the next comma
      comma=StringFind(Pairs, ",", pcomma+1);
      // Gather trailing pair (no comma following last pair)
      // then leave (accounts for one pair on line)
      if(comma<0)
        {
         Pairz[ipair]=StringSubstr(Pairs, pcomma+1, comma-pcomma);
         ptrPMAX=ipair;
         Print(ipair+" "+Pairz[ipair]);      
         break;
        }
      // store the pair into an array
      if(ipair==0) Pairz[ipair]=StringSubstr(Pairs, pcomma, comma-pcomma);
      if(ipair >0) Pairz[ipair]=StringSubstr(Pairs, pcomma+1, comma-pcomma-1);
      
      Print(ipair+" "+Pairz[ipair]);      
      
      // increment pointer for next elemant
      ipair++;
      if(ipair>100) break;
     }
   
   
   Comment(" ");
   logwrite(TradeComment,"Init Complete");



  }

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

int deinit()
  {
   // always indicate deinit statistics
   logwrite(TradeComment,"MAX number of orders "+maxOrders);
   
   Comment(" ");
   logwrite(TradeComment,"DE-Init Complete");
  }


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

int start()
  {

   // The following MUST be done before anything else

      // step through each pair, once a tick
      ptrPairz++;
      if(ptrPairz>=ptrPMAX) ptrPairz=0;
      mySymbol=Pairz[ptrPairz];
      
      Comment("Now trading -"+mySymbol+"- at position "+ptrPairz );      
   
      // get normalized Point based on Broker decimal places
      // every tick, since we may be using multi-pairs
      myPoint = SetPoint();

   // end 'MUST'


   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;
   double CurrentBasket=0;
     
   // direction control
   bool BUYme=false;
   bool SELLme=false;

   double MaCurrent;
   double MaPrevious;


   //safety counter
   int   loopcount=0;


   OrdersPerSymbol=0;
   for(cnt=OrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++;
     }
   // keep some statistics
   if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol;


   //uncomment for MULTIPLE trades per bar 
   //if(OrdersPerSymbol==0) TradeAllowed[ptrPairz]=true;


   // bar counting
   if(bartime[ptrPairz]!=iTime(mySymbol, PERIOD_D1, 0) ) 
     {
      bartime[ptrPairz]=iTime(mySymbol, PERIOD_D1, 0) ;

      //uncomment for SINGLE trade per bar 
      if(OrdersPerSymbol==0) TradeAllowed[ptrPairz]=true;

      //+-----------------------------+
      //| Code here will execute once |
      //| at the OPEN of a NEW BAR    |
      //|                             |
      //| NOTE: use 'tf1' for any     |
      //|       indicator or iCustom  |       
      //|       timeframe parameter   |
      //+-----------------------------+

      
      double RSI1=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,1);
      double RSI2=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,2);
      double RSI3=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,3);
      
      if(WithTrend==false && RSI3<50 && RSI2<RSI3 && RSI1<RSI2)   BUYme=true;
      if(WithTrend==false && RSI3>50 && RSI2>RSI3 && RSI1>RSI2)  SELLme=true;

      if(WithTrend==true  && RSI1<50 && RSI2<RSI3 && RSI1<RSI2)  SELLme=true;
      if(WithTrend==true  && RSI1>50 && RSI2>RSI3 && RSI1>RSI2)   BUYme=true;
         
      //+------------+
      //| End Insert |
      //+------------+

     }



     
   //+-----------------------------+
   //| Insert your indicator here  |
   //| And set either BUYme or     |
   //| SELLme true to place orders |
   //|                             |
   //| NOTE: use 'tf1' for any     |
   //|       indicator or iCustom  |       
   //|       timeframe parameter   |
   //+-----------------------------+

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

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

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


   //
   // Order Management
   //


   //Basket profit


   // Basket profit or loss - count the profit/loss
   // from this EA & Symbol()& magicnumber only
   // calculation can be done in PIPS or DOLLARS

   CurrentBasket=0;
   for(cnt=OrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber)
        {
         // add up pips
         //if(OrderType()==OP_BUY  ) CurrentBasket=CurrentBasket+(  Close[0]-OrderOpenPrice()         );
         //if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( (Close[0]-OrderOpenPrice()) * (-1) );
         //add up dollars
         if(OrderType()==OP_BUY  ) CurrentBasket=CurrentBasket+(  OrderProfit() );
         if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+(  OrderProfit() );
        }
     }


   for(cnt=OrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber )
        {
        
         if(OrderType()==OP_BUY)
           {
            bid=MarketInfo(mySymbol,MODE_BID);
            CurrentProfit=(bid-OrderOpenPrice()) ;

            //
            // Modify for break even
            //=======================
            //
            // OrderStopLoss will be equal to OrderOpenPrice if this event happens
            // thus it will only ever get executed one time per ticket
            if( BreakEven>0 )
              {
               if (CurrentProfit >= BreakEven*myPoint && OrderOpenPrice()>OrderStopLoss())
                 {
                  bid=MarketInfo(mySymbol,MODE_BID);
                  ask=MarketInfo(mySymbol,MODE_ASK);
                  SL=OrderOpenPrice()+(ask-bid);
                  TP=OrderTakeProfit();
                  OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, White);
                  gle=GetLastError();
                  if(gle==0)
                    {
                     logwrite(TradeComment,"MODIFY BUY BE Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
                    }
                     else 
                    {
                     logwrite(TradeComment,"-----ERROR----- MODIFY BUY  BE Bid="+Bid+" error="+gle+" "+ErrorDescription(gle));
                    }
                 }
              }


            //
            // check for trailing stop
            //=========================
            //
            // This starts trailing after 'TrailStop' pips of profit
            if( TrailStop>0 && iClose(mySymbol,PERIOD_D1,0)>OrderOpenPrice()+(TrailStop*myPoint) )  
              {                 
               bid=MarketInfo(mySymbol,MODE_BID);
               if( OrderStopLoss() < bid-(TrailStop*myPoint) )
                 {
                  SL=bid-(TrailStop*myPoint);
                  TP=OrderTakeProfit();
                  OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,White);
                  gle=GetLastError();
                  if(gle==0)
                    {
                     logwrite(TradeComment,"MODIFY BUY TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
                    }
                     else 
                    {
                     logwrite(TradeComment,"-----ERROR----- MODIFY BUY TS Bid="+bid+" error="+gle+" "+ErrorDescription(gle)+" ");
                    }
                 }
              }


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

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


         if(OrderType()==OP_SELL)
           {
            ask=MarketInfo(mySymbol,MODE_ASK);
            CurrentProfit=(OrderOpenPrice()-ask);
            //logwrite(TradeComment,"SELL CurrentProfit="+CurrentProfit/myPoint+" CurrentBasket="+CurrentBasket/myPoint);

           
            //
            // Modify for break even
            //=======================
            //
            // OrderStopLoss will be equal to OrderOpenPrice if this event happens
            // thus it will only ever get executed one time per ticket
            if( BreakEven>0 )
              {
               if (CurrentProfit >= BreakEven*myPoint && OrderOpenPrice()<OrderStopLoss())
                 {
                  bid=MarketInfo(mySymbol,MODE_BID);
                  ask=MarketInfo(mySymbol,MODE_ASK);
                  SL=OrderOpenPrice()-(ask-bid);
                  TP=OrderTakeProfit();
                  OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, Red);
                  gle=GetLastError();
                  if(gle==0)
                    {
                     logwrite(TradeComment,"MODIFY SELL BE Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
                    }
                     else 
                    {
                     logwrite(TradeComment,"-----ERROR----- MODIFY SELL BE Ask="+ask+" error="+gle+" "+ErrorDescription(gle));
                    }
                 }
              }


            //
            // check for trailing stop
            //=========================
            //
            // This starts trailing after 'TrailStop' pips of profit
            if( TrailStop>0 && iClose(mySymbol,PERIOD_D1,0)<OrderOpenPrice()-(TrailStop*myPoint) )  


              {                 
               ask=MarketInfo(mySymbol,MODE_ASK);
               if( OrderStopLoss() > ask+(TrailStop*myPoint) )
                 {
                  SL=ask+(TrailStop*myPoint);
                  TP=OrderTakeProfit();
                  OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,Red);
                  gle=GetLastError();
                  if(gle==0)
                    {
                     logwrite(TradeComment,"MODIFY SELL TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
                    }
                     else 
                    {
                     logwrite(TradeComment,"-----ERROR----- MODIFY SELL TS Ask="+ask+" error="+gle+" "+ErrorDescription(gle));
                    }

                 }

              }


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

            // Did we take a loss
            //====================
            if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint) )
              {
               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("     "+mySymbol+" "+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(mySymbol+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
   if(myhandle>0)
     {
      FileSeek(myhandle,0,SEEK_END);
      FileWrite(myhandle, "     "+mySymbol+" "+mydata+" "+gregorian);
      FileClose(myhandle);
     }
  } 



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

      // PLACE order is independent of MODIFY order. 
      // This is mandatory for ECNs and acceptable for retail brokers

      loopcount=0;
      while(true)          
        {
         bid=MarketInfo(mySymbol,MODE_BID);
         ask=MarketInfo(mySymbol,MODE_ASK);

         // place order - NO TP OR SL
         ticket=OrderSend(mySymbol,OP_BUY,Lots,ask,Slippage,0,0,TradeComment,MagicNumber,White);
         gle=GetLastError();
         if(gle==0)
           {
            logwrite(TradeComment,"BUY PLACED Ticket="+ticket+" Ask="+ask+" Lots="+Lots);
            TradeAllowed[ptrPairz]=false;
            break;
           }
          else 
           {
            logwrite(TradeComment,"-----ERROR-----  Placing BUY order: Lots="+Lots+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); 
            
            RefreshRates();
            Sleep(500);

            // give up after loopcount tries
            loopcount++;
            if(loopcount>maxloop)
              {
               logwrite(TradeComment,"-----ERROR-----  Giving up on placing BUY order"); 
               return(gle);
              }
           }
        }//while - place order 


      // modify the order for users TP & SL
      loopcount=0;
      while(true)
        {
         bid=MarketInfo(mySymbol,MODE_BID);
         ask=MarketInfo(mySymbol,MODE_ASK);

         // don't set TP and SL both to zero, they're already there
         if(LossLimit==0 && ProfitMade==0) break;
         
         if(LossLimit  ==0) SL=0;
         if(ProfitMade ==0) TP=0;
         if(LossLimit   >0) SL=ask-((LossLimit+LL2SL)*myPoint );
         if(ProfitMade  >0) TP=ask+((ProfitMade+LL2SL)*myPoint );
         OrderModify(ticket,OrderOpenPrice(),SL,TP,0,White);
         gle=GetLastError();
         if(gle==0)
           {
            logwrite(TradeComment,"BUY OPENMOD Ticket="+ticket+" Ask="+ask+" Lots="+Lots+" SL="+SL+" TP="+TP);
            break;
           }
          else 
           {
            logwrite(TradeComment,"-----ERROR-----  Modifying 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)
              {
               logwrite(TradeComment,"-----ERROR-----  Giving up on modifying BUY order"); 
               return(gle);
              }
           }
        }//while - modify order
        
        
     }//BUYme



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

      // PLACE order is independent of MODIFY order. 
      // This is mandatory for ECNs and acceptable for retail brokers

      loopcount=0;
      while(true)
        {
         bid=MarketInfo(mySymbol,MODE_BID);
         ask=MarketInfo(mySymbol,MODE_ASK);

         ticket=OrderSend(mySymbol,OP_SELL,Lots,bid,Slippage,0,0,TradeComment,MagicNumber,Red);
         gle=GetLastError();
         if(gle==0)
           {
            logwrite(TradeComment,"SELL PLACED Ticket="+ticket+" Bid="+bid+" Lots="+Lots);
            TradeAllowed[ptrPairz]=false;
            break;
           }
            else 
           {
            logwrite(TradeComment,"-----ERROR-----  placing 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)
              {
               logwrite(TradeComment,"-----ERROR-----  Giving up on placing SELL order"); 
               return(gle);
              }
           }
        }//while

      
      // modify the order for users TP & SL
      loopcount=0;
      while(true)
        {
         bid=MarketInfo(mySymbol,MODE_BID);
         ask=MarketInfo(mySymbol,MODE_ASK);

         // don't set TP and SL both to zero, they're already there
         if(LossLimit==0 && ProfitMade==0) break;
         
         if(LossLimit  ==0) SL=0;
         if(ProfitMade ==0) TP=0;
         if(LossLimit   >0) SL=bid+((LossLimit+LL2SL)*myPoint );
         if(ProfitMade  >0) TP=bid-((ProfitMade+LL2SL)*myPoint );
         OrderModify(ticket,OrderOpenPrice(),SL,TP,0,Red);
         gle=GetLastError();
         if(gle==0)
           {
            logwrite(TradeComment,"SELL OPENMOD Ticket="+ticket+" Bid="+bid+" Lots="+Lots+" SL="+SL+" TP="+TP);
            break;
           }
            else 
           {
            logwrite(TradeComment,"-----ERROR-----  modifying 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)
              {
               logwrite(TradeComment,"-----ERROR-----  Giving up on placing SELL order"); 
               return(gle);
              }
           }

        }//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)
     {
      bid=MarketInfo(mySymbol,MODE_BID);

      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)
        {
         logwrite(TradeComment,"-----ERROR-----  Giving up on closing BUY order"); 
         return(gle);
        }
                     
     }//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)
     {
      ask=MarketInfo(mySymbol,MODE_ASK);

      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)
        {
         logwrite(TradeComment,"-----ERROR-----  Giving up on closing SELL order"); 
         return(gle);
        }
                 
     }//while                 
  }      


// Function to correct the value of Point
// for brokers that add an extra digit to price
// Courtesy of Robert Hill

double SetPoint()
  {
   double mPoint;
   int    digits=MarketInfo(mySymbol,MODE_DIGITS);

   if (digits < 4)
     {
      mPoint = 0.01;
     }
   else
     {
      mPoint = 0.0001;
     }
  
   return(mPoint);
  }

Profitability Reports

PERFORMANCE BY SYMBOL

Expected payoff

Average expected payoff across the available backtests for each symbol.

Positive Negative
6 reports
USD/CAD Jul 2025 - Sep 2025
4.15
Total Trades 5
Won Trades 4
Lost trades 1
Win Rate 80.00 %
Expected payoff 90.84
Gross Profit 598.40
Gross Loss -144.21
Total Net Profit 454.19
-100%
-50%
0%
50%
100%
GBP/USD Jul 2025 - Sep 2025
1.85
Total Trades 10
Won Trades 6
Lost trades 4
Win Rate 60.00 %
Expected payoff 67.62
Gross Profit 1476.20
Gross Loss -800.00
Total Net Profit 676.20
-100%
-50%
0%
50%
100%
USD/CAD Oct 2024 - Jan 2025
0.64
Total Trades 9
Won Trades 3
Lost trades 6
Win Rate 33.33 %
Expected payoff -34.06
Gross Profit 552.74
Gross Loss -859.30
Total Net Profit -306.56
-100%
-50%
0%
50%
100%
GBP/CAD Jul 2025 - Sep 2025
0.56
Total Trades 10
Won Trades 3
Lost trades 7
Win Rate 30.00 %
Expected payoff -44.30
Gross Profit 557.34
Gross Loss -1000.37
Total Net Profit -443.03
-100%
-50%
0%
50%
100%
GBP/AUD Oct 2025 - Feb 2026
0.46
Total Trades 19
Won Trades 5
Lost trades 14
Win Rate 26.32 %
Expected payoff -56.37
Gross Profit 914.70
Gross Loss -1985.66
Total Net Profit -1070.96
-100%
-50%
0%
50%
100%
GBP/USD Oct 2024 - Jan 2025
0.43
Total Trades 8
Won Trades 2
Lost trades 6
Win Rate 25.00 %
Expected payoff -84.97
Gross Profit 520.20
Gross Loss -1200.00
Total Net Profit -679.80
-100%
-50%
0%
50%
100%

Comments