Trailing stop failed EA

 

Good Morning to all members, I have coded a Cross Moving Average EA. And I want to activate a trailing stop when trade is in profit the trailing stop must be set at a certain level after open price for buy or below open price for sell.the problem is that the trailing stop does not activate when the conditions are met here is the mql5 code


//+------------------------------------------------------------------+
//|                                 CrossEA ELECTA.mq5 |
//|                                                                  |
//+------------------------------------------------------------------+

#include <GetIndicatorBuffers.mqh>
#include <Trade\Trade.mqh>

// Create an instance of Ctrade
CTrade trade;

//+------------------------------------------------------------------+
//| Global variables                                                 |
//|                                                                  |
//+------------------------------------------------------------------+
input int SmallMovingAverage = 20 ;
input int BigMovingAverage = 50 ;
input double lotstoput = 0.5 ;
input double Stoploss = 20000 ;
input double Tpprofit = 40000 ;
input ENUM_TIMEFRAMES Periodtochoose = PERIOD_CURRENT ;

//+------------------------------------------------------------------+
//|Trailing stop inputs                                              |
//+------------------------------------------------------------------+
static input long InpMagicNumber = 19982004;
input group "====== trailing stop ======"
input double trailingpoints=150;
input double trailingstep=10;
//+------------------------------------------------------------------+
//|Arrays and Handles inputs                                         |
//+------------------------------------------------------------------+
//---- arrays for indicators
double SmallMovingAverageArray[]; //arrays for Small Moving Average
double BigMovingAverageArray[]; //arrays for Big Moving Average

//---- handles for indicators
int SmallMovingAverage_handle;//handle for Small Moving Average
int BigMovingAverage_handle;//handle for Big Moving Average


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- creation of the robot magic number
trade.SetExpertMagicNumber(InpMagicNumber);
 
//--- creation of the indicator iMA
SmallMovingAverage_handle = iMA(_Symbol,Periodtochoose,SmallMovingAverage,0,MODE_EMA,PRICE_CLOSE);
BigMovingAverage_handle = iMA (_Symbol,Periodtochoose,BigMovingAverage,0,MODE_EMA,PRICE_CLOSE);   

//--- report if there was an error in object creation
   if(SmallMovingAverage_handle<0)
     {
      Print("The creation of SmallMovingAverage has failed: Runtime error =",GetLastError());
      //--- forced program termination
      return(-1);
    if(BigMovingAverage_handle<0)
     {
      Print("The creation of BigMovingAverage has failed: Runtime error =",GetLastError());
      //--- forced program termination
      return(-1);
     }
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//--- filling an array MA[] with current values of iMA
//--- set indexation of array MA[] as timeseries
//--- return if there was an error
   if(!CopyBufferAsSeries(SmallMovingAverage_handle,0,0,100,true,SmallMovingAverageArray)) return;
   if(!CopyBufferAsSeries(BigMovingAverage_handle,0,0,100,true,BigMovingAverageArray)) return;
      
//Calculate the Ask price
double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);

//Calculate the Bid price
double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

//Create a string for signal
string signal=" ";

//Define EA, one line current candle , 100 candles , store result
CopyBuffer(SmallMovingAverage_handle,0,0,100,SmallMovingAverageArray);

//Define EA, one line current candle , 100 candles , store result
CopyBuffer(BigMovingAverage_handle,0,0,100,BigMovingAverageArray);

//Buy condition
if (SmallMovingAverageArray[1]>BigMovingAverageArray[1])
if (SmallMovingAverageArray[2]<=BigMovingAverageArray[2])
  {
   signal ="buy" ;
  }
//Sell condition
if (SmallMovingAverageArray[1]<BigMovingAverageArray[1])
if (SmallMovingAverageArray[2]>=BigMovingAverageArray[2])
  {
   signal ="sell" ;
  }
 
//Buy order
if (signal =="buy" && PositionsTotal()==0){
  trade.Buy(lotstoput,NULL,Ask,Ask-Stoploss*_Point,0,NULL);
  }
 
//Sell order  
if (signal =="sell" && PositionsTotal()==0){
  trade.Sell(lotstoput,NULL,Bid,Bid+Stoploss*_Point,0,NULL);
  }
 

//Function to close sell positions
if (signal =="sell" && PositionsTotal()>=1)
ChecktrailingStopSell(Bid);

//Function to close buy positions

if (signal =="buy" && PositionsTotal()>=1)
ChecktrailingStopBuy(Ask);


} //End of void on tick function

//+------------------------------------------------------------------+
//| Expert trailing stop condition function                          |
//+------------------------------------------------------------------+
void ChecktrailingStopSell (double Bid){
for (int i=PositionsTotal()-1; i>=0; i--){
string symbol=PositionGetSymbol(i);
if (_Symbol==symbol)
if (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL){
ulong ticket = PositionGetInteger(POSITION_TICKET);
double currentstoploss=NormalizeDouble(PositionGetDouble(POSITION_SL),_Digits);
double currentprice=NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);
double price2cur=currentprice+trailingpoints*_Point;
double priceopen=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits);
double nouveausl=priceopen-trailingpoints*_Point;
double profitcon=PositionGetDouble(POSITION_PROFIT);
if (Bid < nouveausl) {
trade.PositionModify(ticket,(priceopen-trailingstep*_Point),Tpprofit);}
}
}
}

void ChecktrailingStopBuy(double Ask){
for (int i=PositionsTotal()-1; i>=0; i--){
string symbol=PositionGetSymbol(i);
if (_Symbol==symbol)
if (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_BUY){
ulong ticket = PositionGetInteger(POSITION_TICKET);
double currentstoploss=PositionGetDouble(POSITION_SL);
double priceopen=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits);
double newsl=NormalizeDouble(priceopen+trailingpoints*_Point,_Digits);
double profitcon=PositionGetDouble(POSITION_PROFIT);
if (Ask > priceopen) {
trade.PositionModify(ticket,(newsl+trailingstep*_Point),Tpprofit);}
}
}
}
 

Hi

There are a few mistakes in your code.

First, why do you activate trailing stop only when there is buy or sell signal? You should call “trailing stop” functions all the time when you have any opened positions from your EA (here you could add a counter for trades only from your EA instead PositlonsTotal()). 

And within CheckTrailingStop… - you should compare

(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)

 instead of 

 (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL)

(same for BUY direction). 

And in the modify function you cannot use direct TPprofit value as take profit level. You need to calculate new TP if you want to modify this also – or use current tp of the trade: PositionGetDouble(POSITION_TP).

Besides that – all prices should be normalized to tick size and you would have to check if the stop levels are not higher than new SL distance – to allow modification (https://book.mql4.com/appendix/limits) etc.  But those are just good coding management. 

Best Regards

Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
  • book.mql4.com
Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
 
Marzena Maria Szmit #:

Hi

There are a few mistakes in your code.

First, why do you activate trailing stop only when there is buy or sell signal? You should call “trailing stop” functions all the time when you have any opened positions from your EA (here you could add a counter for trades only from your EA instead PositlonsTotal()). 

And within CheckTrailingStop… - you should compare

(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)

 instead of 

 (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL)

(same for BUY direction). 

And in the modify function you cannot use direct TPprofit value as take profit level. You need to calculate new TP if you want to modify this also – or use current tp of the trade: PositionGetDouble(POSITION_TP).

Besides that – all prices should be normalized to tick size and you would have to check if the stop levels are not higher than new SL distance – to allow modification (https://book.mql4.com/appendix/limits) etc.  But those are just good coding management. 

Best Regards

Ok thank you for your help

 
I copied the trade, and I had previously opened orders myself, so when the copied orders are closed by my expert, will it result in my previously opened orders being closed?
 
user5568 #:
I copied the trade, and I had previously opened orders myself, so when the copied orders are closed by my expert, will it result in my previously opened orders being closed?
No. Unless your EA, has a function to close all trades, even those opened from a different source.
Reason: