Indicator displays improperly

 

This has been driving me nuts for a week now, hope someone can help.

I have an indicator that draws entry lines at the top and bottem of the bar before an inside bar. It will also allow the user to elect to offset the lines, and to allow an additional offset to the buy indicator to account for the spread. The problem is that some, but not all, of the lines are a pip off. The code that determines the position of the lines is:

//+------------------------------------------------------------------+
//| Function DrawObjects()   Create indicator bars
//+------------------------------------------------------------------+

void DrawObjects()
{

int intSpread;
int intLength;
double dblHigh;
double dblLow;
   // Compute spread for buy indicator
   if (bolBuySpread == true)intSpread = MarketInfo(Symbol(),MODE_SPREAD);
   else intSpread = 0;
   
   // Loop through bars
   for ( int i = 1; i < intNumberOfBars; i++)
   {
      // Check to see if inside bar exists
      if(iHigh(NULL, 0, i) < iHigh(NULL, 0, i+1) && iLow(NULL, 0,i) > iLow(NULL, 0, i+1))
      {
         // Correct indicator line length if number of bars showing are less than specified length
         intLength = intLineLength;
         if ( i < intLineLength) intLength = i+1;

         // Draw buy indicator
         dblHigh = High[i+1] + ((intLineOffset+intSpread)* dblPoints);
         ObjectCreate("IBBUY" + i, OBJ_TREND, 0, Time[i+1], dblHigh, Time[(i+1) - intLength], dblHigh);
         ObjectSet("IBBUY" + i, OBJPROP_RAY, false);
         ObjectSet("IBBUY" + i, OBJPROP_WIDTH, intLineWidth);
         ObjectSet("IBBUY" + i, OBJPROP_COLOR, colBuyLine);
         
         // Draw sell indicator
         dblLow = Low[i+1] - (intLineOffset * dblPoints);
         ObjectCreate("IBSELL" + i, OBJ_TREND, 0, Time[i+1], dblLow, Time[(i+1) - intLength], dblLow);
         ObjectSet("IBSELL" + i, OBJPROP_RAY, false);
         ObjectSet("IBSELL" + i, OBJPROP_WIDTH, intLineWidth);
         ObjectSet("IBSELL" + i, OBJPROP_COLOR, colSellLine);
      } // End if
   } // Next i
    
} // End function DrawObjects()

The global variable dblPoints is set with a seperate function to correct the indicator for brokers that use 3 and 5 digits in the price:

//-------------------------------------------------------------------+
// Function GetPoints()  Correct point value if broker uses 3 or 5
//                       digits in price
//-------------------------------------------------------------------+

double GetPoints()
{
   if (Digits == 2 || Digits == 3) dblPoints = 0.01;
   else dblPoints = 0.0001;
   return(dblPoints);
   
}  // End Function GetPoints()

I don't know if I am running into a type casting problem, rounding error or what, but I have tried everything I can think of. Hoping someone in here can help figure it out.

Thanks in advance.

Bob

 

ObjectCreate may fail when a object with the "name" already exist. Look the code seems trying to name object as "IBSELL" + i. which may explain why some are pip off. when you run the funcation multiple times, chance happen to create more than one "IBSELL" + i for different line, and only one can exist!

you can use TIME of the line as obj name which is always unique.

 
Dow2 wrote >>

ObjectCreate may fail when a object with the "name" already exist. Look the code seems trying to name object as "IBSELL" + i. which may explain why some are pip off. when you run the funcation multiple times, chance happen to create more than one "IBSELL" + i for different line, and only one can exist!

you can use TIME of the line as obj name which is always unique.

I really appreciate your taking the time to look at this.

I don't think this is the problem since DeleteObjects() is called before DrawObjects():

//+------------------------------------------------------------------+
//| Function DeleteObjects()
//+------------------------------------------------------------------+

void DeleteObjects()
{
   // Loop through bars
   for (int i=1; i <= intNumberOfBars; i++)
   {
      // If indicator is found...
      if (ObjectFind("IBBUY" + i) != -1)
      {
         ObjectDelete("IBBUY" + i); // Delete buy indicator
         ObjectDelete("IBSELL" + i); // Delete sell indicator
      }  // End if
   } // Next i
   
} //  End Function DeleteObjects()

This should, I believe, clear the chart of all "IBBUY" and "IBSELL" objects before they are redrawn. I have attached the code if anyone is interested, which is probibly what I should have done in the first place.

I'm sure that a big part of the problem is my unfamiliarity with MQL. All I have ever worked with is ASP/VB.net, and that was some years ago.

Once again, thank you.

Bob

Files:
 

With DeleteObject seems good code. I can't tell where is the problem. however few tips.

1) try to use ObjectsDeleteAll to replace the loop DeleteObjects . which should save some CPU.

2) As a passed bar's status shouldn't change in the future, draw obects in a loop seems not necessary. usualy a indicator only redraw 1 and 0, some of the indicator don't draw 0 bar.

 
Dow2 wrote >>

With DeleteObject seems good code. I can't tell where is the problem. however few tips.

1) try to use ObjectsDeleteAll to replace the loop DeleteObjects . which should save some CPU.

2) As a passed bar's status shouldn't change in the future, draw obects in a loop seems not necessary. usualy a indicator only redraw 1 and 0, some of the indicator don't draw 0 bar.

1) I'm all for saving CPU resources, but I believe using ObjectsDeleteAll would also remove the 89 SSMA which is also a part of the stratagy that I am following. Since this only occurs when the indicator is first loaded, and at a new bar (30M at present), I don't think it is really that critical a problem. That is, of course, unless the bars to test were increased to a ridiculous number. This is unnecessary since they are really only valid for, at the absolute most, 10 bars anyway.

2) This is something I will have to look into, especially since I'm sure I will run into it again as I continue with the MQL learning curve. The reason I did it with a loop was because I'm only testing the last 100 bars by default, and not all the bars on the chart. I will give it a try though...thanks. (Actually, I just realized that I am only testing 99 bars, but close enough.)

Bob

Reason: