Problem when indicator draws on bar 0

 

So i designed a simple indicator which is more less a MACD applied on KAMA averages.

Everything looks to work fine except for one thing: when it comes to draw the indicator its value is always a constant 1. I don't know if it is a problem with the drawing code or a problem with the value of the indicator on bar 0.

//+------------------------------------------------------------------+
//|                                      diferencia_entre_medias.mq4 |
//|                                     javier ignacio pardo lavella |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "javier ignacio pardo lavella"
#property link      ""


#property indicator_separate_window
#property indicator_buffers 1
#property  indicator_color1  Black
#property indicator_level1 100
#property indicator_levelcolor Red
#property indicator_levelstyle 0

//-----parametros
extern int       kama_period_corta = 10;
extern int       MA_Shift_corta=1;
extern int       kama_period_larga = 30;
extern int       MA_Shift_larga=1;
extern double    fast_ma_period = 2.0;
extern double    slow_ma_period = 30.0;
extern string    Price_Customs = "0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW";
extern int       Input_Price_Customs1 = 0;
extern int       Input_Price_Customs2 = 1;
//--------variables
int periodomaximo;

//--------buffers
double DIFERENCIA[];
double KAMA_1[];
double KAMA_2[];

#include <PriceSeries.mqh>
/* Selecting prices, based on which the indicator will be calculated 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
   


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
  //---- 2 additional buffers are used for counting.
   IndicatorBuffers(3);
   SetIndexBuffer(1,KAMA_1);
   SetIndexBuffer(2,KAMA_2);
 
 //---- indicator line
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,DIFERENCIA);
//---- name for DataWindow and indicator subwindow label
   short_name="KAMA("+kama_period_corta+") / KAMA ("+kama_period_larga+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
//----
   periodomaximo = kama_period_larga;
   if (kama_period_corta>kama_period_larga) periodomaximo = kama_period_corta;
   SetIndexDrawBegin(0,periodomaximo);

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
    int  i,  counted_bars=IndicatorCounted();
     
   //----medias
   i = Bars - counted_bars-1;
   
   double fastest = 2 / (fast_ma_period + 1);
   double slowest = 2 / (slow_ma_period + 1); 
    
   
   while(i>0){
   
      double er1 = 1, er2 = 1, noise_1 = 0, noise_2 = 0, signal_1, signal_2;
      double Custom_price_i1 = PriceSeries(Input_Price_Customs1,i);
      double Custom_price_i2 = PriceSeries(Input_Price_Customs2,i);
      double Custom_price_ikamacorta = PriceSeries(Input_Price_Customs1,i+kama_period_corta);
      double Custom_price_ikamalarga = PriceSeries(Input_Price_Customs2,i+kama_period_larga);
      
      
      signal_1 = MathAbs(Custom_price_i1 - Custom_price_ikamacorta);
      
      signal_2 = MathAbs(Custom_price_i2 - Custom_price_ikamalarga);
           
      
            
      for (int j=0; j<kama_period_corta; j++){
      double Custom_price_ijc = PriceSeries(Input_Price_Customs1,i+j);
      double Custom_price_ij1c = PriceSeries(Input_Price_Customs1,i+j+1);
      noise_1 += MathAbs(Custom_price_ijc - Custom_price_ij1c);
      }
      
         
      for (j=0; j<kama_period_larga; j++){
      double Custom_price_ijl = PriceSeries(Input_Price_Customs2,i+j);
      double Custom_price_ij1l = PriceSeries(Input_Price_Customs2,i+j+1);
      noise_2 += MathAbs(Custom_price_ijl - Custom_price_ij1l);
      }
       
      
      if (noise_1 > 0)   
         er1 = signal_1 / noise_1;
      if (noise_2 > 0)
         er2 = signal_2 / noise_2;
         
      double sc_1 = MathPow((er1 * (fastest - slowest) + slowest), 2);
      double sc_2 = MathPow((er2 * (fastest - slowest) + slowest), 2);
     
      KAMA_1[i] = KAMA_1[i+1] + sc_1 * (Custom_price_i1 - KAMA_1[i+1]);
      KAMA_2[i] = KAMA_2[i+1] + sc_2 * (Custom_price_i2 - KAMA_2[i+1]);}
     
      i--;
   }
   
  //----diferencia
   periodomaximo = kama_period_larga;
   if (kama_period_corta>kama_period_larga) periodomaximo = kama_period_corta;
   
   //----
   if(Bars<=periodomaximo) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=periodomaximo;i++) DIFERENCIA[Bars-i]=0.0;
//----
   i=Bars-periodomaximo-1;
   if(counted_bars>=periodomaximo) i=Bars-counted_bars-1;
   while(i>=0)
   {
   
   DIFERENCIA[i] = KAMA_1[i] / KAMA_2[i]*100;
   i--;
      } 
//----

      
   return(0);
  }
//+----------------------------------------

Also, if i want to use this code to draw the SMA of the indicator, how would the init function be in that case so that the indicator draws the signal line? Thanks!!!

//------ properties added or modified
#property indicator_buffers 2
#property  indicator_color2  Orchid


//------parameters and buffers added
extern int SignalSMA=9;
double     SignalBuffer[];

//------iteration code added AFTER everything else in the start() function (before return)

int limit;

//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;

//---- signal line counted in the 2-nd buffer
   for(int t=0; t<limit; t++)
      SignalBuffer[t]=iMAOnArray(DIFERENCIA,Bars,SignalSMA,0,MODE_SMA,t);

//---- done
   return(0);
 
Move
   DIFERENCIA[i] = KAMA_1[i] / KAMA_2[i]*100;

into the first loop and drop everything after the first loop.

Move iMAOnArray into the main loop (index by i not t)

 
thanks, i solved it by changing
while(i>0){
   
      double er1 = 1, er2 = 1, noise_1 = 0, noise_2 = 0, signal_1, signal_2;
      double Custom_price_i1 = PriceSeries(Input_Price_Customs1,i);
to
while(i>=0){
   
      double er1 = 1, er2 = 1, noise_1 = 0, noise_2 = 0, signal_1, signal_2;
      double Custom_price_i1 = PriceSeries(Input_Price_Customs1,i);

on the second problem i did what you suggested WHRoeder (thanks for the answer!!!) without understanding you until after it was done (just realized that i had to many returns and moved all the code inside the first return and it worked (though still indexing by "t", as "i" is used in the program as another variable and i just need an int variable from 0 to the limit [ i copied that code from the original MACD and changed the names and the function iMA to iMAonArray]). This is how the code looks like now, fully working:


Anybody please feel free to use, it is quite easy to read, though i keep to myself the way i look into this indicator, hehe.

//+------------------------------------------------------------------+
//|                                      diferencia_entre_medias.mq4 |
//|                                     javier ignacio pardo lavella |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "javier ignacio pardo lavella"
#property link      ""


#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  Silver
#property indicator_color2  Orchid
#property indicator_level1 0
#property indicator_levelcolor Red
#property indicator_levelstyle 0
#property  indicator_width1  2

//-----parametros
extern int       kama_period_corta = 10;
extern int       MA_Shift_corta=1;
extern int       kama_period_larga = 30;
extern int       MA_Shift_larga=1;
extern double    fast_ma_period = 2.0;
extern double    slow_ma_period = 30.0;
extern string    Price_Customs = "0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW";
extern int       Input_Price_Customs1 = 0;
extern int       Input_Price_Customs2 = 1;
extern int       SignalMA=7;
//--------variables
int periodomaximo;

//--------buffers
double DIFERENCIA[];
double KAMA_1[];
double KAMA_2[];
double SignalBuffer[];

#include <PriceSeries.mqh>
/* Selecting prices, based on which the indicator will be calculated 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
   


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
  //---- 2 additional buffers are used for counting.
   IndicatorBuffers(4);
   SetIndexBuffer(2,KAMA_1);
   SetIndexBuffer(3,KAMA_2);
 
 //---- indicator line
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0,DIFERENCIA);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,SignalBuffer);
//---- name for DataWindow and indicator subwindow label
   short_name="KAMA("+kama_period_corta+") / KAMA ("+kama_period_larga+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
   SetIndexLabel(1,"Signal");
//----
   periodomaximo = kama_period_larga;
   if (kama_period_corta>kama_period_larga) periodomaximo = kama_period_corta;
   SetIndexDrawBegin(0,periodomaximo);
   SetIndexDrawBegin(1,periodomaximo);

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
    int  i,  counted_bars=IndicatorCounted();
     
   //----medias
   i = Bars - counted_bars-1;
   
   double fastest = 2 / (fast_ma_period + 1);
   double slowest = 2 / (slow_ma_period + 1); 
    
   
   while(i>=0){
   
      double er1 = 1, er2 = 1, noise_1 = 0, noise_2 = 0, signal_1, signal_2;
      double Custom_price_i1 = PriceSeries(Input_Price_Customs1,i);
      double Custom_price_i2 = PriceSeries(Input_Price_Customs2,i);
      double Custom_price_ikamacorta = PriceSeries(Input_Price_Customs1,i+kama_period_corta);
      double Custom_price_ikamalarga = PriceSeries(Input_Price_Customs2,i+kama_period_larga);
      
      
      signal_1 = MathAbs(Custom_price_i1 - Custom_price_ikamacorta);
      
      signal_2 = MathAbs(Custom_price_i2 - Custom_price_ikamalarga);
           
      
            
      for (int j=0; j<kama_period_corta; j++){
      double Custom_price_ijc = PriceSeries(Input_Price_Customs1,i+j);
      double Custom_price_ij1c = PriceSeries(Input_Price_Customs1,i+j+1);
      noise_1 += MathAbs(Custom_price_ijc - Custom_price_ij1c);
      }
      
         
      for (j=0; j<kama_period_larga; j++){
      double Custom_price_ijl = PriceSeries(Input_Price_Customs2,i+j);
      double Custom_price_ij1l = PriceSeries(Input_Price_Customs2,i+j+1);
      noise_2 += MathAbs(Custom_price_ijl - Custom_price_ij1l);
      }
       
      
      if (noise_1 > 0)   
         er1 = signal_1 / noise_1;
      if (noise_2 > 0)
         er2 = signal_2 / noise_2;
         
      double sc_1 = MathPow((er1 * (fastest - slowest) + slowest), 2);
      double sc_2 = MathPow((er2 * (fastest - slowest) + slowest), 2);
     
      KAMA_1[i] = KAMA_1[i+1] + sc_1 * (Custom_price_i1 - KAMA_1[i+1]);
      KAMA_2[i] = KAMA_2[i+1] + sc_2 * (Custom_price_i2 - KAMA_2[i+1]);
     
      i--;}
   
   
  //----diferencia
   periodomaximo = kama_period_larga;
   if (kama_period_corta>kama_period_larga) periodomaximo = kama_period_corta;
   
   //----
   if(Bars<=periodomaximo) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=periodomaximo;i++) DIFERENCIA[Bars-i]=0.0;
//----
   i=Bars-periodomaximo-1;
   if(counted_bars>=periodomaximo) i=Bars-counted_bars-1;
   while(i>=0)
   {
   
   DIFERENCIA[i] = (KAMA_1[i] / KAMA_2[i]*100)-100;
   i--;
      } 
//----
//------iteration code added AFTER everything else in the start() function (before return)

int limit;

//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;

//---- signal line counted in the 2-nd buffer
   for(int t=0; t<limit; t++)
      SignalBuffer[t]=iMAOnArray(DIFERENCIA,Bars,SignalMA,0,MODE_LWMA,t);

//---- done
   

      
   return(0);
  }
//+----------------------------------------
Reason: