Can't modify trailing stoploss

 

I want to to create a trailing stoploss and draw a dot on the chart to track the changes. 

The dot tracker works but it moves in both directions I only want it to move up with a buy position and down with a sell position. 

Also the stoploss itself doesn't modify. 

I'm sure there's a simple solution but for the life of me I can't see it! 

Could someone show me where I should be looking please?

//+------------------------------------------------------------------+
//|  Modify Open Orders                                              |
//+------------------------------------------------------------------+   

if(isNewBar()){ 


    for (int i=0; i < PositionsTotal(); i++) {
        if(PositionGetTicket(i)>0) {
            if (PositionGetInteger(POSITION_MAGIC) == magic_nb && PositionGetString(POSITION_SYMBOL) == _Symbol){
                string position_symbol = PositionGetString(POSITION_SYMBOL);
                int ticket = PositionGetInteger(POSITION_TICKET);
                int magic = PositionGetInteger(POSITION_MAGIC);
                double sl=PositionGetDouble(POSITION_SL);
               

                if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY){
                    double newStopLoss =  stopLossLowATR(trailing_stop_period,atrPeriod,atr_stoploss_factor);
                    if(newStopLoss > sl){
                           updatedStopLoss = newStopLoss;
                    }
                    if(newStopLoss <= sl){
                       updatedStopLoss = sl;
                    }
                    if ((newStopLoss - sl)> (stoploss_updaterate)){
                       ZeroMemory(mrequest);
                       ZeroMemory(mresult);
                       mrequest.action = TRADE_ACTION_SLTP;       
                       mrequest.position = ticket;
                       mrequest.symbol = _Symbol;
                       mrequest.magic = magic_nb;
                       mrequest.sl = normalizePrice(updatedStopLoss);
                  
                      //--- send the request
                      if(!OrderSend(mrequest,mresult))
                         PrintFormat("ERROR! Modify stop loss long error: %d",GetLastError());  // if unable to send the request, output the error code
                      //--- information about the operation   
                      PrintFormat("Modified Stop loss long: retcode=%u  deal=%I64u  order=%I64u",mresult.retcode,mresult.deal,mresult.order);
                      ZeroMemory(mrequest);
                      ZeroMemory(mresult); 
                   }
                   
               }
   
               if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL){
                   double newStopLoss =  stopLossHighATR(trailing_stop_period,atrPeriod,atr_stoploss_factor);
                   if(newStopLoss < sl){
                        updatedStopLoss = newStopLoss;
                   }
                   if(newStopLoss >= sl) {
                      updatedStopLoss = sl;
                   }
                   if ((sl - newStopLoss)> (stoploss_updaterate)){
                      ZeroMemory(mrequest);
                      ZeroMemory(mresult);
                      mrequest.action = TRADE_ACTION_SLTP;       
                      mrequest.position = ticket;
                      mrequest.symbol = _Symbol;
                      mrequest.magic = magic_nb;
                      mrequest.sl = normalizePrice(updatedStopLoss);
               
                     //--- send the request
                     if(!OrderSend(mrequest,mresult))
                        PrintFormat("ERROR! Modify stop loss Short error: %d",GetLastError());  // if unable to send the request, output the error code
                     //--- information about the operation   
                     PrintFormat("retcode=%u  deal=%I64u  order=%I64u",mresult.retcode,mresult.deal,mresult.order);
                     ZeroMemory(mrequest);
                     ZeroMemory(mresult); 
                  } 
                  
               } 

               drawDotTacker(stop_name,updatedStopLoss,clrRed);
            } 

        }                   //Position selection[i]
        else{
           Print("ERROR! Can't find open order to modify stop loss: ", GetLastError() );
        } 
    }                     //position for loop
    
 
     

}                        //New bar   


//-- ATR      
double ATR(int ATR_period){  
    double sum;      
    for (int i =ATR_period; i>=1; i--){
        double range= iHigh(NULL,PERIOD_CURRENT,i) - iLow(NULL,PERIOD_CURRENT,i);
        sum += range;
    }
    return(sum / ATR_period);
}     


bool isNewBar()
  {
//--- remember the time of opening of the last bar in the static variable
   static datetime last_time=0;
//--- current time
   datetime lastbar_time=SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);

//--- if it is the first call of the function
   if(last_time==0)
     {
      //--- set time and exit
      last_time=lastbar_time;
      return(false);
     }

//--- if the time is different
   if(last_time!=lastbar_time)
     {
      //--- memorize time and return true
      last_time=lastbar_time;
      return(true);
     }
//--- if we pass to this line then the bar is not new, return false
   return(false);
  }


double normalizePrice(double price)
  {
   double tickSize=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   return(MathRound(price/tickSize)*tickSize);
  }


//-----Find Lowest value in x bars
double findLowest(int lowestRange)
     {
   
   int low_index=iLowest(NULL,0,MODE_LOW,lowestRange,0);
   if(low_index!=-1) 
     {
      double val=iLow(NULL,0,low_index);
      return val;
      }
   else 
      {
      return low_index;
      Print("Error in iLowest. Error code:",GetLastError());
      }
   }


//-----Find Highest value in x bars
double findHighest(int highestRange)
   {
   
   int high_index=iHighest(NULL,0,MODE_HIGH,highestRange,0);
   if(high_index!=-1) 
      {
      double val=iHigh(Symbol(),PERIOD_CURRENT,high_index);
      return val;
      }
   else 
     {
      return high_index;
      Print("Error in iLowest. Error code:",GetLastError());
     }
   }


double stopLossLowATR(int lowestPeriod,int atrPeriod, double ATRfactor)
     {
      double Lowest = findLowest(lowestPeriod);
      double atr= ATR(atrPeriod);
      double stop = Lowest - (atr*ATRfactor);
      return stop;
     }


//--Stop Loss of Highest value + Atr
double stopLossHighATR(int highestPeriod,int atrPeriod, double ATRfactor)
      {
       double highest = findHighest(highestPeriod);
       double atr= ATR(atrPeriod);
       double stop = highest + (atr*ATRfactor);
       return stop;
      }


//--Draw dots to tacker values changes 

void drawDotTacker(string Name, double Value,color Color)  
           {  
             string objName = Name + TimeCurrent(); 
             ObjectCreate(0,objName, OBJ_ARROW, 0, TimeCurrent(),Value); 
             ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,159);
             ObjectSetInteger(0,objName,OBJPROP_COLOR,Color); 
           }




Any help would be greatly appreciated

 
Bruno Harris:

I want to to create a trailing stoploss and draw a dot on the chart to track the changes. 

The dot tracker works but it moves in both directions I only want it to move up with a buy position and down with a sell position. 

Also the stoploss itself doesn't modify. 

I'm sure there's a simple solution but for the life of me I can't see it! 

Could someone show me where I should be looking please?


Any help would be greatly appreciated


Your function which calculates ATR returns its value in points.

To change the position SL you need to pass it a PRICE, so there is some calculation missing on your code.

You have to get que received ATR values, multiply it to the corresponding value on the Symbol Digits.

After that, you have to get the position OpenPrice, and add/subtract the corresponding value to it.

And then you can update the position SL.


Example: if ATR returns 230, convert to the corresponding digits:

atr = atr * _Point 


Considering it is EURUSD, the value will be 0.00230, which means 230 points.

Than get the Opening Price, example: 1.18557 and subtract from it: (1.18557 - 0.00230) which will result in 1.18327

The value which you will pass to update de position SL will be 1.18327


By giving a quick look at your code, it looks like you are mixing/comparing price with points. 


Check/print/debug the final SL value which you are passing to update, and verify if it is really a compatible PRICE, or if it is being passed as an out-of-range value (as I suppose is happening)