Indicator Not Refreshing

 

Hello All

I'm attempting to get this indicator to update every 15 minutes, but it's not working, and switching the timeframe period manually makes it work. The objective is to print the line on the last previous LOW that is above the SMA, and the indication Print line once this LOW it come below the SMA . same vice versa for last high below SMA and print once this high it come above SMA Do you have any clue what's wrong with the code?


Thanks on advance . .


//+------------------------------------------------------------------+
//|                    
//|                   
//|                                           
//+------------------------------------------------------------------+

#property link "123"
#property description "Just for Fun"
#property strict

//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  clrNONE



//--- input parameters

extern bool Refresh_every15M=false;
extern bool reversebs=false;
extern string lnDescriptionbuy="Buy-.01";
extern string lnDescriptionsell="sell-.01";
input string useHLine="HLINE2";
input string useHLine2="HLINE3";
extern bool useLastHigh=true;
extern bool useLastLow=true;

double last_high=0;
double lastlow=200;

double pt;
double shiftHLine3=0;
int highest1=0,lowest1=0;
double HHigh=0,LLow=0;
datetime period1=0;
datetime period2=0;


//+------------------------------------------------------------------+
//| resetALL
//+------------------------------------------------------------------+
void resetALL()
  {
   last_high=0;lastlow=200;
   highest1=0;lowest1=0;
   HHigh=0;LLow=0;
   ObjectDelete(useHLine);
   ObjectDelete(useHLine2);
   
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {

   //initialize myPoint
   if(Digits==3 || Digits==5) pt=10*Point;
   else                       pt=Point;

//----
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+

int deinit()
  {
//----
   ObjectDelete(0,useHLine);
   ObjectDelete(0,useHLine2);
//----
   return(0);
  }
  
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;
 for(int i = limit-1; i >= 0; i--)
     {
   
      if (( Low[i]) > iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, i) && ( Low[i]) <  iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, 0)  )
     
 
        {
         LLow = Low[i]; //Set indicator value at Candlestick Low
         
 
      
        }

    
         if (( High[i]) < iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, i) && ( High[i]) >  iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, 0)   )
     
      
        {
         HHigh = High[i]; //Set indicator value at Candlestick High
                

  
        }
     
        
      

        
        }

        

  
 





   if(ObjectType(useHLine2)==OBJ_HLINE)lastlow=ObjectGet(useHLine2,OBJPROP_PRICE1);
   if(ObjectType(useHLine)==OBJ_HLINE)last_high=ObjectGet(useHLine,OBJPROP_PRICE1);
   if(lastlow!=GlobalVariableGet(useHLine2))GlobalVariableSet(useHLine2,lastlow);
   if(last_high!=GlobalVariableGet(useHLine))GlobalVariableSet(useHLine,last_high);

   if(useLastHigh==true)
     {
      if(HHigh>last_high)
         last_high=HHigh;
     }

   if(useLastLow==true)
     {
      if(LLow<lastlow)
         lastlow=LLow;
     }

   if(reversebs==false)
     {

      ObjectDelete(useHLine2);
      ObjectCreate(useHLine2,OBJ_HLINE,0,0,lastlow);
      ObjectSetText(useHLine2,lnDescriptionbuy);
      ObjectSet(useHLine2,OBJPROP_COLOR,clrAqua);//clrNONE
      ObjectSet(useHLine2,OBJPROP_WIDTH,1);
      ObjectSet(useHLine2,OBJPROP_RAY,False);

      ObjectDelete(useHLine);
      ObjectCreate(useHLine,OBJ_HLINE,0,0,last_high);
      ObjectSetText(useHLine,lnDescriptionsell);
      ObjectSet(useHLine,OBJPROP_COLOR,clrYellow);
      ObjectSet(useHLine,OBJPROP_WIDTH,1);
      ObjectSet(useHLine,OBJPROP_RAY,False);
     }
   if(reversebs==true)
     {

      ObjectDelete(useHLine2);
      ObjectCreate(useHLine2,OBJ_HLINE,0,0,lastlow);
      ObjectSetText(useHLine2,lnDescriptionsell);
      ObjectSet(useHLine2,OBJPROP_COLOR,clrAqua);//clrNONE
      ObjectSet(useHLine2,OBJPROP_WIDTH,1);
      ObjectSet(useHLine2,OBJPROP_RAY,False);

      ObjectDelete(useHLine);
      ObjectCreate(useHLine,OBJ_HLINE,0,0,last_high);
      ObjectSetText(useHLine,lnDescriptionbuy);
      ObjectSet(useHLine,OBJPROP_COLOR,clrYellow);
      ObjectSet(useHLine,OBJPROP_WIDTH,1);
      ObjectSet(useHLine,OBJPROP_RAY,False);
     }

   period1=iTime(NULL,PERIOD_M15,1);
  if(period1>period2 && Refresh_every15M==true)
     {
      resetALL();
      period2=period1;

     }

   return(rates_total);
  }


//+------------------------------------------------------------------+
 
alawy103:

Hello All

I'm attempting to get this indicator to update every 15 minutes, but it's not working, and switching the timeframe period manually makes it work. The objective is to print the line on the last previous LOW that is above the SMA, and the indication Print line once this LOW it come below the SMA . same vice versa for last high below SMA and print once this high it come above SMA Do you have any clue what's wrong with the code?


Thanks on advance . .


int limit = rates_total - prev_calculated;
 for(int i = limit-1; i >= 0; i--)
   if (( Low[i]) > iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, i) && ( Low[i]) <  iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, 0)  )

I'd say this is wrong. It works well when prev_calculated == 0, but won't handle new bars properly.

Let's break down the scenarios for limit and i:

 Scenario
 Result
when rates_total - prev_calculated == rates_total
limit works out to be Bars and i works out to Bars - 1.

This is fine, although your while condition (i >= 0) means you'll be checking the currently open bar when i == 0.
when rates_total - prev_calculated == 0
limit works out to 0 and i works out to -1.

Not necessarily a bad thing because it ignores the currently open bar on new ticks, which means no repainting. However, on a new bar, i == 0, and you're checking the new bar's value. Probably not your intention.
when rates_total - prev_calculated == 1
limit works out to 1 and i works out to 0.

Here's the issue - you're only looking at the currently open bar, and it's only happening once on the close of a bar. Also, when i == 0, Low[i] means that you're checking the Low for the currently open bar.
----
if (( Low[i]) > iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, i) && ( Low[i]) <  iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, 0)  )

Are you sure you want to compare every Low[i] value in your loop to the iMA(SMA) value of the currently open bar?

----

BTW, based on your code (lack of a double array, lack of SetIndexBuffer(0, array)), this seems unnecessary

#property indicator_buffers 1
#property indicator_color1  clrNONE
 
Alexander Martinez #:

I'd say this is wrong. It works well when prev_calculated == 0, but won't handle new bars properly.

Let's break down the scenarios for limit and i:

 Scenario
 Result
when rates_total - prev_calculated == rates_total
limit works out to be Bars and i works out to Bars - 1.

This is fine, although your while condition (i >= 0) means you'll be checking the currently open bar when i == 0.
when rates_total - prev_calculated == 0
limit works out to 0 and i works out to -1.

Not necessarily a bad thing because it ignores the currently open bar on new ticks, which means no repainting. However, on a new bar, i == 0, and you're checking the new bar's value. Probably not your intention.
when rates_total - prev_calculated == 1
limit works out to 1 and i works out to 0.

Here's the issue - you're only looking at the currently open bar, and it's only happening once on the close of a bar. Also, when i == 0, Low[i] means that you're checking the Low for the currently open bar.
----

Are you sure you want to compare every Low[i] value in your loop to the iMA(SMA) value of the currently open bar?

----

BTW, based on your code (lack of a double array, lack of SetIndexBuffer(0, array)), this seems unnecessary


Hi Alexender 

Thank you for responding so quickly. I'm a little perplexed by your example. Could you please provide a code example? Apart from your query, yes, I want the indicator to prints from the last low above the SMA line and meets the conditions like this low[i] is above SMA in previous and below SMA on current bar .. 

Looking forward to hear from you . ..

 
alawy103 #:


Hi Alexender 

Thank you for responding so quickly. I'm a little perplexed by your example. Could you please provide a code example? Apart from your query, yes, I want the indicator to prints from the last low above the SMA line and meets the conditions like this low[i] is above SMA in previous and below SMA on current bar .. 

Looking forward to hear from you . ..

When
int i equals
Result
rates_total - prev_calculated == rates_total
 rates_total - 1
 Your loops checks every bar, including the currently open candle
rates_total - prev_calculated == 0
 -1  Your loop checks nothing, since -1 < 0
rates_total - prev_calculated == 1
 0  Your loop checks 1 bar, the new bar that just opened. It will not check again until another new bar.

Here's an example of how I would do it. I take it you want a repainting indicator.

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[]) {
  const bool isFirstRun = prev_calculated == 0;
  
  if (isFirstRun) {
    scan(Bars - 2); //--- Bars - 2 because we have to check index of Bars - 1;
  } else {
    scan(0);        //--- Check value of currently open bar (and repaint if conditions change)
  }
  
  return rates_total;
}

void scan(int lookback) {
  for (int i = lookback; i >= 0; i--) {
    const int prev                      = i + 1;
    const double prevLow                = Low[prev];
    const double prevSMA                = SimpleMA(prev);
    const double currentSMA             = SimpleMA(i);
    const bool isPrevLowAbovePrevSMA    = prevLow > prevSMA;
    const bool isPrevLowBelowCurrentSMA = prevLow < currentSMA;
    
    if (isPrevLowAbovePrevSMA 
          && isPrevLowBelowCurrentSMA) {
      //--- do something
    }
  }
}

double SimpleMA(const int index) {
  const double value  = iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_SMA, PRICE_CLOSE, index);
  
  return value;
}
 
Alexander Martinez #:
When
int i equals
Result
rates_total - prev_calculated == rates_total
 rates_total - 1
 Your loops checks every bar, including the currently open candle
rates_total - prev_calculated == 0
 -1  Your loop checks nothing, since -1 < 0
rates_total - prev_calculated == 1
 0  Your loop checks 1 bar, the new bar that just opened. It will not check again until another new bar.

Here's an example of how I would do it. I take it you want a repainting indicator.


Thanks Alex 

I just finished compiling it. However, it appears to be functioning in the last LOW[] on the chart which suppose the last low[] in the right side was above the SMA Line. 

 
alawy103 #:


Thanks Alex 

I just finished compiling it. However, it appears to be functioning in the last LOW[] on the chart which suppose the last low[] in the right side was above the SMA Line. 

No problem!

The loop itself should be fixed and should fix the issue of "not refreshing."

Don't worry about the following logic as it was only my interpretation of what you're trying to do and I didn't quite understand what you were trying to do, so it's probably not what you want.

const int prev                      = i + 1;
const double prevLow                = Low[prev];
const double prevSMA                = SimpleMA(prev);
const double currentSMA             = SimpleMA(i);
const bool isPrevLowAbovePrevSMA    = prevLow > prevSMA;
const bool isPrevLowBelowCurrentSMA = prevLow < currentSMA;
Fix the logic according to your needs.
 
Alexander Martinez #:

No problem!

The loop itself should be fixed and should fix the issue of "not refreshing."

Don't worry about the following logic as it was only my interpretation of what you're trying to do and I didn't quite understand what you were trying to do, so it's probably not what you want.

Fix the logic according to your needs.

Thanks Alex !! 


It Works Perfectly .. Your time and support are much appreciated.

 
alawy103 #:

Thanks Alex !! 


It Works Perfectly .. Your time and support are much appreciated.

You're welcome! Take care, alawy. 👍

 
I've searched for a solution to update my own indicator while backtesting and for continuous drawing when new market data is coming. Thank you very much! Your answer helped me as well. Great support, great example code!