• Sign up >>

Trailing positions using the 3rd candle high/low

To add comments, please log in or register
Nelson Wanyama
424
Nelson Wanyama  

Hello esteemed experts! I have created an expert adviser but have a little problem here. I would like to use the 3rd candle low or high to trail my open positions. Attached is the code for the high and low. I also need the trailing to start when break even has occurred. The system is promising. Your help will be highly appreciated.

void OnTick()
{
            MqlRates PriceInformation1[], PriceInformation2[];
            ArraySetAsSeries(PriceInformation1,true);
            ArraySetAsSeries(PriceInformation2,true);
            int Data1= CopyRates(_Symbol,_Period,0,3,PriceInformation1);
            int Data2= CopyRates(_Symbol,_Period,0,3,PriceInformation2);
            
     //highest
            int HighestCandle;
            double High[];
            ArraySetAsSeries(High,true);
            CopyHigh(_Symbol,_Period,0,3,High);
            HighestCandle= ArrayMaximum(High,0,3);
            
            
     ObjectCreate(_Symbol, "Line1", OBJ_HLINE,0,0,PriceInformation1[HighestCandle].high);
     ObjectSetInteger(0, "Line1", OBJPROP_COLOR, clrGreen);
     ObjectSetInteger(0, "Line1", OBJPROP_WIDTH,1);
     ObjectMove(_Symbol, "Line1",0,0,PriceInformation1[HighestCandle].high);
     
     //lowest
            int LowestCandle;
            double Low[];
            ArraySetAsSeries(Low,true);
            CopyLow(_Symbol,_Period,0,3,Low);
            LowestCandle= ArrayMinimum(Low,0,3);
            
            
     ObjectCreate(_Symbol, "Line2", OBJ_HLINE,0,0,PriceInformation2[LowestCandle].low);
     ObjectSetInteger(0, "Line2", OBJPROP_COLOR, clrGreen);
     ObjectSetInteger(0, "Line2", OBJPROP_WIDTH,1);
     ObjectMove(_Symbol, "Line2",0,0,PriceInformation2[LowestCandle].low);
     

}
Vladimir Karputov
Moderator
175307
Vladimir Karputov  

I would redo this block.

  1. Two lines need to be created once in OnInit
  2. You need to have two variables - High prices and Low prices and at each tick to calculate these two prices. Only if the price has changed - only then move the line.
Nelson Wanyama
424
Nelson Wanyama  
Vladimir Karputov:

I would redo this block.

  1. Two lines need to be created once in OnInit
  2. You need to have two variables - High prices and Low prices and at each tick to calculate these two prices. Only if the price has changed - only then move the line.
Can you illustrate? 
Vladimir Karputov
Moderator
175307
Vladimir Karputov  
Nelson Wanyama :
Can you illustrate? 

Example:


//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                              Copyright © 2019, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//--- input parameters
input string      InpLineHigh       = "High";   // Line High Name
input string      InpLineLow        = "Low";    // Line Low Name
input uchar       InpSearchBoxWidth = 3;        // Search box width (in bars)
//---
double m_price_high;
double m_price_low;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   m_price_high=0.0;
   m_price_low=0.0;
   if(!HLineCreate(0,InpLineHigh,0,m_price_high,clrBlue) ||!HLineCreate(0,InpLineLow,0,m_price_low,clrRed))
      return(INIT_FAILED);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   HLineDelete(0,InpLineHigh);
   HLineDelete(0,InpLineLow);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double highest=DBL_MIN;
   double lowest=DBL_MAX;
   MqlRates rates[];
   ArraySetAsSeries(rates,true);

   int start_pos=0,count=InpSearchBoxWidth;
   if(CopyRates(Symbol(),Period(),start_pos,count,rates)!=count)
      return;

   for(int i=0; i<count; i++)
     {
      if(rates[i].high>highest)
         highest=rates[i].high;
      if(rates[i].low<lowest)
         lowest=rates[i].low;
     }

   if(highest==DBL_MIN || lowest==DBL_MAX)
      return;

   if(highest!=m_price_high)
     {
      m_price_high=highest;
      HLineMove(0,InpLineHigh,m_price_high);
     }
   if(lowest!=m_price_low)
     {
      m_price_low=lowest;
      HLineMove(0,InpLineLow,m_price_low);
     }
  }
//+------------------------------------------------------------------+
//| Create the horizontal line                                       |
//+------------------------------------------------------------------+
bool HLineCreate(const long            chart_ID=0,        // chart's ID
                 const string          name="HLine",      // line name
                 const int             sub_window=0,      // subwindow index
                 double                price=0,           // line price
                 const color           clr=clrRed,        // line color
                 const ENUM_LINE_STYLE style=STYLE_SOLID, // line style
                 const int             width=1,           // line width
                 const bool            back=false,        // in the background
                 const bool            selection=true,    // highlight to move
                 const bool            hidden=true,       // hidden in the object list
                 const long            z_order=0)         // priority for mouse click
  {
//--- if the price is not set, set it at the current Bid price level
   if(!price)
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
   ResetLastError();
//--- create a horizontal line
   if(!ObjectCreate(chart_ID,name,OBJ_HLINE,sub_window,0,price))
     {
      Print(__FUNCTION__,
            ": failed to create a horizontal line! Error code = ",GetLastError());
      return(false);
     }
//--- set line color
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set line display style
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set line width
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the line by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Move horizontal line                                             |
//+------------------------------------------------------------------+
bool HLineMove(const long   chart_ID=0,   // chart's ID
               const string name="HLine", // line name
               double       price=0)      // line price
  {
//--- if the line price is not set, move it to the current Bid price level
   if(!price)
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
   ResetLastError();
//--- move a horizontal line
   if(!ObjectMove(chart_ID,name,0,0,price))
     {
      Print(__FUNCTION__,
            ": failed to move the horizontal line! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Delete a horizontal line                                         |
//+------------------------------------------------------------------+
bool HLineDelete(const long   chart_ID=0,   // chart's ID
                 const string name="HLine") // line name
  {
//--- reset the error value
   ResetLastError();
//--- delete a horizontal line
   if(!ObjectDelete(chart_ID,name))
     {
      Print(__FUNCTION__,
            ": failed to delete a horizontal line! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
Files:
Test.mq5 14 kb
Nelson Wanyama
424
Nelson Wanyama  
Vladimir Karputov:

Example:


Thank you. Let me work on it and see how it goes.  I will get back to  you 
Vladimir Karputov
Moderator
175307
Vladimir Karputov  
Nelson Wanyama :
Thank you. Let me work on it and see how it goes.  I will get back to  you 

Yes, of course I will wait.

By the way, pay attention to the parameter "Search box width (in bars)"

Nelson Wanyama
424
Nelson Wanyama  
Vladimir Karputov:

Yes, of course I will wait.

By the way, pay attention to the parameter "Search box width (in bars)"

Okay
Nelson Wanyama
424
Nelson Wanyama  
Vladimir Karputov:

Yes, of course I will wait.

By the way, pay attention to the parameter "Search box width (in bars)"

void CheckTrailingStop2(double Bid)
{  
     MqlRates PriceInformation1[], PriceInformation2[];
            ArraySetAsSeries(PriceInformation1,true);
            ArraySetAsSeries(PriceInformation2,true);
            int Data1= CopyRates(_Symbol,_Period,0,3,PriceInformation1);
            int Data2= CopyRates(_Symbol,_Period,0,3,PriceInformation2);
            
             //highest
            int HighestCandle;
            double High[];
            ArraySetAsSeries(High,true);
            CopyHigh(_Symbol,_Period,0,3,High);
            HighestCandle= ArrayMaximum(High,0,3);
   //set ts to 150 points
   double SL1=(PriceInformation1[HighestCandle].high);
   
   //go through all positions
   for (int i=PositionsTotal()-1; i>=0; i--)
   {
         string symbol=PositionGetSymbol(i); //symbol of the positions
         
         if (_Symbol==symbol) //if currency pair is equal
         
         //if we have sell positions
         if (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL)
         
         {
         //get ticket number
         ulong PositionTicket=PositionGetInteger(POSITION_TICKET);
         
         //calculate current sl
         double CurrentStopLoss=PositionGetDouble(POSITION_SL);
         double OpenPrice2=PositionGetDouble(POSITION_PRICE_OPEN);
         double m_trail2= (OpenPrice2-(BreakEven*2)*_Point);
         
         if (CurrentStopLoss>SL1)
         if (Bid<=m_trail2)
         {
         trade.PositionModify(PositionTicket, SL1, 0);
         }
         }
   }
}

I completed the task using my code above(just a section). 

It is working just as I expected. I tried understanding your code in vain. Thank you still.

Nelson Wanyama
424
Nelson Wanyama  
I hid the high and low lines. Don't fell bad as there is no object_create.
To add comments, please log in or register