Changing stoploss!?

dclark24  

Hello any help with the below would be appreciated...

At the bottom of the image the trades are shown.  The last trades are a buy in at 2865 with a S/L at 2860.75. The buy in is closed with a sell out at 2862.25.  Question, why doesn't the sell out wait until the price drops to 2860.75?  Why does the S/L change to 2862 as shown on the line where the sell out occurs?  This is strange to me but maybe someone else understands clearly what is going on.  I stopped trading til I figure this out.  I included the code also.


changing stoploss!!


#property copyright "Copyright 2019"
#property link      ""

// libraries included for coding routines
#include <Trade\Trade.mqh> 
//#include <MovingAverages.mqh>
#include <initmql4.mqh>

input double slopetoclose = 0;
input int EMAlength1 = 8;
input int EMAlength2 = 34;
input int EMAlength3 = 89; 
input int EMAlength4 = 200;
input int minvolume = 100;
input double longlength = 7.0;
input double atrlimit = 1.0;
input double atrlongmult = 3.0;
input double atrshortmult =3.0;
input double slope1min= 0.00;
input double slope2min= 0.00;
input double slope3min= 0.00;
input double slope4min= 0.00;
input int minvolumeshort = 50;
input double slope1minshort= 0.00;
input double slope2minshort= 0.00;
input double slope3minshort= 0.00;
input double slope4minshort= 0.00;
input double buy_takeprofit= 1;
input double buy_stoploss = 1;
input double sell_takeprofit= 2.5;
input double sell_stoploss = 2;

input ENUM_MA_METHOD averageType = MODE_EMA;

input bool close_on_bollinger_band_r1 = false;
input bool close_on_ma_crossing = false;
input bool close_profit_in_pips = true;
input bool close_loss_in_pips = true;

input int contracts = 1;

input bool close_on_bar_end = false;
input int seconds_before_bar_end = 22;

input ENUM_TIMEFRAMES Aggregation = PERIOD_M1;

input bool daily_close = true;
input int close_hour = 20;
input int close_minute = 55;

input bool use_trailing = false;

input double sell_trailing_start = 5.0; 
input double sell_trailing_distance = 1.0; 
input double sell_trailing_step = 5.0; 

input double buy_trailing_start = 2.0; 
input double buy_trailing_distance = 8.0; 
input double buy_trailing_step = 7.0; 

input bool plot_lines = true;

// unique ID of trade
int magic_number = 22052019;

// max acceptable slippage 
//int slippage = 3;


datetime last_bar = 0;
datetime last_Mbar = 0;

CTrade trade; 

double global_SL; // uses for "close_on_HL_and_stoploss" option

int cnt = 0; // counter for objects on chart

int last_position = 0;

//+------------------------------------------------------------------+
// Initialization of empty values on start
int OnInit() {
   last_bar = TimeCurrent();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}
//+------------------------------------------------------------------+
void OnTick() {

   if (use_trailing) {
      trailingStop();
   }

   if (daily_close) {
      closeDaily();
   }

   // chech closing in time
   
   if (close_on_bar_end)
   if (TimeCurrent() > iTime(Symbol(),Aggregation,0) + Aggregation*60 - seconds_before_bar_end) {
      closePosition(POSITION_TYPE_SELL);
      closePosition(POSITION_TYPE_BUY);
   }
   
   datetime current_bar = iTime(Symbol(),Aggregation,0); 
   
   // if new bar comes
   if (current_bar > last_bar) {
 
      double EMA11 = iMA_(Symbol(), Aggregation, EMAlength1, 0, MODE_EMA, PRICE_CLOSE, 1);
      double EMA21 = iMA_(Symbol(), Aggregation, EMAlength2, 0, MODE_EMA, PRICE_CLOSE, 1);
      double EMA31 = iMA_(Symbol(), Aggregation, EMAlength3, 0, MODE_EMA, PRICE_CLOSE, 1);
      double EMA41 = iMA_(Symbol(), Aggregation, EMAlength4, 0, MODE_EMA, PRICE_CLOSE, 1);
      double EMA12 = iMA_(Symbol(), Aggregation, EMAlength1, 0, MODE_EMA, PRICE_CLOSE, 2);
      double EMA22 = iMA_(Symbol(), Aggregation, EMAlength2, 0, MODE_EMA, PRICE_CLOSE, 2);
      double EMA32 = iMA_(Symbol(), Aggregation, EMAlength3, 0, MODE_EMA, PRICE_CLOSE, 2);
      double EMA42 = iMA_(Symbol(), Aggregation, EMAlength4, 0, MODE_EMA, PRICE_CLOSE, 2);
      double atrvalue = iATR_(Symbol(),Aggregation, 14,1);
      double length1 = MathAbs(iClose(Symbol(), Aggregation, 1)-iOpen(Symbol(), Aggregation, 1));
      
      double slope1 = EMA11-EMA12;
      double slope2 = EMA21-EMA22;
      double slope3 = EMA31-EMA32;
      double slope4 = EMA41-EMA42;
      
      int volavg1 = iVolume_(Symbol(),50,VOLUME_TICK,1);
     
      bool golong = false;
      bool goshort = false;
  
 //Long 4EMA approach
     // if (EMA21>EMA31 && EMA31>EMA41) //proper order of EMAs 
      if (EMA11>EMA21 && EMA12<EMA22) //crossing of fastest with second fastest EMA
      if (slope3>0)
      //if (slope4>slope4min)//note: total profit goes up if this is removed but this yields a higher profit margin and lower drawdown
      if (length1<=(atrlongmult*atrvalue))
      if (length1<longlength)
      if (atrvalue<atrlimit)
      if (slope1>=slope1min)// && slope2>=slope2min && slope3>=slope3min && slope4>=slope4min)
      if (volavg1 >= minvolume)
      golong = true;
      
  //Short 4EMA approach
     // if (EMA21<EMA31 && EMA31<EMA41) //proper order of EMAs 
      if (EMA11<EMA21 && EMA12>EMA22) //crossing of fastest with second fastest EMA
      //if (slope3<0)
      //if (slope4<slope4minshort)
      if (length1<=(atrshortmult*atrvalue))
      if (slope1<=slope1minshort)// && slope2<=slope2minshort && slope3<=slope3minshort && slope4<=slope4minshort)
      if (volavg1 >= minvolumeshort)
      goshort = true;

      // check for opening
     
      if (golong) {
         Alert("golong");
         PlaySound("stops.wav");
         //if (close_on_reverse) closePosition(POSITION_TYPE_SELL);
         openBuy();
      }
 
      if (goshort) {
         Alert("goshort");
         PlaySound("stops.wav");
         //if (close_on_reverse) closePosition(POSITION_TYPE_BUY);
         openSell();
      } 
      
      if (close_on_ma_crossing) {
        // if (EMA11<EMA41 && EMA12>EMA42)
   //      if (slope4<0)
     //       closePosition(POSITION_TYPE_BUY);
        // if (ma_signal_sell>ma_signal_l_sell && ma_presignal_sell<ma_presignal_l_sell) 
        //    closePosition(POSITION_TYPE_SELL);
      }
       
 /*  if (close_on_bollinger_band_r1) {
         if (exceed_upper_band || MA_switch_close_r1_buy)
            closePosition(POSITION_TYPE_BUY);
         if (exceed_lower_band || MA_switch_close_r1_sell) 
            closePosition(POSITION_TYPE_SELL);
      }*/
      
   /*    if (plot_lines) {
         
         cnt++;
         
         string name;
         
         name = "upperband"+cnt;
      
         ObjectCreate(0,name,OBJ_ARROW,0,TimeCurrent(),upper_band);  
         ObjectSetInteger(0, name, OBJPROP_COLOR, clrCyan);  
         ObjectSetInteger(0,name,OBJPROP_ARROWCODE,115);      
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);  // dot size
         ObjectSetInteger(0,name,OBJPROP_SELECTABLE,true);
         ObjectSetInteger(0,name,OBJPROP_SELECTED,false); // set this TRUE to highlight these dots
         
         name = "lowerband"+cnt;
      
         ObjectCreate(0,name,OBJ_ARROW,0,TimeCurrent(),lower_band);  
         ObjectSetInteger(0, name, OBJPROP_COLOR, clrRed);  
         ObjectSetInteger(0,name,OBJPROP_ARROWCODE,115);      
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);  // dot size
         ObjectSetInteger(0,name,OBJPROP_SELECTABLE,true);
         ObjectSetInteger(0,name,OBJPROP_SELECTED,false); // set this TRUE to highlight these dots
      
      }*/
      
      // update time of bar and waiting when new opens
      last_bar = current_bar;
   }

   //last_position = PositionsTotal();
   
   return;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void closeDaily() {
   //if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return;
   MqlDateTime tm;
   TimeCurrent(tm);
   if (tm.hour == close_hour && tm.min >= close_minute) {  
      closePosition(POSITION_TYPE_BUY);
      closePosition(POSITION_TYPE_SELL);
   }
}
//+------------------------------------------------------------------+

// routines to open and close trades 

//+------------------------------------------------------------------+
void openBuy() {
   if (PositionsTotal() > 0) return;
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return;
   ENUM_ORDER_TYPE side = ORDER_TYPE_BUY;
   double SL = 0;
   double TP = 0; 
   global_SL = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + buy_stoploss*4*0.25;
   if (buy_stoploss > 0 && close_loss_in_pips)
      SL = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - buy_stoploss*4*0.25; // here we multiply stoploss/takeprofit to 4 because of point step 0.25
   if (buy_takeprofit > 0 && close_profit_in_pips) 
      TP = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + buy_takeprofit*4*0.25;
   trade.PositionOpen(Symbol(), side, getContracts(), SymbolInfoDouble(Symbol(), SYMBOL_ASK), SL, TP, "");
   return;
}

//+------------------------------------------------------------------+
void openSell() {
   if (PositionsTotal() > 0) return;
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return;
   ENUM_ORDER_TYPE side = ORDER_TYPE_SELL;
   double SL = 0;
   double TP = 0;
   global_SL = SymbolInfoDouble(Symbol(), SYMBOL_BID) - sell_stoploss*4*0.25;
   if (sell_stoploss > 0 && close_loss_in_pips)
      SL = SymbolInfoDouble(Symbol(), SYMBOL_BID) + sell_stoploss*4*0.25;
   if (sell_takeprofit > 0 && close_profit_in_pips) 
      TP = SymbolInfoDouble(Symbol(), SYMBOL_BID) - sell_takeprofit*4*0.25;
   trade.PositionOpen(Symbol(), side, getContracts(), SymbolInfoDouble(Symbol(), SYMBOL_BID), SL, TP, "");
   return;
}
//+------------------------------------------------------------------+
void closePosition(ENUM_POSITION_TYPE side) {
   //if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return;
   for(int i=0; i<PositionsTotal(); i++) {
      if(!PositionSelect(Symbol())) continue;
      long type=PositionGetInteger(POSITION_TYPE);
      double amount = PositionGetDouble(POSITION_VOLUME);
      if (type == side) {
         ENUM_ORDER_TYPE close_side = ORDER_TYPE_SELL;
         if (type == POSITION_TYPE_SELL) close_side = ORDER_TYPE_BUY;
         //if (type == ORDER_TYPE_BUY) close_side = ORDER_TYPE_SELL;
         //trade.PositionClose(Symbol(),amount,slippage); 
         trade.PositionOpen(Symbol(), close_side, getContracts(), SymbolInfoDouble(Symbol(), SYMBOL_BID), 0, 0, "");
         global_SL = 0;
      }   
   }
}
//+------------------------------------------------------------------+
void trailingStop() {
   //if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return;
   for(int i=0; i<PositionsTotal(); i++) {
      if(!PositionSelect(Symbol())) continue;
      long type=PositionGetInteger(POSITION_TYPE);
      double open_price=PositionGetDouble(POSITION_PRICE_OPEN);
      double current_stop_loss=PositionGetDouble(POSITION_SL);
      double current_take_profit=PositionGetDouble(POSITION_TP);
      double new_stop_loss;
      double ask_price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
      double bid_price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
      if (type == POSITION_TYPE_SELL) {
         if (open_price-ask_price > sell_trailing_start*4*0.25)   
            if (current_stop_loss-ask_price > (sell_trailing_distance + sell_trailing_step) * 4 * 0.25 || current_stop_loss == 0) {
               new_stop_loss=NormalizeDouble(ask_price + sell_trailing_distance*4*0.25,Digits());
               if (current_stop_loss > new_stop_loss || current_stop_loss == 0)
                  trade.PositionModify(Symbol(),new_stop_loss, current_take_profit);
            }
      }   
      if (type == POSITION_TYPE_BUY) {
         if (bid_price-open_price > buy_trailing_start*4*0.25)   
            if (bid_price-current_stop_loss > (buy_trailing_distance + buy_trailing_step) * 4 * 0.25 || current_stop_loss == 0) {
               new_stop_loss=NormalizeDouble(bid_price - buy_trailing_distance*4*0.25,Digits());
               if (current_stop_loss < new_stop_loss || current_stop_loss == 0)
                  trade.PositionModify(Symbol(),new_stop_loss, current_take_profit);
            }
      }    
   }
}

//+------------------------------------------------------------------+
// returns number of contracts to trade
double getContracts() {
   double l = contracts;
   return (NormalizeDouble(l,2));
}
//+------------------------------------------------------------------+
double iMA_(string symbol,
               int tf,
               int period,
               int ma_shift,
               int method,
               int price,
               int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   ENUM_MA_METHOD ma_method=MethodMigrate(method);
   ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
   int handle=iMA(symbol,timeframe,period,ma_shift,
                  ma_method,applied_price);
   if(handle<0)
     {
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,0,shift));
  }
  //+------------------------------------------------------------------+
double iBands_(string symbol,
               int tf,
               int period,
               int ma_shift,
               double deviation,
               int price,
               int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
   int handle=iBands(symbol,timeframe,period,ma_shift,
                  deviation,applied_price);
   if(handle<0)
     {
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,0,shift));
  }
//+------------------------------------------------------------------+
double iADXW(string symbol,
                int tf,
                int period,
                int price,
                int mode,
                int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   int handle=iADXWilder(symbol,timeframe,period);
   if(handle<0)
     {
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,mode,shift));
  }
//+------------------------------------------------------------------+
double iRSI_(string symbol,
                int tf,
                int period,
                int price,
                int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
   int handle=iRSI(symbol,timeframe,period,applied_price);
   if(handle<0)
     {
      Print("The iRSI object is not created: Error",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,0,shift));
  }
//+------------------------------------------------------------------+
double iATR_(string symbol,
                int tf,
                int period,
                int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   int handle=iATR(symbol,timeframe,period);
   if(handle<0)
     {
      Print("The iATR object is not created: Error",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,0,shift));
  }
//+------------------------------------------------------------------+
//| Variance                                                         |
//+------------------------------------------------------------------+
double Variance(double &arr[],double mx)
  {
   int size=ArraySize(arr);
//--- check  
   if(size<=1)
     {
      Print(__FUNCTION__+": array size error");
      return(EMPTY_VALUE);
     }
//--- calculation
   double sum=0.0;
   for(int i=0;i<size;i++)
      sum+=MathPow(arr[i]-mx,2);
//---
   return(sum/(size-1));
  }
  //+------------------------------------------------------------------+
//| Arithmetical mean of entire sampling                             |
//+------------------------------------------------------------------+
double Average(double &arr[])
  {
   int size=ArraySize(arr);
//--- check
   if(size<=0)
     {
      Print(__FUNCTION__+": array size error");
      return(EMPTY_VALUE);
     }
//--- calculation
   double sum=0.0;
   for(int i=0;i<size;i++)
      sum+=arr[i];
//--- returning the result
   return(sum/size);
  }
//+------------------------------------------------------------------+
//| Get value of buffers for the iBands                              |
//|  the buffer numbers are the following:                           |
//|   0 - BASE_LINE, 1 - UPPER_BAND, 2 - LOWER_BAND                  |
//+------------------------------------------------------------------+
double iBandsGet(const int handle_iBands,const int buffer,const int index)
  {
   double Bands[1];
//ArraySetAsSeries(Bands,true);
//--- reset error code 
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iBands,buffer,index,1,Bands)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iBands indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(Bands[0]);
  }
  //+---------------------------------------------------------------------+
  double iVolume_(string symbol,
                int period,
                int applied_volume,
                int shift)
  {
  //ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK;
   int handle=iVolumes(symbol,PERIOD_CURRENT, VOLUME_TICK);
   if(handle<0)
     {
      Print("The iVolumes object is not created: Error",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,0,shift));
}
  //+------------------------------------------------------------------+
//| Stoploss calculator                                                         |
//+------------------------------------------------------------------+
double Stoplossval(double lowerband, double upperband)
  {
//--- calculation
   double stopval=(upperband-lowerband)/2;
//---
   return(stopval);
Reason: