Can somebody help me with this OsMA-Indicator?

 

Hey guys,

I made a ColorOsMA Indicator and it works fine. Now I wanted to add two horizontal lines to the indicator. It is the first step to program my own divergence-indicator.

The indicator should print the lines at the last top and the last low of the indicator. My definition for the last top / low is very simple: As soon as the first bar is printed which has a lower OsMA value, the last OsMA bar is "my" top. Same with the lows. You can see rising and falling values in different colors, so it is easier to see when the values of the OsMA are rising or falling compared to the last period.

But although the code seems to be correct, the lines are drawn totally wrong. The arrows show the correct places where the lines should be printed.

Can somebody help?

Here is the code:

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Blue
#property indicator_color2 Navy
#property indicator_color3 Maroon
#property indicator_color4 FireBrick

//---- indicator buffers
double OsMAPosRise[];
double OsMAPosFall[];
double OsMANegRise[];
double OsMANegFall[];
//----
extern bool IndicatorLines = true;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
  int init()
  {
   string indi_name;
//---- indicator line
   SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,5);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,5);
   SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,5);
   SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID,5);
   
   SetIndexBuffer(0,OsMAPosRise);
   SetIndexBuffer(1,OsMAPosFall);
   SetIndexBuffer(2,OsMANegRise);
   SetIndexBuffer(3,OsMANegFall);
      
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));

//---- name for DataWindow and indicator subwindow label   
   indi_name="ColorOsMA";
   IndicatorShortName(indi_name);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
   {
   int counted_bars = IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit = MathMin(Bars - counted_bars, Bars-1);
   
   for(int i = limit; i >= 0; i--)
   {    
      double OsMA1 = iOsMA(NULL, 0, 12, 26, 9, PRICE_CLOSE, i+1);
      double OsMA2 = iOsMA(NULL, 0, 12, 26, 9, PRICE_CLOSE, i+2);
               
      if (OsMA1 >= 0) 
      {
              OsMANegRise[i+1] = 0;
              OsMANegFall[i+1] = 0;
         if (OsMA1 >= OsMA2)
         {
            OsMAPosRise[i+1] = OsMA1;
                 OsMAPosFall[i+1] = 0;
              }
              else if (OsMA1 < OsMA2)
              {
            OsMAPosRise[i+1] = 0;
                 OsMAPosFall[i+1] = OsMA1;
                 if (IndicatorLines)
                 {
                 if (ObjectFind("BlueLine")) ObjectDelete("BlueLine");
                 ObjectCreate("BlueLine", OBJ_TREND, 1, iTime(NULL, 0, i+2), OsMA2, TimeCurrent(), OsMA2);
                 ObjectSet("BlueLine", OBJPROP_COLOR, clrBlue);
              }
              }         
      }
      else if (OsMA1 < 0)
      {
              OsMAPosRise[i+1] = 0;
              OsMAPosFall[i+1] = 0;
         if (OsMA1 >= OsMA2)
         {
            OsMANegRise[i+1] = OsMA1;
                 OsMANegFall[i+1] = 0;
                 if (IndicatorLines)
                 {
                 if (ObjectFind("RedLine")) ObjectDelete("RedLine");
                 ObjectCreate("RedLine", OBJ_TREND, 1, iTime(NULL, 0, i+2), OsMA2, TimeCurrent(), OsMA2);
                 ObjectSet("RedLine", OBJPROP_COLOR, clrRed);
              }
              }
              else if (OsMA1 < OsMA2)
              {
            OsMANegRise[i+1] = 0;
                 OsMANegFall[i+1] = OsMA1;
              }         
      }
          
        }
        return(0);      
 }
 
if (IndicatorLines)
   {
   for(int x = 1; x <= limit; x++)
      {
      if (OsMAPosRise[x] > OsMAPosFall[x + 1])
         {
         if (ObjectFind("BlueLine")) ObjectDelete("BlueLine");
         ObjectCreate("BlueLine", OBJ_TREND, 1, iTime(NULL, 0, x), OsMAPosRise[x], TimeCurrent(), OsMAPosRise[x]);
         ObjectSet("BlueLine", OBJPROP_COLOR, clrBlue);
         break;
         }
      }
      for(x = 1; x <= limit; x++)
         {
         if (OsMANegFall[x] < OsMANegRise[x + 1])
            {
            if (ObjectFind("RedLine")) ObjectDelete("RedLine");
            ObjectCreate("RedLine", OBJ_TREND, 1, iTime(NULL, 0, x), OsMANegFall[x], TimeCurrent(), OsMANegFall[x]);
            ObjectSet("RedLine", OBJPROP_COLOR, clrRed);
            break;
            }
         }
   }
 

Hi qjol,

it works perfect!! Thank you very much!

I studied your code and my code again. To be honest, I still have no idea why my code didn't work. When I look at the positive OsMA values: Every time the OsMA(x) < OsMA(x+1) I color the OsMA in navy. So when there is a color change from blue to navy, I know that the last blue value ( OsMA(x+1) ) is the place the line should be printed. Where is my logical mistake? Even if I look at your code I don't find the error in my code..


Edit:

I just see that it is not 100% ok. Here is the problem: The Blue Line is printed correct. But now the OsMA shows only FALLING red values for some periods without a RISING red value. So the Red Line is always printed at the current value, although it should be printed before the blue line at the last Crimson-colored value.

Excuse my English. I hope it was understandable...

 

Here a screenshot:


 

I corrected it the code and inserted also some corresponding lines in the chart. As I said, this will be the beginning of my own divergence-indicator.

There is just one thing that is not clear to me. When I change timeframes, the lines in the indicator also move to their correct place. But the corresponding lines in the chart are not replaced. And when I delete them manually, they don't comeback until I manually refresh the chart. Sounds strange, doesn't it?

Here is the code:

if (IndicatorLines)
   {
   for(int x = 1; x <= limit; x++)
      {
      if (OsMAPosRise[x] == 0 && OsMAPosRise[x + 1] > 0)
         {
         if (ObjectFind("OsMAPos")) ObjectDelete("OsMAPos");
         ObjectCreate("OsMAPos", OBJ_TREND, 1, iTime(NULL, 0, x+1), OsMAPosRise[x+1], TimeCurrent(), OsMAPosRise[x+1]);
         ObjectSet("OsMAPos", OBJPROP_COLOR, clrBlue);
         ObjectSet("OsMAPos", OBJPROP_RAY_RIGHT, false);
         if (ObjectFind("ChartLine1")) ObjectDelete("ChartLine1");
         ObjectCreate("ChartLine1", OBJ_TREND, 0, iTime(NULL, 0, x+1), iHigh(NULL, 0, x+1), TimeCurrent(), iHigh(NULL, 0, x+1));
         ObjectSet("ChartLine1", OBJPROP_COLOR, clrBlue);
         ObjectSet("ChartLine1", OBJPROP_RAY_RIGHT, false);
         break;
         }
      }
      for(x = 1; x <= limit; x++)
         {
         if (OsMANegFall[x] == 0 && OsMANegFall[x + 1] < 0)
            {
            if (ObjectFind("OsMANeg")) ObjectDelete("OsMANeg");
            ObjectCreate("OsMANeg", OBJ_TREND, 1, iTime(NULL, 0, x+1), OsMANegFall[x+1], TimeCurrent(), OsMANegFall[x+1]);
            ObjectSet("OsMANeg", OBJPROP_COLOR, clrRed);
            ObjectSet("OsMANeg", OBJPROP_RAY_RIGHT, false);
            if (ObjectFind("ChartLine2")) ObjectDelete("ChartLine2");
            ObjectCreate("ChartLine2", OBJ_TREND, 0, iTime(NULL, 0, x+1), iLow(NULL, 0, x+1), TimeCurrent(), iLow(NULL, 0, x+1));
            ObjectSet("ChartLine2", OBJPROP_COLOR, clrRed);
            ObjectSet("ChartLine2", OBJPROP_RAY_RIGHT, false);
            break;
            }
         }
   }
 
if(!ObjectCreate("OsMAPos", OBJ_TREND, 1, iTime(NULL, 0, x+1), OsMAPosRise[x+1], TimeCurrent(), OsMAPosRise[x+1]))
   {
   ObjectSet("OsMAPos", OBJPROP_COLOR, clrBlue);
   ObjectSet("OsMAPos", OBJPROP_RAY_RIGHT, false);
   }
 

Sorry, I don't get the point. The indicator lines work 100% now. It is just about the additional lines in the chart.

I modified the code like you did above but that doesn't fix the error.

 

you wrote

mar:

There is just one thing that is not clear to me. When I change timeframes, the lines in the indicator also move to their correct place. But the corresponding lines in the chart are not replaced. And when I delete them manually, they don't comeback until I manually refresh the chart. Sounds strange, doesn't it?


 

If you put that code in the init, the line will be deleted when changing timeframe, and redrawed then after

int init()
  {
  if (ObjectFind("OsMAPos")) ObjectDelete("OsMAPos");
   if (ObjectFind("OsMANeg")) ObjectDelete("OsMANeg");
  if (ObjectFind("ChartLine1")) ObjectDelete("ChartLine1");
  if (ObjectFind("ChartLine2")) ObjectDelete("ChartLine2");
}
 
Maybe I didn't explain it correctly. I mean the lines in the price-area of the chart. Not the indicator window. And the additional code you showed concerns window #1, the indicator. But the lines in the indicator work fine. Just the lines of the price-area don't work when I change time frames.
 
@fforr: I tried this before and I did it again right now. I put this code into the init() and into the deinit(). But with no success. When I place the indicator in the chart once, it works fine. As soon as I change timeframe, the indicator lines are modified correctly but the price-lines are still placed like they have been the first time I dragged the indicator to the chart. I always have to remove them manually, update the chart manually and then they are correctly placed. I have no idea why.... The price-lines are printed in the same routine like the indicator lines...
Reason: