IMAOnArray() Issue

 

Good night ;-)

I am writing a little oscillator to test short-term trading even in range-bound markets. I am using IMAOnArray() to calculate two thresholds that point out when is the market flat.

My problem is that IMAOnArray does not work as I expected. I have read all the documentation and searched similar entries in this forum and so forth :P.

The following code does paint but Buffer3 and Buffer4 do not hold the value properly, and it is very slow to calculate.

// Check if ignore bar 0
if(CalculateOnBarClose == true) { start = 1; }
   
// Iteration from past to present
for(int pos = limit; pos >= start; pos--)
{  
      // Median
      double median = iMA(Symbol(), 0, OsPeriod, 0, MODE_EMA, PRICE_MEDIAN, pos);
      double median1 = iMA(Symbol(), 0, OsPeriod, 0, MODE_EMA, PRICE_MEDIAN, pos+1);
     
      // Difference
      FextMapBuffer8[pos] = median - median1;
      
      // Save current absolute value
      FextMapBuffer7[pos] = MathAbs(FextMapBuffer8[pos]);
      
      // Flat lines
      double flat = iMAOnArray(FextMapBuffer7, Bars, AvPeriod, pos, MODE_EMA, pos);
      FextMapBuffer3[pos] = (flat * Gamma);
      FextMapBuffer4[pos] = 0 - (flat * Gamma);
     
      // More code down here
}

The following modification causes flat to acquire the value of EMPTY_VALUE. (Unless it is recompiled with the indicator attached to a chart, weird)

double flat = iMAOnArray(FextMapBuffer7, Bars, AvPeriod, 0, MODE_EMA, pos);

Which would be the appropiate way to do it? Full source ahead, you might like the indicator though.

//+------------------------------------------------------------------+
//| DonkeyOscillator.mq4
//| Short term trading indicator
//+------------------------------------------------------------------+
#property copyright "Flaab"
#property link      ""

//---- Properties
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_color1 DodgerBlue
#property indicator_color2 Red
#property indicator_color3 DarkSlateGray
#property indicator_color4 DarkSlateGray
#property indicator_color5 DodgerBlue
#property indicator_color6 Red
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 1
#property indicator_width4 1
#property indicator_width5 2
#property indicator_width6 2
#property indicator_style3 STYLE_DOT
#property indicator_style4 STYLE_DOT
#property indicator_style5 STYLE_DOT
#property indicator_style6 STYLE_DOT

//---- External variables
extern bool CalculateOnBarClose = true;
extern int OsPeriod             = 20;
extern int AvPeriod             = 100;
extern double Gamma             = 1;

//---- Buffers
double FextMapBuffer1[];
double FextMapBuffer2[];
double FextMapBuffer3[];
double FextMapBuffer4[];
double FextMapBuffer5[];
double FextMapBuffer6[];
double FextMapBuffer7[];
double FextMapBuffer8[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
int init()
{
   // Total buffers
   IndicatorBuffers(8);
   
   // Visible buffers
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0, FextMapBuffer1);
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(1, FextMapBuffer2);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,FextMapBuffer3);    
   SetIndexStyle(3,DRAW_LINE);
   SetIndexBuffer(3,FextMapBuffer4);
   SetIndexStyle(4,DRAW_ARROW); SetIndexArrow(4,159);    
   SetIndexStyle(5,DRAW_ARROW); SetIndexArrow(5,159);    
   
   // Internal
   SetIndexBuffer(4,FextMapBuffer5);  
   SetIndexBuffer(5,FextMapBuffer6);   
   SetIndexBuffer(6,FextMapBuffer7);  
   SetIndexBuffer(7,FextMapBuffer8);       
   
   // My name
   IndicatorShortName("Donkey short term trading test");
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   // Start, limit, etc..
   int start = 0;
   int limit;
   int counted_bars = IndicatorCounted();
   
   // nothing else to do?
   if(counted_bars < 0) 
       return(-1);

   // do not check repeated bars
   limit = Bars - 1 - counted_bars;
   
   // Check if ignore bar 0
   if(CalculateOnBarClose == true) { start = 1; }
   
   // Iteration from past to present
   for(int pos = limit; pos >= start; pos--)
   {  
      // Median
      double median = iMA(Symbol(), 0, OsPeriod, 0, MODE_EMA, PRICE_MEDIAN, pos);
      double median1 = iMA(Symbol(), 0, OsPeriod, 0, MODE_EMA, PRICE_MEDIAN, pos+1);
     
      // Difference
      FextMapBuffer8[pos] = median - median1;
      
      // Save current absolute value
      FextMapBuffer7[pos] = MathAbs(FextMapBuffer8[pos]);
      
      // Flat lines
      double flat = iMAOnArray(FextMapBuffer7, Bars, AvPeriod, pos, MODE_EMA, pos);
      FextMapBuffer3[pos] = (flat * Gamma);
      FextMapBuffer4[pos] = 0 - (flat * Gamma);
      
      // Bar open and Close
      double CLOSE = iClose(Symbol(),0, pos);
      double OPEN = iOpen(Symbol(),0, pos);
      double HIGH = iHigh(Symbol(),0, pos);
      double LOW = iLow(Symbol(),0, pos);
      
      //---- Deceleration
      if(FextMapBuffer8[pos] < FextMapBuffer8[pos+1])
      {
         // This is a red line
         FextMapBuffer2[pos] = FextMapBuffer8[pos];
         FextMapBuffer1[pos] = 0;
         
         // Calculate short-term trend
         if(FextMapBuffer8[pos] < 0)
         {
            if(CLOSE < OPEN) { FextMapBuffer6[pos] = 0; }
         } else if(FextMapBuffer8[pos] > 0 && FextMapBuffer8[pos] < FextMapBuffer3[pos+1]){
            if(CLOSE < OPEN) { FextMapBuffer6[pos] = 0; }
         }
         
      //---- Acceleration
      } else if(FextMapBuffer8[pos] > FextMapBuffer8[pos+1]){
         
         // This is a blue line
         FextMapBuffer1[pos] = FextMapBuffer8[pos];
         FextMapBuffer2[pos] = 0;
         
         // Calculate short-term trend
         if(FextMapBuffer8[pos] > 0)
         {
            if(CLOSE > OPEN) { FextMapBuffer5[pos] = 0; }
         } else if(FextMapBuffer8[pos] < 0 && FextMapBuffer8[pos] > FextMapBuffer4[pos+1] ){
            if(CLOSE > OPEN) { FextMapBuffer5[pos] = 0; }
         }
      }
   }
   
   // Flat lines
   //for(int i = limit; i >= start; i--)
   //{
   //   // Flat lines
   //   double flat = iMAOnArray(FextMapBuffer7, Bars, AvPeriod, , MaMethod, i);
   //   FextMapBuffer3[i] = (flat * Gamma);
   //   FextMapBuffer4[i] = 0 - (flat * Gamma);
   //}
   return(0);
}

Thank you ;)

 

the result of doing iMAOnArray() of your indicator buffer is going to be another buffer array so you need to

do it like this ...

for(int pos = limit; pos >= start; pos--) //first indicator loop
  { 
   buffer1[pos] = vals   //fill an indicator buffer
  }

for(int pos = limit; pos >= start; pos--) //second indicator loop
  { 
   buffer2[pos] = iMAOnArray(buffer1,0,0,0,0,pos); //fill iMAOnArray buffer
  }
 
SDC:

the result of doing iMAOnArray() of your indicator buffer is going to be another buffer array so you need to

do it like this ...

Hello SDC,

Thanks for answering. That is how I made it on the first place, but the values from past vars weren't available in the main loop :(

 

I think the problem is you miss these code ...

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

I have no idea what donkey CI look like, hopefully not looks like me but looks like ... ehm ...

Basically for iMAOnArray we have to prepare the data first, then we can do something later - something else ... .

Files:
 
onewithzachy:

I think the problem is you miss these code ...

I have no idea what donkey CI look like, hopefully not looks like me but looks like ... ehm ...

Basically for iMAOnArray we have to prepare the data first, then we can do something later - something else ... .

Thank you! I'll test it tonight ;-) The donkey oscillator is supposed to be of help for short-term trading and detecting/trading flat markets.

I'll apply it to a MACD and release it as "Donkey MACD". Blue/red dots "predict" the short/term price action.

 
flaab:

Hello SDC,

Thanks for answering. That is how I made it on the first place, but the values from past vars weren't available in the main loop :(


Try it like this then. Use buffers and separate loops for all of it, when you have it working you might merge some of the loops but for testing it is better to do separate loops. Replace your double flat with a buffer. Test each loop by setting all the buffers to draw lines so you will know if any of the calculations is creating unexpected values, and always do iMAOnArray() in a new loop.

Also check your iMAOnArray() parameters, in your full code you have pos as the forth (ma shift) parameter, when pos is limit the shift will be thousands of bars

for(pos = limit; pos >= start; pos--) //first indicator loop
  { 
   buffer1[pos] = iMA(,,,,,,pos);  
   buffer2[pos] = iMA(,,,,,,pos+1);
  }

for(pos = limit; pos >= start; pos--) //second indicator loop
  { 
   buffer3[pos] = buffer2[pos] - buffer1[pos];
  }

for(pos = limit; pos >= start; pos--) //third indicator loop
  {
   buffer4[pos] = MathAbs(buffer3[pos]);
  }

for(pos = limit; pos >= start; pos--) //forth indicator loop
  {
   buffer5[pos] = iMAOnArray(buffer4,,,,,pos); //fill iMAOnArray buffer
  }
Reason: