Why does my EA keeps giving negative profit when back testing?

 

I imitate and wrote a same EA with the example in here https://www.mql5.com/en/articles/1510 except the conditions for buy/sell

 Condition to open buy position : RSI below 5 AND Ask price above 200 Day moving average, exit when Ask price is above 5 day moving average.

Condition to open sell position : RSI is above 95 AND Bid price is below 200 Day moving aver age, exit when Bid price is below 5 day moving average.g

 When i back tests i get negative profit everytime which i dont know why. The best part is sometimes it gives me error 134 which means not having enough money.

On a side note, may i know what is shift and ma_shift and how should i fill it in? its a parameter required for iRSI() indicator i didnt know what to write so i just assign 0 to it.

 

heres the code

 

//+------------------------------------------------------------------+
//|                                              My RSI strategy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#include <stderror.mqh> 
#include <stdlib.mqh>  
//All Variables here

extern double UpperBound    =  90;      //set upper bound value for RSI
extern double LowerBound    =  5;      //set lower bound value for RSI
extern double VarPeriod     =  2;      //number of periods
extern double BuyVolume     = 0.1;       //set buying volume(lots)
extern double SellVolume    = 0.1;       //set selling volume(lots)
extern double StopLoss      = 25;       //Set the stop loss level
extern double TakeProfit    = 25;       //Set the take profit level
extern double TrailingStop = 30;


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   Alert ("The minimum stoploss and take profit is " + MarketInfo(Symbol(),MODE_STOPLEVEL));
   double CurrentRSI;                  //Finds out the RSI for now
   double MA200;                       //200 day Moving Average           
   double MA5;                         //5 day Moving Average
   double CurrentAsk;                  //Finds out the Ask price now
   double CurrentBid;                  //Finds out the Bid price now
  
   
   CurrentAsk = MarketInfo(Symbol(), MODE_ASK);
   CurrentBid = MarketInfo(Symbol(), MODE_BID);
   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);
   
   Alert("Bid is " + CurrentBid);
   Alert("Ask is " + CurrentAsk);
   Alert("200 Day Moving Average is " + MA200); 
   Alert("5 Day Moving Average is " + MA5); 
   Alert("RSI Index is " + CurrentRSI);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   
   double CurrentRSI;                  //Finds out the RSI for now
   double MA200;                       //200 day Moving Average           
   double MA5;                         //5 day Moving Average
   double CurrentAsk;                  //Finds out the Ask price now
   double CurrentBid;                  //Finds out the Bid price now
   int Ticket;
   int cnt;
   int Ticket2;
   int Total;
   
   CurrentAsk = MarketInfo(Symbol(), MODE_ASK);
   CurrentBid = MarketInfo(Symbol(), MODE_BID);
   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);
   
   
    if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
   
   if(AccountFreeMargin()<(1000*BuyVolume))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
   
    if (CurrentRSI < LowerBound && MarketInfo(Symbol(), MODE_ASK) > MA200 ) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, BuyVolume, Ask, 3, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ), "Buy.", 111,0,Yellow)   ;       //execute buy order
   
    if(Ticket>0)
           {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("BUY order opened : ",OrderOpenPrice());
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   return(0);
  }
  
 
  if (CurrentRSI > UpperBound && MarketInfo(Symbol(), MODE_BID) > MA200) {     //Condition to execute sell entry
  
       Ticket2 = OrderSend(Symbol(), OP_SELL, SellVolume, Bid, 3, Ask + ( StopLoss * Point ), Bid - ( TakeProfit * Point ), "Sell.",000, 0, Yellow)  ;     //execute sell order
       if(Ticket2>0)
           {
            if(OrderSelect(Ticket2,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("SELL order opened : ",OrderOpenPrice());
           }
         if (Ticket2<0) {
          Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
        }
       return(0);
   
   } 
   
   Total=OrdersTotal();
    for(cnt=0;cnt<Total;cnt++)
  {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())  // check for symbol and check for opened position 
     {
if(OrderType()==OP_BUY)   // long position is opened
{
   
   if (CurrentAsk > MA5){      //condition to close long position
    OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close long position
   return(0); // exit
   
   if(TrailingStop>0)  
              {                 
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                     return(0);
                    }
                 }
              }
   
   }
   }
   
   if(OrderType()==OP_SELL)   // long position is opened
{
   if(CurrentBid < MA5){       //condition to close short position
   OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close short position
   return(0); // exit
   }
   
  if(TrailingStop>0)  
              {                 
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                     return(0);
                    }
                 }
              }
   }
   }
   }
   
    
   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

RSI parameter set to 0, no result as . . . Nothing

RSI 0 

At least 2

rsi 2 

 

Not every EA and not every Strategy is profitable

With using the strategytester do it also with visual mode on  and place on the chart the indicators you are with the same settings you have set in the EA

   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);

 Every tick you are calculating the values above and they can change with every tick because you have chosen            " ....,PRICE_CLOSE, 0);"

The values you see on chart when the test is done aren't the values you had when a trade opens...

   if(AccountFreeMargin()<(1000*BuyVolume))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
   
    if (CurrentRSI < LowerBound && MarketInfo(Symbol(), MODE_ASK) > MA200 ) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, BuyVolume, Ask, 3, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ), "Buy.", 111,0,Yellow)   ;       //execute buy order
   
    if(Ticket>0)
           {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("BUY order opened : ",OrderOpenPrice());
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   return(0);
  }
  

When the conditions are met for open a buy  ,  and the tester opens a buy ,then there is no check if you already have one opened with same condition.

After a buy opens the next tick you can have again the condition for opening a trade. 

This opening of trades can work in StrategyTester but in real time on demo on real account,

you can get errors you don't see in tester.  For example chosing "3" Slippage is too low for trading on '5 digit'  account

Sending the OrderSend  with a value for OrderStopLoss() and OrdertakeProfit()   > 0  will fail for ECN accounts 

   Total=OrdersTotal();
    for(cnt=0;cnt<Total;cnt++)
  {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())  // check for symbol and check for opened position 
     {
In the OrderSend and in this loop for checking trades I miss you make use of your OrderMagicNumber()

 and I see the loop is counting up instead of counting down while you also want it close positions if needed    So another error

The OrderModify can happen with every Point  this can lead to errors from broker like tradecontext too busy

 
FXEWEN:

RSI parameter set to 0, no result as . . . Nothing

 

At least 2

 

 I did set the iRSI period to 2....

 
cyxstudio:


On a side note, may i know what is shift and ma_shift and how should i fill it in? its a parameter required for iRSI() indicator i didnt know what to write so i just assign 0 to it.


Not sure where you got that information from but it's incorrect . . .

iRSI()   double iRSI(string symbol, int timeframe, int period, int applied_price, int shift)

perhaps you meant iMA()  ?   shift is the bar number of the time that you want the MA for,  ma_shift allows you to move the MA value relative to the bar number,  so if you give it a shift of 5 and a ma_shift of -2 it will give you the MA for bar 7,  you would need to experiment with this a little to check I'm correct,  in principle I am.


 
deVries:


With using the strategytester do it also with visual mode on  and place on the chart the indicators you are with the same settings you have set in the EA

 Every tick you are calculating the values above and they can change with every tick because you have chosen            " ....,PRICE_CLOSE, 0);"


 

 

 what should i choose for the shift value   " ....,PRICE_CLOSE, 0);" then?

 

 
cyxstudio:

what should i choose for the shift value   " ....,PRICE_CLOSE0);" then?

What does your strategy call for  ?  use that.  Use bar 0 if you want,  but it will "re-paint"  even if you use PRICE_CLOSE,  Close[0]  (close price of bar 0)  == Bid.  When Bar 0 finally closes it is no longer Bar 0 it becomes Bar 1.
 
deVries:

Not every EA and not every Strategy is profitable

With using the strategytester do it also with visual mode on  and place on the chart the indicators you are with the same settings you have set in the EA

 Every tick you are calculating the values above and they can change with every tick because you have chosen            " ....,PRICE_CLOSE, 0);"

The values you see on chart when the test is done aren't the values you had when a trade opens...

When the conditions are met for open a buy  ,  and the tester opens a buy ,then there is no check if you already have one opened with same condition.

After a buy opens the next tick you can have again the condition for opening a trade. 

This opening of trades can work in StrategyTester but in real time on demo on real account,

you can get errors you don't see in tester.  For example chosing "3" Slippage is too low for trading on '5 digit'  account

Sending the OrderSend  with a value for OrderStopLoss() and OrdertakeProfit()   > 0  will fail for ECN accounts 

In the OrderSend and in this loop for checking trades I miss you make use of your OrderMagicNumber()

 and I see the loop is counting up instead of counting down while you also want it close positions if needed    So another error

The OrderModify can happen with every Point  this can lead to errors from broker like tradecontext too busy

 

 

 

 

 

I've redone everything and fixed the loop,slippage, fixed the moving average and RSI values, made sure that every opened positions are closed before start new position. but when i backtest it, nothing happens, no buy/sell were executed... whats the problem with it again?

 

//+------------------------------------------------------------------+
//|                                                My Strategy 4.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

extern double StopLoss = 40;
extern double TakeProfit = 40;
extern double Lots = 0.1;
extern double Slippage = 10;
extern double RSINow;
extern double MA200;
extern double MA5;
extern bool A1 = false;
extern bool A2 = false;
extern int Ticket;
extern int Ticket2;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+ 
int init()
  {
//----
   Alert("Minimum Stop Level is " + MarketInfo(Symbol(), MODE_STOPLEVEL)); //find out minimum stop loss
   
   RSINow = iRSI(NULL, 1440, 2, PRICE_CLOSE, 0);			//calculates the RSI value for 2 days
   MA200 = iMA(NULL, 1440, 200, 0, MODE_SMA, PRICE_CLOSE,0);		//calculates the moving average for 200 days
   MA5 = iMA(NULL, 1440, 5, 0, MODE_SMA, PRICE_CLOSE,0);     		//calculates the moving average for 5 days
   Alert(RSINow);
   Alert(MA200);
   Alert(MA5);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----

   
   
   //check if a long position is possible, A is false means no buy trade is open , execute buy when RSI drops below 5 and when Ask price rises above 200 day moving average
   if (A1 == false && RSINow < 5 && Ask > MA200) {
   
   Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ));
   
   if(Ticket>0) {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) {
               Print("BUY order opened : ",OrderOpenPrice());
               A1 = true;
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   }
   } 
   
   
   
     //check if a short position is possible, A2 is false means no sell trade is open , execute sell when RSI rises above 95 and when Bid price drops below 200 day moving average

   if (A2 == false && RSINow > 95 && Bid < MA200) {
   
   Ticket2 = OrderSend(Symbol(), OP_BUY, Lots, Bid, Slippage, Ask + ( StopLoss * Point ), Bid - ( TakeProfit * Point ));
   if(Ticket2>0) {
            if(OrderSelect(Ticket2,SELECT_BY_TICKET,MODE_TRADES)) {
               Print("SELL order opened : ",OrderOpenPrice());
               A2 = true;
           }
         if (Ticket2 < 0) {
         Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
         }
   }
   
   } 
   
   
   //check if buy position can be closed, once Ask price rises above 5 day moving average, its time to close the position.
   
   if ((A1 == true) && (Ask > MA5)) {
   OrderClose(Ticket, Lots, Bid, Slippage, Violet);
   A1 = false;
   return(0);
   }
   
   
   
   
   //check if sell position can be closed, if Bid price drops below 5 day moving average, close sell position.
   
   if ((A2 == true) && (Bid < MA5)) {
   OrderClose(Ticket2, Lots, Bid, Slippage, Violet);
   A2 = false;
   return(0);
   }
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
cyxstudio:

I've redone everything and fixed the loop,slippage, fixed the moving average and RSI values, made sure that every opened positions are closed before start new position. but when i backtest it, nothing happens, no buy/sell were executed... whats the problem with it again?

 


no the loop is not fixed it is removed with that the problem is bigger

.  you are using A1 and A2 which get value true the moment trade opens

   but what will happen if your power suply of your pc gets down and you have to restart your pc and metatrader.

   You have to check that moment if there are trades open from your EA

   How you gonna do that ???? 

   To make it more easy use a specific OrderMagicNumber opening and checking your trades

the moving average is now not moved some bars in future ok

but you calculate it only in section init()  this will only run in starting up your Expert Advisor

I miss it in Start() ....    Why did you remove it there ??? 

 .

 

Have rewritten your code and tried a test   see also the settings  

Not with the best backtestdata but if you do it right it can be profitable

Strategy Tester Report
RSI_strategy_cyxstudio
AlpariUK-Demo - Micro+Classic (Build 451)

SymbolEURUSD (Euro vs US Dollar)
PeriodDaily (D1) 2010.10.01 00:00 - 2013.01.29 00:00 (2010.10.01 - 2013.01.30)
ModelEvery tick (the most precise method based on all available least timeframes)
ParametersRSIPeriod=3; UpperBound=90; LowerBound=5; MASlowPeriod=200; MAFastPeriod=5; Lots=0.1; StopLoss=60; TakeProfit=120; TrailingStop=40; MagicNumber=54333; CommentEA="RSI strategy"; Slippage.Pips=3;
Bars in test1603Ticks modelled40187739Modelling qualityn/a
Mismatched charts errors2062601
Initial deposit3000.00
Total net profit967.18Gross profit2226.34Gross loss-1259.16
Profit factor1.77Expected payoff13.62
Absolute drawdown107.10Maximal drawdown327.47 (7.99%)Relative drawdown7.99% (327.47)
Total trades71Short positions (won %)66 (69.70%)Long positions (won %)5 (80.00%)
Profit trades (% of total)50 (70.42%)Loss trades (% of total)21 (29.58%)
Largestprofit trade120.07loss trade-60.00
Averageprofit trade44.53loss trade-59.96
Maximumconsecutive wins (profit in money)8 (424.26)consecutive losses (loss in money)3 (-179.93)
Maximalconsecutive profit (count of wins)424.26 (8)consecutive loss (count of losses)-179.93 (3)
Averageconsecutive wins4consecutive losses2

 

 

 
deVries:

Have rewritten your code and tried a test   see also the settings  

Not with the best backtestdata but if you do it right it can be profitable


Total trades71Short positions (won %)66 (69.70%)Long positions (won %)5 (80.00%)





That would makes me think there is something not right.