Perché il mio EA continua a dare profitti negativi durante il back testing?

 

Ho imitato e scritto lo stesso EA con l'esempio qui https://www.mql5.com/en/articles/1510 tranne le condizioni di acquisto/vendita

Condizione per aprire una posizione di acquisto: RSI inferiore a 5 E prezzo Ask sopra la media mobile a 200 giorni, uscire quando il prezzo Ask è sopra la media mobile a 5 giorni.

Condizione per aprire una posizione di vendita: RSI è superiore a 95 E il prezzo Bid è inferiore alla media mobile a 200 giorni, uscire quando il prezzo Bid è inferiore alla media mobile a 5 giorni.

Quando faccio i back test ottengo sempre un profitto negativo e non so perché. La parte migliore è che a volte mi dà l'errore 134 che significa non avere abbastanza soldi.

In una nota a margine, posso sapere cos'è shift e ma_shift e come dovrei compilarlo? è un parametro richiesto per l'indicatore iRSI() e non sapevo cosa scrivere, così ho semplicemente assegnato 0 ad esso.

Ecco il codice

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

Parametro RSI impostato su 0, nessun risultato come . . . Niente

RSI 0

Almeno 2

rsi 2

 

Non tutti gli EA e non tutte le strategie sono redditizie

Quando usi lo strategytester fallo anche con la modalità visiva attiva e metti sul grafico gli indicatori che hai con le stesse impostazioni che hai impostato nell'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);

Ogni tick stai calcolando i valori di cui sopra e possono cambiare ad ogni tick perché hai scelto "....,PRICE_CLOSE, 0);"

I valori che vedi sul grafico quando il test è fatto non sono i valori che hai quando si apre un trade...

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

Quando le condizioni sono soddisfatte per aprire un acquisto, e il tester apre un acquisto, allora non c'è nessun controllo se ne hai già uno aperto con le stesse condizioni.

Dopo l'apertura di un acquisto il prossimo tick si può avere di nuovo la condizione per l'apertura di un trade.

Questa apertura di trade può funzionare in StrategyTester ma in tempo reale su demo su conto reale,

Per esempio scegliendo "3" lo slippage è troppo basso per il trading su un conto a 5 cifre.

L'invio di OrderSend con un valore per OrderStopLoss() e OrdertakeProfit() > 0 fallirà per i conti ECN

   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 
     {
Nell'OrderSend e in questo ciclo per controllare le transazioni mi manca che tu faccia uso del tuo OrderMagicNumber()

e vedo che il ciclo sta contando verso l'alto invece che verso il basso mentre si vuole anche chiudere le posizioni se necessario Quindi un altro errore

L'OrderModify può accadere con ogni punto questo può portare ad errori dal broker come tradecontext troppo occupato

 
FXEWEN:

Parametro RSI impostato su 0, nessun risultato come . . . Niente

Almeno 2

Ho impostato il periodo iRSI a 2....

 
cyxstudio:


Come nota a margine, posso sapere cos'è shift e ma_shift e come dovrei compilarlo? è un parametro richiesto per l'indicatore iRSI() e non sapevo cosa scrivere così ho semplicemente assegnato 0 ad esso.


Non so da dove hai preso questa informazione, ma non è corretta.

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

Forse intendevi iMA()? shift è il numero della barra del tempo per il quale vuoi il MA, ma_shift ti permette di spostare il valore del MA rispetto al numero della barra, quindi se gli dai uno shift di 5 e un ma_shift di -2 ti darà il MA per la barra 7, dovresti sperimentare un po' con questo per verificare che sia corretto, in linea di principio lo sono.


 
deVries:


Usando lo strategytester, fallo anche con la modalità visiva attivata e metti sul grafico gli indicatori che sei con le stesse impostazioni che hai impostato nell'EA

Ogni tick stai calcolando i valori di cui sopra e possono cambiare ad ogni tick perché hai scelto "....,PRICE_CLOSE, 0);"


cosa dovrei scegliere per il valore di spostamento" ....,PRICE_CLOSE, 0);" allora?

 
cyxstudio:

cosa dovrei scegliere per il valore di spostamento" ....,PRICE_CLOSE,0);" allora?

Cosa richiede la tua strategia? Usa la barra 0 se vuoi, ma "ridipinge" anche se usi PRICE_CLOSE, Close[0](prezzo di chiusura della barra 0) == Bid. Quando la barra 0 si chiude finalmente non è più la barra 0 ma diventa la barra 1.
 
deVries:

Non tutti gli EA e non tutte le strategie sono redditizie

Usando lo strategytester fallo anche con la modalità visiva attiva e posiziona sul grafico gli indicatori che hai con le stesse impostazioni che hai impostato nell'EA

Ogni tick stai calcolando i valori di cui sopra e possono cambiare ad ogni tick perché hai scelto "....,PRICE_CLOSE, 0);"

I valori che vedi sul grafico quando il test è fatto non sono i valori che avevi quando si apre un trade...

Quando le condizioni sono soddisfatte per aprire un acquisto, e il tester apre un acquisto, allora non c'è nessun controllo se ne hai già uno aperto con le stesse condizioni.

Dopo l'apertura di un acquisto il prossimo tick si può avere di nuovo la condizione per l'apertura di un trade.

Questa apertura di trade può funzionare in StrategyTester ma in tempo reale su demo su conto reale,

Per esempio scegliendo "3" lo slippage è troppo basso per il trading su un conto a 5 cifre.

L'invio di OrderSend con un valore per OrderStopLoss() e OrdertakeProfit() > 0 fallirà per i conti ECN

Nell'OrderSend e in questo ciclo per controllare le transazioni mi manca che tu faccia uso del tuo OrderMagicNumber()

e vedo che il ciclo sta contando verso l'alto invece che verso il basso mentre si vuole anche chiudere le posizioni se necessario Quindi un altro errore

L'OrderModify può accadere con ogni punto questo può portare ad errori dal broker come tradecontext troppo occupato

Ho rifatto tutto e sistemato il loop, lo slippage, sistemato la media mobile e i valori RSI, fatto in modo che ogni posizione aperta sia chiusa prima di iniziare una nuova posizione. ma quando faccio il backtest, non succede niente, nessun acquisto/vendita è stato eseguito... qual è il problema ancora?

//+------------------------------------------------------------------+
//|                                                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:

Ho rifatto tutto e sistemato il loop, lo slippage, sistemato la media mobile e i valori RSI, fatto in modo che ogni posizione aperta sia chiusa prima di iniziare una nuova posizione. ma quando faccio il backtest, non succede niente, nessun acquisto/vendita è stato eseguito... qual è il problema ancora?


No, il ciclo non è fisso, è stato rimosso e il problema è più grande.

. stai usando A1 e A2 che ottengono il valore vero nel momento in cui si apre la negoziazione

ma cosa succederà se il tuo alimentatore del tuo pc viene meno e devi riavviare il tuo pc e metatrader.

Devi controllare in quel momento se ci sono operazioni aperte dal tuo EA

Come farai ????

Per renderlo più facile usa uno specifico OrderMagicNumber che apre e controlla i tuoi trade

.

la media mobile ora non è spostata di alcune barre nel futuro ok

ma la si calcola solo nella sezione init() che verrà eseguita solo all'avvio del tuo Expert Advisor

Mi manca in Start() .... Perché l'hai rimosso lì??

.

 

Ho riscritto il tuo codice e provato un test, vedi anche le impostazioni

Non con i migliori backtestdata ma se lo fai bene può essere redditizio

Rapporto del tester di strategia
RSI_strategia_cyxstudio
AlpariUK-Demo - Micro+Classic (Build 451)

SimboloEURUSD (Euro contro Dollaro USA)
PeriodoQuotidiano (D1) 2010.10.01 00:00 - 2013.01.29 00:00 (2010.10.01 - 2013.01.30)
ModelloOgni tick (il metodo più preciso basato su tutti i timeframe minimi disponibili)
ParametriRSIPeriod=3; UpperBound=90; LowerBound=5; MASlowPeriod=200; MAFastPeriod=5; Lots=0.1; StopLoss=60; TakeProfit=120; TrailingStop=40; MagicNumber=54333; CommentEA="strategia RSI"; Slippage.Pips=3;
Bars in test1603Ticks modellati40187739Qualità della modellazionen/a
Errori di grafici non corrispondenti2062601
Deposito iniziale3000.00
Profitto netto totale967.18Utile lordo2226.34Perdita lorda-1259.16
Fattore di profitto1.77Guadagno previsto13.62
Drawdown assoluto107.10Dispersione massima327.47 (7.99%)Prelievo relativo7.99% (327.47)
Totale operazioni71Posizioni corte (vinto %)66 (69.70%)Posizioni lunghe (% won)5 (80.00%)
Operazioni con profitto (% del totale)50 (70.42%)Operazioni in perdita (% del totale)21 (29.58%)
Il più grandeprofitto120.07operazione in perdita-60.00
Mediadi profitto44.53commercio in perdita-59.96
Massimovittorie consecutive (profitto in denaro)8 (424.26)perdite consecutive (perdita in denaro)3 (-179.93)
Massimoprofitto consecutivo (conteggio delle vittorie)424.26 (8)perdita consecutiva (conteggio delle perdite)-179.93 (3)
Mediavittorie consecutive4perdite consecutive2

 
deVries:

Ho riscritto il tuo codice e provato un test, vedi anche le impostazioni

Non con i migliori backtestdata ma se lo fai bene può essere redditizio


Totale transazioni71Posizioni corte (% vinte)66 (69.70%)Posizioni lunghe (% vinte)5 (80.00%)





Questo mi fa pensare che ci sia qualcosa che non va.