Problem: Crossing condition does not work in live trading - although everything runs smoothly in the simulation

 

Hello,

i hope you can help me because i have a strange problem, my idea is to open a buy order whenever the ADX value is greater than a preset ADX value and the D+ value crosses the D- value of the ADX. This works fine in the simulation, but not in the live account. I do not even get an error message. But it is interesting, if I change the entry condition and change it in such a way that the D+ (the green curve) is above the D- (red) curve, then the Buy Trade Order in connection with the preset ADX value works perfectly.

What is the problem?

I'm posting my source code:

//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

// Eingaben und Array- und Variablendefinitionen
   // Stop Loss
   input int      StopLoss=30;     
   // Take Profit
   input int      TakeProfit=20;  
   //  ADX Setting for Crossing between D+ and D-
   input int setADX = 10; 

   // für ADX-Wert
   double ArrayADX[];
   // für D+-Wert
   double ArrayDpl[];
   // für D- -Wert
   double ArrayDmi[]; 
  
   // To be used for Stop Loss & Take Profit values
   int SL, TP;  
  
    // handle for our ADX indicator
   int adx;
   
   

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- Get handle for ADX indicator
   adx=iADX(Symbol(),_Period,14);
   
   //--- What if handle returns Invalid Handle
   if(adx<0)
     {
      Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
      return(-1);
     }
     
   //--- Let us handle currency pairs with 5 or 3 digit prices instead of 4
   SL = StopLoss;
   TP = TakeProfit;
   if(_Digits==5 || _Digits==3)
     {
      SL = SL*10;
      TP = TP*10;
     }
     
        return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
      //--- Release our indicator handles
   IndicatorRelease(adx);
  }
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- Do we have enough bars to work with
   if(Bars(_Symbol,_Period)<60) // if total bars is less than 60 bars
     {
      Alert("We have less than 60 bars, EA will now exit!!");
      return;
     }  
   
   // We will use the static Old_Time variable to serve the bar time.
   // At each OnTick execution we will check the current bar time with the saved one.
   // If the bar time isn't equal to the saved time, it indicates that we have a new tick.

   static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar=false;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }

//--- EA should only check for new trade if we have a new bar
   if(IsNewBar==false)
     {
      return;
     }
 
//--- Do we have enough bars to work with
   int Mybars=Bars(_Symbol,_Period);
   if(Mybars<60) // if total bars is less than 60 bars
     {
      Alert("We have less than 60 bars, EA will now exit!!");
      return;
     }

//--- Define some MQL5 Structures we will use for our trade
   MqlTick latest_price;      // To be used for getting recent/latest price quotes
   MqlTradeRequest mrequest = {0};  // To be used for sending our trade requests
   MqlTradeResult mresult ={0};    // To be used to get our trade results
   // Initialization of mrequest structure
   ZeroMemory(mrequest);      
   
   //Anfang ADX-Handelsstrategie Umsetzung 
      
   // sortiere die Preise abwärts von der aktuellen Kerze
   ArraySetAsSeries(ArrayADX,true);  
   ArraySetAsSeries(ArrayDpl,true);
   ArraySetAsSeries(ArrayDmi,true);

   //--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }
   
   // Definierter EA, erste Indikatorlinie (ADX) = (erste 0) die 1 liefert den Wert für die zweite Indikatorlinie D+ usw., aktuelle Kerze (zweite Index 0), 3 Kerzen (Kopieren der Daten für 3 Kerzen), speichere Resultat in meinPreisArray  // Mit der Funktion Copybuffer füllen wir unser Preisarray aufgrund der ADX Definition
   CopyBuffer(adx,0,0,3,ArrayADX);   // ADX-Wert
   CopyBuffer(adx,1,0,3,ArrayDpl);         // Dplus
   CopyBuffer(adx,2,0,3,ArrayDmi);   // D-Minus
  
// Kann für die Anzeige der Indikatorwerte in Verbindung mit der comment Funktion verwendet werden 
   
   // Berechne den EA für für die aktuelle Kerze (ADX)
   double ADXWert=NormalizeDouble(ArrayADX[0],2);  // ADX
   double DplWert=NormalizeDouble(ArrayDpl[0],2);  // D+
   double DminWert=NormalizeDouble(ArrayDmi[0],2);  // D-

// Ende der ADX-Handelsstrategie Umsetzung 
   
   // Testkommentar
   //Comment ("The current ADX signal is: ",ADXWert);
   //Comment ("The current Dpl signal is: ",DplWert);
   //Comment ("The current Dmin signal is: ",DminWert);
    Comment ("The current Dpl is: ",DplWert);
   //--- Do we have positions opened already?
   bool Buy_opened=false;  // variable to hold the result of Buy opened position
   bool Sell_opened=false; // variables to hold the result of Sell opened position
   
   if(PositionSelect(_Symbol)==true) // we have an opened position
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_opened=true;  //It is a Buy
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_opened=true; // It is a Sell
        }
     } // Ende if PositionSelect

//   bool Buy_Condition_1 = (ArrayDpl[0] > ArrayDmi[0]); /*&& (ArrayDpl[1] < ArrayDmi[1]);  */     // +DI greater than -DI - für die aktuelle Kerze - Crossing
   
   if( (ADXWert>=setADX)  && ((ArrayDpl[0] > ArrayDmi[0]) && (ArrayDpl[1] <= ArrayDmi[1])))   //Crossing condition is commented out
   {
    // any opened Buy position?
   if(Buy_opened)
   {
   Alert("We already have a Buy Position!!!");
   return;    // Don't open a new Buy Position
   } // Ende Buy_opened
           
   ZeroMemory(mrequest);
   mrequest.action = TRADE_ACTION_DEAL;                                                        // Typ der Transaktion
   mrequest.symbol =Symbol();                                                                             // Symbol
   mrequest.volume = 0.01;                                                                                     // Volumen von 0.1 Lot
   mrequest.type = ORDER_TYPE_BUY;                                                               // Ordertyp
   mrequest.price =SymbolInfoDouble(Symbol(),SYMBOL_ASK);                             // Eröffnungspreis
   mrequest.deviation=5;                                                                                     // zulässige Abweichung vom Kurs
   mrequest.magic = 12345;                                                                              // MagicNumber der Order
 
   mrequest.sl = NormalizeDouble(latest_price.ask - SL*_Point,_Digits); // Stop Loss
   mrequest.tp = NormalizeDouble(latest_price.ask + TP*_Point,_Digits); // Take Profit
  
   mrequest.type_filling = ORDER_FILLING_IOC;                             // Order execution type
     
   //--- send order - ab hier kommt der return value of "Order send" should be checked Fehler 4756 The buy order request could not be completed - und invalid stops im journal
   
   //--- Send Buy order
   int trade_order_1 = OrderSend(mrequest, mresult);
   
   
   //--- Get the result code
   if ( mresult.retcode == 10009 || mresult.retcode == 10008 ) 
   {          
      Alert("A buy order has been successfully placed with Ticket #", mresult.order, "!");
   } else {
               Alert("The buy order request could not be completed - error: ", GetLastError(), "!");
               ResetLastError();
               return;
        } // Ende else
     } // Ende if Buy Condition   
  } // Ende on Tick

I am really very grateful for any help.

Best regards

Paul

 
PS-WW-Trader:

Hello,

i hope you can help me because i have a strange problem, my idea is to open a buy order whenever the ADX value is greater than a preset ADX value and the D+ value crosses the D- value of the ADX. This works fine in the simulation, but not in the live account. I do not even get an error message. But it is interesting, if I change the entry condition and change it in such a way that the D+ (the green curve) is above the D- (red) curve, then the Buy Trade Order in connection with the preset ADX value works perfectly.

What is the problem?

I'm posting my source code:

I am really very grateful for any help.

Best regards

Paul

Since you're checking once per bar, you should compare indicator values of bars 1 and 2, not 0 and 1.

 
  1. PS-WW-Trader: buy order whenever the ADX value is greater than a preset ADX value and the D+ value crosses the D- value of the ADX.
    if( (ADXWert>=setADX)  && ((ArrayDpl[0] > ArrayDmi[0]) && (ArrayDpl[1] <= ArrayDmi[1])))   //Crossing condition is commented out

    Both conditions must occur on the same bar (1) no trade otherwise. I suggest

    1. You are looking at a signal. Act on a change of signal. (ADX above.)
                MQL4 (in Strategy Tester) - double testing of entry conditions - Strategy Tester - Expert Advisors and Automated Trading - MQL5 programming forum #1
    2. Don't use the crossover as part of the signal, use them only to determine the trade direction.

  2.    input int      StopLoss=30;     
       input int      TakeProfit=20;  
    ⋮
          SL = SL*10;
          TP = TP*10;
    
    Inputs can't be modified.
              Language Basics / Variables / Input Variables - Reference on algorithmic/automated trading language for MetaTrader 5
Reason: