Arrow Indicator - No signals?

 

Hi guys,


I am learning to make indicators, for now I want to make simple one:

Indicator rule:

If close price [1] is x amount higher then close price [2] then place buy arrow on close price [1];

If close price [1] is x amount lower then close price [2] then place sell arrow on close price[1].


But the indicator does not produce any arrows.  Can someone point me in the right direction why its not placing arrows?

//+------------------------------------------------------------------+
//|                               Simple Arrow Indicators Part 1.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Buy
#property indicator_label1  "Buy"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLime
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Sell
#property indicator_label2  "Sell"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters
input int      InpPeriod = 1;

input double BuyTrigger = 0.005; //Buy Trigger in Decimals
input double SellTrigger = -0.005; //Sell Trigger in Decimals
//--- indicator buffers
double         BuyBuffer[];
double         SellBuffer[];
double PriceDif[];
//---Arrow Shift in pixels
int      m_ArrowShift = 10;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, SellBuffer, INDICATOR_DATA);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(0, PLOT_ARROW, 233);
   PlotIndexSetInteger(1, PLOT_ARROW, 234);
//---Set when the Indicator stasrt Drawing
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpPeriod);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpPeriod);
//---The Value that our Indicator takes if it is Invalid/Empty
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//---Set Number of Pixels to shift our Arrows by from the set Plot Price
   PlotIndexSetInteger(0, PLOT_ARROW_SHIFT, m_ArrowShift);
   PlotIndexSetInteger(1, PLOT_ARROW_SHIFT, -m_ArrowShift);
//---Array Set Series
   ArraySetAsSeries(BuyBuffer, true);
   ArraySetAsSeries(SellBuffer, true);
   ArraySetAsSeries(PriceDif,true);


//---
   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[])
  {
//---array series setting
   ArraySetAsSeries(time, true);
   ArraySetAsSeries(open, true);
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);
   ArraySetAsSeries(tick_volume, true);
   ArraySetAsSeries(volume, true);
   ArraySetAsSeries(spread, true);
//---Create Control
   int limit;
   if(prev_calculated<InpPeriod)
     
      limit=rates_total;
      else limit =prev_calculated-rates_total;
        

//---Main loop
   for(int i = 0; i <= limit && !IsStopped(); i++)
     {
  PriceDif[i+1] = (close[i+1]-close[i+2])/close[2];
     Comment(close[i+1]+"\n"+close[i+2]+"\n"+PriceDif[i+1]);
  
    
       
      //---Buy Conditions
      if(PriceDif[i+1]>BuyTrigger)//buy true
        {
         BuyBuffer[i+1] = close[i+1];
        }
      else //Buy is false
        {
         BuyBuffer[i+1] = EMPTY_VALUE;
        }

      //Sell Conditions
      if(PriceDif[i+1]<SellTrigger)//Sell true
        {
         SellBuffer[i+1] = close[i+1];
        }
      else //Sell is false
        {
         SellBuffer[i+1] = EMPTY_VALUE;
        }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


 
Divania111: But the indicator does not produce any arrows.
  1. Please edit your (original) post and use the CODE button (Alt-S)! (For large amounts of code, attach it.)
              General rules and best pratices of the Forum. - General - MQL5 programming forum (2019)
              Messages Editor

  2.   SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA);
      SetIndexBuffer(1, SellBuffer, INDICATOR_DATA);

    Read what indicator data means.

  3.    if(prev_calculated<InpPeriod)
    
          limit=rates_total;
          else limit =prev_calculated-rates_total;
    
       for(int i = 0; i <= limit && !IsStopped(); i++){
           PriceDif[i+1] = (close[i+1]-close[i+2])/close[2];
    If limit equals rates_total, you try to access beyond your arrays; array Exceeded.
              How to do your lookbacks correctly #9#14 & #19
  4. Did you set the direction of close?
    To define the indexing direction in the time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[] arrays, call the ArrayGetAsSeries() function. In order not to depend on defaults, call the ArraySetAsSeries() function for the arrays to work with.
              Event Handling / OnCalculate - Reference on algorithmic/automated trading language for MetaTrader 5
 

Hi William,


Thanks for the pointers. I adjusted the code a bit based on your input. Now i only get sell arrows at the bottom of the charts. 


In regards to your pointers:

Indicator Data buffer:

From my understanding it stores the value at which the plotting should start.  So first I calculate the price difference between the closing prices [i+1] and [i+2] inside the main loop. 

//---Main loop
   for(int i = 0; i <= limit && !IsStopped(); i++)
     {
  PriceDif[i+1] = (close[i+1]-close[i+2]); //calculating price difference between the closing prices
     
  Comment(close[i+1]+"\n"+close[i+2]+"\n"+PriceDif[i+1]);

To keep it simple, I just store the positive or negative number. The buy trigger is >0 the sell trigger is <0.



So next I check the buy trigger inside the main loop:

 If the price difference is larger than the buy trigger then I store the closing price inside the buy buffer [i+1] and otherwise buy buffer [i+1] = empty. 

So I would expect an up arrow to be drawn at the previous bar (i+1) at close price of the same i+1 bar. (excluding the arrow shift of 10 pixels). 


Yet now I only receive sell arrows at the bottom of the chart. Furthermore, I wanted to check the values with the comment opperator as seen above, but it doesnt print it. 


  //---Buy Conditions
      if(PriceDif[i+1]>BuyTrigger)//buy true
        {
         BuyBuffer[i+1] = close[i+1];
        }
      else //Buy is false
        {
         BuyBuffer[i+1] = EMPTY_VALUE;
        }


As with regard to the direction of close  I believe I did set it as a series:

//---array series setting
   ArraySetAsSeries(time, true);
   ArraySetAsSeries(open, true);
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);
   ArraySetAsSeries(tick_volume, true);
   ArraySetAsSeries(volume, true);
   ArraySetAsSeries(spread, true);


I also changed the limit check code, based on your feedback:

int limit = prev_calculated <= InpPeriod ? rates_total - InpPeriod - 1 : rates_total - prev_calculated;


Could you give additional pointers?

Reason: