Mql5 | How can i call the last indicator signal?

 

Hello, i have an indicator that gives me signals (buy and sell).


I want to determine if the current signal is buy and the preview signal is sell and the preview signal is buy, drawing lines between these signals as the picture to link the last 2 signals with the current one.


How can i do this simply?




#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2

#property indicator_type1 DRAW_ARROW
#property indicator_width1 3
#property indicator_color1 0xFF901E
#property indicator_label1 "Buy"

#property indicator_type2 DRAW_ARROW
#property indicator_width2 3
#property indicator_color2 0xFF00FF
#property indicator_label2 "Sell"

//--- indicator buffers
double Buffer1[];
double Buffer2[];

datetime time_alert; //used when sending alert
input bool Send_Email = true;
double myPoint; //initialized in OnInit
double Open[];
double Close[];
int RSI_handle;
double RSI[];
double Low[];
double High[];

void myAlert(string type, string message)
  {
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | TEST @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
     }
   else if(type == "modify")
     {
     }
   else if(type == "indicator")
     {
      if(Send_Email) SendMail("TEST", type+" | TEST @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
  }

void DrawLine(string objname, double price, int count, int start_index) //creates or modifies existing object if necessary
  {
   if((price < 0) && ObjectFind(0, objname) >= 0)
     {
      ObjectDelete(0, objname);
     }
   else if(ObjectFind(0, objname) >= 0 && ObjectGetInteger(0, objname, OBJPROP_TYPE) == OBJ_TREND)
     {
      datetime cTime[];
      ArraySetAsSeries(cTime, true);
      CopyTime(Symbol(), Period(), 0, start_index+count, cTime);
      ObjectSetInteger(0, objname, OBJPROP_TIME, cTime[start_index]);
      ObjectSetDouble(0, objname, OBJPROP_PRICE, price);
      ObjectSetInteger(0, objname, OBJPROP_TIME, 1, cTime[start_index+count-1]);
      ObjectSetDouble(0, objname, OBJPROP_PRICE, 1, price);
     }
   else
     {
      datetime cTime[];
      ArraySetAsSeries(cTime, true);
      CopyTime(Symbol(), Period(), 0, start_index+count, cTime);
      ObjectCreate(0, objname, OBJ_TREND, 0, cTime[start_index], price, cTime[start_index+count-1], price);
      ObjectSetInteger(0, objname, OBJPROP_RAY_LEFT, 0);
      ObjectSetInteger(0, objname, OBJPROP_RAY_RIGHT, 0);
      ObjectSetInteger(0, objname, OBJPROP_COLOR, C'0x00,0x00,0xFF');
      ObjectSetInteger(0, objname, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, objname, OBJPROP_WIDTH, 2);
     }
  }

double Support(int time_interval, bool fixed_tod, int hh, int mm, bool draw, int shift)
  {
   int start_index = shift;
   int count = time_interval / PeriodSeconds();
   if(fixed_tod)
     {
      datetime start_time;
      datetime cTime[];
      ArraySetAsSeries(cTime, true);
      CopyTime(Symbol(), Period(), 0, Bars(Symbol(), Period())-count, cTime);
      if(shift == 0)
             start_time = TimeCurrent();
      else
         start_time = cTime[shift-1];
      datetime dt = StringToTime(TimeToString(start_time, TIME_DATE)+" "+IntegerToString(hh)+":"+IntegerToString(mm)); //closest time hh:mm
      if (dt > start_time)
         dt -= 86400; //go 24 hours back
      int dt_index = iBarShift(Symbol(), Period(), dt, true);
      datetime dt2 = dt;
      while(dt_index < 0 && dt > cTime[Bars(Symbol(), Period())-1-count]) //bar not found => look a few days back
        {
         dt -= 86400; //go 24 hours back
         dt_index = iBarShift(Symbol(), Period(), dt, true);
        }
      if (dt_index < 0) //still not found => find nearest bar
         dt_index = iBarShift(Symbol(), Period(), dt2, false);
      start_index = dt_index + 1; //bar after S/R opens at dt
     }
   double cLow[];
   ArraySetAsSeries(cLow, true);
   CopyLow(Symbol(), Period(), start_index, count, cLow);
   double ret = cLow[ArrayMinimum(cLow, 0, count)];
   if (draw) DrawLine("Support", ret, count, start_index);
   return(ret);
  }

double Resistance(int time_interval, bool fixed_tod, int hh, int mm, bool draw, int shift)
  {
   int start_index = shift;
   int count = time_interval / PeriodSeconds();
   if(fixed_tod)
     {
      datetime start_time;
      datetime cTime[];
      ArraySetAsSeries(cTime, true);
      CopyTime(Symbol(), Period(), 0, Bars(Symbol(), Period())-count, cTime);
      if(shift == 0)
             start_time = TimeCurrent();
      else
         start_time = cTime[shift-1];
      datetime dt = StringToTime(TimeToString(start_time, TIME_DATE)+" "+IntegerToString(hh)+":"+IntegerToString(mm)); //closest time hh:mm
      if (dt > start_time)
         dt -= 86400; //go 24 hours back
      int dt_index = iBarShift(Symbol(), Period(), dt, true);
      datetime dt2 = dt;
      while(dt_index < 0 && dt > cTime[Bars(Symbol(), Period())-1-count]) //bar not found => look a few days back
        {
         dt -= 86400; //go 24 hours back
         dt_index = iBarShift(Symbol(), Period(), dt, true);
        }
      if (dt_index < 0) //still not found => find nearest bar
         dt_index = iBarShift(Symbol(), Period(), dt2, false);
      start_index = dt_index + 1; //bar after S/R opens at dt
     }
   double cHigh[];
   ArraySetAsSeries(cHigh, true);
   CopyHigh(Symbol(), Period(), start_index, count, cHigh);
   double ret = cHigh[ArrayMaximum(cHigh, 0, count)];
   if (draw) DrawLine("Resistance", ret, count, start_index);
   return(ret);
  }

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {   
   SetIndexBuffer(0, Buffer1);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(0, PLOT_ARROW, 161);
   SetIndexBuffer(1, Buffer2);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(1, PLOT_ARROW, 161);
   //initialize myPoint
   myPoint = Point();
   if(Digits() == 5 || Digits() == 3)
     {
      myPoint *= 10;
     }
   RSI_handle = iRSI(NULL, PERIOD_CURRENT, 11, PRICE_CLOSE);
   if(RSI_handle < 0)
     {
      Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
     
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int    Account_Number=0;
string Expire_Date="2128.09.28 02:22"; 


int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
   int limit = rates_total - prev_calculated;
   
   //--- counting from 0 to rates_total
   ArraySetAsSeries(Buffer1, true);
   ArraySetAsSeries(Buffer2, true);
   //--- initial zero
   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
      ArrayInitialize(Buffer2, EMPTY_VALUE);
     }
   else
      limit++;
   datetime Time[];
   
   if(CopyOpen(Symbol(), PERIOD_CURRENT, 0, rates_total, Open) <= 0) return(rates_total);
   ArraySetAsSeries(Open, true);
   if(CopyClose(Symbol(), PERIOD_CURRENT, 0, rates_total, Close) <= 0) return(rates_total);
   ArraySetAsSeries(Close, true);
      if(BarsCalculated(RSI_handle) <= 0) 
      return(0);
   if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total);
   ArraySetAsSeries(RSI, true);
   if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
   ArraySetAsSeries(Low, true);
   if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
   ArraySetAsSeries(High, true);
   if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
   ArraySetAsSeries(Time, true);
   //--- main loop
   for(int i = limit-1; i >= 0; i--)
     {
      if (i >= MathMin(200000-1, rates_total-1-50)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
      
      //Indicator Buffer 1
      if(Low[1+i]>Low[5+i]
      && Low[2+i]>Low[5+i]
      && Low[3+i]>Low[5+i]
      && Low[4+i]>Low[5+i]
      && Low[6+i]>Low[5+i]
      && Low[7+i]>Low[5+i]
      && Low[8+i]>Low[5+i]
      && Low[9+i]>Low[5+i]
      )
        {
         Buffer1[5+i] = Low[5+i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer1[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 2
      if(High[1+i]<High[5+i]
      && High[2+i]<High[5+i]
      && High[3+i]<High[5+i]
      && High[4+i]<High[5+i]
      && High[6+i]<High[5+i]
      && High[7+i]<High[5+i]
      && High[8+i]<High[5+i]
      && High[9+i]<High[5+i]
      )
        {
         Buffer2[5+i] = High[5+i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer2[i] = EMPTY_VALUE;
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Or how to determine those last 2 signals by coding?
 

I don't really understand what you try to get. :(

This

        {
         Buffer2[5+i] = High[5+i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer2[i] = EMPTY_VALUE;
        }

looks strange. A value is assigned to Buffer2[ 5+i ] or otherwise Buffer2[ i ] = EMPTY_VALUE;

It looks a bit like fractals do you know it...

 
Carl Schreiber #:

I don't really understand what you try to get. :(

This

looks strange. A value is assigned to Buffer2[ 5+i ] or otherwise Buffer2[ i ] = EMPTY_VALUE;

It looks a bit like fractals do you know it...

Thanks at this note, i'll fix it

 

Another example, i want to compare the current SAR value with the last Sar value to say:

if(first SAR value > first last  SAR value)



 

CopyBuffer() is what you are lo0oking for - I guess.

Look at the example and imagine iSAR in stead if iMA.

Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
CopyBuffer - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Carl Schreiber #:

CopyBuffer() is what you are lo0oking for - I guess.

Look at the example and imagine iSAR in stead if iMA.


I tried to do this with ZigZag indicator  by this function, but it is failed!

double ZagZag(int Q)
{
int First=0;

for(int i=0;i<7777;i++)
{
if(ZigZag_handle!=0)First++;
if(First==1&&Q==0&&ZigZag_handle!=0){return(ZigZag_handle);}
if(First==2&&Q==1&&ZigZag_handle!=0){return(ZigZag_handle);}
if(First==3&&Q==2&&ZigZag_handle!=0){return(ZigZag_handle);}
if(First==4&&Q==3&&ZigZag_handle!=0){return(ZigZag_handle);}
if(First==5&&Q==4&&ZigZag_handle!=0){return(ZigZag_handle);}
if(First==6&&Q==5&&ZigZag_handle!=0){return(ZigZag_handle);}

}
return(0);
}
 

I told you to look at the example there - you didn't!

What you did is just a mess.

One handle in OnInit and CopyBuffer in OnTick (or even in OnCalculate) where is that structure?

May you should read this:
Step-by-step for beginners: https://www.mql5.com/en/articles/100
quickentry: https://www.mql5.com/en/articles/496

Step-By-Step Guide to writing an Expert Advisor in MQL5 for Beginners
Step-By-Step Guide to writing an Expert Advisor in MQL5 for Beginners
  • www.mql5.com
The Expert Advisors programming in MQL5 is simple, and you can learn it easy. In this step by step guide, you will see the basic steps required in writing a simple Expert Advisor based on a developed trading strategy. The structure of an Expert Advisor, the use of built-in technical indicators and trading functions, the details of the Debug mode and use of the Strategy Tester are presented.
 
Carl Schreiber #:

I told you to look at the example there - you didn't!

What you did is just a mess.

One handle in OnInit and CopyBuffer in OnTick (or even in OnCalculate) where is that structure?

May you should read this:
Step-by-step for beginners: https://www.mql5.com/en/articles/100
quickentry: https://www.mql5.com/en/articles/496


Here i made CopyBuffer for SAR


#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2

#property indicator_type1 DRAW_ARROW
#property indicator_width1 3
#property indicator_color1 0xFF901E
#property indicator_label1 "Buy"

#property indicator_type2 DRAW_ARROW
#property indicator_width2 3
#property indicator_color2 0xFF00FF
#property indicator_label2 "Sell"

//--- indicator buffers
double Buffer1[];
double Buffer2[];

double myPoint; //initialized in OnInit
double Open[];
double Close[];
double Low[];
double High[];
int SAR_handle;
double SAR[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {   
   SetIndexBuffer(0, Buffer1);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(0, PLOT_ARROW, 161);
   SetIndexBuffer(1, Buffer2);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(1, PLOT_ARROW, 161);
   //initialize myPoint
   myPoint = Point();
   if(Digits() == 5 || Digits() == 3)
     {
      myPoint *= 10;
     }
   SAR_handle = iSAR(NULL, PERIOD_CURRENT, 0.02, 0.2);
   if(SAR_handle < 0)
     {
      Print("The creation of iSAR has failed: SAR_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
   int limit = rates_total - prev_calculated;
   //--- counting from 0 to rates_total
   ArraySetAsSeries(Buffer1, true);
   ArraySetAsSeries(Buffer2, true);
   //--- initial zero
   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
      ArrayInitialize(Buffer2, EMPTY_VALUE);
     }
   else
      limit++;
   datetime Time[];
   
   if(BarsCalculated(SAR_handle) <= 0) 
      return(0);
   if(CopyBuffer(SAR_handle, 0, 0, rates_total, SAR) <= 0) return(rates_total);
   ArraySetAsSeries(SAR, true);
   if(CopyOpen(Symbol(), PERIOD_CURRENT, 0, rates_total, Open) <= 0) return(rates_total);
   ArraySetAsSeries(Open, true);
   if(CopyClose(Symbol(), PERIOD_CURRENT, 0, rates_total, Close) <= 0) return(rates_total);
   ArraySetAsSeries(Close, true);
   if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
   ArraySetAsSeries(Low, true);
   if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
   ArraySetAsSeries(High, true);
   if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
   ArraySetAsSeries(Time, true);
   //--- main loop
   for(int i = limit-1; i >= 0; i--)
     {
      if (i >= MathMin(200000-1, rates_total-1-50)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
      
      //Indicator Buffer 1
      if(true
      
      )
        {
         Buffer1[5+i] = Low[5+i]; //Set indicator value at Candlestick Low
         
        }
      else
        {
         Buffer1[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 2
      if(true
      
      )
        {
         Buffer2[5+i] = High[5+i]; //Set indicator value at Candlestick High
         
        }
      else
        {
         Buffer2[i] = EMPTY_VALUE;
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+


So how can i write this condition :

if(first SAR value > first last  SAR value)



 

Can you read or do you only know how to copy and paste?

Here is decribed that CopyBuffer fills an array with values, now you have to access the values in the filled array. This is described and explained in the a.m. articles:
Step-by-step for beginners: https://www.mql5.com/en/articles/100
quickentry: https://www.mql5.com/en/articles/496

Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
CopyBuffer - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Carl Schreiber #:

Can you read or do you only know how to copy and paste?

Here is decribed that CopyBuffer fills an array with values, now you have to access the values in the filled array. This is described and explained in the a.m. articles:
Step-by-step for beginners: https://www.mql5.com/en/articles/100
quickentry: https://www.mql5.com/en/articles/496

There are 3 variants of function calls:

Call by the first position and the number of required elements

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer number
   int       start_pos,            // start position
   int       count,                // amount to copy
   double    buffer[]              // target array to copy
   );

Call by the start date and the number of required elements

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer number
   datetime  start_time,           // start date and time
   int       count,                // amount to copy
   double    buffer[]              // target array to copy
   );

Call by the start and end dates of a required time interval

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer number
   datetime  start_time,           // start date and time
   datetime  stop_time,            // end date and time
   double    buffer[]              // target array to copy
   );



---------------

I guess what I'm asking is not in line with these three.

Reason: